Commit graph

65 commits

Author SHA1 Message Date
42cefaddb2 feat: Platform Kernel v1 -- workspaces, ExecutionContext, /v1/navigation, event envelope
Specul de arhitectura cere Platform Kernel INAINTEA modulelor de domeniu.
Modulele A1/A2 au fost construite peste un kernel caruia ii lipseau exact
piesele astea. Le adaug acum, aditiv, fara sa rup ce merge.

- workspaces: tenant != workspace. Workspace-ul e contextul de lucru DIN
  tenant. Backfill: fiecare tenant existent primeste workspace implicit,
  altfel SessionGuard i-ar respinge toate requesturile.
- memberships.workspace_id + valid_from/valid_until: rol per workspace si
  acces delegat cu expirare (contabil pana la o data). SessionGuard respinge
  membership expirat si membership legat de alt workspace.
- ExecutionContext inlocuieste sesiunea subtire (userId+tenantId+role):
  requestId, correlationId, workspaceId, membershipId, roles, permissions,
  purpose, timezone, source. Tipul vechi ramane exportat sub acelasi nume,
  ca sa nu ating ~15 module de domeniu doar pentru o redenumire.
- GET /v1/navigation: menu registry mutat in backend. Filtreaza pe rol, tip
  de workspace, permisiuni si feature flags; intoarce doar itemii autorizati.
  Ramane UX, nu securitate -- fiecare endpoint verifica din nou.
- event envelope: workspace_id, occurred_at, actor_id, aggregate_type,
  causation_id, classification, provenance
- audit envelope: workspace_id, actor_type, purpose, changed_fields,
  before/after hash, session_id
2026-07-29 11:46:20 +02:00
3bc0d65c46 feat: AI Gateway -- Context Manifest, model routing, cost audit, guardrails
- AiGatewayService: punct unic de acces la modele (LiteLLM -> OpenRouter).
  Clasele de actiuni din blueprint 14.3 sunt aplicate hard: high_risk blocat
  permanent, material blocat pana exista coada de aprobare + idempotency;
  doar read_only si draft ruleaza.
- Spotlighting (design doc Strat 1): continutul untrusted (date Apollo) e
  impachetat in <untrusted-data> cu instructiune de sistem ca e DATE, nu
  comenzi -- plus redactie PII deterministica (email/telefon/CNP) inainte
  sa plece catre provider extern.
- ai_requests: adaugat action_class + context_manifest complet (nu doar
  hash) pentru audit; cost_usd_minor_units (integer) inlocuit cu
  cost_usd numeric(12,6) -- costurile reale sunt fractiuni de cent.
- research-briefs: POST /draft genereaza un rezumat AI din datele Apollo
  fara sa salveze nimic (clasa draft -- userul revizuieste, apoi salveaza).
- briefing: aiExplanation devine narativ real peste prioritizarea
  determinista; esecul AI intoarce null, nu strica briefingul.
- teste: clase de actiuni blocate, spotlighting, redactie PII.
2026-07-28 22:34:36 +02:00
0f8390f31b feat: Faza A2 -- intelligence proxy, saved segments, research briefs, briefing
- IntelligenceModule: proxy tenant-scoped catre intelligence-api
  (/companies/search, /companies/{id}); ceo-web nu vorbeste niciodata
  direct cu intelligence-api (blueprint 10.3/16).
- SavedSegments: salveaza o cautare Apollo si o ruleaza din nou oricand.
- ResearchBriefs: dovezi curatate manual per companie, cu sursa Apollo
  implicita plus surse suplimentare -- explicit fara rezumat generat de
  AI (AI Gateway inca neconstruit, blueprint 14).
- BriefingService: /v1/briefing/today, agregare deterministica de
  taskuri restante/viitoare + activitate saptamanala; campul
  aiExplanation ramane null si vizibil in raspuns, nu simulat.
