Skip to content
Guide

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.

Code example
Shell
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-ansi

Review 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.

Code example
Shell
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 vite

After 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:

PathResponsibility
database/migrations/tenant/*_create_wsp_notes_table.phpTenant table, UUID and indexes
src/Models/Note.phpPersistence, list fields and visibility
src/Enums/NoteStatus.phpStatus values and localized labels
src/Http/Controllers/NoteController.phpValidation, authorized queries and API responses
src/Policies/NotePolicy.phpAction and record authorization
src/Contribution/Resources/NoteModule.phpDescriptor, permissions, navigation and Shell contract
resources/js/resources/notes/Contract, information schema, surfaces, sections and Inspector
tests/Feature/NoteAuthorizationTest.phpGenerated 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-ownerUse forScope UI
legal_entity (default)Records owned by one Legal EntityPage-owned list selector; explicit create target
tenantStandard common data shared by a tenantNo 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.

Source of truth: docs/developers/content/en/building-apps/create-a-resource.md