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:
@@ -26,7 +26,7 @@ export const GET = withAuth(
|
||||
);
|
||||
|
||||
export const POST = withAuth(
|
||||
withPermission('invoices', 'record_payment', async (req, ctx, params) => {
|
||||
withPermission('payments', 'record', async (req, ctx, params) => {
|
||||
try {
|
||||
// Body's interestId must match the URL param — defense-in-depth against
|
||||
// a client that sends one ID in the URL but another in the body.
|
||||
|
||||
@@ -7,7 +7,7 @@ import { updatePaymentSchema } from '@/lib/validators/payments';
|
||||
import { deletePayment, updatePayment } from '@/lib/services/payments.service';
|
||||
|
||||
export const PATCH = withAuth(
|
||||
withPermission('invoices', 'record_payment', async (req, ctx, params) => {
|
||||
withPermission('payments', 'record', async (req, ctx, params) => {
|
||||
try {
|
||||
const body = await parseBody(req, updatePaymentSchema);
|
||||
const payment = await updatePayment(params.id!, ctx.portId, body, {
|
||||
@@ -24,7 +24,7 @@ export const PATCH = withAuth(
|
||||
);
|
||||
|
||||
export const DELETE = withAuth(
|
||||
withPermission('invoices', 'record_payment', async (_req, ctx, params) => {
|
||||
withPermission('payments', 'delete', async (_req, ctx, params) => {
|
||||
try {
|
||||
await deletePayment(params.id!, ctx.portId, {
|
||||
userId: ctx.userId,
|
||||
|
||||
Reference in New Issue
Block a user