Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
359 changes: 126 additions & 233 deletions .agents/docs/architecture/auth-and-permissions.md

Large diffs are not rendered by default.

211 changes: 58 additions & 153 deletions .agents/docs/architecture/instrument-pipeline.md

Large diffs are not rendered by default.

218 changes: 38 additions & 180 deletions .agents/docs/architecture/runtime-and-vendor.md

Large diffs are not rendered by default.

265 changes: 99 additions & 166 deletions .agents/docs/architecture/testing-strategy.md

Large diffs are not rendered by default.

47 changes: 0 additions & 47 deletions .agents/docs/packages/esbuild-plugin-prisma.md

This file was deleted.

39 changes: 0 additions & 39 deletions .agents/docs/packages/eslint-config.md

This file was deleted.

83 changes: 29 additions & 54 deletions .agents/docs/packages/index.md
Original file line number Diff line number Diff line change
@@ -1,59 +1,34 @@
# Internal DNP packages

Open Data Capture depends on 11 `@douglasneuroinformatics/*` packages, maintained in separate repos and consumed from npm. Consult this before adding a third-party dependency or writing utility/crypto/stats/form-typing/UI code from scratch — one of these may already solve it.

Versions are pinned in the `catalog:` block of `pnpm-workspace.yaml`, except the three root-level dev tools, which are versioned directly in the root `package.json`.

### Config & build tooling

| Package | Purpose | Consumed by | Docs |
| --------------------- | ----------------------------------------------------- | ------------------------------- | ---------------------------------------------------- |
| eslint-config | ESLint flat-config factory for DNP TS/JS projects | `eslint.config.js` (root) | [eslint-config.md](eslint-config.md) |
| prettier-config | Prettier config factory + pre-commit binary | `prettier.config.js` (root) | [prettier-config.md](prettier-config.md) |
| tsconfig | Shared `tsconfig.json` base | `tsconfig.json` (root) | [tsconfig.md](tsconfig.md) |
| esbuild-plugin-prisma | Copies the Prisma query engine into an esbuild outdir | `apps/gateway/scripts/build.ts` | [esbuild-plugin-prisma.md](esbuild-plugin-prisma.md) |

### Utilities & single-purpose libraries

| Package | Purpose | Used here? | Docs |
| ---------------- | ------------------------------------------------------------ | ----------------------------------------------------- | ------------------------------------------ |
| libjs | Utility functions/types (arrays, dates, zod schemas, etc.) | yes — the most broadly depended-on DNP package here | [libjs.md](libjs.md) |
| libcrypto | Web Crypto API wrappers (hashing, hybrid encryption) | yes — `api`, `gateway`, `playground`, `subject-utils` | [libcrypto.md](libcrypto.md) |
| libpasswd | Password strength estimation (zxcvbn wrapper) | yes — `api` and `web`, password forms only | [libpasswd.md](libpasswd.md) |
| libstats | Basic stats in Rust/NAPI (sum, mean, std, linear regression) | yes — one call site in `api` | [libstats.md](libstats.md) |
| libui-form-types | Type-only declarative form schema (`FormTypes`) | yes — direct dependency of `packages/runtime-core` | [libui-form-types.md](libui-form-types.md) |

### Framework/UI (heavily used)

| Package | Purpose | Used here? | Docs |
| ------- | --------------------------------------------------------------------------------------- | ----------------------------------------------------- | ------------------------ |
| libnest | NestJS decorators/pipes/modules (config, prisma, mail, logging, crypto, virtualization) | yes — heavy, `api` only | [libnest.md](libnest.md) |
| libui | React/Tailwind UI components, hooks, providers | yes — heavy, every frontend surface plus `react-core` | [libui.md](libui.md) |
The 11 `@douglasneuroinformatics/*` packages, maintained in separate repos. Use this file to find
which one already does what you need, then read that package's source for the API. This file does
not copy APIs, because copies drift.

