> ## Documentation Index
> Fetch the complete documentation index at: https://docs.ooneex.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Address Resource

> A ready-to-run spec that scaffolds the `address` module as private, user-owned postal data with a single default per user and owner/admin permissions on every operation.

## The prompt

```yaml theme={null}
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
  - 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.
  - Dependencies — `user`, `city`. Resolve before the `/module:create` step
    above: for each missing `modules/<dep>/`, create it FIRST from its prompt at
    https://docs.ooneex.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
```
