summaryrefslogtreecommitdiffhomepage
path: root/notes/archived-workspace-create-warning-plan.md
blob: 537473bb145ec9aab03d4e76935a127d4c6835e1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# Plan — Warn when creating a workspace whose slug belongs to an archived workspace

Status: requested by user, ready to implement
Branch: `feature/archived-workspace-create-warning`
Scope: **frontend only**. No backend change (the backend already exposes everything needed).

---

## 1. User requirement

> "I want the frontend to warn me if I try to create a workspace that already
> exists and is archived (it should say you can't)."

So: when the user submits the **New workspace** form with a slug that matches an
existing **archived** workspace, the frontend must **not** create/ensure it and
must show a message saying it **can't** be created because a workspace with that
name already exists and is archived.

## 2. Current behavior (why it's wrong today)

- `HomeHeader.svelte` (`src/features/workspaces/ui/HomeHeader.svelte`) — the
  New-workspace popover. `submit()` validates the slug with `isValidSlug`, then
  calls `onCreate(slug)` and shows `result.error` in the existing `slugError`
  slot when `result.ok === false`.
- `WorkspacesHome.svelte` → `createWorkspace(slug)` calls `store.ensure(slug)`,
  then `store.refresh()`, `tiles.placeFirstEmpty(slug, …)`, and enters rename
  mode (`renamingId = slug`).
- `store.ensure` → `http.ensure` → backend `PUT /workspaces/:id`, which is
  **idempotent**: for an existing archived workspace it just returns it
  (`archived: true`) — no error. The active list (`GET /workspaces`, archived
  excluded by default) doesn't contain it, yet the home grid places a tile for
  it and enters rename mode. Silent and confusing.

Backend facts (no change needed):
- `GET /workspaces/:id` → the workspace incl. `archived: boolean`, or 404.
  Frontend adapter already has `http.get(id)` (`src/features/workspaces/adapter/http.ts`)
  — note it currently returns `null` for **both** 404 and network/other errors.
- `GET /workspaces?archived=true` → archived-only list (the store's
  `refreshArchived()` / `archivedList`, used by the Archived view).

## 3. Required behavior

1. On submit, **before** calling `ensure`, determine whether a workspace with
   that slug exists and is archived. Use an authoritative check against the
   backend (e.g. `GET /workspaces/:id`) — do **not** rely on `archivedList`
   alone, since it's only loaded when the Archived view is opened.
2. If it exists and is archived:
   - do **not** call `ensure`, do not refresh/place a tile, do not enter rename;
   - keep the popover open and show the error in the existing `slugError` slot,
     clearly saying it can't be created because an archived workspace with that
     name already exists. Suggested wording:
     `A workspace named "<slug>" already exists and is archived — you can't create it.`
     (It's fine to append a short hint that it can be restored from Archived
     workspaces, but don't add new UI controls for that.)
3. If it doesn't exist, or exists and is **not** archived → today's behavior,
   unchanged.
4. If the existence check itself fails (network/server error), don't silently
   swallow it in a way that creates an archived workspace's tile: either surface
   an error, or proceed exactly as today — pick one, keep it simple, and justify
   it in the report. (Distinguishing 404 from "request failed" may require a
   small adapter/store change; that's in scope.)
5. While the check is in flight, the existing `submitting` state should cover it
   (no double submits).

Follow the frontend's architecture rules in `AGENTS.md` (where decision logic
lives, store/adapter boundaries, Svelte 5 runes conventions, styling).

## 4. Out of scope
- Creating a slug that matches an existing **active** workspace (unchanged).
- Any backend change (e.g. making `PUT /workspaces/:id` reject archived ids).
- New UI for unarchiving from the popover.

## 5. Tests
- Unit/store test: creating an archived slug returns `ok: false` with the
  "can't create" message and does **not** call `ensure`.
- Non-archived existing slug and brand-new slug → `ensure` is called as before.
- Check-failure path per your choice in 3.4.
- Component test (`HomeHeader.test.ts` or `WorkspacesHome` level, whichever
  matches existing patterns): the message renders in the popover and the
  popover stays open.

## 6. Verification gate
`bun install`, `bun run typecheck`, `bun run test`, `bun run check`,
`bun run build` — all green. Commit to
`feature/archived-workspace-create-warning` only. Do not merge or push.