| Package | Reach for it when you need | Used in |
| ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `libjs` | array/object/string/date/number helpers, `Result` helpers over neverthrow, Zod coercers for env strings (`$BooleanLike`, `$NumberLike`, `$UrlLike`), `replacer`/`reviver` to round-trip `Date`/`Set`/`Map` through JSON, `formatError`/`serializeError` | api, web, schemas, react-core and most others |
| `libcrypto` | `sha256`, or hybrid public-key encryption (`HybridCrypto`, HPKE), in Node or the browser, instead of calling `crypto.subtle` | api, gateway, playground, subject-utils |
| `libpasswd` | password strength score plus EN/FR feedback (`estimatePasswordStrength`, wrapping zxcvbn-ts) | api, web |
| `libstats` | `sum`, `mean`, `std`, `linearRegression`. It is a Rust native addon, so it runs in Node only and never in a browser bundle | api |
| `libui-form-types` | the `FormTypes` declarative-form types. Instrument code uses runtime-core's `FormInstrument` types, which wrap these | runtime-core, and libui's `Form` |
| `libnest` | the Nest layer of `apps/api`: bootstrap, config, Prisma models, validation pipes, logging, crypto, virtualization, test doubles (`./testing`). `apps/api/AGENTS.md` covers how the app uses it | api |
| `libui` | React/Tailwind components, hooks (`useTranslation`, `useNotificationsStore`, …), `cn`, i18n, `CoreProvider`. It has no root export: import `./components`, `./hooks`, `./utils`, `./i18n`, `./providers` or `./tailwind/globals.css` | web, gateway, playground, outreach, react-core, serve-instrument |
| `eslint-config` | the `config()` factory behind the root `eslint.config.js` | root |
| `prettier-config` | `createConfig()` behind the root `prettier.config.js`, and the `prettier-pre-commit` bin that `.husky/pre-commit` runs | root |
| `tsconfig` | the base that the root `tsconfig.json` extends. It sets `noEmit: true`, so the `tsc` in every `lint` script only typechecks | root |
| `esbuild-plugin-prisma` | `prismaPlugin({ outdir })`, which copies Prisma's query engine next to an esbuild bundle | gateway's `scripts/build.ts` |

## Reading the source

These docs are hand-written snapshots and are **not** auto-synced with upstream. Treat them as a map, not an API reference: when you need an exact signature or a complete export list, read the installed package.

Every one of these packages is inspectable from `node_modules` — there is no need to clone a sibling repo. Fidelity varies:

| Fidelity | Packages | What you get |
| ------------------------------------------ | -------------------------------------------- | ----------------------------------------------------------------------------- |
| Original TypeScript source (`src/`) | `libnest`, `libui`, `libcrypto`, `libpasswd` | Full `.ts`/`.tsx` sources — these publish `src` alongside `dist` |
| Original JavaScript source (`src/`, JSDoc) | `prettier-config`, `esbuild-plugin-prisma` | Authored JSDoc-typed `.js` plus hand-written `.d.ts` |
| Compiled but unbundled and unminified | `libjs`, `eslint-config` | Readable per-module `.js` with JSDoc intact, plus `.d.ts` and `.d.ts.map` |
| The published file _is_ the source | `libui-form-types`, `tsconfig` | `lib/index.d.ts` / `tsconfig.json` — type-only and config-only packages |
| Opaque | `libstats` | Native `.node` binary; only the NAPI-generated `index.d.ts` describes the API |

Because this is a pnpm workspace, resolve a package through a workspace that depends on it, not through the repo root. Only `eslint-config`, `prettier-config`, and `tsconfig` are linked at the root:

```sh
# root-level dev tooling
ls node_modules/@douglasneuroinformatics/eslint-config/dist

# workspace-scoped dependencies
ls apps/api/node_modules/@douglasneuroinformatics/libnest/src
ls apps/web/node_modules/@douglasneuroinformatics/libui/src/components
ls packages/runtime-core/node_modules/@douglasneuroinformatics/libui-form-types/lib
```

Each package's doc gives its own read-the-source path. Export lists for the larger packages (`libnest`, `libui`) are illustrative, not exhaustive — check the source or the hosted docs before concluding something doesn't exist.
Resolve a package through a workspace in its "Used in" column. Only `eslint-config`,
`prettier-config` and `tsconfig` are linked at the repo root. For example:
`apps/api/node_modules/@douglasneuroinformatics/libnest/src/index.ts`.

- `libnest`, `libui`, `libcrypto`, `libpasswd`: original TypeScript under `src/`.
- `prettier-config`, `esbuild-plugin-prisma`: JSDoc-typed `.js` under `src/`, plus a hand-written
`.d.ts`.
- `libjs`, `eslint-config`: `dist/` only, but unbundled and unminified with JSDoc intact, one file
per module.
- `libui-form-types`, `tsconfig`: the published file is the whole package (`lib/index.d.ts`,
`tsconfig.json`).
- `libstats`: a native binary, so its `index.d.ts` is the complete API.
50 changes: 0 additions & 50 deletions .agents/docs/packages/libcrypto.md

This file was deleted.

Loading
Loading