Create a Resource
Generate Note, install Workshop for one tenant, and create your first record.
Create a Resource
Add Note to Create an App Package, then create and edit a record in the tenant Shell. Run these commands from the Core root against a practice environment. The package must exist and its API route group must retain app.installed:workshop.
task artisan -- nexia-apps:make-package-resource workshop Note --record-owner=legal_entity --label-ko=노트 --label-zh=笔记 --dry-run
task artisan -- nexia-apps:make-package-resource workshop Note --record-owner=legal_entity --label-ko=노트 --label-zh=笔记
task artisan -- tenants:list --no-ansiReview the dry run before generation. Copy the practice tenant's ID, not its domain, from tenants:list; replace REPLACE_WITH_TENANT_ID below. If you need an empty tenant, create it in Central administration as described in Set up App development.
nexia_tenant=REPLACE_WITH_TENANT_ID
task artisan -- nexia-runtime:clear-translation-catalog-cache
task artisan -- nexia-apps:activate-package-app workshop
task artisan -- nexia-apps:install-dev-app workshop --tenant="$nexia_tenant" --dry-run
task artisan -- nexia-apps:install-dev-app workshop --tenant="$nexia_tenant" --with-prerequisites
task app:reload
docker compose restart vite
docker compose up --wait --no-deps viteAfter activation, the development command migrates and initializes Workshop and its prerequisites for the specified tenant, then enables them. It requires APP_ENV=local and an explicit --tenant. It does not require Central catalog registration or publication and leaves package readiness unchanged. Assign user access separately. Correct any failure and rerun the same command to retry. For production publication and installation, follow Release an App.
Verify in the tenant Shell
In Access Management, give your test user an App Role containing workshop.note.read, workshop.note.create, and workshop.note.update, with an appropriate Legal Entity Access Grant. Installation registers permissions but grants no user authority.
Open the practice tenant, launch Workshop, and choose Operations → Note. Select New Note, choose an authorized Legal Entity, enter a name and save. Open the list row's Inspector, detail and edit screens. The generated status is draft; the enum also contains active and archived. Delete is scaffolded but the default Policy denies it until you define retention and audit rules.
Locate the code
All paths below are relative to Workshop:
| Path | Responsibility |
|---|---|
database/migrations/tenant/*_create_wsp_notes_table.php | Tenant table, UUID and indexes |
src/Models/Note.php | Persistence, list fields and visibility |
src/Enums/NoteStatus.php | Status values and localized labels |
src/Http/Controllers/NoteController.php | Validation, authorized queries and API responses |
src/Policies/NotePolicy.php | Action and record authorization |
src/Contribution/Resources/NoteModule.php | Descriptor, permissions, navigation and Shell contract |
resources/js/resources/notes/ | Contract, information schema, surfaces, sections and Inspector |
tests/Feature/NoteAuthorizationTest.php | Generated authorization declaration check |
The generator also updates App routes, the Manifest and locale catalogs. Keep its registration markers. The frontend entry discovers Resource inspectors; the Overview remains yours to design.
The canonical API collection is /api/workshop/notes. List targets use legal_entity_public_ids[]; creation takes one legal_entity_public_id. Detail and edit identify the Note by public UUID and restore its stored owner. Do not take record ownership from Shell-global state.
Choose ownership for another Resource
--record-owner | Use for | Scope UI |
|---|---|---|
legal_entity (default) | Records owned by one Legal Entity | Page-owned list selector; explicit create target |
tenant | Standard common data shared by a tenant | No organization selector |
These are the only accepted values. A singleton setting or a child row inside a parent does not automatically need a generated top-level Resource. Keep custom authorization explicit when neither standard profile fits.
A Resource Module publishes a stable key such as workshop.note, a public descriptor, its authorization contract and navigation. publicForBuilder opts into discovery but does not bypass actor authorization or descriptor eligibility. Set it to false for internal ledgers and attempts. See Resource contracts for the full declaration and generator options.
Add your first field
Continue with Data Model and Migrations to add category through storage, validation, API, form and list. Then use Test an App to check both allowed and refused requests. A successful package doctor confirms wiring; it does not prove those behaviors.