Both guards were fully implemented but never actually wired in -- Nest
doesn't enforce a guard just because its module is imported, it needs
an explicit APP_GUARD registration. Registered both globally so every
new controller is deny-by-default and rate-limited unless it opts out.
Added a @Public() decorator (checked via Reflector in TenantGuard) for
routes that legitimately have no session, applied it to /health so the
global guard doesn't break it.
CORS was wide open (enableCors() with no origin restriction, effectively
allow-any-origin). Now reads an explicit CORS_ORIGINS allowlist from env,
defaulting to localhost:3000 for local dev.
Per Blueprint v4.0 §12 canonical data models:
- Business Engine: organizations extended (legal_name, country, registry_id,
domain, external_ids), transactions (minor-unit amounts, evidence_status),
documents (metadata only -- binary/OCR stays in Paperless via paperless_id)
- Life Engine: goals (horizon/metric/target/milestones)
- Intelligence Engine: decisions (context/options/assumptions/evidence),
opportunities, ai_requests (context_manifest_hash for audit without
storing sensitive payload content in Postgres)
- Trust Engine: observations (generic subject_type/subject_id so any
entity -- user, org, device -- can feed reputation/trust scores)
Applied directly to Supabase staging Postgres (14 tables total now).
This is also the first drizzle/ migration actually committed -- the
earlier one from the Identity Engine work never made it into git.
Adds tenants/memberships/consent_records tables, a CASL AbilityFactory
keyed on membership role, and a TenantGuard that derives tenant_id from
session only (never client-supplied), per blueprint 8.2/8.3/11.3.
Adds outbox_events + audit_log tables, an OutboxService for transactional
writes, and a Cron-based OutboxDispatcher that publishes pending events
to a BullMQ queue, per blueprint 9.1 (events before intelligence).