project-map.ts54 lines · main
| 1 | /** |
| 2 | * Briven projectId → briven-engine app/tenant map (Path A). |
| 3 | * |
| 4 | * Phase 1: pure mapping rules (no Multitenancy recipe yet). |
| 5 | * Later: Multitenancy creates tenants in briven-engine; this stays the source of truth |
| 6 | * for which Briven project owns which engine tenant. |
| 7 | * |
| 8 | * Isolation rule: one Briven project = one tenantId under app "public" |
| 9 | * (default app until Phase 6 enterprise apps). |
| 10 | */ |
| 11 | |
| 12 | const ST_APP_ID = 'public'; |
| 13 | |
| 14 | /** |
| 15 | * Normalize project id into a briven-engine-safe tenant id. |
| 16 | * Core allows only letters, numbers, hyphens (no underscores). |
| 17 | */ |
| 18 | export function projectIdToTenantId(projectId: string): string { |
| 19 | const cleaned = projectId |
| 20 | .trim() |
| 21 | .toLowerCase() |
| 22 | .replace(/_/g, '-') |
| 23 | .replace(/[^a-z0-9-]/g, '-') |
| 24 | .replace(/-+/g, '-') |
| 25 | .replace(/^-|-$/g, ''); |
| 26 | if (!cleaned) { |
| 27 | throw new Error('projectId is empty'); |
| 28 | } |
| 29 | return `proj-${cleaned}`.slice(0, 64); |
| 30 | } |
| 31 | |
| 32 | export function tenantIdToProjectId(tenantId: string): string | null { |
| 33 | if (!tenantId.startsWith('proj-')) return null; |
| 34 | // Reverse hyphenation is lossy for original underscores; store projectId separately in product. |
| 35 | return tenantId.slice('proj-'.length); |
| 36 | } |
| 37 | |
| 38 | export type AuthCoreProjectMap = { |
| 39 | projectId: string; |
| 40 | appId: typeof ST_APP_ID; |
| 41 | tenantId: string; |
| 42 | phase: 1; |
| 43 | }; |
| 44 | |
| 45 | export function mapProjectToAuthCore(projectId: string): AuthCoreProjectMap { |
| 46 | return { |
| 47 | projectId, |
| 48 | appId: ST_APP_ID, |
| 49 | tenantId: projectIdToTenantId(projectId), |
| 50 | phase: 1, |
| 51 | }; |
| 52 | } |
| 53 | |
| 54 | export const AUTH_CORE_DEFAULT_APP_ID = ST_APP_ID; |