Skip to content

feat: SvelteKit web app (prod parity) - #52

Merged
szymeo merged 36 commits into
mainfrom
feat/svelte
Oct 9, 2026
Merged

szymeo merged 36 commits into
mainfrom
feat/svelte

Conversation

@szymeo

@szymeo szymeo commented Apr 27, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • Replaces the legacy React app with the SvelteKit app in apps/web (Cloudflare Worker), at parity with what's in production today.
  • Backend/API parity work, typed OpenAPI SDK package, Cloudflare/CI wiring, and shared agent commands from the recovered branch history.
  • Merged current main (PostHog sourcemaps + backend deploy changes) and fixed the code this branch added against it.

Prod parity pass (this round)

Each gap was reproduced end-to-end against a local stack and checked against the React app with screenshot diffs.

  • Unsaved edits: the editor stays mounted across tabs, so edits survive tab switches.
    Project switches with unsaved edits go through the unsaved-changes dialog instead of silently reloading the editor.
    The dialog supports ⌘S, warns when the project changed elsewhere, and closes on Esc.
  • Live sync: the project events stream reconnects after drops (with token refresh), so "updated elsewhere" keeps protecting edits.
    Push is blocked while the project was updated elsewhere.
  • Restored features: first-run tour, drag-to-reorder projects, one-click suggested projects, prod-style search results, active invites (copy link, created time, refresh after invite), history author overflow, settings tab, prod mobile layout (header Save/Push, compact history, "Changed by" footer).
  • Visual parity: tooltips, toasts (top-center, GitHub sync toast), dialogs, user menus, kbd hints, Tabler icons, editor framing, unlock dialog.
    Desktop and mobile states diff at <0.1% against prod except the intentional differences below.
  • GitHub App callback: keeps the one-time state check (CSRF guard) and now explains the failure instead of silently redirecting.
  • Config: Worker vars carry the public Google/GitHub OAuth client IDs (they were empty, which would have broken login after cutover).

Repo/CI fixes

  • The root pnpm-workspace.yaml broke CLI releases (installs and changesets resolved the workspace root) and left the backend with a second, drifting lockfile.
    The repo is now one workspace with one lockfile: cli joined it, changesets config moved to the repo root, and the backend image builds from the repo root via pnpm deploy.
  • Local pnpm build in backend/ no longer uploads sourcemaps to PostHog; the Dockerfile uses build:release.
  • Web lint works again (prettier plugin crash fixed, eslint parses TS in .svelte) and runs in CI.
  • Removed the never-imported application/infrastructure/domain layer and other dead files.

Intentional differences from prod

  • History masks secret values according to the project's "reveal on" setting (prod shows them in plaintext).
  • No client-side PostHog; key product events are recorded by the backend.
  • No /app/developer page.
  • Browser auto-locks after 30 minutes idle.

Deploy notes

  • Merging redeploys the backend (Docker build now uses the repo root as context) and deploys the Worker.
    cryptly.dev DNS currently points at Vercel (not proxied), so the Worker route takes no traffic until the cutover in docs/web-app-cutover-runbook.md.

Verification

  • backend: pnpm test (199 passed), pnpm build; Docker image built from the repo root and booted against Mongo.
  • apps/web: pnpm lint, pnpm check, pnpm build, Playwright browser-lock (incl. new unsaved-edits regression test) and visual parity suites.
  • frontend: pnpm build. cli: pnpm test, pnpm build, changeset dry-run bumps only @cryptly/cli.
  • Manual E2E against a local stack: invite link create/accept with decryption, SSE reconnect across a backend restart, mobile save/push.

szymeo added 19 commits April 26, 2026 19:25
- Remove AppLayout from /app routes so login matches React (no extra chrome)
- Implement BlogEditorPage with React parity (admin gate, split editor, save flows)
- Add blog API client, BlogMarkdown, and markdown rendering helpers
- Align AcceptInvitationPage guest state and LocalLoginForm with React
- Add Playwright visual parity tests (pixelmatch) and test:parity script
- Ignore Playwright output dirs; extend apps/web devDependencies

Made-with: Cursor
- Replace stub ProjectsPage with GripLoader, auto-redirect to latest project,
  and first-project create flow (encrypted payload + ProjectsApi)
