Skip to main content

The prompt

title: "Scaffold the country module and its resources"
context: |
  Build a `country` domain: a shared list of countries used as reference data
  (cities, addresses, currencies, dialing codes). Not user-owned — auth is
  role-based: any authenticated user reads and lists; only an admin
  creates/updates/deletes. Slugs and ISO codes are unique. If `modules/country/`
  already exists, this work is void — do not run.
goal: |
  Create the `country` module + needed resources, wired admin-only on mutations.

  ## Notes
  - If `modules/country/` exists, STOP and report. Else `/module:create` country,
    then build each resource via its `*:create` skill (`--module=country`),
    respecting controllers → services → repositories → entities, registering all.
  - Judge each resource; create the justified, skip the rest with a reason.
    Defaults: entity + repository always; service + controller per use case;
    permission always (admin-only guard on create/update/delete, read/list open
    to any authenticated user, reuse the permission service); seed if the project
    uses seeds (ISO 3166 list); migration/event/translation only if applicable
    (names are translation candidates); storage/queue/workflow skip.
  - Enforce uniqueness on both `slug` and `code`; throw a typed conflict (e.g.
    `CountryAlreadyExistsException`).
  - Throw typed exceptions (e.g. `CountryNotFoundException`), never return null.
  - Locating modules (e.g. `city`) reference this by relation, not copied codes.

  ### Data Model
  - `Country.cities` ↔ `City.country` — OneToMany / ManyToOne (inverse on `city`)
dod: |
  - [ ] Aborts with a report if `modules/country/` exists
  - [ ] `country` module created and registered into the app and `SharedModule`
  - [ ] `Country` entity with fields: `name`, `slug` (unique), `code` (ISO
    3166-1 alpha-2, unique), `code3` (alpha-3), `numericCode`, `callingCode`,
    `currency` (ISO 4217), `flag`, `continent`, `capital`, `lang` (`LocaleType`),
    `createdAt`, `updatedAt`
  - [ ] Full CRUD; any authenticated user reads/lists; only admin mutates;
    non-admin rejected on create/update/delete
  - [ ] Duplicate slug or code rejected
  - [ ] If seeds are used, the ISO 3166 list is seeded
  - [ ] Unneeded resources skipped and reported with a reason
  - [ ] `bun run fmt`, `bun run lint`, `bun run test` pass from the root