feat(permissions): carve out dedicated payments resource

Payments (deposit / balance / refund records on an interest) used to
share `invoices.record_payment`, which forces a port that doesn't
issue invoices at all to still navigate the invoicing permission
group to grant its sales reps payment-recording rights. Splitting
the resource lets admins gate the two surfaces independently.

The new resource has three actions:
  - view   — gates the UI affordance (API reads still go through
             `interests.view`)
  - record — POST / PATCH a payment
  - delete — DELETE a payment record

Seed maps updated for all six system roles; existing role rows +
per-user permission overrides are backfilled by migration 0064 so
upgrades don't silently lose access. Two call sites (POST /interests/
[id]/payments, PATCH /payments/[id]) → payments.record; one
(DELETE /payments/[id]) → payments.delete. The PermissionGates on the
payments-section UI swap to the new keys.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-14 03:46:01 +02:00
parent 6b28459c45
commit 905852b8a5
10 changed files with 64 additions and 5 deletions

View File

@@ -59,6 +59,7 @@ const DEFAULT_PERMISSIONS: Record<string, Record<string, boolean>> = {
record_payment: false,
export: false,
},
payments: { view: false, record: false, delete: false },
files: { view: false, upload: false, edit: false, delete: false, manage_folders: false },
email: { view: false, send: false, configure_account: false },
reminders: {
@@ -105,6 +106,7 @@ const GROUP_LABELS: Record<string, string> = {
documents: 'Documents',
expenses: 'Expenses',
invoices: 'Invoices',
payments: 'Payments',
files: 'Files',
email: 'Email',
reminders: 'Reminders',