- Add ProjectsApi client (list/create) and GripLoader (accent #DDA15E)
- Add auth store, AuthApi, user API, and symmetric/asymmetric crypto helpers
  required for project creation (wrap key with user public key)

Made-with: Cursor
- Add daisyui devDependency so @plugin resolves on CI (Svelte app.css).
- Document Node >=20.19 via root + apps/web engines and .nvmrc files.
- Set wrangler compatibility_flags to nodejs_als and nodejs_compat for SvelteKit.

Made-with: Cursor
AcceptInvitationPage and auth UI import $lib/auth/after-login; the file was untracked so Vite failed on CI.

Made-with: Cursor
- loadUserData returns boolean; default PUBLIC_APP_URL to dev port 9090
- ProjectsApi: getProject, updateProjectContent
- ProjectsPage: load profile before projects; errors, retry, passphrase hint, create errors
- SecretsEditorPage: fetch/decrypt via keystore like main app; debounced save, Save/⌘S, locked/read-only states

Made-with: Cursor
- Add /app/cli-authorize in SvelteKit with cli-flow API and client-side crypto
- Preserve allowlisted return path via sessionStorage through OAuth; invite still wins in gotoAfterLogin
- Remove unused device-flow placeholder module
- Expand visual parity routes; add MANUAL_SMOKE matrix
- Document flip/rollback in docs/web-app-cutover-runbook.md; README and WEB_APP_URL defaults for Svelte dev (9090)
- Add web-ci.yml for pnpm --filter web check + build

Made-with: Cursor
…nav guard

- Backend: ProductAnalyticsService + identify/login + project/secrets/git semantic events; POST analytics/secrets-pushed ack; Jest imports PosthogAnalyticsModule
- Web: remove posthog-js; device-flow SSE + UnlockBrowserDialog + approver dialog in layout
- Members: pending link/personal invitations list + revoke (admin)
- Secrets editor: unsaved SPA navigation guard + beforeunload dialog
- Integrations: acknowledge secrets-pushed after GitHub push; MOBILE_QA_CHECKLIST.md

Made-with: Cursor
@vercel

vercel Bot commented Apr 27, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated
cryptly Ready Ready Preview Oct 9, 2026 3:36am UTC

@cloudflare-workers-and-pages

cloudflare-workers-and-pages Bot commented Apr 27, 2026 •

Copy link
Copy Markdown

Deploying with  Cloudflare Workers  Cloudflare Workers

The latest updates on your project. Learn more about integrating Git with Workers.

Status Name Latest Commit Updated (UTC)
✅ Deployment successful!
View logs
cryptly 241fff4 Apr 28 2026, 08:50 AM

szymeo added 2 commits October 8, 2026 19:41
- add cli to the workspace and drop per-package lockfiles so the root lockfile is the single source of truth
- move the changesets config to the repo root (changesets resolves the workspace root) and keep private packages unversioned
- build the backend image from the repo root with pnpm deploy, and point backend/cli CI at the root lockfile
- split the PostHog sourcemap upload into build:release so local builds stop uploading
- set the public OAuth client ids for the Cloudflare worker
szymeo added 6 commits October 8, 2026 20:56
- keep the secrets editor mounted across tabs so unsaved edits survive tab switches
- route project switches with unsaved edits through the unsaved-changes guard instead of silently reloading the editor
- reconnect the project events stream after drops (with token refresh) so external updates keep protecting edits
- block pushes while the project was updated elsewhere
- restore the first-run tour, drag-to-reorder projects, one-click suggested projects, and legacy search results
- restore active invites (copy link, created time, refresh after invite), history author overflow, and the settings tab
- match prod tooltips, toasts, dialogs, kbd hints, icons, and editor framing
- legacy-style user menu dropdowns (desktop + mobile) that are no longer hidden behind the main pane
- add-people, member, integration, and create-project dialogs match prod headers, steppers, tooltips, and Tabler icons
- integrations rows, suggestions, and push tip use prod icons/states; history search no longer steals focus
- regression test for unsaved edits across tab and project switches
- mobile tabs use prod icons with scroll fades and the header Save/Push split button
- mobile editor uses the prod font size and gutter, with the "Changed by" footer
- mobile history uses the compact list + diff layout instead of the desktop panes
- floating save/push pill and first-run tour stay desktop-only, like prod
Same position, overlay, spacing, Tabler icons, autofocused input, and error row as prod; the editor stays blank behind the dialog like prod.
- fix the prettier crash (prettier-plugin-tailwindcss 0.6 -> 0.7), add .prettierignore, format the app
- parse TS in .svelte for eslint and fix all reported issues (resolve() navigation, keyed each blocks, real types)
- run lint in web CI
- delete the never-imported application/infrastructure/domain layer, dev page, and unused UI
@szymeo szymeo changed the title feat: svelte xP feat: SvelteKit web app (prod parity) Oct 9, 2026
- backend: declare 200/201 responses so OpenAPI types response bodies, fix
  record, optional, query, and wrong response schemas
- sdk: regenerate, expose the typed openapi-fetch client plus unwrap()
- web: move all API modules onto the SDK and drop hand-written DTOs; the
  types caught a phantom project.integrations field
- web: replay the request body when retrying after a token refresh
- web: close project dialogs on Escape, keep role tooltips unclipped
- cli: replace axios with the SDK client, test the 401 refresh replay
- ci: fail when the generated SDK is stale, check the CLI with the web app
@szymeo
szymeo marked this pull request as ready for review October 9, 2026 03:38
@szymeo
szymeo merged commit e50d15b into main Oct 9, 2026
3 checks passed

This branch was successfully deployed

1 active deployment
Preview — e7f6940c Deployed Oct 9, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant