Mobile view-only support: below a md-width viewport (phone, or a narrow browser window), the app now forces view-only — same canEdit mechanism used for shared view-only diagrams — rather than trying to support touch editing on a canvas built for a mouse. The palette and inspector hide, the top bar collapses to just Diagrams + Account, and a bottom tab bar swaps between a full-screen canvas and a full-screen Bill of Materials.
A few real bugs surfaced by actually testing this on a phone got fixed along the way: h-screen → h-dvh (mobile browsers clip content under 100vh once the address bar collapses), quick-add's anti-stack offset was too small to actually prevent devices landing on top of each other, and the canvas's interactivity-lock button (misleading when editing's already disabled) now hides in any view-only context.
CI/CD pipeline (Woodpecker): every push lints, typechecks, and auto-deploys to a fully separate staging environment (own Supabase Cloud project, own Cloudflare Workers, staging.diagrav.com / staging-app.diagrav.com) — verified end-to-end with a real sign-in through the deployed staging app. Promoting to production is a manual "Deploy" button click on a main pipeline run, not automatic.
A couple of pipeline bugs (an invalid Woodpecker event name, an unpinned wrangler/supabase CLI version that hit a transient npm registry gap) got caught and fixed from real pipeline runs, not just written and hoped for.
A marketing-site bug surfaced by staging actually existing: site/'s Log in/Sign up links were hardcoded to the production app URL, so staging visitors were being sent to prod. Fixed with a small hostname-aware rewrite at load time.
Test plan
Verified pan/pinch-zoom on a real phone (not just browser dev-tools emulation, which has its own touch-simulation quirks)
Verified the full mobile layout (palette/inspector hidden, top bar trimmed, bottom tab bar, view-only banner) at narrow widths
Verified tsc -b clean at every step
Verified the CI pipeline end-to-end: staging deploy succeeds from a real push, production path is gated behind a manual deploy event and untouched by any of this
Verified staging's marketing site links to staging-app.diagrav.com, production's still links to app.diagrav.com
Manual production deploy (the "Deploy" button) — intentionally not exercised yet; no reason to touch real prod while proving this out
## Summary
- **Mobile view-only support**: below a `md`-width viewport (phone, or a narrow browser window), the app now forces view-only — same `canEdit` mechanism used for shared view-only diagrams — rather than trying to support touch editing on a canvas built for a mouse. The palette and inspector hide, the top bar collapses to just Diagrams + Account, and a bottom tab bar swaps between a full-screen canvas and a full-screen Bill of Materials.
- A few real bugs surfaced by actually testing this on a phone got fixed along the way: `h-screen` → `h-dvh` (mobile browsers clip content under `100vh` once the address bar collapses), quick-add's anti-stack offset was too small to actually prevent devices landing on top of each other, and the canvas's interactivity-lock button (misleading when editing's already disabled) now hides in any view-only context.
- **CI/CD pipeline** (Woodpecker): every push lints, typechecks, and auto-deploys to a fully separate staging environment (own Supabase Cloud project, own Cloudflare Workers, `staging.diagrav.com` / `staging-app.diagrav.com`) — verified end-to-end with a real sign-in through the deployed staging app. Promoting to production is a manual "Deploy" button click on a `main` pipeline run, not automatic.
- A couple of pipeline bugs (an invalid Woodpecker event name, an unpinned `wrangler`/`supabase` CLI version that hit a transient npm registry gap) got caught and fixed from real pipeline runs, not just written and hoped for.
- A marketing-site bug surfaced by staging actually existing: `site/`'s Log in/Sign up links were hardcoded to the production app URL, so staging visitors were being sent to prod. Fixed with a small hostname-aware rewrite at load time.
## Test plan
- [x] Verified pan/pinch-zoom on a real phone (not just browser dev-tools emulation, which has its own touch-simulation quirks)
- [x] Verified the full mobile layout (palette/inspector hidden, top bar trimmed, bottom tab bar, view-only banner) at narrow widths
- [x] Verified `tsc -b` clean at every step
- [x] Verified the CI pipeline end-to-end: staging deploy succeeds from a real push, production path is gated behind a manual deploy event and untouched by any of this
- [x] Verified staging's marketing site links to `staging-app.diagrav.com`, production's still links to `app.diagrav.com`
- [ ] Manual production deploy (the "Deploy" button) — intentionally not exercised yet; no reason to touch real prod while proving this out
Below md width, the app now forces view-only (same canEdit mechanism as a
shared view-only diagram) rather than trying to support touch editing:
palette and inspector panels hide, editing controls disable, and the top
bar collapses to just Diagrams + Account. A bottom tab bar swaps between a
full-screen canvas and a full-screen Bill of Materials, since there's no
room for both side by side. Canvas gets a few mobile-specific trims too:
MiniMap and the interactivity lock button hide whenever canEdit is false
(the lock button doesn't actually grant editing either way — nodesDraggable/
nodesConnectable already override it — so leaving it visible would just be
misleading), and h-screen is replaced with h-dvh throughout so the layout
doesn't get clipped by a mobile browser's collapsing address bar.
Also fixes quick-add's anti-stack offset (24px — far smaller than a device
node) to actually tile devices apart instead of leaving them nearly
overlapping, and logs a deferred "Auto-arrange" layout feature in
organized-ideas.md, surfaced by mobile visitors having no way to fix an
overlapping diagram themselves.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
Adds a dev:lan script (vite --host) so testing on a real device doesn't
require permanently changing vite.config.ts's default 127.0.0.1-only
binding. Pairs with a small supabaseClient change: when the configured
Supabase URL is local (127.0.0.1/localhost), the client now swaps in
whatever hostname the page itself was loaded from, so a phone hitting the
dev server's LAN IP gets API calls routed to that same IP automatically —
no more hand-editing VITE_SUPABASE_URL per network. Never touches a real
production Supabase URL.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
Adds .woodpecker.yml (lint + typecheck on every push, auto-deploy to a
shared staging environment on every push, manual Deploy-button promotion to
production on main) and env.staging blocks in both wrangler configs so
staging gets its own Workers (diagrav-app-staging/diagrav-site-staging at
staging-app.diagrav.com/staging.diagrav.com) rather than sharing anything
with production.
Staging also got its own fully separate Supabase Cloud project (own
database, own Auth config reusing the same Google OAuth client with an
extra redirect URI, own Resend-backed SMTP) — migrated, seeded with the
public catalog, and verified end-to-end with a real sign-in through the
deployed app before wiring any of this into CI.
Updates deployment-plan.md's CI/CD section to match what actually got
built, superseding the earlier manual-pushbutton-for-both-environments
version of the plan.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
Caught from the linter warnings on the first real pipeline run (#1) — the
production-promotion step's event filter used \`deploy\`, an invalid event
name, so it would never have matched Woodpecker's actual deploy-button
event (\`deployment\`) and the production step would have silently never
run. Staging's own deploy (a push-triggered step) was unaffected and
verified working on that same run.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
Woodpecker's linter flags steps with no event filter as a "bad habit" (they'd
otherwise run on every event type, including ones added to Woodpecker in the
future). Scoped to [push, deployment] specifically — not just push — since a
production deploy re-runs the whole pipeline as a deployment event, and
deploy-production's build needs these steps (especially install's node_modules)
to have actually run first.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
site/ has no build step (served as-is, no per-environment templating), so
its three app links were hardcoded to https://app.diagrav.com/ in the
markup — meaning staging.diagrav.com was sending visitors to the production
app instead of staging-app.diagrav.com. Rewrites them at load time based on
location.hostname instead of maintaining a second copy of the file;
defaults to the production app host everywhere except the exact staging
hostname, so production's own links are unaffected.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
The last pipeline run failed on \`npx wrangler deploy\` with npm unable to
find wrangler@4.144.0 — a transient registry propagation gap right after
that version's release, not an actual config problem (it installs fine
moments later, confirmed locally). Both wrangler and the supabase CLI were
being fetched fresh via bare npx on every single pipeline run instead of
coming from the lockfile like every other dependency, which is exactly
what left CI exposed to whatever npm's registry happens to be doing at
that moment. Pinning them means npm ci resolves the exact locked version
every time, and npx picks up the local install instead of hitting the
registry at all.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017DUU6CnxECCDeqDNYJgr5x
aarbit
merged commit e4c36e2960 into main2026-09-29 21:55:52 +00:00
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
md-width viewport (phone, or a narrow browser window), the app now forces view-only — samecanEditmechanism used for shared view-only diagrams — rather than trying to support touch editing on a canvas built for a mouse. The palette and inspector hide, the top bar collapses to just Diagrams + Account, and a bottom tab bar swaps between a full-screen canvas and a full-screen Bill of Materials.h-screen→h-dvh(mobile browsers clip content under100vhonce the address bar collapses), quick-add's anti-stack offset was too small to actually prevent devices landing on top of each other, and the canvas's interactivity-lock button (misleading when editing's already disabled) now hides in any view-only context.staging.diagrav.com/staging-app.diagrav.com) — verified end-to-end with a real sign-in through the deployed staging app. Promoting to production is a manual "Deploy" button click on amainpipeline run, not automatic.wrangler/supabaseCLI version that hit a transient npm registry gap) got caught and fixed from real pipeline runs, not just written and hoped for.site/'s Log in/Sign up links were hardcoded to the production app URL, so staging visitors were being sent to prod. Fixed with a small hostname-aware rewrite at load time.Test plan
tsc -bclean at every stepstaging-app.diagrav.com, production's still links toapp.diagrav.com