Commit Graph

2 Commits

Author SHA1 Message Date
769fbdcba2 feat(mcp): per-resource Vibn-project ownership + backfill endpoint
Stage 3 of per-project Coolify isolation. Adds an authoritative ownership
table so apps_list { projectId } returns ONLY the resources actually owned
by that Vibn project, even when multiple Vibn projects share a single
Coolify project (the legacy workspace-level vibn-ws-{slug}).

- New table fs_project_resources (project_id, resource_uuid, type, workspace).
  Auto-created on first use.
- lib/projects.ts: linkResourceToProject / unlinkResource /
  getProjectResourceUuids / getProjectIdForResource helpers.
- apps_list { projectId }: when the project's coolifyProjectUuid equals the
  legacy workspace project, restrict results to explicitly-linked resources.
  When it has a dedicated Coolify project, return everything in that project.
- apps_create / databases_create: auto-link the newly-created resource to
  the requesting Vibn project.
- apps_delete / databases_delete / services_delete: unlink on success.
- projects_get → possibleDeployments: prefer explicit links; fuzzy-match
  fallback only fires when no link table entry exists yet.
- POST /api/projects/backfill-isolation: idempotent migration that mints a
  dedicated Coolify project for every Vibn project AND records existing
  coolifyServiceUuid/coolifyAppUuid/coolifyDatabaseUuid links. Resolves
  the "Twenty CRM project shows n8n" bug for legacy projects without
  needing to physically move services in Coolify.

Made-with: Cursor
2026-04-27 19:33:07 -07:00
1a686c2a23 Per-project Coolify project isolation (Stage 1)
Each Vibn project now gets its OWN Coolify project named
vibn-{workspace-slug}-{project-slug}. All apps/databases/services
deployed for the project land inside that Coolify project, giving
us clean grouping, cascading delete, and per-project domain
namespaces.

Changes:
- New lib/projects.ts: ensureProjectCoolifyProject (idempotent
  create/lookup), getProjectCoolifyUuid, getOwnedCoolifyProjectUuids
- /api/projects/create: pre-insert row, mint per-project Coolify
  project, then complete the row with productData (preserves the
  coolifyProjectUuid that was just set)
- apps.list (MCP): without projectId, aggregates across ALL
  workspace-owned Coolify projects; with projectId, scopes to
  that project's Coolify project. Returns coolifyProjectUuid
  on each result so the AI knows where things live.
- apps.create (MCP): accepts projectId; auto-mints the Vibn
  project's Coolify project on first deploy if missing
- apps_list/apps_create tool defs: projectId param surfaced
- System prompt: Project as first-class — planning + live as
  facets of ONE thing, never as separate worlds. AI told to
  always pass projectId on apps_create.

Stage 2 (next): set-aware ensureResourceInProject across all
single-resource MCP tools (apps.get/delete/exec/etc.) and
cascading delete via projects.delete.

Made-with: Cursor
2026-04-27 19:02:43 -07:00