Repository navigation
Conversation
One page that sends a scene (a bundled sample, or a dropped scene.json or zip) to the placement server's POST /v1/placements and shows the answer: an inspector's stamp for the decision, the spot and cable run, the server's site plan, every check with its reason, and the views still missing. Loading, refusals and an unreachable server are their own states; with no server, a sample can show the answer recorded for it. The server address is configurable (VITE_PLACEMENT_API, a dev proxy at /api, or Change in the page) and ?sample= links to a sample. The result types are generated from a vendored copy of server/schemas/result.schema.json (t3/server at 6a623d8) and answers are validated against it at runtime; a test fails when the copy, the generated types and the server's schema disagree. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: trueThanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
- A new answer no longer arrives dimmed: the 150ms delay applies only to dimming a stale answer, not to undoing it. - Screen readers hear one line per state from a status region instead of the whole answer; the verdict is a heading and the page has one h1. - Focus returns to Change when the server form closes; Escape cancels; the address field has URL keyboard hints, a 16px font (no iOS zoom) and a 3:1 edge. - The root font size follows the browser setting; no grey tap flash; forced-colors and reduced-motion states keep their meaning. - Answers are validated by a generated standalone validator instead of Ajv compiling the schema with Function() at load: no eval, and the bundle drops from 125 to 92 KB gzipped. - State: health follows each answer, a file refused in the browser aborts the request in flight and can't be resent, changing the server aborts the old request and retries a failed scene, storage errors are survivable, and a file pick clears ?sample=. - Drops outside the zone no longer navigate away; the zone doesn't flicker; the site plan reserves its size; replacing an answer only re-stamps instead of replaying every section. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Behavior-preserving: the failure view reads its input once instead of re-checking it inside each handler, and an unnamed policy reads as "unnamed" rather than "?". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…ed API Vercel answers an upload over 4.5 MB with a bare 413 before the server sees it; the page now says the upload is too big and to send scene.json or a zip without the photos, instead of calling the server unreachable. The README records that previews build with VITE_PLACEMENT_API set to https://house-scanning-server.vercel.app. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Size: the hosted server's host refuses bodies over 4.5 MB without CORS headers, so the browser saw only a network error and the page said to start uvicorn. The page now refuses such files before sending and, for a zip, says scene.json alone is enough. - One upload per refusal: the answer is requested first; the site plan is asked for only after it, and fills in when it arrives. - HTTP errors without the server's format (a 504 from the host, a 404 from another site) are reported as HTTP errors with their status, not as an unreachable server. An http:// server entered on the https page gets a warning, and its failure says the browser blocked it. - The stamp reads "Needs review" whenever the rules aren't approved for automatic decisions, whatever the decision field says. - Samples are re-recorded under the public rules the hosted server uses (all manual review), replacing an invented auto-approving policy. - Contract: answers with added fields are accepted within the same major schema version, as the iOS app does. The drift test against server/schemas now always runs (this branch is stacked on t3/server), and web CI also runs when server/schemas changes. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Deployment failed for project house-scanning-web with the following error: Learn More: https://vercel.com/sam-gus-projects-7a4b6082?upgradeToPro=build-rate-limit |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The server's requests now say how far a view must reach. The vendored schema and the generated types and validator are regenerated, and the samples re-recorded against the same server. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Note Review skipped Codemetrics is installed on this repository, but it hasn't been added to your team yet. To enable AI code reviews for this repo, go to your dashboard and add house-scanning to your team's repositories. |
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The hosted server now decides under a labelled demo policy, so the saved sample answers are re-recorded under it (a pass, a manual review and a reject, each saying the rules are not Base's), and the vendored result schema adds policy.notice. The server appends the notice to the summary, so the page shows it without a change. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
|
Closing without merging. The page has been parked since the morning because the product is the iOS app, and it was useful only for checking the server before the app could upload. The branch stays if a reviewer view comes back. |
A6 imports lamar_io with a star import, which ruff flags as F403 and F405. Those folders are synced from the store, so the ignore belongs in the breadth per-file-ignores.
The placement result on the web: a single page that sends a scan to the placement server and shows the answer. A Base reviewer or homeowner can read it in a few seconds.
Stacked on #11 (base
t3/server), so the page's copy of the result schema is tested against the server's in CI. Merge #11 first; this PR's own changes are inweb/and.github/workflows/web.yml.Live preview: https://house-scanning-p56ke670g-sam-gus-projects-7a4b6082.vercel.app, deployed at 1ebc0f4. Previews build with
VITE_PLACEMENT_API=https://house-scanning-server.vercel.app, the hosted placement server (public rules under its labelled demo policy, #11), so they answer live with no laptop. Git auto-deploy is off for this project, so previews are deployed by hand when the page changes.What changed
A new reviewer page in
web/. It is one page with no routing or state library.scene.jsonor zip bundle. The page posts it toPOST /v1/placementson the placement server (server: placement solver, rules and API (S2) #11).http://server entered on the https page gets a warning, because the browser will block it. With no server, a sample can show the answer the server gave when it was recorded, labelled "Saved answer".scene.jsonis small, so the team kept it that way.VITE_PLACEMENT_API, or/api, whichpnpm devandpnpm previewproxy to a local server. A reviewer can change it in the page.?sample=<id>opens a sample, so a link can share an answer. The address can't be set from a link, so a link can't send someone's scan to another server.How the result types stay in sync
src/contract/result.schema.jsonis a byte-identical copy ofserver/schemas/result.schema.json, most recently updated formissing_evidence[].out_ft(ef15f1e).pnpm contractgenerates two files from it:result.ts(the types) andvalidate-result.js, a standalone validator. Every answer is validated at runtime, so a server that breaks the contract shows a specific error ("at /decision: must be equal to one of the allowed values") instead of a broken page.The generated files accept fields the copy doesn't know, as long as
schema_versionhas the same major version (1.x), so a server that adds a field doesn't break a deployed page; the iOS app does the same. An answer from schema 2 is refused at/schema_version. Only the generated files are loosened (tolerantSchemainscripts/contract-lib.ts); the copy stays identical to the server's.scripts/contract.test.tsfails when the generated files don't match the copy, or the copy doesn't match the server's schema. Because this PR is stacked on #11,server/schemasis present and the drift test always runs; a one-byte change to the server schema makes it fail. The Web workflow also runs whenserver/schemas/**changes. The bundled samples' saved answers are recorded under the public rules the hosted server uses, and a test checks that.UI changes
A new page, so the captures are after-only. Since #11's demo policy (cd0da8b), the hosted server decides automatically and labels each answer as demo rules, so the samples read Fits, Needs review and No spot. Captured from the preview at 1ebc0f4, 1280 px wide:
The captures below are from a7c9b12, when the hosted server's public rules sent every answer to a person; the layout hasn't changed since. Desktop is 1280 px wide; phone is 390 px (iPhone 12 Pro).
Verification
At 1ebc0f4, from
web/:pnpm check(lint, typecheck, test, build): passes, with 74 tests and none skipped; CI runs it, including the contract drift test. Tests cover the size refusal before sending, one request per refused scene, HTTP errors apart from network errors, answers with added fields under 1.x, the mixed-content check, the stamp under unapproved rules, and that every saved answer was recorded under the hosted server's demo policy with the decision it gives (pass, manual review, reject).413 FUNCTION_PAYLOAD_TOO_LARGEwith noaccess-control-allow-origin, which is why the page refuses such files itself.prep-for-prodreview.Risk
scene.jsonalone.objects[2] garage_door). Fixing that wording belongs to the server.Checklist
🤖 Generated with Claude Code