← back to NationalPaperHangers
AR_MEASURE_KIT_SPEC.md
120 lines
# AR Wall Measurement Kit — Standalone Product Spec
**Status:** P0 + P1 + P3 BUILT — local only, not deployed (P3 added 2026-06-02).
Surface **A** (`/measure` on NPH), **both** handoffs (shop DW + find installer),
manual width fallback for non-WebXR devices. Deploy is Steve-gated.
**Brand:** National Paper Hangers (nationalpaperhangers.com)
**Audience:** Interior designers + DIYers (NOT just installers booking a job)
**Foundation:** Reuse the already-shipped `public/js/room-measure.js` engine verbatim.
---
## 1. Why this is mostly *extraction*, not new R&D
The measurement brain already exists and ships in `/book`:
- `window.RoomMeasure` (public/js/room-measure.js)
- `.method()` → `'webxr' | 'gyro' | null`
- `.measure()` → `Promise<{ width_ft, height_ft, method }>`
- WebXR (Android Chrome): immersive-ar + hit-test, 3 taps → true-scale **width + height**.
- Gyro (iPhone Safari): DeviceOrientation clinometer → **height only**.
The standalone product = a **new public route/surface** that drives `RoomMeasure`
for a multi-wall, calculator-first workflow — none of the existing `/book`
installer flow is modified.
## 2. What the product adds on top of the engine
| Capability | Status today | Standalone adds |
|---|---|---|
| Single wall W×H | ✅ `RoomMeasure.measure()` | reuse as-is |
| Multi-wall room (sum sq ft) | ❌ | accumulate N measurements |
| Doors/windows subtraction | ❌ | optional deductions per wall |
| **Rolls / panels needed** | ❌ none | core calculator (see §4) |
| iPhone width fallback | partial (height only) | manual width entry / photo-box |
| Save / share / export | ❌ | shareable result link + PDF/email |
| Order handoff | ❌ | deep-link to DW / wallco / "find an installer" |
## 3. Surface options (DECISION — needs Steve)
- **A. New route on NPH** — `/measure` (or `/tools/measure`) on the existing
pm2 app. Cheapest, inherits SSL/branding/analytics, lives under the NPH brand.
**(Recommended.)**
- **B. Standalone microsite** — own domain (e.g. measure.* / a new domain),
own pm2 process. More "product," more infra + DNS + cert work.
- **C. Embeddable widget** — single JS bundle other DW sites drop in. Most
reusable, most engineering.
Default unless told otherwise: **A**, with the engine factored so B/C stay open.
## 4. Roll / panel calculator (the real value-add)
Inputs: total wall area (ft²), product format, pattern repeat, roll/panel
coverage, waste factor.
- **Standard roll (US "single roll" ≈ 28 ft² usable, sold in double rolls):**
`rolls = ceil( area_with_waste / usable_per_roll )`
- **Euro roll (~21" × 33 ft ≈ 57 ft²):** same shape, different constant.
- **Mural / panel goods:** `panels = ceil( wall_width / panel_width )` per wall.
- **Waste factor:** default +15%; +20–25% when pattern `repeat > 0`
(drop-match eats more). Repeat is a user input; preset by product when the
calc is launched from a DW/wallco PDP.
- Output: rolls/panels **per wall** and **per room**, plus a plain-English
"buy N double-rolls" line and a "always confirm with your installer" caveat.
> Numbers above are the standard trade rules of thumb; final constants get a
> quick sanity pass against DW's existing product data before shipping.
## 5. UX flow (designer/DIY, mobile-first)
1. Landing: "Measure any wall with your phone — no tape measure." Device-aware
CTA (`RoomMeasure.label()` already returns the right button text per method).
2. Measure wall 1 → show W×H + ft². "Add another wall" or "Done."
3. (Optional) subtract a door/window.
4. Pick product format + repeat (or auto-filled from a DW/wallco link).
5. Result card: total ft², rolls/panels, waste assumption, share/export.
6. Handoff CTAs: shop the look (DW/wallco) · find an installer (NPH core).
## 6. Compliance / standing-rules checklist
- [ ] Camera/motion permission only on explicit user tap (engine already does this).
- [ ] Privacy: AR frames never leave the device; only final numbers are stored
*if* the user saves. Update DATA_POLICY.md.
- [ ] If results are emailed → CAN-SPAM footer + the existing George/mailer path.
- [ ] Disclaimer: estimates only, confirm before ordering (liability).
- [ ] Admin-facing save list (if any) → created date+time chip per standing rule.
- [ ] Any product grid shown → sort + density controls per standing rule.
- [ ] Deploy/DNS (option B) → Steve-gated, never autonomous.
## 7. Phased build plan
- **P0 — Extract & prove (no new infra):** ✅ DONE. `/measure` route + view;
`RoomMeasure` loads on the bare page; device-aware CTA; single-wall measure →
ft² readout. (Real-phone AR pass still recommended before any deploy.)
- **P1 — Calculator:** ✅ DONE. Multi-wall accumulation, optional door/window
deductions, roll/panel calc (§4) in `public/js/measure-kit.js` (14 unit tests,
all pass), live result card with plain-English buy line + both handoff CTAs.
- **P2 — Save/share/export:** shareable link, PDF/email, deductions.
- **P3 — Order handoff:** ✅ DONE. `/measure` reads sanitized product context
from the launch URL (`?sku=&name=&from=&repeat=&format=&panelw=&shop=`),
shows a "Sizing for <product>" banner, pre-fills the calculator (format /
repeat / panel width), and points the "Shop the look" CTA back at the exact
PDP. The `shop` return URL is **host-allowlisted** (designerwallcoverings.com,
wallco.ai, philipperomano.com, novasuede.com + subdomains) so the page can
never become an open redirect; product strings are EJS-escaped and the prefill
JSON block escapes `<`. 7 route tests in `tests/measure-route.test.js`
(deep-link prefill + the full security boundary), all pass. The
"find an installer" tie-in already links to NPH `/find`.
- **P4 — (optional) widget/microsite:** only if option B or C is chosen.
Deploy of anything customer-facing is gated on explicit Steve approval.
## 8. Open questions for Steve
1. Surface: **A (NPH /measure)**, B (microsite), or C (embeddable widget)?
2. Audience handoff: should results push toward **DW/wallco purchase**,
**NPH installer booking**, or **both**?
3. iPhone width: acceptable to ask for manual width entry (since Apple ships no
WebXR), or invest in a photo-reference width estimate?
4. Scope for *this* session: P0 prototype only, or P0+P1 (measure + calculator)?