INSTALL: "Field Measurement" module inside TAO Nexus. # Context TAO Nexus is our construction intelligence platform (this workspace). TAO Vision is a standalone room-scan / measurement tool I built in a separate Emergent workspace for drywall, paint, and flooring contractors. I want you to rebuild it natively as a module inside TAO Nexus, adapted to our stack, our auth, and our brand. Reference (visual + feature parity target): https://ar-room-scanner.preview.emergentagent.com (login: demo@ar.com / demo123) # Where it lives in TAO Nexus Add a top-level module called "Field Measurement" reachable from: 1. The main platform navigation (add nav item between "Field Operations" and "AI Insights"). 2. A card on /platform titled "Field Measurement" that links into it. 3. A dedicated route /platform/field-measurement (or /app/measurement — match the routing convention we already use). The module has its own left-side sub-nav with 4 sections: • Home — recent scans + 6 category tiles (Kitchen, Bedroom, Office, Exterior, Bathroom, Living Room) + NEW SCAN CTA • Gallery — filterable list of every scan across all jobs • Jobs — multi-scan projects grouped by customer/site • Settings — company presets used by the PDF quote # Data model (Postgres / MongoDB — match what TAO Nexus already uses) USER (reuse the existing TAO Nexus user model — do NOT duplicate auth) PROJECT (also called "Job" in the UI) id uuid pk owner_user_id fk -> USER name text required client_name text address text notes text created_at timestamptz updated_at timestamptz ROOM (also called "Scan" in the UI) id uuid pk project_id fk -> PROJECT name text required category enum('kitchen','bedroom','office','exterior','bathroom', 'living_room','other') default 'other' customer text -- optional per-scan override address text -- optional per-scan override device text -- e.g. "iOS LiDAR (RoomPlan)", "web-chrome" length_ft numeric default 0 width_ft numeric default 0 height_ft numeric default 8 voids jsonb default '[]' -- array of { kind, label, width_ft, height_ft, count } -- kind is one of window|door|opening|other photos jsonb default '[]' -- array of base64 or URLs thumbnail text -- optional base64 or URL mesh_file text -- optional URL to LiDAR mesh vertices int faces int notes text ai_summary jsonb -- { summary, generated_at, tone } created_at timestamptz updated_at timestamptz # Business logic (must match exactly — contractors sign quotes off these numbers) Given length_ft L, width_ft W, height_ft H and a list of voids V, metrics = perimeter_ft = 2 * (L + W) floor_sqft = L * W ceiling_sqft = L * W gross_wall_sqft = perimeter_ft * H void_sqft = sum over v in V of v.width_ft * v.height_ft * v.count net_wall_sqft = max(0, gross_wall_sqft - void_sqft) area_sqft = floor_sqft volume_cuft = floor_sqft * H Materials estimator (default unit costs, overridable per request): paint_per_gallon $45.00 coverage: 1 gal ≈ 350 sqft, applied 2 coats drywall_per_sheet $18.00 coverage: 32 sqft/sheet, +10% waste flooring_per_sqft $4.50 +10% waste labor_wall_per_sqft $1.75 labor_floor_per_sqft $2.25 paint.gallons = ceil(net_wall_sqft * 2 / 350), min 1 if net_wall_sqft > 0 drywall.sheets = ceil(net_wall_sqft * 1.10 / 32), min 1 if net_wall_sqft > 0 flooring.sqft = round(floor_sqft * 1.10, 2) labor.cost = net_wall_sqft * labor_wall + floor_sqft * labor_floor total_cost = paint.cost + drywall.cost + flooring.cost + labor.cost # API contract (add these under /api/measurement/*, or wherever TAO Nexus mounts feature APIs — the paths are illustrative, adapt to house style) All endpoints require the TAO Nexus session (use the existing auth middleware — do NOT build your own JWT layer). GET /api/measurement/projects → 200 [{ id, name, client_name, address, room_count, updated_at, ... }] POST /api/measurement/projects body: { name, client_name?, address?, notes? } → 200 Project GET /api/measurement/projects/:id PATCH /api/measurement/projects/:id DELETE /api/measurement/projects/:id GET /api/measurement/projects/:id/rooms → 200 [Room[]] POST /api/measurement/projects/:id/rooms body: RoomIn (all fields optional except name; category default 'other') → 200 Room GET /api/measurement/rooms/:id PATCH /api/measurement/rooms/:id body: RoomIn → 200 Room (Room includes computed .metrics) DELETE /api/measurement/rooms/:id GET /api/measurement/scans?category=kitchen&limit=200 → 200 [Room[]] -- cross-project, newest first, auth-scoped POST /api/measurement/rooms/:id/materials body: { unit_costs?: {...} } → 200 { metrics, materials } POST /api/measurement/rooms/:id/ai-summary body: { tone: 'professional' | 'friendly' | 'detailed' } Uses Claude Sonnet 4.5 (or whatever LLM TAO Nexus already integrates with — reuse the existing key, do NOT add a new secret) to produce a client-ready 180-word scope summary using metrics + materials + project + room fields. → 200 { summary: string, metrics, materials } POST /api/measurement/rooms/:id/pdf-quote body: { quote_title?, contractor_name?, contractor_company?, contractor_email?, contractor_phone?, unit_costs?, include_ai_summary?: boolean } Renders a client-ready PDF containing (in order): header (TAO NEXUS™ brand · Field Measurement · quote number · date) quote title + contractor line job / client / site / room / device info block MEASUREMENTS table (perimeter, floor, ceiling, gross wall, voids, net wall, volume) VOIDS DEDUCTED table (#, Kind, Label, W, H, Qty, Area) MATERIALS & LABOR table (category, quantity, unit price, line total) GRAND TOTAL bar (black background, electric-blue price) PROJECT SUMMARY paragraph (only if include_ai_summary and one exists) Terms clause + ACCEPTED BY / DATE signature line Node: use `pdfkit` or `puppeteer` — whichever TAO Nexus already uses. If neither exists, add `pdfkit` (lightweight, no headless browser). → 200 application/pdf binary body Content-Disposition: attachment; filename="tao-nexus-quote-.pdf" # Screens (Next.js pages — match TAO Nexus routing convention) /platform/field-measurement → Home /platform/field-measurement/gallery → Gallery /platform/field-measurement/jobs → Jobs list /platform/field-measurement/jobs/[id] → Job detail (rooms in that job) /platform/field-measurement/scan/new → Create scan /platform/field-measurement/scan/[id] → Scan (Room) detail /platform/field-measurement/scan/[id]/mark → Precision Void Marker /platform/field-measurement/scan/[id]/ar → Guided AR-style scan HUD (webcam) /platform/field-measurement/settings → Company defaults for PDF quote ## Home Personalized greeting. 6-tile category grid: Kitchen, Bedroom, Office, Exterior, Bathroom, Living Room (icons: fork-knife, bed, briefcase, tree, bathtub, couch). Tapping a tile → /scan/new?category= with category preselected. Below: a horizontal RECENT SCANS carousel + a "SEE ALL" link to Gallery. Sticky "NEW SCAN" primary CTA button in top-right. ## Gallery Horizontal category chip row (chrome, single-line, never wraps — flex-shrink:0 on each chip). Chips: All · Kitchen · Bedroom · Office · Exterior · Bathroom · Living Room. Selected chip = filled black background; others = outlined only, size stays the same. Below: vertical list of scan cards showing: • black square thumb with the category short code (KIT / BED / OFF / ...) • scan name + category + optional customer • 3 mini-stats: AREA, NET WALL, PERIM Pull to refresh (web equivalent: refresh button in header) + empty state. ## Jobs Standard list of projects. Cards show name, client, address, room count, last updated. Tapping a project → Job detail with a totals bento (net wall / floor / perimeter across all rooms in the job) + list of rooms + an ADD ROOM button. ## Scan (Room) detail -- the workhorse screen Sticky header: back arrow · scan name (uppercase) · share icon. Below header, a horizontal category chip row (same interaction pattern as Gallery — patches the scan's category on tap). Then a metrics bento with 2 rows: Row 1 (spans full width): NET WALL (huge 56-pt display number, "sq ft") Row 2 (three equal columns divided by 1px lines): AREA PERIMETER VOLUME Row 3 (three equal columns): VOIDS (red num) VERTICES (or "no lidar") FACES (or "no lidar") Then a horizontal action row: [ AR SCAN ] [ LiDAR ] [ VOID ] AR SCAN → /scan/[id]/ar LiDAR → placeholder screen that says "Native mobile build required. Publish TAO Nexus's iOS build to enable LiDAR mesh ranging." VOID → opens the Quick Add void modal (bottom sheet on mobile, dialog on desktop) Then sections in this order: MEASUREMENTS 3 side-by-side numeric inputs: LENGTH · WIDTH · HEIGHT (all in ft). Persist on blur (PATCH the room). VOIDS · N Row of TWO buttons: [ QUICK ADD ] [ PRECISION MARK ] Quick Add opens the modal (kind chips, label, width, height, count). Precision Mark → /scan/[id]/mark (the new precision marker screen — spec below). List of existing voids: red circular "N×" badge, label · kind, W×H = area. Long-press or trash icon deletes. MATERIALS "ESTIMATE MATERIALS & COST" button. On tap, POST to /materials and render a table (paint / drywall / flooring / labor) plus a black GRAND TOTAL bar with electric-blue price. AI CLIENT SUMMARY "GENERATE WITH CLAUDE 4.5" button. On tap, POST to /ai-summary and render the returned summary in a bordered card. "Regenerate" link. PDF QUOTE "GENERATE PDF QUOTE" button. On tap, reveal an inline form with 5 fields: Quote title, Contractor name, Company, Email, Phone. Cancel / DOWNLOAD PDF actions. On DOWNLOAD, POST to /pdf-quote, receive the binary, and trigger a browser download. METADATA + NOTES Two-cell grid: CUSTOMER (editable, patches on blur) · DEVICE (read-only). Multi-line notes textarea below (patches on blur). ## Precision Void Marker (the standout feature — build this well) Full-screen web-camera preview using getUserMedia({ video: { facingMode: 'environment' } }). If camera permission is denied, show a subtle grid fallback so the numeric flow still works. Overlays (from front to back): 1. A center fine reticle: two concentric cyan rings + a red crosshair pin + horizontal/vertical calibration ticks. 2. Corner markers 1 and 2 (red-filled 28px circles with white number). 3. A live red translucent bounding box drawn between the two corners (position: absolute; top:min(y1,y2); left:min(x1,x2); w=|dx|; h=|dy|; border: 2px solid #FF3B30; background: rgba(255,59,48,0.15) ). Top HUD (sticky): Close button (left) Step pill (center): "STEP 1/3 · TAP TOP-LEFT CORNER" → "STEP 2/3 · TAP BOTTOM-RIGHT CORNER" → "STEP 3/3 · CONFIRM DIMENSIONS" Reset button (right) — clears both corners Second row: zoom slider with − / + buttons and a % readout. The zoom applies to the camera via CSS transform: scale(1 + zoom) on the video element (with transform-origin: center), or getSettings zoom on capable devices. 0-100% range. Full-screen pressable behind everything captures pointer events: first tap → sets corner1 = { x, y } second tap → sets corner2 = { x, y } third tap → resets to a fresh corner1 Bottom sheet: Row of 4 kind chips: window · door · opening · other. Selecting a kind auto-fills sensible defaults: window → 3 ft × 4 ft label "Window" door → 3 ft × 7 ft label "Door" opening → 6 ft × 7 ft label "Opening" other → 2 ft × 2 ft label "Other" Row of 4 inputs: W(ft), H(ft), QTY, LABEL. Primary CTA: disabled → "MARK BOTH CORNERS FIRST" both set → "SAVE SQFT VOID" On save: fetch the current Room, append the new void, PATCH. ## Guided AR-style scan HUD (/scan/[id]/ar) Full-screen webcam preview + laser-cyan corner reticle + a bottom card that walks the user through capture: LENGTH → WIDTH → HEIGHT → optional voids. A top row of "live" telemetry pills: NET WALL · FLOOR · PERIM (computed from the current entered values). Below those, a live "tracking strip" showing TRACK-quality bar, DIST, VERT, TRI, FPS. On non-LiDAR devices these are visual telemetry only and are NEVER persisted to the DB — only real LiDAR scans persist vertices/faces to the Room. Copy this exactly, it is what makes the flow feel professional without lying to contractors about accuracy. # Design tokens (must feel like TAO Nexus, not TAO Vision) TAO Nexus is matte-black + electric-blue-lion. Use these tokens; do NOT reuse the TAO Vision cyan+red palette wholesale: --tn-bg #0A0A0A or #FFFFFF depending on theme mode --tn-surface #F4F5F7 --tn-border #1F2937 (dark) / #E2E8F0 (light) --tn-primary #0A0A0A --tn-primary-on #FFFFFF --tn-accent #1E90FF (electric blue — the "lion eyes" from the TAO Nexus landing page) --tn-accent-2 #00A8B5 (secondary cool teal — use sparingly for HUD/laser overlays only) --tn-danger #FF3B30 (used only for voids + destructive actions) --tn-text #111827 --tn-text-2 #4B5563 --tn-text-3 #9CA3AF Type scale — reuse the TAO Nexus fonts already loaded (do NOT introduce a new font family). Numbers in metrics bentos must be tabular-nums, weight 900, letter-spacing -0.5 at 26pt+. Every interactive element MUST have a data-testid in kebab-case describing its role (e.g. add-void-precision, pdf-generate, gallery-filter-kitchen). # Third-party integrations - LLM: reuse whatever TAO Nexus already integrates. If nothing, use the Emergent LLM key already in scope for TAO Nexus and target claude-sonnet-4-5-20250929 for AI summary. Do NOT hard-code any API keys. - PDF: prefer pdfkit for Node; if TAO Nexus's backend is Python, use reportlab (same library TAO Vision uses). - Auth: reuse TAO Nexus's existing session/user model. Every measurement API route must be behind the existing auth guard. # Testing checklist (run before you tell me it's done) Backend: [ ] Auth is enforced on every /api/measurement/* route (401 without session) [ ] Ownership check on Room/Project routes (404 or 403 on cross-user access) [ ] Room metrics math matches the formulas above exactly. Verify with: L=15, W=12, H=9, voids=[{w:4,h:3,c:2},{w:3,h:7,c:1}] → perimeter 54, floor 180, gross_wall 486, void 45, net_wall 441, volume 1620 [ ] Materials for the same inputs (defaults): paint=3 gal ($135), drywall≈16 sheets ($288), flooring=198 sqft ($891), labor=$1176.75, total=$2490.75 [ ] /scans filter by category works and is empty for users with no projects [ ] /pdf-quote returns Content-Type application/pdf and starts with %PDF- [ ] /pdf-quote works even when the room has no ai_summary Frontend: [ ] All 4 Field Measurement sub-nav routes render [ ] Home category tile tap → /scan/new?category=kitchen with category chip preselected and scan name pre-filled ("Kitchen") [ ] Creating a scan from Home without a job auto-creates a hidden "Quick Scans" project and drops the user on the scan detail [ ] Gallery filter chips filter the list; chips do not wrap or resize [ ] Precision Void Marker: camera preview shows; two taps place markers and draw the bounding box; save button correctly disabled until both corners are placed [ ] Zoom slider changes the video scale; percentage readout updates [ ] Kind chip defaults populate width/height/label as specified [ ] PDF form downloads a real .pdf that opens in the browser [ ] AI summary button hits the LLM and renders the returned text [ ] Every listed testID exists # What NOT to do - Do not build a new user model or a new session/JWT layer. Reuse TAO Nexus's. - Do not commit or hard-code any API keys. Reuse the Emergent LLM key already in the platform's environment. - Do not fake accuracy: if the device isn't LiDAR-capable, show the guided AR HUD with live telemetry visuals but never persist vertex/face counts. - Do not use the TAO Vision brand mark inside TAO Nexus. Header should read "TAO NEXUS — Field Measurement". # Delivery When you're done, produce: 1. A short changelog of files added/modified. 2. One screenshot per sub-nav section (Home, Gallery, Jobs, Scan detail, Precision Marker). 3. A test report showing every checklist item above passing. 4. A sample generated PDF quote (attach the file). That's the full spec — ship it.