7.7 KiB
Audience Scoping Backlog
Date: 2026-03-30 Purpose: Collect the remaining audience-scoping work into a single batch backlog so the small auth-hardening slices can be finished before broader architecture work starts.
Status Snapshot
Done
blueprint.listSummaries: narrowed toplanning-readentitlement.getBalance,entitlement.getBalanceDetail: narrowed to self-service with elevated cross-resource access for controller, manager, and adminvacation.previewRequest: now enforces owned-resource access for normal usersholidayCalendar.resolveResourceHolidays,holidayCalendar.resolveResourceHolidaysDetail: now enforce self-service ownership with elevated manager/admin reads
Dirty Files To Avoid Mixing Into This Batch
packages/api/src/router/assistant-tools.tspackages/api/src/router/notification.tspackages/api/src/__tests__/assistant-tools-import-export.test.tspackages/api/src/__tests__/notification-router.test.ts
These files already have unrelated local edits. Audience parity work that would normally touch them should be deferred or handled through adjacent files and dedicated follow-up tests.
Batch Categories
Ready Now
These are small, well-bounded slices that should fit the existing hardening pattern: narrow the procedure, add router authorization tests, update docs, and commit separately.
1. packages/api/src/router/blueprint.ts -> getGlobalFieldDefs
- Current state:
protectedProcedure - Likely target:
planning-read - Why it is ready:
- the route returns global blueprint field definitions across active blueprints
- that is broader than a low-risk lookup and belongs with other blueprint configuration reads
- the audience class already exists in route-access-matrix.md
- Expected work:
- switch to
planningReadProcedure - add a focused auth test covering unauthenticated, plain user, and planning-enabled caller
- update matrix wording if needed
- switch to
2. packages/api/src/router/resource.ts -> chapters
- Current state:
protectedProcedure - Likely target:
authenticated-safe-lookup - Why it is ready:
- the route only returns distinct active
chapterstrings - it does not expose resource records, counts, hierarchy, or staffing data
- it looks more like a shared filter/lookup helper than a resource-overview read
- the route only returns distinct active
- Expected work:
- keep implementation shape, but make the intended audience explicit in docs
- add auth coverage proving normal authenticated access is allowed while unauthenticated access is blocked
- only tighten further if a concrete leak is found
3. packages/api/src/router/project.ts -> isImageGenConfigured, isDalleConfigured
- Current state:
protectedProcedure - Likely target: keep as authenticated low-risk checks
- Why it is ready:
- these are explicit boolean readiness/configuration checks already called out in the matrix
- the main gap is CI-enforced audience intent, not router logic
- Expected work:
- add auth tests for authenticated vs unauthenticated callers
- assert the result shape stays narrow (
configured, optional provider) - document them explicitly in the backlog as
tests/docs only
4. packages/api/src/router/assistant.ts -> listPendingApprovals
- Current state:
protectedProcedure - Likely target: keep as self-service
- Why it is ready:
- the implementation reads approvals by
ctx.dbUser!.id - it is already effectively scoped to the current user
- this can be locked down by tests without touching dirty assistant tool files
- the implementation reads approvals by
- Expected work:
- add router-level auth coverage for self-only behavior
- document the route in the access matrix
Tests Or Docs Only
These routes look conceptually acceptable already, but the classification is not yet enforced clearly enough.
packages/api/src/router/assistant.ts -> chat
- Current state:
protectedProcedure - Working model:
- chat session itself is authenticated
- actual tool visibility is permission-gated inside assistant selection
- Remaining gap:
- the matrix does not yet document this route explicitly
- parity expectations should remain in
assistant.tstests untilassistant-tools.tsis safe to touch
- Follow-up:
- add matrix entry describing chat as an authenticated shell with tool-level audience enforcement
- avoid deeper changes until dirty assistant-tool files are clear
packages/api/src/router/resource.ts -> importSkillMatrix
- Current state:
protectedProcedure - Working model:
- the mutation resolves the linked resource from the current user and writes only to that resource
- Remaining gap:
- no explicit self-service classification in the matrix
- auth regression coverage should be verified
- Follow-up:
- document as self-service
- add or tighten tests only if coverage is missing
packages/api/src/router/project.ts -> isImageGenConfigured, isDalleConfigured
- The likely outcome is to keep the current procedure and add explicit tests/docs rather than re-architecting the route.
Needs Architecture Or Policy Design
These routes should not be batch-edited as “small safe slices” until a visibility model exists.
packages/api/src/router/comment.ts
- Current state: all core routes are
protectedProcedure - Why this is not a small slice:
- reads and writes are keyed by generic
entityTypeandentityId - visibility depends on the backing entity, not on the comment record alone
- the current author/admin checks for resolve/delete are not enough to decide who may list or create comments on each entity class
- reads and writes are keyed by generic
- Design work needed:
- define which entity types can host comments
- map each entity type to its audience source of truth
- centralize entity visibility checks before any comment read/write
- Recommended path:
- treat comments as a separate architecture ticket, not part of the quick hardening batch
Blocked By Dirty Files
packages/api/src/router/assistant-tools.ts
- Why blocked:
- unrelated local edits are already present
- tool gating changes would mix poorly with concurrent work
- Interim rule:
- keep parity changes on the
assistant.tsside where possible - defer tool-level cleanups until the file is stable
- keep parity changes on the
packages/api/src/router/notification.ts
- Why blocked:
- unrelated local edits are already present
- TypeScript verification currently also reports a foreign issue in this file
- Interim rule:
- do not mix notification hardening into this batch unless the other worker clears the file first
Recommended Batch Order
blueprint.getGlobalFieldDefsassistant.listPendingApprovalsplus matrix entryresource.chaptersclassification and auth testproject.isImageGenConfiguredandproject.isDalleConfiguredauth testsresource.importSkillMatrixdocs/test verificationassistant.chatmatrix clarification and parity reviewcommentarchitecture design ticket
Slice Definition
Each “ready now” slice should follow the same template:
- change the router audience only if the current procedure is too broad
- add focused auth tests for unauthenticated, plain authenticated, and elevated callers as applicable
- update route-access-matrix.md
- verify with targeted
vitest - run
git diff --check - commit in isolation
Exit Criteria For This Batch
- every route in this document is classified as either
done,ready now,tests/docs only,needs architecture, orblocked - every
ready nowroute has router-level authorization coverage - the access matrix documents all low-risk exceptions explicitly
- larger architecture work starts only after this batch is either completed or intentionally deferred