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>
Replaces the free-text "Place of Delivery" with a dropdown sourced from a new
admin-managed Delivery Locations list (each = a Company FK + free-text address).
- schema + migration: new DeliveryLocation model (companyId, address, isActive).
- permission: manage_delivery_locations granted to Manager + SuperUser + Admin
(Manager-accessible, not admin-only, per the issue).
- admin screen /admin/delivery-locations: table + Add/Edit dialogs +
activate/deactivate + delete (mirrors /admin/sites); sidebar link under
Administration for Manager/SuperUser/Admin.
- PO forms (new / edit / manager-edit): shared <DeliveryLocationField> native
select populated from active locations, formatted "Company — address".
- PurchaseOrder.placeOfDelivery stays a free-text SNAPSHOT (no FK) — the dropdown
only changes how the value is picked, so export/import/historical POs are
unchanged, and an edit preserves a current value not in the list as a
"(current)" option. Deleting a location is therefore always safe.
- tests: delivery-location CRUD + permission guard (6).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Office/admin crewing-management surface behind a new manage_crew permission
(Manager + SuperUser + Admin). Stacks on 4b. Behind NEXT_PUBLIC_CREWING_ENABLED.
What's in
- Permission: manage_crew added to the §6 matrix (MGR/SU/ADMIN).
- Direct placement (placeCrew): a Manager assigns a crew member to a vessel/site
WITHOUT a requisition — creates an ACTIVE CrewAssignment, promotes a candidate to
EMPLOYEE with a CRW- number (generateEmployeeId), blocked if already actively
assigned.
- Admin crew CRUD: createCrewMember / updateCrewMember / deleteCrewMember (delete
blocked when assignments/applications exist).
- Crew strength config: upsert/delete VesselRankRequirement (the minStrength that
drives R6 leave-clash detection).
- Screens under Administration (flag-gated, MGR/SU/ADMIN): /admin/crew (list + add/
edit/delete + Place modal) and /admin/crew-strength (requirement table + form).
Tests & docs
- Unit: permissions-crewing.test.ts gains a manage_crew check. Integration:
crewing-admin.test.ts (9) — CRUD, delete guard, direct placement (+promotion,
+active-assignment guard), strength upsert/delete, manage_crew gating.
type-check clean; full unit (241) + integration (192) green.
- CLAUDE.md updated with the crewing-admin surface.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Gated behind NEXT_PUBLIC_SUBMITTER_VIEW_ALL_ENABLED (opt-in, "true").
When on, submitter roles (TECHNICAL/MANNING) get read-only access to every
PO: the History page + report export, any other user's PO detail page, and
the per-PO Export PDF/XLSX buttons. No approval/payment/edit rights are added.
- lib/feature-flags.ts: SUBMITTER_VIEW_ALL_ENABLED flag
- lib/permissions.ts: isSubmitterRole / submitterCanViewAll / canViewAllPos
- po/[id] page + export route: gate via canViewAllPos
- history page + reports/export route: OR submitterCanViewAll into export_reports
- sidebar: show History to submitters when flag on
- tests: permission helpers, both flag states
- docs: .env.example, CLAUDE.md (wiki updated separately)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Managers and superusers can cancel a PO from any state via a confirmation modal
that requires typing "cancel" and a mandatory reason. A cancelled PO becomes a
terminal CANCELLED state and drops out of every spend tracker/graph (those filter
on POST_APPROVAL_STATUSES / explicit whitelists, none of which include CANCELLED).
A cancelled PO may optionally be linked to the existing PO that supersedes it
(by PO number); the replacement shows the reciprocal "supersedes" link. No
vessel/account/vendor match is enforced and the link can be added any time.
Cancelled POs remain visible (greyed in history) and exportable, with a diagonal
"CANCELLED" watermark on both the PDF and XLSX exports.
- schema: POStatus CANCELLED; cancelledAt/cancellationReason; self-referential
supersededById relation; ActionType CANCELLED/SUPERSEDED (+ migration)
- state machine canCancel(); cancel_po permission (MANAGER + SUPERUSER)
- cancelPo / supersedePo server actions + PO_CANCELLED notification
- cancel modal + supersede form; cancelled banner with reciprocal links
- exhaustive CANCELLED entries in all status label/variant maps
- diagonal CANCELLED watermark embedded for PDF (CSS) and XLSX (image)
- integration tests (cancel from any state, reason/role guards, supersede)
Inventory reversal on cancel is deferred to #55 (inventory is feature-flagged off).
Closes#53
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Profile (fixes Safari/SSO no-password redirect):
- User lookup falls back to email when JWT id is stale (SSO users)
- generateDownloadUrl wrapped in try/catch so storage never crashes the page
- Signature gate now uses approve_po permission (approvers only)
- SSO/no-password users see a Set Password form (current-password field hidden)
Vendors:
- New create_vendor permission for all PO roles incl. submitters
- Submitters create UNVERIFIED vendors (no Vendor ID); simple form mode
- verifyVendor action + Verify menu item (manage_vendors)
- Vendors auto-verify when a PO closes with them (receipt confirm + import)
- Add Vendor button on /inventory/vendors
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
MANAGER had the Vessels link in the sidebar but lacked the permission,
causing a redirect to dashboard on click.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>