Worker Factory & Member API
Worker factory
Section titled “Worker factory”createApp() (src/api/index.ts) is the factory that assembles the OpenAPIHono app — middleware chain, route registration, error envelope — and is reused everywhere the API runs: the Worker entry (src/worker.ts) and the test harness (tests/helpers/test-worker.ts) both build the app from the same factory, so tests exercise the real middleware/route wiring. See Worker API & Clerk Auth for the chain.
The same factory feeds production and tests, and registers the membership routes that back list sharing:
flowchart LR
W["src/worker.ts"] --> APP["createApp()<br/>src/api/index.ts"]
T["tests/helpers/test-worker.ts"] --> APP
APP --> LM["registerListMembersRoutes<br/>src/api/routes/list-members.ts"]
LM --> REPO["createListMembersRepository<br/>src/db/repositories/list-members.ts"]
REPO --> D1[("D1: listMembers")]
LM --> NM["notifyMembership()<br/>src/api/lib/notify.ts"]
SS["ShareSurface.tsx<br/>island"] -->|"add / remove member"| LM
Member API
Section titled “Member API”List sharing is the membership surface (src/api/routes/list-members.ts, registerListMembersRoutes) backed by createListMembersRepository (src/db/repositories/list-members.ts):
- Add/remove Members of a List — owner-only; a List can only be shared with registered Users (Product Brief §5.2).
- Membership changes drive
notifyMembership(...)(signals the list’s users and the affected user) and, on removal, client-sideevictRevoked(...)(see DB Schema & Notify-Affected, Sync-Core Reconcilers). - The
ShareSurface.tsxisland is the client UI for managing Members. - Assignment (spec 012) is membership-dependent: a Task may be assigned only to a Member; removing a Member clears their assignments.
A member removal commits to D1, then fans a signal to both the list’s users and the removed user so their client evicts the revoked list:
sequenceDiagram participant Owner participant LM as "registerListMembersRoutes" participant Repo as "listMembersRepository" participant D1 as "D1: listMembers" participant Notify as "notifyMembership()" Owner->>LM: DELETE member (owner-only) LM->>Repo: remove(listId, userId, now) Repo->>D1: soft-delete membership row D1-->>Repo: ok LM->>Notify: notifyMembership(c, listId, removedUserId) Notify-->>Owner: 2xx (fan-out off response path) Note over Notify: signals list users + removed user<br/>client evictRevoked drops the list
Related: Worker API & Clerk Auth, Idempotency & List-Members Repos, Group & List Context Menus (the share entry point).