fix(audit): critical C3 — enforce residential module gate on all v1 API routes
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>
This commit is contained in:
@@ -5,6 +5,7 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { db } from '@/lib/db';
|
import { db } from '@/lib/db';
|
||||||
import { roles, user, userPortRoles } from '@/lib/db/schema/users';
|
import { roles, user, userPortRoles } from '@/lib/db/schema/users';
|
||||||
import { errorResponse } from '@/lib/errors';
|
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
|
* Returns the set of users in the current port who can be assigned a
|
||||||
@@ -21,6 +22,7 @@ import { errorResponse } from '@/lib/errors';
|
|||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_interests', 'view', async (_req, ctx) => {
|
withPermission('residential_interests', 'view', async (_req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const rows = await db
|
const rows = await db
|
||||||
.selectDistinct({
|
.selectDistinct({
|
||||||
id: user.id,
|
id: user.id,
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { db } from '@/lib/db';
|
import { db } from '@/lib/db';
|
||||||
import { residentialClients } from '@/lib/db/schema/residential';
|
import { residentialClients } from '@/lib/db/schema/residential';
|
||||||
import { loadEntityActivity } from '@/lib/services/entity-activity.service';
|
import { loadEntityActivity } from '@/lib/services/entity-activity.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse, NotFoundError } from '@/lib/errors';
|
import { errorResponse, NotFoundError } from '@/lib/errors';
|
||||||
|
|
||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_clients', 'view', async (_req, ctx, params) => {
|
withPermission('residential_clients', 'view', async (_req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
if (!id) throw new NotFoundError('residential client');
|
if (!id) throw new NotFoundError('residential client');
|
||||||
const exists = await db
|
const exists = await db
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { updateNoteSchema } from '@/lib/validators/notes';
|
import { updateNoteSchema } from '@/lib/validators/notes';
|
||||||
import * as notesService from '@/lib/services/notes.service';
|
import * as notesService from '@/lib/services/notes.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse, NotFoundError } from '@/lib/errors';
|
import { errorResponse, NotFoundError } from '@/lib/errors';
|
||||||
|
|
||||||
export const PATCH = withAuth(
|
export const PATCH = withAuth(
|
||||||
withPermission('residential_clients', 'edit', async (req, ctx, params) => {
|
withPermission('residential_clients', 'edit', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
const noteId = params.noteId;
|
const noteId = params.noteId;
|
||||||
if (!id || !noteId) throw new NotFoundError('Residential client note');
|
if (!id || !noteId) throw new NotFoundError('Residential client note');
|
||||||
@@ -24,6 +26,7 @@ export const PATCH = withAuth(
|
|||||||
export const DELETE = withAuth(
|
export const DELETE = withAuth(
|
||||||
withPermission('residential_clients', 'edit', async (_req, ctx, params) => {
|
withPermission('residential_clients', 'edit', async (_req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
const noteId = params.noteId;
|
const noteId = params.noteId;
|
||||||
if (!id || !noteId) throw new NotFoundError('Residential client note');
|
if (!id || !noteId) throw new NotFoundError('Residential client note');
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { createNoteSchema } from '@/lib/validators/notes';
|
import { createNoteSchema } from '@/lib/validators/notes';
|
||||||
import * as notesService from '@/lib/services/notes.service';
|
import * as notesService from '@/lib/services/notes.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse, NotFoundError } from '@/lib/errors';
|
import { errorResponse, NotFoundError } from '@/lib/errors';
|
||||||
|
|
||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_clients', 'view', async (req, ctx, params) => {
|
withPermission('residential_clients', 'view', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
if (!id) throw new NotFoundError('Residential client');
|
if (!id) throw new NotFoundError('Residential client');
|
||||||
const aggregate = new URL(req.url).searchParams.get('aggregate') === 'true';
|
const aggregate = new URL(req.url).searchParams.get('aggregate') === 'true';
|
||||||
@@ -25,6 +27,7 @@ export const GET = withAuth(
|
|||||||
export const POST = withAuth(
|
export const POST = withAuth(
|
||||||
withPermission('residential_clients', 'edit', async (req, ctx, params) => {
|
withPermission('residential_clients', 'edit', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
if (!id) throw new NotFoundError('Residential client');
|
if (!id) throw new NotFoundError('Residential client');
|
||||||
const body = await parseBody(req, createNoteSchema);
|
const body = await parseBody(req, createNoteSchema);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
import { withAuth, withPermission } from '@/lib/api/helpers';
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import {
|
import {
|
||||||
archiveResidentialClient,
|
archiveResidentialClient,
|
||||||
getResidentialClientById,
|
getResidentialClientById,
|
||||||
@@ -13,6 +14,7 @@ import { updateResidentialClientSchema } from '@/lib/validators/residential';
|
|||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_clients', 'view', async (req, ctx, params) => {
|
withPermission('residential_clients', 'view', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const client = await getResidentialClientById(params.id!, ctx.portId);
|
const client = await getResidentialClientById(params.id!, ctx.portId);
|
||||||
return NextResponse.json({ data: client });
|
return NextResponse.json({ data: client });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -24,6 +26,7 @@ export const GET = withAuth(
|
|||||||
export const PATCH = withAuth(
|
export const PATCH = withAuth(
|
||||||
withPermission('residential_clients', 'edit', async (req, ctx, params) => {
|
withPermission('residential_clients', 'edit', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const body = await parseBody(req, updateResidentialClientSchema);
|
const body = await parseBody(req, updateResidentialClientSchema);
|
||||||
const updated = await updateResidentialClient(params.id!, ctx.portId, body, {
|
const updated = await updateResidentialClient(params.id!, ctx.portId, body, {
|
||||||
userId: ctx.userId,
|
userId: ctx.userId,
|
||||||
@@ -41,6 +44,7 @@ export const PATCH = withAuth(
|
|||||||
export const DELETE = withAuth(
|
export const DELETE = withAuth(
|
||||||
withPermission('residential_clients', 'delete', async (req, ctx, params) => {
|
withPermission('residential_clients', 'delete', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
await archiveResidentialClient(params.id!, ctx.portId, {
|
await archiveResidentialClient(params.id!, ctx.portId, {
|
||||||
userId: ctx.userId,
|
userId: ctx.userId,
|
||||||
portId: ctx.portId,
|
portId: ctx.portId,
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
import { withAuth, withPermission } from '@/lib/api/helpers';
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||||
import { parseQuery, parseBody } from '@/lib/api/route-helpers';
|
import { parseQuery, parseBody } from '@/lib/api/route-helpers';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import {
|
import {
|
||||||
createResidentialClient,
|
createResidentialClient,
|
||||||
listResidentialClients,
|
listResidentialClients,
|
||||||
@@ -15,6 +16,7 @@ import {
|
|||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_clients', 'view', async (req, ctx) => {
|
withPermission('residential_clients', 'view', async (req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const query = parseQuery(req, listResidentialClientsSchema);
|
const query = parseQuery(req, listResidentialClientsSchema);
|
||||||
const result = await listResidentialClients(ctx.portId, query);
|
const result = await listResidentialClients(ctx.portId, query);
|
||||||
const { page, limit } = query;
|
const { page, limit } = query;
|
||||||
@@ -39,6 +41,7 @@ export const GET = withAuth(
|
|||||||
export const POST = withAuth(
|
export const POST = withAuth(
|
||||||
withPermission('residential_clients', 'create', async (req, ctx) => {
|
withPermission('residential_clients', 'create', async (req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const body = await parseBody(req, createResidentialClientSchema);
|
const body = await parseBody(req, createResidentialClientSchema);
|
||||||
const client = await createResidentialClient(ctx.portId, body, {
|
const client = await createResidentialClient(ctx.portId, body, {
|
||||||
userId: ctx.userId,
|
userId: ctx.userId,
|
||||||
|
|||||||
@@ -5,11 +5,13 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { db } from '@/lib/db';
|
import { db } from '@/lib/db';
|
||||||
import { residentialInterests } from '@/lib/db/schema/residential';
|
import { residentialInterests } from '@/lib/db/schema/residential';
|
||||||
import { loadEntityActivity } from '@/lib/services/entity-activity.service';
|
import { loadEntityActivity } from '@/lib/services/entity-activity.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse, NotFoundError } from '@/lib/errors';
|
import { errorResponse, NotFoundError } from '@/lib/errors';
|
||||||
|
|
||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_interests', 'view', async (_req, ctx, params) => {
|
withPermission('residential_interests', 'view', async (_req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
if (!id) throw new NotFoundError('residential interest');
|
if (!id) throw new NotFoundError('residential interest');
|
||||||
const exists = await db
|
const exists = await db
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { updateNoteSchema } from '@/lib/validators/notes';
|
import { updateNoteSchema } from '@/lib/validators/notes';
|
||||||
import * as notesService from '@/lib/services/notes.service';
|
import * as notesService from '@/lib/services/notes.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse, NotFoundError } from '@/lib/errors';
|
import { errorResponse, NotFoundError } from '@/lib/errors';
|
||||||
|
|
||||||
export const PATCH = withAuth(
|
export const PATCH = withAuth(
|
||||||
withPermission('residential_interests', 'edit', async (req, ctx, params) => {
|
withPermission('residential_interests', 'edit', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
const noteId = params.noteId;
|
const noteId = params.noteId;
|
||||||
if (!id || !noteId) throw new NotFoundError('Residential interest note');
|
if (!id || !noteId) throw new NotFoundError('Residential interest note');
|
||||||
@@ -24,6 +26,7 @@ export const PATCH = withAuth(
|
|||||||
export const DELETE = withAuth(
|
export const DELETE = withAuth(
|
||||||
withPermission('residential_interests', 'edit', async (_req, ctx, params) => {
|
withPermission('residential_interests', 'edit', async (_req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
const noteId = params.noteId;
|
const noteId = params.noteId;
|
||||||
if (!id || !noteId) throw new NotFoundError('Residential interest note');
|
if (!id || !noteId) throw new NotFoundError('Residential interest note');
|
||||||
|
|||||||
@@ -4,11 +4,13 @@ import { withAuth, withPermission } from '@/lib/api/helpers';
|
|||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { createNoteSchema } from '@/lib/validators/notes';
|
import { createNoteSchema } from '@/lib/validators/notes';
|
||||||
import * as notesService from '@/lib/services/notes.service';
|
import * as notesService from '@/lib/services/notes.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse, NotFoundError } from '@/lib/errors';
|
import { errorResponse, NotFoundError } from '@/lib/errors';
|
||||||
|
|
||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_interests', 'view', async (_req, ctx, params) => {
|
withPermission('residential_interests', 'view', async (_req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
if (!id) throw new NotFoundError('Residential interest');
|
if (!id) throw new NotFoundError('Residential interest');
|
||||||
const notes = await notesService.listForEntity(ctx.portId, 'residential_interests', id);
|
const notes = await notesService.listForEntity(ctx.portId, 'residential_interests', id);
|
||||||
@@ -22,6 +24,7 @@ export const GET = withAuth(
|
|||||||
export const POST = withAuth(
|
export const POST = withAuth(
|
||||||
withPermission('residential_interests', 'edit', async (req, ctx, params) => {
|
withPermission('residential_interests', 'edit', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const id = params.id;
|
const id = params.id;
|
||||||
if (!id) throw new NotFoundError('Residential interest');
|
if (!id) throw new NotFoundError('Residential interest');
|
||||||
const body = await parseBody(req, createNoteSchema);
|
const body = await parseBody(req, createNoteSchema);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
import { withAuth, withPermission } from '@/lib/api/helpers';
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import {
|
import {
|
||||||
archiveResidentialInterest,
|
archiveResidentialInterest,
|
||||||
getResidentialInterestById,
|
getResidentialInterestById,
|
||||||
@@ -13,6 +14,7 @@ import { updateResidentialInterestSchema } from '@/lib/validators/residential';
|
|||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_interests', 'view', async (req, ctx, params) => {
|
withPermission('residential_interests', 'view', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const interest = await getResidentialInterestById(params.id!, ctx.portId);
|
const interest = await getResidentialInterestById(params.id!, ctx.portId);
|
||||||
return NextResponse.json({ data: interest });
|
return NextResponse.json({ data: interest });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
@@ -24,6 +26,7 @@ export const GET = withAuth(
|
|||||||
export const PATCH = withAuth(
|
export const PATCH = withAuth(
|
||||||
withPermission('residential_interests', 'edit', async (req, ctx, params) => {
|
withPermission('residential_interests', 'edit', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const body = await parseBody(req, updateResidentialInterestSchema);
|
const body = await parseBody(req, updateResidentialInterestSchema);
|
||||||
const updated = await updateResidentialInterest(params.id!, ctx.portId, body, {
|
const updated = await updateResidentialInterest(params.id!, ctx.portId, body, {
|
||||||
userId: ctx.userId,
|
userId: ctx.userId,
|
||||||
@@ -41,6 +44,7 @@ export const PATCH = withAuth(
|
|||||||
export const DELETE = withAuth(
|
export const DELETE = withAuth(
|
||||||
withPermission('residential_interests', 'delete', async (req, ctx, params) => {
|
withPermission('residential_interests', 'delete', async (req, ctx, params) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
await archiveResidentialInterest(params.id!, ctx.portId, {
|
await archiveResidentialInterest(params.id!, ctx.portId, {
|
||||||
userId: ctx.userId,
|
userId: ctx.userId,
|
||||||
portId: ctx.portId,
|
portId: ctx.portId,
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { z } from 'zod';
|
|||||||
import { withAuth } from '@/lib/api/helpers';
|
import { withAuth } from '@/lib/api/helpers';
|
||||||
import { parseBody } from '@/lib/api/route-helpers';
|
import { parseBody } from '@/lib/api/route-helpers';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import {
|
import {
|
||||||
archiveResidentialInterest,
|
archiveResidentialInterest,
|
||||||
updateResidentialInterest,
|
updateResidentialInterest,
|
||||||
@@ -48,6 +49,7 @@ const PERMISSION_BY_ACTION: Record<
|
|||||||
export const POST = withAuth(async (req, ctx) => {
|
export const POST = withAuth(async (req, ctx) => {
|
||||||
let body: z.infer<typeof bulkSchema>;
|
let body: z.infer<typeof bulkSchema>;
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
body = await parseBody(req, bulkSchema);
|
body = await parseBody(req, bulkSchema);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return errorResponse(error);
|
return errorResponse(error);
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { NextResponse } from 'next/server';
|
|||||||
import { withAuth, withPermission } from '@/lib/api/helpers';
|
import { withAuth, withPermission } from '@/lib/api/helpers';
|
||||||
import { parseQuery, parseBody } from '@/lib/api/route-helpers';
|
import { parseQuery, parseBody } from '@/lib/api/route-helpers';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import {
|
import {
|
||||||
createResidentialInterest,
|
createResidentialInterest,
|
||||||
listResidentialInterests,
|
listResidentialInterests,
|
||||||
@@ -15,6 +16,7 @@ import {
|
|||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_interests', 'view', async (req, ctx) => {
|
withPermission('residential_interests', 'view', async (req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const query = parseQuery(req, listResidentialInterestsSchema);
|
const query = parseQuery(req, listResidentialInterestsSchema);
|
||||||
const result = await listResidentialInterests(ctx.portId, query);
|
const result = await listResidentialInterests(ctx.portId, query);
|
||||||
const { page, limit } = query;
|
const { page, limit } = query;
|
||||||
@@ -39,6 +41,7 @@ export const GET = withAuth(
|
|||||||
export const POST = withAuth(
|
export const POST = withAuth(
|
||||||
withPermission('residential_interests', 'create', async (req, ctx) => {
|
withPermission('residential_interests', 'create', async (req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const body = await parseBody(req, createResidentialInterestSchema);
|
const body = await parseBody(req, createResidentialInterestSchema);
|
||||||
const interest = await createResidentialInterest(ctx.portId, body, {
|
const interest = await createResidentialInterest(ctx.portId, body, {
|
||||||
userId: ctx.userId,
|
userId: ctx.userId,
|
||||||
|
|||||||
@@ -9,11 +9,13 @@ import {
|
|||||||
saveStages,
|
saveStages,
|
||||||
type ResidentialStage,
|
type ResidentialStage,
|
||||||
} from '@/lib/services/residential-stages.service';
|
} from '@/lib/services/residential-stages.service';
|
||||||
|
import { assertResidentialModuleEnabled } from '@/lib/services/residential-module.service';
|
||||||
import { errorResponse } from '@/lib/errors';
|
import { errorResponse } from '@/lib/errors';
|
||||||
|
|
||||||
export const GET = withAuth(
|
export const GET = withAuth(
|
||||||
withPermission('residential_interests', 'view', async (_req, ctx) => {
|
withPermission('residential_interests', 'view', async (_req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const stages = await listStages(ctx.portId);
|
const stages = await listStages(ctx.portId);
|
||||||
const orphans = await findOrphanInterests(
|
const orphans = await findOrphanInterests(
|
||||||
ctx.portId,
|
ctx.portId,
|
||||||
@@ -45,6 +47,7 @@ const putSchema = z.object({
|
|||||||
export const PUT = withAuth(
|
export const PUT = withAuth(
|
||||||
withPermission('admin', 'manage_settings', async (req, ctx) => {
|
withPermission('admin', 'manage_settings', async (req, ctx) => {
|
||||||
try {
|
try {
|
||||||
|
await assertResidentialModuleEnabled(ctx.portId);
|
||||||
const body = await parseBody(req, putSchema);
|
const body = await parseBody(req, putSchema);
|
||||||
await saveStages(
|
await saveStages(
|
||||||
{
|
{
|
||||||
|
|||||||
Reference in New Issue
Block a user