docs: reflect data-model refactor in CLAUDE.md + DB schema overview
All checks were successful
Build & Push Docker Images / lint (pull_request) Successful in 1m2s
Build & Push Docker Images / build-and-push (pull_request) Has been skipped

PR 15 (docs): the numbered spec files mostly described the new model
already at the conceptual level, but two needed concrete updates:

- 07-DATABASE-SCHEMA.md: schema overview now lists the new Yacht /
  Company / Reservation domains alongside the existing ones, names the
  partial unique indexes (idx_yoh_active, idx_br_active) that enforce
  exclusivity, and notes that yacht/company details are no longer
  stored on `clients`.
- CLAUDE.md: the Conventions section now points future contributors at
  the new schema files, the polymorphic ownership pattern, the
  EoiContext/dual-path EOI flow, and the merge-token allow-list. Adds
  a pointer to the husky `.env*` block so it doesn't trip people up.
  References the new field-mapping doc and `assets/README.md`.

Task 15.3 (Tier 4 golden-image PDF regression) is deferred — those
tests need committed reference PDFs that come out of a real, manually
verified EOI render. Best landed once the actual `assets/eoi-template.pdf`
is in place; tracking as a follow-up.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
Matt Ciaccio
2026-04-26 14:14:34 +02:00
parent 4c67b9dbd4
commit 4da8ed3ae4
2 changed files with 42 additions and 5 deletions

View File

@@ -20,16 +20,42 @@
### Client Domain ### Client Domain
- `clients` — Anchor records for people/entities - `clients` — Anchor records for people/entities. Yacht and company details
are no longer stored here — see the Yacht and Company domains.
- `client_contacts` — Multi-channel contact entries per client - `client_contacts` — Multi-channel contact entries per client
- `client_addresses` — Physical addresses per client (primary + others)
- `client_relationships` — Relationships between clients (referrals, broker, family) - `client_relationships` — Relationships between clients (referrals, broker, family)
- `client_notes` — Timestamped notes on clients - `client_notes` — Timestamped notes on clients
- `client_tags` — Tags assigned to clients - `client_tags` — Tags assigned to clients
- `client_merge_log` — Audit trail of client merges - `client_merge_log` — Audit trail of client merges
### Yacht Domain
- `yachts` — First-class yacht records. Polymorphic ownership via
`current_owner_type` (`'client' | 'company'`) + `current_owner_id`.
- `yacht_ownership_history` — Append-only log of every transfer; partial
unique index `idx_yoh_active` enforces a single active owner per yacht.
- `yacht_notes`, `yacht_tags` — Notes / tags on yachts.
### Company Domain
- `companies` — Legal entities that may own yachts or be billed.
- `company_addresses` — Addresses per company.
- `company_memberships` — Active client ↔ company links with role
(director / shareholder / beneficial_owner / authorised_signatory),
start/end dates.
### Reservation Domain
- `berth_reservations` — Concrete client + yacht + berth holds with
start/end dates and status. Partial unique index `idx_br_active`
enforces one active reservation per berth.
### Interest Domain ### Interest Domain
- `interests` — Per-berth pipeline records, each belonging to a client (milestone dates are inline columns) - `interests` — Per-berth pipeline records. Each row references a
`client_id`, `yacht_id` (the yacht in scope for the inquiry), and
optional `berth_id`. Milestone dates are inline columns.
- `interest_notes` — Timestamped notes on interests - `interest_notes` — Timestamped notes on interests
- `interest_tags` — Tags assigned to interests - `interest_tags` — Tags assigned to interests

View File

@@ -70,10 +70,13 @@ src/
- **Formatting:** Prettier - single quotes, semicolons, trailing commas, 2-space indent, 100 char line width. - **Formatting:** Prettier - single quotes, semicolons, trailing commas, 2-space indent, 100 char line width.
- **Lint:** ESLint flat config extending `next/core-web-vitals`, `next/typescript`, `prettier`. Unused vars prefixed with `_` are allowed. - **Lint:** ESLint flat config extending `next/core-web-vitals`, `next/typescript`, `prettier`. Unused vars prefixed with `_` are allowed.
- **Imports:** Use `@/*` path alias (maps to `src/*`). - **Imports:** Use `@/*` path alias (maps to `src/*`).
- **Components:** shadcn/ui pattern - base components in `src/components/ui/`, domain components in `src/components/[domain]/`. - **Components:** shadcn/ui pattern - base components in `src/components/ui/`, domain components in `src/components/[domain]/`. Yacht / company / reservation domains live in `components/yachts`, `components/companies`, `components/reservations` respectively.
- **DB schema:** One file per domain in `src/lib/db/schema/`, re-exported from `index.ts`. Relations in `relations.ts`. - **DB schema:** One file per domain in `src/lib/db/schema/`, re-exported from `index.ts`. Relations in `relations.ts`. Domain files include `clients.ts`, `yachts.ts`, `companies.ts`, `reservations.ts`, `interests.ts`, `berths.ts`, `documents.ts`, `invoices.ts`, etc.
- **Polymorphic ownership:** Yachts and invoice billing-entities use `<entity>_type` + `<entity>_id` column pairs (`'client' | 'company'`). Resolve owner identity through `src/lib/services/yachts.service.ts` / `eoi-context.ts` rather than reading the columns ad hoc — those services apply the type discriminator.
- **EOI generation:** Two pathways share the same `EoiContext` (`src/lib/services/eoi-context.ts`). Documenso pathway calls the template-generate endpoint via `documenso-payload.ts`; in-app pathway fills the same source PDF (`assets/eoi-template.pdf`) via `src/lib/pdf/fill-eoi-form.ts` (pdf-lib AcroForm). Routed through `generateAndSign(...)` in `src/lib/services/document-templates.ts` with a `pathway` parameter.
- **Merge fields:** Token catalog lives in `src/lib/templates/merge-fields.ts`; the `createTemplateSchema` validator uses `VALID_MERGE_TOKENS` as an allow-list, so unknown tokens are rejected at template creation time.
- **Routes:** Multi-tenant via `[portSlug]` dynamic segment. Typed routes enabled. - **Routes:** Multi-tenant via `[portSlug]` dynamic segment. Typed routes enabled.
- **Pre-commit:** Husky + lint-staged runs ESLint fix + Prettier on staged `.ts`/`.tsx` files. - **Pre-commit:** Husky + lint-staged runs ESLint fix + Prettier on staged `.ts`/`.tsx` files. The hook also blocks `.env*` files (including `.env.example`) from being committed; pass them via a separate workflow if needed.
## Environment ## Environment
@@ -89,3 +92,11 @@ Copy `.env.example` to `.env` for local dev. See `src/lib/env.ts` for the full s
## Architecture docs ## Architecture docs
Numbered spec files in repo root (`01-CONSOLIDATED-SYSTEM-SPEC.md` through `15-DESIGN-TOKENS.md`) contain detailed architecture decisions, feature specs, DB schema docs, API catalog, and implementation sequence. Numbered spec files in repo root (`01-CONSOLIDATED-SYSTEM-SPEC.md` through `15-DESIGN-TOKENS.md`) contain detailed architecture decisions, feature specs, DB schema docs, API catalog, and implementation sequence.
Domain-specific references:
- `docs/eoi-documenso-field-mapping.md` — canonical mapping from `EoiContext`
paths to the Documenso template's `formValues` keys, with the matching
AcroForm field names used by the in-app pathway.
- `assets/README.md` — what the in-app EOI source PDF must contain and how
to override its path in dev/test.