# Decided layout

Every project has the same shape at every size. The root holds a fixed set
of files and folders. All application code lives in domains under
`domains/`, one level deep, and every domain contains the same fixed
folders, with no subfolders. A file's path follows from two facts: its
domain and what kind of declaration it is.

A small app:

```text
app.jadpo                  application, principal, health, readiness, language version
config.jadpo               configuration: names, types, bindings, defaults
authentication.jadpo       authentication methods and their failures
policy.jadpo               application-wide policy, such as tenancy
jadpo.lock                 installed packages: version, source and digest
packages/                  installed packages, committed and read-only
api/
  main.jadpo_record        the public API record
domains/
  planning/
    entities/
      todo.jadpo           Todo: fields, unique rules, lifecycle, policy
      todo.test.jadpo      its tests, beside it
      user.jadpo
      service.jadpo
      service_credential.jadpo
    types/
      todo_view.jadpo      shared within the domain: used by more than one file
    queries/
      todos_for_owner.jadpo     every query, one per file
    actions/
      complete_todo.jadpo       every action, one per file
      send_due_reminders.jadpo
    failures/
      todo_not_found.jadpo      every failure, one per file
    routes/
      todos.jadpo          route group Todos, prefix /todos: every /todos route
      todos.test.jadpo
      users.jadpo
    schedules/
      overdue_reminders.jadpo
database/
  identities.jadpo_record  stable identity of every renamed table, column and declaration
  migrations/
    20261012T0930_initial/
build/                     generated output, never committed
```

The same rules for a large application, with most of the folders a project
can have:

```text
app.jadpo  config.jadpo  authentication.jadpo  policy.jadpo  flags.jadpo  jadpo.lock
shared/
  types/          stock.jadpo  country_code.jadpo  address.jadpo
  libraries/      rounding.jadpo
  translations/   order_reference.jadpo  en_gb.jadpo  de_de.jadpo  sources.jadpo_record
  emails/         layout.html  layout.txt  button.jadpo  button.html  button.txt
  providers/      acme_couriers/v1/          the app's own integration, in the package format
packages/         stripe/v2024_06_20/  postcodes/v2/   installed: in jadpo.lock, read-only
api/              main.jadpo_record  admin.jadpo_record
acceptances/      20261020T1400_remove_todo_priority.jadpo
domains/
  ordering/
    entities/     cart.jadpo  order.jadpo  order.test.jadpo
    actions/      checkout.jadpo
    queries/      order_history.jadpo
    routes/       orders.jadpo  admin_orders.jadpo
    events/       order_event.jadpo
    subscribers/  cancel_unpaid_orders.jadpo
    schedules/    expire_quotes.jadpo
    fixtures/     sample_catalogue.jadpo
    translations/ order_shipped.jadpo  en_gb.jadpo  de_de.jadpo  sources.jadpo_record
    prompts/      suggest_gift_note.jadpo  suggest_gift_note.prompt
    documents/    invoice_document.jadpo  invoice_document.html
  inventory/
    actions/      reserve_stock.jadpo        public: called by checkout in one transaction
  payments/
    subscribers/  payment_succeeded.jadpo    on Stripe.events.PaymentIntentSucceeded
  notifications/
    subscribers/  send_order_confirmation.jadpo
  catalogue/  fulfilment/  identity/
database/
  identities.jadpo_record
  migrations/     20260901T1000_initial/  20261012T0930_add_order_channel/
  seeds/          local_demo.jadpo
translations/     fr_fr.jadpo        the app's wording for Jadpo's and packages' text
tests/            checkout_to_delivery.test.jadpo
build/
```
