From 036a5116b8324ff4e164e9e40f05e80e0b8023f1 Mon Sep 17 00:00:00 2001 From: Torres Date: Wed, 11 Nov 2026 00:21:15 -0400 Subject: [PATCH] =?UTF-8?q?b1:=20README=20=E2=80=94=20B1=20develop=20notes?= =?UTF-8?q?=20(columns,=20importer,=20/img=3Fi=3D=20route,=20mirror=20nami?= =?UTF-8?q?ng,=20payload=20fields,=20FE=20gestures,=20fe=5Fwalk=5Fb1=20usa?= =?UTF-8?q?ge,=20test=20data=20paths)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 44 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/README.md b/README.md index 842d420..a6ec5fb 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@ A private, Tinder-style web app for browsing the motorcycle market: swipe real l **Status:** Phase 3 (personalization) built on `dev` (2026-11-11): sections of 25 (wildcards + second looks + new), taste engine with match points, tank gauges, dossier "Why this rank", real Trends tab, agent pass (mock / live / fallback). Phase 2 remains shipped as-is; deployment (podman stack) is Phase 4 — not started. +**B1 (photo experience v2)** built on `dev`: full photo galleries mirrored locally, deck flips (tap left/right thirds, clamped), segment bars, a fullscreen viewer (swipe nav, pinch/double-tap zoom, pull-down close), and repeat rotation (a re-shown card leads at its next photo). See UI-SPEC §11 + the "B1 develop notes" section below. + ## How it works ``` @@ -87,6 +89,48 @@ Stage 2 + the task brief. `data/` and `.venv/` are gitignored — the DB, image mirror and venv are local state. +## B1 develop notes (photo experience v2) + +- **Columns** (guarded in `db.init_db`): `listings.imgs TEXT` (JSON array of + gallery URLs, page order; entry 0 = the primary = `img_url`) · + `swipes.last_photo_idx INTEGER` (photo on screen at swipe time; drives §11.5 + rotation `(last+1) % n`; NULL = photo 0). +- **Importer** copies the hunt state's `imgs[]` into `listings.imgs`; `img_url` + stays the state `img` and falls back to `imgs[0]`. Re-imports are + byte-stable (selfcheck proves it on the 640-row copy). +- **Route:** `GET /img/{id}?i=n` — mirrored file → CDN 302 → 404. `i=0` + (default) keeps the legacy chain (`{id}.webp`, then `{id}_0.webp`, then + `img_url`); `i>0` serves `{id}_{n}.webp` with the CDN fallback from + `imgs[n]`. Out-of-range/unknown → 404. +- **Mirror:** `app/imgfetch.py` downloads every `imgs[n]`. The primary (n=0) + lands at the legacy `data/img/{id}.webp` (one canonical file — no duplicate + fetch); extras land at `data/img/{id}_{n}.webp`. Same politeness as P2 + (~1 req/s, skip-existing, `.part`-atomic, per-file CLI progress). +- **Payload:** deck/section/list/listing items add `n_photos` (int) and + `last_photo_idx` (int|null). `POST /api/swipe` accepts optional `photo_idx` + (non-negative int; persisted; absent key preserves, explicit null clears). +- **Frontend:** tap LEFT/RIGHT third = photo flip (clamped, no wrap, commits + nothing), CENTER third = fullscreen viewer (ⓘ still wins); segment bars per + photo (Tinder-style; band chips drop to `top:22px` when segments exist); + viewer = swipe nav + pinch 1×–4× + double-tap 1×↔2.5× + ✕/pull-down close + (returns to the same card/photo); re-shown cards lead at `(last+1) % n`; + preloads the top card's next photo + next card's lead; `sw.js` cache is + `bike-tinder-v3`. +- **FE walk (evidence):** `app/fe_walk_b1.py` — deterministic, headless: + + ```sh + .venv/bin/python -m app.fe_walk_b1 setup # fixtures: copy DB + 701-706 synthetics + local photos + env -u OPENROUTER_API_KEY .venv/bin/python -m app.serve \ + --db /var/home/admin/dev/bike-tinder-b1/test-walk.sqlite3 \ + --img-dir /var/home/admin/dev/bike-tinder-b1/test-img \ + --host 127.0.0.1 --port 9454 # scratch server (mock forge) + .venv/bin/python -m app.fe_walk_b1 # 390 DOM checks + ``` +- **Test data:** `b1/test-state/` = hunt-state sample with `imgs` (8/3-photo + galleries; refresh `fetched_at` before an import gate test) · + `b1/test-img/` = staged `{id}_{n}.webp` photos · `b1/test-copy.sqlite3` = + pristine live-DB snapshot (selfcheck copies it; never write to it). + ## Deployment (planned) A small podman compose stack on the Rotarran under `/var/mnt/DATA/podman-stacks/bike-tinder/`, its own systemd user unit (`Delegate=yes`), SQLite database. The stack ships its own Tailscale node (sidecar container — no host-tailnet coupling) and serves the app privately at `https://biketinder.tailf35a34.ts.net`. Single user; reachable only from Glenn's own devices.