feat(api): pending-changes + audit routes

Owner-only routes wired with an applyPendingChange dispatch helper
covering page/project/task/ref/resource/source_doc create/update/delete.
Approve and reject emit their own audit_log entries (actions already in
the CHECK vocab) so the audit trail is self-contained.

Documents a latent bug in security-followups.md: pending_changes.action
CHECK constraint blocks 'upsert' / 'add_dependency' / 'remove_dependency'
divertToPending paths in refs/resources routes when an agent at suggest
tier hits them.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
root
2026-06-01 02:01:10 +10:00
parent 5aa6fe772d
commit ec96e4e2e3
6 changed files with 424 additions and 0 deletions

View File

@@ -17,6 +17,8 @@ import { router as conversationsRouter } from './routes/conversations.js';
import { conversationsScopedRouter as messagesByConvRouter } from './routes/messages.js';
import { router as tagsRouter, entityScopedRouter as tagsByEntityRouter } from './routes/tags.js';
import { router as linksRouter } from './routes/links.js';
import { router as pendingChangesRouter } from './routes/pending_changes.js';
import { router as auditRouter } from './routes/audit.js';
export function mountApi(app) {
const api = Router();
@@ -41,6 +43,8 @@ export function mountApi(app) {
api.use('/conversations/:conversation_id/messages', messagesByConvRouter);
api.use('/tags', tagsRouter);
api.use('/links', linksRouter);
api.use('/pending-changes', pendingChangesRouter);
api.use('/audit', auditRouter);
api.use('/:entity_type/:entity_id/tags', tagsByEntityRouter);
api.use((_req, _res, next) => next(new NotFoundError('route not found')));