Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
88 changes: 88 additions & 0 deletions .agent/context/20260908T000000Z-recovery-route-composition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Session Context: recovery-route-composition

## Date/time

- UTC: 2026-09-08T18:25:19Z

## User goal

Serve the existing `apps/web` frontend at the domain root and the recovery UI
at `/recovery` from the same Cloudflare assets deployment.

## Original prompt/request

The current Cloudflare deployment includes `./apps/web/dist`, while UI exists
in `packages/recovery-ui`. Combine them so `oneshot.kapustazh.dev` keeps the
current pages and `oneshot.kapustazh.dev/recovery` serves the recovery UI; do
this on a new branch.

## Assumptions

- The recovery site is the existing synthetic fixture viewer, not a new live
API integration.
- The current Wrangler assets directory remains `apps/web/dist`.
- The branch should start from the clean current `develop` branch.

## Plan

1. Build the main app and recovery site into one static asset tree.
2. Verify asset paths, production builds, and Wrangler configuration.

## Key decisions

- Emit recovery files to `apps/web/dist/recovery` and use Vite base
`/recovery/`, preserving the root app bundle and making nested assets resolve
under the route.
- Keep Cloudflare's existing SPA fallback because both apps are static entry
points and the recovery viewer does not require server-side routes.

## Files/components touched

- `package.json`: added the combined frontend build script.
- `wrangler.jsonc`: changed the Cloudflare build command to the combined build.
- `packages/recovery-ui/vite.site.config.ts`: configured the `/recovery/` base
and shared output directory.
- `apps/web/README.md`: documented the deployed route and build command.
- `packages/recovery-ui/README.md`: updated the package deployment instructions
for the combined asset tree and `/recovery/` route.

## Commands/checks

- Branch creation: `feature/recovery-route-composition`.
- `pnpm build:frontend` - passed; root output and `/recovery/` output were
emitted into one asset tree.
- `pnpm --filter @oneshot/web test` - passed, 27 tests.
- `pnpm --filter @oneshot/recovery-ui test` - passed, 51 tests.
- Both package typechecks and linters - passed.
- `pnpm exec wrangler deploy --dry-run` - passed; Wrangler read 9 asset files
from `apps/web/dist` and exited without uploading.
- Prettier check on changed config files - passed.
- Documentation correction: `packages/recovery-ui/README.md` now documents
`pnpm build:frontend`, `apps/web/dist/recovery`, and `/recovery/`.

## External-doc findings

- None required; this change uses the repository's existing Vite and Wrangler
configuration.

## Unresolved questions

- None.

## Git and PR state

- Branch: `feature/recovery-route-composition`
- Base: `develop` (working tree was clean at branch creation)
- Commit: uncommitted
- PR: not created
- CI: not run

## Review gates

- Gate A: FAIL on prior tree due stale recovery deployment docs; fresh review
pending for the corrected tree.
- Gate B: NOT RUN

## Handoff/next steps

1. Review the branch and deploy it through the normal Cloudflare workflow.
16 changes: 13 additions & 3 deletions apps/web/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@

Minimal operator UI for creating or replaying a Business Intent and reading its authoritative status.

This package is not the production Worker asset target yet. Deploy it only after
`VITE_ONESHOT_API_BASE_URL` points to a reachable OneShot API. An assets-only
Worker cannot serve `/health` or `/v1`.
The Cloudflare asset deployment serves this app at the domain root and the
recovery fixture viewer from `@oneshot/recovery-ui` at `/recovery/`. Deploy it
only after `VITE_ONESHOT_API_BASE_URL` points to a reachable OneShot API. An
assets-only Worker cannot serve `/health` or `/v1`.

```powershell
pnpm --filter @oneshot/web dev
```

Vite proxies `/v1` and `/health` to the local API. For a separate deployed API, set the public build variable `VITE_ONESHOT_API_BASE_URL`. Enter the demo service token at runtime; the UI keeps it in memory and never persists it.

The combined production asset tree is built with:

```powershell
pnpm build:frontend
```

This emits the main app to `apps/web/dist` and the recovery viewer to
`apps/web/dist/recovery`, matching the Wrangler asset directory.

The client consumes generated `@oneshot/contracts` types from frozen OpenAPI v1. Tests use deterministic fetch responses matching that contract.
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"db:reset-demo": "pnpm --filter @oneshot/storage-postgres build && node scripts/reset-demo-db.mjs",
"deploy": "wrangler deploy",
"dev:frontend": "wrangler dev",
"build:frontend": "pnpm --filter @oneshot/web build && pnpm --filter @oneshot/recovery-ui build:site",
"dev:web": "pnpm --filter @oneshot/web dev",
"format": "prettier --write \"**/*.{ts,mts,mjs,json,jsonc,yml,yaml}\"",
"format:check": "prettier --check \"**/*.{ts,mts,mjs,json,jsonc,yml,yaml}\"",
Expand Down
9 changes: 5 additions & 4 deletions packages/recovery-ui/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ pnpm --filter @oneshot/recovery-ui dev
Open `/?scenario=aged-unknown`. Any scenario exported by
`RECOVERY_SCENARIOS` may be selected.

The same fixture viewer is the Wrangler static-asset target. From the repository
root, `pnpm deploy` builds `site-dist` and deploys it to the configured custom
domain. Its persistent banner identifies all data as synthetic review fixtures;
it is not live sponsor evidence.
The same fixture viewer is included in the combined Wrangler static-asset
target. From the repository root, `pnpm build:frontend` builds the main app and
emits this viewer to `apps/web/dist/recovery`, where it is served at
`/recovery/` on the configured custom domain. Its persistent banner identifies
all data as synthetic review fixtures; it is not live sponsor evidence.

## Frozen mock boundary

Expand Down
3 changes: 2 additions & 1 deletion packages/recovery-ui/vite.site.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@ import { defineConfig } from 'vite';

export default defineConfig({
plugins: [react()],
base: '/recovery/',
build: {
outDir: 'site-dist',
outDir: '../../apps/web/dist/recovery',
emptyOutDir: true,
},
});
2 changes: 1 addition & 1 deletion wrangler.jsonc
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"name": "oneshot",
"compatibility_date": "2026-09-07",
"build": {
"command": "pnpm --filter @oneshot/web build",
"command": "pnpm build:frontend",
},
"assets": {
"directory": "./apps/web/dist",
Expand Down
Loading