feat(auth): classify planning and resource read audiences

This commit is contained in:
2026-03-30 08:51:07 +02:00
parent f6daf21983
commit db45829eca
7 changed files with 154 additions and 138 deletions
+4 -4
View File
@@ -12,7 +12,7 @@ import { paginate, paginateCursor, PaginationInputSchema, CursorInputSchema } fr
import { assertBlueprintDynamicFields } from "./blueprint-validation.js";
import { buildDynamicFieldWhereClauses } from "./custom-field-filters.js";
import { loadProjectPlanningReadModel } from "./project-planning-read-model.js";
import { adminProcedure, controllerProcedure, createTRPCRouter, managerProcedure, protectedProcedure, requirePermission } from "../trpc.js";
import { adminProcedure, controllerProcedure, createTRPCRouter, managerProcedure, planningReadProcedure, protectedProcedure, requirePermission } from "../trpc.js";
import { createDalleClient, isDalleConfigured, loggedAiCall, parseAiError } from "../ai-client.js";
import { generateGeminiImage, isGeminiConfigured, parseGeminiError } from "../gemini-client.js";
import { invalidateDashboardCache } from "../lib/cache.js";
@@ -411,7 +411,7 @@ async function readProjectByIdentifierDetailSnapshot(
}
export const projectRouter = createTRPCRouter({
resolveByIdentifier: protectedProcedure
resolveByIdentifier: planningReadProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ ctx, input }) => {
const select = {
@@ -454,7 +454,7 @@ export const projectRouter = createTRPCRouter({
return project;
}),
searchSummaries: protectedProcedure
searchSummaries: planningReadProcedure
.input(z.object({
search: z.string().optional(),
status: z.nativeEnum(ProjectStatus).optional(),
@@ -577,7 +577,7 @@ export const projectRouter = createTRPCRouter({
};
}),
getByIdentifier: protectedProcedure
getByIdentifier: planningReadProcedure
.input(z.object({ identifier: z.string() }))
.query(async ({ ctx, input }) => resolveProjectIdentifierSnapshot(ctx, input.identifier)),
+6 -14
View File
@@ -51,7 +51,7 @@ Write a 23 sentence professional bio. Be specific, use skill names. No fluff.
import { TRPCError } from "@trpc/server";
import { z } from "zod";
import { findUniqueOrThrow } from "../db/helpers.js";
import { adminProcedure, controllerProcedure, createTRPCRouter, managerProcedure, protectedProcedure, requirePermission } from "../trpc.js";
import { adminProcedure, controllerProcedure, createTRPCRouter, managerProcedure, protectedProcedure, requirePermission, resourceOverviewProcedure } from "../trpc.js";
import { ROLE_BRIEF_SELECT } from "../db/selects.js";
import type { TRPCContext } from "../trpc.js";
@@ -831,7 +831,7 @@ export const resourceRouter = createTRPCRouter({
return resource;
}),
resolveResponsiblePersonName: protectedProcedure
resolveResponsiblePersonName: resourceOverviewProcedure
.input(z.object({ name: z.string() }))
.query(async ({ ctx, input }) => {
const exact = await ctx.db.resource.findFirst({
@@ -1176,7 +1176,7 @@ export const resourceRouter = createTRPCRouter({
};
}),
listSummaries: protectedProcedure
listSummaries: resourceOverviewProcedure
.input(z.object({
search: z.string().optional(),
country: z.string().optional(),
@@ -1199,7 +1199,7 @@ export const resourceRouter = createTRPCRouter({
return resources.map(mapResourceSummary);
}),
listSummariesDetail: protectedProcedure
listSummariesDetail: resourceOverviewProcedure
.input(z.object({
search: z.string().optional(),
country: z.string().optional(),
@@ -1433,17 +1433,9 @@ export const resourceRouter = createTRPCRouter({
return { resources, total, page, limit, nextCursor };
}),
listStaff: protectedProcedure
listStaff: resourceOverviewProcedure
.input(ResourceListQuerySchema)
.query(async ({ ctx, input }) => {
if (!canReadAllResources(ctx)) {
throw new TRPCError({
code: "FORBIDDEN",
message: "You need resource overview access to list staff resource data",
});
}
return listStaffResources(ctx, input);
}),
.query(async ({ ctx, input }) => listStaffResources(ctx, input)),
/** Lightweight resource card for hover tooltips on the timeline. */
getHoverCard: protectedProcedure