2.7 KiB
2.7 KiB
Comment Visibility Architecture
Date: 2026-03-30 Status: Phase 1 implemented
Problem
The original comment router accepted arbitrary entityType and entityId pairs behind protectedProcedure.
That was too broad:
- comment visibility depends on the backing entity, not on the comment record alone
- generic strings allowed clients and assistant tools to imply support for entity types that had no explicit policy
- author/admin checks on
resolveanddeletewere not enough, because list/create access was still effectively "any authenticated user"
Current Product Reality
There is only one real first-party consumer today:
- web UI estimate workspace comments via
entityType: "estimate"
The older examples for scope_item, estimate_version, and demand_line were aspirational, not backed by an explicit visibility model or active UI.
Architecture Decision
Comments now use an explicit entity registry.
- supported entity types are allowlisted, not free-form
- each entity type owns:
- its audience rule
- its existence check
- its deep link builder for notifications
- every comment route calls the entity access layer before touching comment data
Phase 1 Policy
Supported entity types:
estimate
Audience:
- same audience as the estimate workspace
- controller, manager, or admin only
Route effects:
list,count,create,resolve, anddeleteall require estimate visibility firstresolveanddeletestill require comment author or admin after entity visibility is granted- replies are only allowed when the parent comment belongs to the same entity tuple
- mention notifications use the entity policy link builder instead of hardcoded route assumptions scattered through the router
Why This Shape
- It closes the real security gap now without pretending a generic multi-entity policy already exists.
- It keeps future comment expansion additive: a new entity type must be onboarded deliberately.
- It gives the assistant and UI one source of truth for what is actually supported today.
Extension Rules For Future Entity Types
To add another commentable entity:
- Add the entity type to the registry, not just to input examples.
- Define the backing audience source of truth.
- Add an existence check for that entity.
- Add a notification link builder for that entity.
- Update assistant tool metadata and assistant visibility gates in the same change.
- Add router auth tests for unauthenticated, plain authenticated, and elevated callers.
- Update
docs/route-access-matrix.md.
Non-Goals In Phase 1
- generic comment support for arbitrary entities
- row-level polymorphic authorization based only on
entityTypestrings - automatic inheritance for future entities without explicit onboarding