title: "Scaffold the address module and its resources"
context: |
Build an `address` domain: private postal addresses owned by a user (billing,
shipping). Addresses are personal data, never readable by other users — auth
is owner-or-admin on EVERY operation, reads and lists included. Each user has
at most one default address. An address points at a shared `City` (city
module) for city/region/country/coordinates; it stores only street-specific
data. If `modules/address/` already exists, this work is void — do not run.
goal: |
Create the `address` module + needed resources, wired owner-or-admin on every op.
## Notes
- Run autonomously — do NOT ask the user questions. At every option or
judgment call, pick the recommended/default and proceed, reporting the
choices made in the final summary.
- If `modules/address/` exists, STOP and report. Else `/module:create` address,
then build each resource via its `*:create` skill (`--module=address`),
respecting controllers → services → repositories → entities, registering all.
- Destination — the `/module:create` step takes a `--destination` arg: pass
`app` when the project has a single `api` module; when it has several
`api`/`microservice` modules, infer the destination from this request.
- Dependencies — `user`, `city`. Resolve before the `/module:create` step
above: for each missing `modules/<dep>/`, create it FIRST from its prompt at
https://docs.talosjs.com/ai/prompts/resources/<dep>-resource (resolving its
own dependencies transitively).
- Judge each resource; create the justified, skip the rest with a reason.
Defaults: entity + repository always; service + controller per use case;
permission always (owner-or-admin on read, list, update, delete — reuse the
permission service, never hand-roll); migration if the project uses
migrations; seed if it uses seeds; event/queue/translation/storage/workflow —
skip (private data, no files, no lifecycle).
- Wire the `City` relation and reject an address whose `city` does not resolve;
do not duplicate city fields.
- Single default per user: on create/update with `isDefault` true, atomically
clear it on the user's other addresses.
- Throw typed exceptions (e.g. `AddressNotFoundException`), never return null;
another user's address must return the same not-found result.
### Data Model
- `Address.owner` ↔ `User.addresses` — ManyToOne / OneToMany
- `Address.city` ↔ `City.addresses` — ManyToOne / OneToMany
dod: |
- [ ] Aborts with a report if `modules/address/` exists
- [ ] Missing dependency modules (`user`, `city`) created first from their docs prompts
- [ ] `address` module created and registered into the app and `SharedModule`
- [ ] `Address` entity with fields: `label`, `type` (billing/shipping),
`recipient`, `phone`, `line1`, `line2` (nullable), `postalCode`, `city`
(City relation), `latitude`/`longitude` (nullable), `isDefault`, `owner`,
`createdAt`, `updatedAt`
- [ ] Full CRUD; user accesses only their own, admin any; another user's
address returns not-found
- [ ] References a `City`, not free-text geo; unresolved `city` rejected
- [ ] Setting default demotes the previous default
- [ ] Unneeded resources skipped and reported with a reason
- [ ] `bun run fmt`, `bun run lint`, `bun run test` pass from the root