feat(po): admin-managed Terms & Conditions catalogue + PO dropdowns (#11) #106

Merged
shad0w merged 2 commits from feat/terms-conditions-admin into master 2026-06-23 22:14:06 +00:00
Owner

Closes #11. (Per your steer: dropped the "work order" distinction — POs only.)

Summary

The PO Terms & Conditions fields are now sourced from an admin-managed clause catalogue, exactly the Place-of-Delivery (#19) pattern.

Admin

  • New TermsCondition model — category (TermsCategory enum) + text + isActive (schema + migration). The migration seeds the prior TC_DEFAULTS wording so the catalogue is usable immediately and the existing defaults stay selectable.
  • New permission manage_terms → Manager + SuperUser + Admin.
  • Admin screen at /admin/terms: searchable table + Add/Edit dialogs + activate/deactivate + delete (mirrors /admin/delivery-locations). Sidebar link under Administration.

PO forms

  • The five named T&C slots — Delivery / Dispatch / Inspection / Transit Insurance / Payment Terms — become a shared <TermsField> native <select> populated from the active clauses of that category (lib/terms.ts maps each tc* field → category; lib/terms-data.ts groups them). Applied to all three forms (new / edit / manager-edit).
  • "Others" stays free text, and the fixed boilerplate lines (TC_FIXED_LINE / TC_FIXED_LINE_2) are unchanged.

Design choice — snapshot, not FK

The tc* columns stay free-text snapshots: the dropdown only changes how a clause is picked, so the export, import, and historical POs are untouched. Editing a PO whose current clause isn't in the active list preserves it as a "(current)" option (no silent loss); deleting a clause is always safe.

Heads-up

The five named slots are now dropdowns (no per-PO free-typing), consistent with what you approved for Place of Delivery. If you'd rather they be pick-or-type comboboxes (so a one-off custom clause is still possible on a slot), that's a small follow-up — tell me and I'll switch <TermsField> to a combobox.

Tests

  • terms.test.ts (6): CRUD + the manage_terms guard + the active-only grouping helper.
  • Full integration suite green (263), tsc --noEmit clean.

Deploy

Adds migration 20260624140000_terms_conditions (table + enum + seed) → prisma migrate deploy. Applied to the local dev DB already.

🤖 Generated with Claude Code

Closes #11. (Per your steer: dropped the "work order" distinction — POs only.) ## Summary The PO **Terms & Conditions** fields are now sourced from an admin-managed clause catalogue, exactly the **Place-of-Delivery (#19)** pattern. ## Admin - New `TermsCondition` model — `category` (`TermsCategory` enum) + `text` + `isActive` (schema + migration). The migration **seeds** the prior `TC_DEFAULTS` wording so the catalogue is usable immediately and the existing defaults stay selectable. - New permission **`manage_terms`** → Manager + SuperUser + Admin. - Admin screen at **`/admin/terms`**: searchable table + Add/Edit dialogs + activate/deactivate + delete (mirrors `/admin/delivery-locations`). Sidebar link under **Administration**. ## PO forms - The **five named** T&C slots — Delivery / Dispatch / Inspection / Transit Insurance / Payment Terms — become a shared `<TermsField>` native `<select>` populated from the active clauses of that category (`lib/terms.ts` maps each `tc*` field → category; `lib/terms-data.ts` groups them). Applied to all three forms (new / edit / manager-edit). - **"Others" stays free text**, and the fixed boilerplate lines (`TC_FIXED_LINE` / `TC_FIXED_LINE_2`) are unchanged. ## Design choice — snapshot, not FK The `tc*` columns stay **free-text snapshots**: the dropdown only changes how a clause is *picked*, so the export, import, and historical POs are untouched. Editing a PO whose current clause isn't in the active list preserves it as a "(current)" option (no silent loss); deleting a clause is always safe. ## Heads-up The five named slots are now **dropdowns** (no per-PO free-typing), consistent with what you approved for Place of Delivery. If you'd rather they be **pick-or-type comboboxes** (so a one-off custom clause is still possible on a slot), that's a small follow-up — tell me and I'll switch `<TermsField>` to a combobox. ## Tests - `terms.test.ts` (6): CRUD + the `manage_terms` guard + the active-only grouping helper. - Full integration suite green (263), `tsc --noEmit` clean. ## Deploy Adds migration `20260624140000_terms_conditions` (table + enum + seed) → `prisma migrate deploy`. Applied to the local dev DB already. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
shad0w added 1 commit 2026-06-23 22:08:52 +00:00
feat(po): admin-managed Terms & Conditions catalogue + PO dropdowns (#11)
All checks were successful
PR checks / checks (pull_request) Successful in 43s
PR checks / integration (pull_request) Successful in 31s
a99b2ed5df
Mirrors the Place-of-Delivery (#19) pattern: an admin clause library that feeds
the PO T&C fields as dropdowns. (No "work order" type — POs only, per steer.)

- schema + migration: TermsCondition (category enum + text + isActive); the
  migration seeds the prior TC_DEFAULTS as the starting clauses.
- permission manage_terms (Manager + SuperUser + Admin).
- admin screen /admin/terms: table + Add/Edit dialogs + activate/deactivate +
  delete (mirrors /admin/delivery-locations); sidebar link under Administration.
- PO forms (new / edit / manager-edit): the five named T&C slots (Delivery /
  Dispatch / Inspection / Transit Insurance / Payment Terms) become a shared
  <TermsField> select sourced from active clauses of that category; "Others"
  stays free text; the fixed boilerplate lines are untouched.
- tc* columns stay free-text SNAPSHOTS (export/import unchanged); a current value
  not among active clauses is preserved as a "(current)" option.
- tests: terms CRUD + permission guard + grouping helper (6).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shad0w added 1 commit 2026-06-23 22:12:41 +00:00
feat(po): make TermsField a combobox (type-or-pick)
All checks were successful
PR checks / checks (pull_request) Successful in 43s
PR checks / integration (pull_request) Successful in 30s
f4c8ec7585
Per review: the five named PO T&C slots now allow a one-off custom clause as
well as picking a catalogued one. TermsField becomes a native <input list> +
<datalist> combobox (still plain FormData, no form/page changes). Any current/
custom value is preserved as the input value.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
shad0w merged commit fced7cc307 into master 2026-06-23 22:14:06 +00:00
Sign in to join this conversation.
No description provided.