2026-07-28 22:01:17 +02:00
0ea8e69233 feat: multi-tenant core -- session auth, RBAC, organizations, tasks, audit
- SessionGuard resolves Supabase JWT (local HS256 verify, GoTrue fallback)
  and loads the tenant membership from x-tenant-id; TenantGuard keeps
  deny-by-default and rejects client-supplied tenant_id (blueprint 11.3).
- New bootstrap routes: GET /v1/me, POST/GET /v1/tenants, tenant member
  management (list/add/remove) with owner/admin RBAC.
- Organizations and Tasks modules: full CRUD scoped to session.tenantId,
  soft delete, audit log + outbox events on every write.
- AuditService (global) for blueprint 3.4 "100% audit on material ops".
- jest + tenant.guard.spec covering deny-by-default and anti-IDOR cases.
2026-07-28 21:15:43 +02:00
4d7450f910 feat: add agent niche registry (SKILL.md-style) grouping AI tools by domain
Ports the SKILL.md/frontmatter pattern from skills-claude (fork of
anthropics/skills) to define user-facing "niches" (legal, financial,
business-capability) that each group one or more AGENT_TOOL_REGISTRY
entries. NicheRegistryService loads and validates src/agent-niches/
definitions/*.md at boot, failing loudly on unknown tool references so a
niche can never silently grant access to an undeclared capability. This
is the data model for the planned dashboard where memberships access
Hermes agents scoped by niche instead of by raw tool name.
2026-07-24 00:00:42 +02:00
261bd0dba1 feat: add AI tool capability permissions and secret masking to CASL layer
Extends AbilityFactory with a risk-stratified capability model for Hermes
MCP tools (economic-data/capability-reasoning/legislation-search), ported
from Open.Jarvis's plugin permission system: non-owner/admin roles only
get low/medium risk tools by default, high/critical stay reserved. Adds
maskSensitiveValue as a reusable secret/PII redaction utility for future
outbox/audit logging, reinforcing the existing ai_requests hash-only
storage principle.
2026-07-23 23:36:20 +02:00
5a1206118a security: enforce TenantGuard and ThrottlerGuard globally, lock down CORS
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.
2026-07-21 19:48:17 +02:00
5656f1cc1c feat: scaffold Business/Life/Intelligence/Trust Engine tables
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.
2026-07-21 19:44:45 +02:00
0a4ffc41e6 fix: scope tsconfig to src/ so nest build emits dist/main.js
Without an include filter, tsc pulled in drizzle.config.ts from the
repo root too, which widened the inferred rootDir and nested output
under dist/src/main.js instead of dist/main.js -- crashing the
container (Cannot find module '/app/dist/main') since the Dockerfile
CMD expects the standard Nest layout.
2026-07-21 12:07:06 +02:00
fe42a1ae57 fix: force devDependencies install in ceo-api Docker build stage
npm ci silently skips devDependencies when NODE_ENV=production is set
in the environment, which broke the build (nest: not found) once
Coolify injected NODE_ENV=production as a build-time var. --include=dev
makes the build stage robust regardless of that env var; the runtime
stage now does its own --omit=dev install instead of copying the build
stage's node_modules wholesale, keeping the final image prod-only.
2026-07-21 12:03:42 +02:00
4372684f1b fix: correct ceo-api Dockerfile port and dependency install
EXPOSE was 3000 but main.ts defaults PORT to 3001. npm install had no
lockfile/legacy-peer-deps, which now fails on the @nestjs/swagger v8
vs @nestjs/common v11 peer conflict. Also adds .dockerignore so the
build stage's node_modules isn't clobbered by a local one.
2026-07-21 02:50:53 +02:00
722113a359 feat: scaffold Identity Engine (CASL/tenant guard) and Event Fabric (outbox)
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).
2026-07-21 02:46:35 +02:00
Claude
3fe8d24179 feat: add Drizzle ORM, Supabase admin client, Swagger, Helmet, Pino logging, rate limiting 2026-07-20 22:41:09 +02:00
Claude
ce5cf134ae feat: scaffold NestJS API skeleton with health check 2026-07-20 22:26:33 +02:00
407312e9a2 Initial commit 2026-07-20 20:23:56 +00:00