# Dry Run: Trial Cut of the Rewrite into frontend-v3

Started and finished: 6 October 2026 (result: `REWRITE-DRY-RUN-LOG.md`, section 8 of `REWRITE-INTEGRATION.md`) · Maintained by: Mitko (with Claude Code) · Part of `REWRITE-INTEGRATION.md`, section 8 (Phase B)

## Purpose

A practice version of the cut, done on a throwaway branch, to learn what the real cut costs and what breaks, before Bolt's last day is fixed and before anything is frozen or archived. Result: a measured effort, a list of problems, a list of changes that are cheaper in the rewrite beforehand, something the PO can see, and a go or no-go for the real cut.

## Rules

- **Throwaway.** Branch `dry-run/rewrite-cut` in the worktree `../kulibri-dry`, cut from `vue3-redesign`. Never merged, never pushed. Nothing changes in `vue3-redesign`, `master` or the rewrite repository.
- **Snapshot, no freeze.** The rewrite is copied from `origin/main` plus the unmerged branch `test/a1-a6-detail-view` (24 characterisation tests), merged in a detached temporary worktree, so no branch is created in the rewrite repository. Bolt keeps working.
- **No root `npm`.** All `npm` commands run inside `frontend-v3` or the rewrite worktree.
- **Rough is fine.** Goal is information. When a step passes its time box, write down where it stands and move on.
- **Everything is measured.** Each step ends with numbers in the log (`REWRITE-DRY-RUN-LOG.md`, in the dry-run branch): counts, errors by cause, minutes spent.

## Steps

### Step 0: Setup and baselines (time box 2 h)

1. Worktrees: `../kulibri-dry` (branch `dry-run/rewrite-cut`), `../kulibri-rewrite-snap` (detached rewrite snapshot).
2. Baseline of `frontend-v3`: `npm ci`, `npm run test`, `npm run build`. Record test files and tests passed, build time, bundle size.
3. Baseline of the rewrite snapshot: `npm ci`, `npm test`, `npm run typecheck`, `npm run build`. Record the same.
4. Collision list: every path that exists in both `src/` trees (`App.vue`, `main.ts`, `router/`, `i18n/`, `stores/auth.ts`, `api.ts` against `api/index.ts`, `index.css`, `__tests__/`).

**Done when:** both baselines are green or their failures are written down, and the collision list exists.

### Step 1: Copy the code (time box 4 h)

1. Rule for collisions: the rewrite wins for `views/`, `components/`, `composables/`, `utils/`, `__tests__/`; `frontend-v3` wins for the shell (`main.ts`, `App.vue`, `router/`, `stores/auth.ts`, `api/`, `index.css`); each other collision is decided one by one and logged.
2. Copy files. Keep the rewrite's folder structure and relative imports (no alias conversion).
3. Watch the `api.ts` against `api/index.ts` clash: `./api` resolves to the file first.

**Measure:** files copied, collisions and how each was decided.

### Step 2: Align tool versions (time box 4 h)

1. Take `frontend-v3`'s `package.json` as the base and add what the rewrite needs (`xlsx`, `lucide-vue-next` is shared). Pinia 3, vue-i18n 11, Vite 6, TypeScript 5.8.
2. `npm install`, then `vue-tsc -b`. Group the errors by cause.
3. Run the copied rewrite tests under the new versions. Group failures by cause (vue-i18n is the expected one).

**Measure:** type errors and failing tests, each by cause, and the fix per cause.

### Step 3: Merge the shell (time box 6 h)

1. Keep `frontend-v3`'s `main.ts`, `App.vue`, router guards (`createLoginGuard`, `createHandoverGuard`) and the catch-all.
2. Point the existing route names at the rewrite's views: dashboard, poll detail, editor, share, new poll, course, contacts, profile and membership. Keep the `/preview/…` rule for anything not adopted.
3. CSS: compare `index.css` and `tailwind.config.js` (both come from the Bolt prototype); merge the content globs and tokens; run `designTokens.spec.ts`.
4. Build: `vite build` writes `public/v3` and `resources/views/v3.blade.php` in the worktree.

**Measure:** routes rewired, token and class conflicts, build result.

### Step 4: Session login (time box 6 h)

1. The token layer (`http.ts`, `stores/auth.ts`) is replaced by `frontend-v3`'s session layer (`api/http.ts`, `stores/auth.ts`). Adapt the rewrite's `api.ts` to the helper signatures.
2. Take the token login screens (login, register, reset, Google, about 20 files) out of the router. They are not deleted in the dry run, only listed.
3. Update the specs that call `setToken` (8 files, among them the `PollDetailView` harness).

**Measure:** files changed, specs changed, anything the session model cannot do the way the token did (list it).

### Step 5: Run everything (time box 3 h)

1. Rewrite tests (about 1072 at the snapshot), `frontend-v3` tests, `vue-tsc -b`, build.
2. Classify each failure: caused by the cut, caused by the older `frontend-v3` screens being replaced, or pre-existing.
3. No fixes beyond what Steps 2 to 4 needed; everything else is listed.

**Measure:** pass and fail counts against the baselines, with causes.

### Step 6: See it run (time box 1 day; needs a decision)

Open the dashboard and one poll in the new UI with a real session, through `?ui=v3`. Two ways, to be decided at this point:
- **Local Laravel** in the dry-run worktree (`.env`, database, `composer install`, `php artisan serve`), with the built classic bundle copied from the main checkout (`public/legacy`, `resources/views/legacy.blade.php`, both gitignored) and `KULIBRI_UI_V3_ENABLED=true`.
- **Test server:** needs `master` merged into the branch and a deploy (the server's branch is set by hand in the Ansible repo). Heavier; only if local is not possible.

**Check:** log in at `/signin`, open `/dashboard` as v3, open a poll as owner, as participant and anonymously, use `?classic=1`, log out.

### Step 7: Report (time box 3 h)

1. Fill the log. Update the effort table in the plan (estimate against measured).
2. Write the report into `REWRITE-INTEGRATION.md`, section 8: effort, problems in order, changes that are cheaper before the freeze, the demo, go or no-go.
3. Keep the dry-run branch locally until the real cut, then delete it.

## Decision points

- After Step 2: if the version alignment alone exceeds two days, stop and decide whether to align before the cut in the rewrite.
- Before Step 6: local or test server.
- After Step 7: go or no-go, and Bolt's last day.

## Time box in total

About 3 working days to a running branch (Steps 0 to 6), then half a day for the report. If a step doubles its box, it is written down and the dry run continues.
