Skip to content

refactor(api): include type segment in DO names#1520

Merged
braden-w merged 1 commit intomainfrom
opencode/curious-garden
Mar 13, 2026
Merged

refactor(api): include type segment in DO names#1520
braden-w merged 1 commit intomainfrom
opencode/curious-garden

Conversation

@braden-w
Copy link
Member

@braden-w braden-w commented Mar 13, 2026

DO names currently encode the user but not the resource type—user:{userId}:{resourceName} is the same shape for both workspace and document routes. Since WORKSPACE_ROOM and DOCUMENT_ROOM are separate Cloudflare namespaces, idFromName() produces different DO instances, so this hasn't caused runtime issues. But the name strings themselves are ambiguous: given user:abc:notes, you can't tell if it's a workspace or a document without additional context.

This becomes a real problem for any tracking or observability layer that stores DO names. A UNIQUE constraint on doName would collide when a user has a workspace and document with the same name, and log entries become unparseable without the namespace context that produced them.

The fix adds a type segment to every DO name:

user:{userId}:{type}:{name}

Both stub functions in app.ts change from a bare resource name to an explicit type prefix:

// Before
function getWorkspaceStub(c: Context<Env>) {
    const doName = `user:${c.var.user.id}:${c.req.param('workspace')}`;
    return c.env.WORKSPACE_ROOM.get(c.env.WORKSPACE_ROOM.idFromName(doName));
}

// After
function getWorkspaceStub(c: Context<Env>) {
    const doName = `user:${c.var.user.id}:workspace:${c.req.param('workspace')}`;
    return c.env.WORKSPACE_ROOM.get(c.env.WORKSPACE_ROOM.idFromName(doName));
}

Same pattern for getDocumentStub:document: instead of bare name.

┌─────────────────────────────────────────────────────────┐
│  Route                              │  DO Name          │
├─────────────────────────────────────┼───────────────────┤
│  GET /workspaces/epicenter.tab-mgr  │  Before: user:abc:epicenter.tab-mgr          │
│                                     │  After:  user:abc:workspace:epicenter.tab-mgr │
├─────────────────────────────────────┼───────────────────┤
│  GET /documents/my-note             │  Before: user:abc:my-note                     │
│                                     │  After:  user:abc:document:my-note             │
└─────────────────────────────────────┴───────────────────┘

Migration

Clean break—same approach as the tab-managerepicenter.tab-manager rename. Local-first clients hold the full Y.Doc locally and re-sync to the new (empty) DO on next connection. Old DOs sit idle until cleanup. Document snapshots stored in old DO SQLite are lost, which is acceptable during early development.

Change DO naming from `user:{userId}:{name}` to
`user:{userId}:{type}:{name}` so names are globally unique across
DO namespaces. Clean break—clients re-sync to new DOs.
@braden-w braden-w merged commit 274cdc4 into main Mar 13, 2026
1 of 8 checks passed
@braden-w braden-w deleted the opencode/curious-garden branch March 13, 2026 20:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant