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

# Repository structure

> The categories, kind folders, banned folders, file suffixes and test tiers every member follows, generated from tools/scripts/structure.mjs.

The rules below are the single source for the scaffold (`pnpm new`) and the validator (`pnpm validate`). Each row names the ADR, or the settlement item, it comes from.

## Package categories

A package lives at `packages/<category>/<name>`. Tooling presets live at `packages/tooling/<name>` and carry `tier:config`.

| Category | Holds | Source |
| - | - | - |
| `foundation` | contracts, validation and errors every layer imports | ADR 0127 |
| `application` | actions, AI, IR and the registry | ADR 0127 |
| `communication` | webhooks, notifications, versioning and integrations | ADR 0127 |
| `commerce` | money, ledger and pricing primitives | ADR 0127 |
| `cross-cutting` | brand and concerns that span layers (settlement Q3.1) | ADR 0127 |
| `data` | model, database, content, media, search, assets, filesystem, storage | ADR 0127 |
| `developer` | CLI, gen, coding standard and the Vite plugin | ADR 0127 |
| `experience` | UI, experience, navigation, console and panel | ADR 0127 |
| `infrastructure` | Pulumi-based packages named `infra-<name>` | ADR 0127 |
| `runtime` | outbox, queue, scheduler, workflow, realtime, locking and cache | ADR 0127 |
| `security` | identity, IAM, tenancy, connections, entitlements and licensing | ADR 0127 |
| `state` | settings, feature flags and theming | ADR 0127 |
| `tooling` | build, lint and test presets with no workspace dependencies (tier:config) | ADR 0003 |

## Package entries

Core `.` is always present. Other entries are added only with real code (ADR 0126).

| Entry | Holds | Source |
| - | - | - |
| `contracts` | vocabulary only: types, as-const objects and tokens | ADR 0117 |
| `node` | code that needs Node built-ins | ADR 0126 |
| `react` | React components and hooks | ADR 0126 |
| `native` | React Native code | ADR 0126 |
| `testing` | test helpers and fakes for consumers | ADR 0126 |
| `devtools` | developer tooling, only with real code | ADR 0126 |

## Kind folders

Code of a module sits in these folders under `src/`. A file's suffix names its kind; the test column is the tier its file needs.

