232 Domain Registry Deployment Handoff
Documentation for Sessions
S232/S233 Handoff: Domain Registry & Multi-Project Deployment Spec
Date: 2026-03-18
Session: 232
Status: Handoff for next session/agent
Branch: session-232-233
1. Executive Summary
This document provides a comprehensive spec and implementation plan for the Domain Registry and Multi-Project Deployment architecture. It also requests analysis from the next agent on several open questions.
Critical constraint: We MUST maintain multi-project infrastructure (one Cloudflare project per universe). Do NOT suggest Option B (single project per space with path-based app).
2. Context & Prior Decisions
2.1 Problems Addressed
| Problem | Status |
|---|---|
Duplicate space DBs (space_chrome-space-1 vs space_chrome-space-1_79fe44376823) |
Fixed (resolver slug→ObjectId) |
| Duplicate universes in gograb-api | Mitigated (resolver ensures consistent spaceId) |
universe_universe_* double-prefix collections |
Fixed (buildCollectionName + space-module-database) |
| Subdomain collision risk (universe slug only) | To implement (domain registry) |
| Deployment URL routing (path vs subdomain) | Spec complete, implementation pending |
2.2 Routing Modes (Configurable per Space)
Multi-universe spaces can choose:
| Mode | URL Pattern | When |
|---|---|---|
| Path-based | {spaceSlug}.gograb.space/{universeSlug} |
Space prefers path routing |
| Subdomain-based | {universeSlug}.gograb.space |
Space prefers subdomain per universe |
| Single universe | {spaceSlug}.gograb.space |
One universe at root |
2.3 Uniqueness Model
- Not about spaceSlug vs universeSlug uniqueness in isolation.
- Only about subdomain/domain uniqueness globally.
- Single domain registry collection is the source of truth for availability.
3. Domain Registry Specification
3.1 Collection Schema
Collection: gograb-api.deployed_domains (or domain_registry)
| Field | Type | Purpose |
|---|---|---|
host |
string | Host part (e.g. chrome-space-1, portal, app.mycompany.com) |
path |
string | Path if any (e.g. '', '/', '/portal') |
fullKey |
string | Unique key: {host} or {host}{path} |
spaceId |
string | Owning space |
universeId |
string | Owning universe |
projectName |
string | Cloudflare project name |
domainType |
'gograb_subdomain' | 'custom' |
gograb.space vs custom |
status |
'active' | 'released' |
In use or freed |
createdAt |
Date | |
updatedAt |
Date |
Indexes:
{ fullKey: 1 }unique wherestatus: 'active'{ spaceId: 1, status: 1 }{ universeId: 1, status: 1 }
3.2 Availability Logic
A subdomain/domain is available iff it does not appear in deployed_domains with status: 'active'.
| Routing Mode | host | path | fullKey |
|---|---|---|---|
| Path-based | spaceSlug | /{universeSlug} |
host + path |
| Subdomain-based | universeSlug | '' |
host |
| Custom domain | full host (e.g. app.mycompany.com) |
'' or path |
host or host + path |
3.3 Space Config (space_metadata or space document)
deployment: {
routingMode: 'path' | 'subdomain'; // for multi-universe
defaultUniverseId?: string; // for path mode, which universe at /
}
4. API Endpoints (To Implement)
| Endpoint | Purpose |
|---|---|
GET /api/deployed-domains/check?host={host}&path={path} |
Check availability |
GET /api/deployed-domains/suggest?spaceId={id}&routingMode=path|subdomain |
List taken + suggest options |
POST /api/deployed-domains |
Register on deploy (internal) |
DELETE /api/deployed-domains/:id or soft-release |
Release on undeploy |
5. Deploy Flow (Multi-Project Preserved)
- Resolve
tenantId→spaceSlug(via spaces API). - Read space
deployment.routingModeanddeployment.defaultUniverseId. - Compute
hostandpathfrom routing mode + universe. - Check availability in
deployed_domains. - Create/update Cloudflare project (one per universe).
- Add custom domain(s) to project if configured.
- Upsert
deployed_domainswithhost,path,fullKey,spaceId,universeId,projectName,domainType,status: 'active'. - If path-based: update Worker routing config.
6. Custom Domain Handling (Open)
Current understanding:
- Custom domain is another
hostin the registry. - Same conflict rules: if
app.mycompany.comis taken, not available. - Ownership verification (DNS TXT, CNAME) is a separate step before allowing use.
Questions for next agent:
- How should we verify user ownership of a custom domain before allowing registration?
- Should we support path vs subdomain on custom domains (e.g.
mycompany.com/portalvsportal.mycompany.com)? - What happens when a user releases a deployment—do we soft-delete the registry entry or hard-delete?
7. Implementation Plan (Recommended Order)
| Phase | Tasks |
|---|---|
| 1. Schema | Create deployed_domains collection + indexes, migration script |
| 2. Service | DeployedDomainsService with check, suggest, register, release |
| 3. API | Controller + DTOs for check, suggest |
| 4. Deploy integration | Update deployment.service.ts to use registry, space config |
| 5. Routing | Cloudflare Worker for path-based routing (if not exists) |
| 6. Custom domain | Ownership verification flow (TBD) |
8. Files to Modify/Create
| File | Action |
|---|---|
APIs/backend-api/src/app/deployment/deployment.service.ts |
Use registry, space config, routing mode |
APIs/backend-api/src/app/deployment/deployment.controller.ts |
Add check/suggest endpoints |
APIs/backend-api/src/app/deployed-domains/ |
New module (service, controller, schema) |
APIs/backend-api/src/app/spaces/space-database/services/space-database-metadata.service.ts |
Read deployment config |
APIs/backend-api/src/app/cloudflare/cloudflare-pages.service.ts |
Project naming from registry |
9. Requested Analysis (Next Agent)
Please provide:
Gap analysis: Compare this spec against current
deployment.service.tsandcloudflare-pages.service.ts. List concrete diffs (line-level where possible).Custom domain strategy: Recommend an approach for ownership verification and conflict handling. Consider Cloudflare’s custom domain APIs and DNS verification patterns.
Migration path: How to backfill
deployed_domainsfrom existingdeploymentscollection? What about orphan/orphaned deployments?Edge cases: What happens when:
- Space switches routing mode (path ↔ subdomain)?
- Universe is deleted but deployment remains?
- Two spaces claim same custom domain (race)?
Verification: After implementation, how to validate no regressions? Suggest E2E or integration test scenarios.
10. References
docs/english/sessions/S232/232-universe-space-database-duplication-research.md— DB naming fixesAPIs/backend-api/src/app/deployment/deployment.service.ts— Current deploy logicAPIs/backend-api/src/app/cloudflare/cloudflare-pages.service.ts— Cloudflare integrationAGENTS.md— Session protocol, commit format
Handoff prepared by S232. Next session: increment subSession, continue on session-232-233 branch.