diff --git a/src/app/api/coach/about-me/adopt/__tests__/route.test.ts b/src/app/api/coach/about-me/adopt/__tests__/route.test.ts index f25792089..90db34e4a 100644 --- a/src/app/api/coach/about-me/adopt/__tests__/route.test.ts +++ b/src/app/api/coach/about-me/adopt/__tests__/route.test.ts @@ -43,6 +43,9 @@ vi.mock("@/lib/ai/coach/bytes-codec", () => ({ vi.mock("@/lib/ai/coach/about-me", () => ({ getSelfContextForUser: vi.fn(), })); +vi.mock("@/lib/modules/gate", () => ({ + requireModuleEnabled: vi.fn(async () => ({ enabled: true })), +})); vi.mock("@/lib/api-response", () => ({ apiSuccess: (data: unknown) => ({ data, error: null, status: 200 }), diff --git a/src/app/api/coach/about-me/adopt/route.ts b/src/app/api/coach/about-me/adopt/route.ts index 5f8c1d8e5..5ffb8692d 100644 --- a/src/app/api/coach/about-me/adopt/route.ts +++ b/src/app/api/coach/about-me/adopt/route.ts @@ -41,6 +41,7 @@ import { prisma } from "@/lib/db"; import { checkRateLimit, rateLimitHeaders } from "@/lib/rate-limit"; import { encryptToBytes } from "@/lib/ai/coach/bytes-codec"; import { getSelfContextForUser } from "@/lib/ai/coach/about-me"; +import { requireModuleEnabled } from "@/lib/modules/gate"; import { ABOUT_ME_FIELD_MAX_CHARS, ABOUT_ME_MAX_CHARS, @@ -93,6 +94,9 @@ function normalise(s: string): string { export const POST = apiHandler(async (req: Request) => { const { user } = await requireAuth(); + // v1.18.0 — Coach module gate (operator availability + disableCoach). + const gate = await requireModuleEnabled(user.id, "coach"); + if (!gate.enabled) return gate.response; const rl = await checkRateLimit( `coach-about-me:adopt:${user.id}`, diff --git a/src/app/api/coach/about-me/questions/route.ts b/src/app/api/coach/about-me/questions/route.ts index 1c4094d21..58841bd91 100644 --- a/src/app/api/coach/about-me/questions/route.ts +++ b/src/app/api/coach/about-me/questions/route.ts @@ -24,6 +24,7 @@ import { PENDING_QUESTION_MAX_CHARS, setPendingQuestionsForUser, } from "@/lib/ai/coach/about-me"; +import { requireModuleEnabled } from "@/lib/modules/gate"; const dismissSchema = z.object({ /** Exact question text to dismiss. Omitted = dismiss all. */ @@ -32,6 +33,9 @@ const dismissSchema = z.object({ export const GET = apiHandler(async () => { const { user } = await requireAuth(); + // v1.18.0 — Coach module gate (operator availability + disableCoach). + const gate = await requireModuleEnabled(user.id, "coach"); + if (!gate.enabled) return gate.response; const questions = await getPendingQuestionsForUser(user.id); annotate({ action: { name: "coach.about_me.questions.get" }, @@ -42,6 +46,9 @@ export const GET = apiHandler(async () => { export const DELETE = apiHandler(async (req: Request) => { const { user } = await requireAuth(); + // v1.18.0 — Coach module gate (operator availability + disableCoach). + const gate = await requireModuleEnabled(user.id, "coach"); + if (!gate.enabled) return gate.response; const { data: body, error: jsonError } = await safeJson(req, { maxBytes: 4 * 1024, diff --git a/src/app/api/coach/about-me/route.ts b/src/app/api/coach/about-me/route.ts index 3c2b18bc2..b594e772d 100644 --- a/src/app/api/coach/about-me/route.ts +++ b/src/app/api/coach/about-me/route.ts @@ -43,6 +43,7 @@ import { setPendingQuestionsForUser, } from "@/lib/ai/coach/about-me"; import { deriveClarifyingQuestions } from "@/lib/ai/coach/self-context-questions"; +import { requireModuleEnabled } from "@/lib/modules/gate"; import { ABOUT_ME_FIELD_MAX_CHARS, ABOUT_ME_MAX_CHARS, @@ -54,6 +55,9 @@ const PUT_WINDOW_MS = 60_000; export const GET = apiHandler(async () => { const { user } = await requireAuth(); + // v1.18.0 — Coach module gate (operator availability + disableCoach). + const gate = await requireModuleEnabled(user.id, "coach"); + if (!gate.enabled) return gate.response; const [ctx, pendingQuestions, row] = await Promise.all([ getSelfContextForUser(user.id), @@ -89,6 +93,9 @@ export const GET = apiHandler(async () => { export const PUT = apiHandler(async (req: Request) => { const { user } = await requireAuth(); + // v1.18.0 — Coach module gate (operator availability + disableCoach). + const gate = await requireModuleEnabled(user.id, "coach"); + if (!gate.enabled) return gate.response; const rl = await checkRateLimit( `coach-about-me:put:${user.id}`,