diff --git a/.yoi/tickets/00001KWWE8E04/artifacts/.gitkeep b/.yoi/tickets/00001KWWE8E04/artifacts/.gitkeep new file mode 100644 index 00000000..e69de29b diff --git a/.yoi/tickets/00001KWWE8E04/item.md b/.yoi/tickets/00001KWWE8E04/item.md new file mode 100644 index 00000000..e3449c57 --- /dev/null +++ b/.yoi/tickets/00001KWWE8E04/item.md @@ -0,0 +1,66 @@ +--- +title: 'Scope Workspace Browser routes and API by workspace id' +state: 'ready' +created_at: '2026-07-06T19:25:08Z' +updated_at: '2026-07-06T19:48:42Z' +assignee: null +--- + +## 背景 + +現在の Workspace Browser は 1 Backend = 1 Workspace を前提に、Frontend route と Browser-facing API のどちらも暗黙の current Workspace を参照している。 + +```text +/ +/repositories/ +/objectives +/settings +/runtimes//workers//console + +/api/workspace +/api/repositories +/api/objectives +/api/settings/runtime-connections +/api/workers +``` + +この形では、将来 1 Backend process が複数 Workspace を扱う設計に進んだとき、URL / API authority / Sidebar data / Worker console context がどの Workspace に属するのか曖昧になる。1 Backend = 1 Workspace の間でも、Browser URL と API contract は Workspace id を含む形にしておく。 + +Workspace URL は slug/renameable handle ではなく immutable Workspace id を使う。多少長い id は許容し、URL の安定性を優先する。Route prefix は短く `/w//...` とする。Backend 管理 UI や global settings は将来 `/admin` / `/settings` / `/backend` など別 top-level に置ける。 + +同時に、Browser から叩く SvelteKit/Backend product API も Workspace id scope を持たせる。UI route だけ Workspace scoped にして API が `/api/...` のままだと、暗黙 current Workspace が残るため、Frontend は scoped API を使う。 + +## 要件 + +- Browser routes を `/w//...` に移す。 +- Browser-facing API に `/api/w//...` を追加する。 +- 1 Backend = 1 Workspace の現状でも、request path の `workspace-id` と Backend が serving している `workspace_id` を照合する。 +- workspace id mismatch は typed sanitized error として返す。Browser-facing には raw path / internal store / authority-bearing internals を漏らさない。 +- Frontend は route params の `workspaceId` を使う workspace-scoped API client/helper から API を呼ぶ。 +- Sidebar / settings / repository / objectives / worker console の links は workspace id を含む。 +- 既存 unscoped API は互換 alias として残してよいが、Frontend からは scoped API を使う。 +- 既存 unscoped routes は redirect するか、互換を残す場合も canonical route は `/w//...` とする。 +- Runtime API (`/v1/runtime`, `/v1/workers`) とは混同しない。この Ticket の API scope は Browser-facing Workspace Backend API の話である。 + +## 受け入れ条件 + +- `/w/` が現行 overview を表示する。 +- `/w//repositories/` が Repository detail を表示する。 +- `/w//objectives` と `/w//objectives/` が動く。 +- `/w//settings` が Runtime/Workspace settings を表示する。 +- `/w//runtimes//workers//console` が Worker console を表示する。 +- Frontend の API 呼び出しは `/api/w//...` を使う。 +- `/api/w//workspace`, `/repositories`, `/objectives`, `/workers`, `/settings/runtime-connections` など主要 Browser-facing API が scoped path で動く。 +- `workspace-id` が Backend の current `workspace_id` と違う場合は typed 404 または equivalent mismatch diagnostic を返す。 +- Sidebar navigation links と Worker console links は workspace id を含む。 +- 旧 unscoped route/API を互換として残す場合でも、Frontend test は scoped route/API を期待する。 +- `cd web/workspace && deno task check && deno task test` が通る。 +- `cargo test -p yoi-workspace-server` が通る。 + +## 非目標 + +- Backend の canonical store を multi-workspace DB に移行すること。 +- `/api/workspaces//...` 形式の long form API を同時に実装すること。 +- Workspace slug / handle / rename / alias 機能を実装すること。 +- Runtime `/v1/...` API に workspace id を path segment として入れること。 +- Backend global admin UI を完成させること。 diff --git a/.yoi/tickets/00001KWWE8E04/thread.md b/.yoi/tickets/00001KWWE8E04/thread.md new file mode 100644 index 00000000..f423772c --- /dev/null +++ b/.yoi/tickets/00001KWWE8E04/thread.md @@ -0,0 +1,24 @@ + + +## 作成 + +LocalTicketBackend によって作成されました。 + +--- + + + +## Intake summary + +Marked ready by `yoi ticket state`. + +--- + + + +## State changed + +Marked ready by `yoi ticket state`. + + +---