Adds assertResidentialModuleEnabled(ctx.portId) as the first statement in every residential v1 handler (24 handlers across 13 files), mirroring the Tenancies pattern. Previously the disabled-module state was enforced only in the page layout, so a disabled module still accepted API writes (including partner-forward emails on residential interest creation). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
52 lines
1.9 KiB
TypeScript
52 lines
1.9 KiB
TypeScript
import { NextResponse } from 'next/server';
|
|
import { and, eq, or, sql } from 'drizzle-orm';
|
|
|
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
|
import { db } from '@/lib/db';
|
|
import { roles, user, userPortRoles } from '@/lib/db/schema/users';
|
|
import { errorResponse } from '@/lib/errors';
|
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
|
|
|
/**
|
|
* Returns the set of users in the current port who can be assigned a
|
|
* residential interest. A user qualifies when ANY of their port-role
|
|
* grants either:
|
|
* - role.permissions.residential_interests.view = true, OR
|
|
* - role.permissions.residential_clients.view = true, OR
|
|
* - the per-user `residentialAccess` toggle is set on this port
|
|
*
|
|
* Used by the residential-interest detail page's "Assigned to" picker.
|
|
* Returns minimal `{ id, name, email }` rows so the dropdown stays
|
|
* fast and the JSON payload doesn't leak more than the picker needs.
|
|
*/
|
|
export const GET = withAuth(
|
|
withPermission('residential_interests', 'view', async (_req, ctx) => {
|
|
try {
|
|
await assertResidentialModuleEnabled(ctx.portId);
|
|
const rows = await db
|
|
.selectDistinct({
|
|
id: user.id,
|
|
name: user.name,
|
|
email: user.email,
|
|
})
|
|
.from(userPortRoles)
|
|
.innerJoin(roles, eq(roles.id, userPortRoles.roleId))
|
|
.innerJoin(user, eq(user.id, userPortRoles.userId))
|
|
.where(
|
|
and(
|
|
eq(userPortRoles.portId, ctx.portId),
|
|
or(
|
|
eq(userPortRoles.residentialAccess, true),
|
|
sql`${roles.permissions}->'residential_interests'->>'view' = 'true'`,
|
|
sql`${roles.permissions}->'residential_clients'->>'view' = 'true'`,
|
|
)!,
|
|
),
|
|
)
|
|
.orderBy(user.name);
|
|
return NextResponse.json({ data: rows });
|
|
} catch (error) {
|
|
return errorResponse(error);
|
|
}
|
|
}),
|
|
);
|