| Folder | File suffix | Required test | Holds | Source |
| - | - | - | - | - |
| `actions` | `*.action.ts` | `unit` | one action per file; its test covers the happy path and one refusal | ADR 0098 |
| `queries` | `*.query.ts` | `unit` | read-only operations | ADR 0126 |
| `models` | `*.model.ts` | `int` | persistence models; their tests need the real database | ADR 0014 |
| `migrations` | `*.migration.ts` | none | schema changes, applied in order | ADR 0014 |
| `seeds` | `*.seed.ts` | none | seed data for local and test databases | ADR 0014 |
| `factories` | `*.factory.ts` | none | test-data factories | ADR 0022 |
| `policies` | `*.policy.ts` | `unit` | authorisation rules, one case per verb | ADR 0130 |
| `permissions` | `*.permission.ts` | `contract` | declared permission names, covered by the member manifest test | ADR 0130 |
| `settings` | `*.setting.ts` | `contract` | declared settings, covered by the member manifest test | ADR 0130 |
| `events` | `*.event.ts` | `contract` | versioned event declarations, covered by the member manifest test | ADR 0141 |
| `listeners` | `*.listener.ts` | `unit` | @OnEvent handlers, one toEmit case each | ADR 0264 d8 |
| `workflows` | `*.workflow.ts` | `int` | durable, compensating workflows | ADR 0130 |
| `services` | `*.service.ts` | `unit` | application services that actions and listeners depend on | ADR 0264 d10 |
| `hooks` | `*.hook.ts` | `unit` | extension hooks only; React hooks are `use-*.ts` files, not a folder | ADR 0264 d7 |
| `links` | `*.link.ts` | none | named links between modules (purpose not yet specified) | ADR 0264 d7 |
| `drivers` | `*.driver.ts` | `unit` | port drivers; the memory driver is unit, a real one also needs int | ADR 0264 d7 |
| `widgets` | `*.widget.ts` | `unit` | UI widgets; the test sits beside the component | ADR 0264 d7 |
| `pages` | `*.page.ts` | `unit` | route pages | ADR 0264 d7 |
| `resources` | `*.resource.ts` | `unit` | admin-UI @Resource declarations; the word resource is reserved for them | ADR 0234 |
| `ai` | none | none | AI code: prompts, tools and agents | ADR 0264 d7 |
| `raw` | none | `unit` | raw @Controller endpoints only: webhooks, streaming and the /api/auth paths; actions never use it | ADR 0130 |
| `decorators` | none | `unit` | decorator packages with their Explorer (backend-decorator-package skill) | ADR 0130 |
| `contracts` | none | `contract` | vocabulary under src/contracts/, used by the package entry of that name | ADR 0117 |
| `config` | `*.config.ts` | `contract` | typed configuration inside src/config/, not beside src | ADR 0025 |
| `interfaces` | `*.interface.ts` | `contract` | type-only shapes | ADR 0128 |
| `types` | `*.type.ts` | `contract` | type aliases and unions | ADR 0128 |
| `tokens` | `*.token.ts` | `contract` | DI tokens made with defineToken | ADR 0231 |
| `constants` | `*.constant.ts` | `contract` | module-level constants, SCREAMING\_SNAKE | ADR 0231 |
| `enums` | `*.enum.ts` | `contract` | const-object enums with a same-named union type; the enum keyword is banned | ADR 0128 d1 (file name only; no ADR names the folder) |
| `errors` | `*.error.ts` | `contract` | StackraError subclasses | ADR 0232 |
| `schemas` | `*.schema.ts` | `contract` | Zod schemas | ADR 0095 |
| `components` | none | `unit` | components as folders: `components/<name>/<name>.tsx` with its `__tests__` beside it | ADR 0128 |

Root module: `src/<name>.module.ts`, test `<name>.module.int.test.ts`, ADR 0090.

React hooks: `use-<name>.ts` beside their component, test `use-<name>.test.ts` (unit), ADR 0129. Extension hooks are the only `hooks/` files.

Static files: `assets/<kind>/` beside the root module (`public`, `lang`, `templates`, `stubs`, `data`), ADR 0234. static files shipped with a module; the word resource is reserved for @Resource.

## Banned folders

| Folder | Why | Source |
| - | - | - |
| `controllers` | raw endpoints live in raw/ only; actions are the unit | ADR 0130 |
| `dtos` | Zod schemas replace DTO classes | ADR 0095 |
| `repositories` | MikroORM models and queries replace repositories | ADR 0014 |
| `helpers` | name the kind the code serves instead | ADR 0126 |
| `utils` | shared pure functions go to @stackra/support or the kind they serve | ADR 0126 |
| `presentation` | there is no presentation layer folder | ADR 0130 |

## Test tiers

| Tier | File infix | Holds | Source |
| - | - | - | - |
| `unit` | `.test` | fast, no external services | ADR 0182 |
| `int` | `.int.test` | needs a real database or container | ADR 0182 |
| `contract` | `.contract.test` | checks a declared contract, such as the manifest | ADR 0182 |
| `load` | `.load.test` | k6 load tests, run weekly against staging | ADR 0182 |
| `e2e` | `.e2e.test` | runs a whole app | ADR 0022 |

Every test file sits directly in a `__tests__/` folder beside its subject (ADR 0022). `.spec.*` is not used.

## Documented exceptions

| Rule | Why | Source |
| - | - | - |
| App e2e: `apps/<app>/e2e/__tests__/<name>.e2e.test.ts` | app e2e lives in the app, a documented exception to the member test rule | ADR 0022 |
| Manifest contract test: `app-manifest.contract.test.ts` | gen does not exist before W6; flip required to true at M2; required from M2 | ADR 0182 |

## Forbidden files

| Name | Rule | Source |
| - | - | - |
| `stories` | no Storybook; test the component in `__tests__/` | ADR 0126 |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.