Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,16 @@ Adheres to [Semantic Versioning](https://semver.org/).

## [Unreleased]

### Added

- Epic #920 — Country-Aware Scanner & Submission Pipeline: 12 issues (#921–#932),
10 new migrations, `gs1_country_hint()` GS1 prefix → country utility,
`scan_country` + `suggested_country` columns, region-preferred product matching,
country-aware quality scoring, cross-country analytics views
(`v_cross_country_scan_analytics`, `v_cross_country_ean_candidates`,
`v_submission_country_analytics`), admin mismatch badges, 3 new QA checks
(view_consistency 13→16), frontend country propagation for scan/submit flows

### Fixed

- Populate `nutri_score_source` for all products — pipeline now sets source
Expand Down
81 changes: 40 additions & 41 deletions CURRENT_STATE.md
Original file line number Diff line number Diff line change
@@ -1,17 +1,44 @@
# CURRENT_STATE.md

> **Last updated:** 2026-03-17 by GitHub Copilot (session 51)
> **Last updated:** 2026-03-21 by GitHub Copilot (epic #920 closeout)
> **Purpose:** Volatile project status for AI agent context recovery. Read this FIRST at session start.

---

## Active Branch & PR

- **Branch:** `main`
- **Latest SHA (main):** `b4e3c877` (fix(scanner): permission-aware error recovery + extract scan page into modules #918)
- **Open PRs:** 0
- **Latest SHA (main):** `dbe06364` (feat(scanner): cross-country analytics views (#932) (#945))
- **Open PRs:** 1 (Dependabot #941 — Next.js 16.1.6→16.1.7 security patch, 5 CVEs)
- **Mode:** 🟢 Clean — no active work

## Recently Shipped (Epic #920 — Country-Aware Scanner & Submission Pipeline)

12/12 issues implemented, merged, and closed. Epic #920 closed.

| PR | Issue | Summary |
| ---- | ----- | ----------------------------------------------------------------- |
| #933 | #921 | `scan_country` column on `scan_history` |
| #934 | #922 | `scan_country` + `suggested_country` on `product_submissions` |
| #935 | #923 | Pass user region through `api_record_scan` / `api_submit_product` |
| #936 | #924 | Frontend scan/submit country propagation |
| #937 | #925 | Admin submission review UI country context |
| #938 | #926 | Region-preferred product matching in `api_record_scan` |
| #939 | #927 | Cross-country product badge in scan result card |
| #940 | #928 | GS1 prefix → country hint utility function |
| #942 | #929 | Country mismatch detection badges in admin review |
| #943 | #930 | Country-scoped pending submission uniqueness |
| #944 | #931 | Country-aware submission quality scoring |
| #945 | #932 | Cross-country analytics views (3 views) |

**10 new migrations** (`20260320000100`–`20260321000700`), 3 new views, 1 new function (`gs1_country_hint`), 4 modified RPC functions, 3 new QA checks (view consistency 13→16).

## Recently Shipped (Session 51 — Scanner Error Recovery + Extraction)

| PR | Summary |
| ---- | ------------------------------------------------------------------------------------- |
| #918 | fix(scanner): permission-aware error recovery + extract scan page into modules (#889) |

## Recently Shipped (Session 49 — Next.js 16 Upgrade)

| PR | Summary |
Expand All @@ -31,34 +58,11 @@

**Security CVEs patched:** CVE-2025-59471, CVE-2025-59472, CVE-2026-23864

## Recently Shipped (Session 51 — Scanner Error Recovery + Extraction)

| PR | Summary |
| ---- | -------------------------------------------------------------------------------------- |
| #918 | fix(scanner): permission-aware error recovery + extract scan page into modules (#889) |

**Phase 1 — Permission-aware error recovery:**
- 5-state camera error model (`CameraErrorKind`): permission-prompt, permission-denied, permission-unknown, no-camera, generic
- Per-error-kind user guidance with contextual hints and retry/settings CTAs
- `classifyCameraError()` maps DOMException names to structured error kinds
- Browser detection for permission-recovery instructions (Chrome vs Safari vs Firefox)

**Phase 2 — Scan page extraction (856→463 lines, 46% reduction):**
- `useBarcodeScanner` hook: ZXing camera lifecycle, device enumeration, torch control, watchdog timeout
- `ScannerErrorState` component: 5-state error card with i18n text and callbacks
- `ScanResultView` component: 4 sub-components (Error, NotFound, LookingUp, Found)

**Phase 3 — CI fixes + test coverage:**
- Fixed `Typecheck & Lint` CI failure: downgraded `react-hooks/purity` to "warn" (5th React Compiler rule)
- 66 new tests: 24 hook tests + 20 error state tests + 22 result view tests
- i18n: en/pl/de `scan.cameraStarting` key + error state strings
- 12 files changed, +1,992 / -433 lines

## Recently Shipped (Session 50 — Scanner Black Camera Fix)

| PR | Summary |
| ---- | -------------------------------------------------------------------------------------- |
| #916 | fix(scanner): resolve black camera feed with event-driven stream readiness (#889) |
| PR | Summary |
| ---- | --------------------------------------------------------------------------------- |
| #916 | fix(scanner): resolve black camera feed with event-driven stream readiness (#889) |

**6 root causes diagnosed and fixed in scan/page.tsx:**
- `decodeFromVideoDevice()` not awaited → now properly awaited
Expand All @@ -70,12 +74,6 @@

**3 new tests + MediaStream jsdom stub. i18n: en/pl/de `scan.cameraStarting` key.**

## Recently Shipped (Session 49 — Next.js 16 Upgrade)

| PR | Summary |
| ---- | ----------------------------------------------------------------------------------- |
| #904 | chore(deps): bump next 15.5.12 → 16.1.6 + eslint-config-next 16.1.6 (MAJOR upgrade) |

## Recently Shipped (Session 48 — CI Baseline Restoration)

| PR | Summary |
Expand Down Expand Up @@ -122,8 +120,8 @@
| ------------ | ------ | --------------------------------------------------------------------- |
| pr-gate | ✅ | Typecheck, lint, unit tests, build, Playwright smoke |
| main-gate | ✅ | All passing |
| qa.yml | ✅ | 756/756 checks passing (48 suites) |
| deploy.yml | | All 209 migrations on production (deployed 2026-03-16T08:24:26Z) |
| qa.yml | ✅ | 759/759 checks passing (48 suites) |
| deploy.yml | ⚠️ | 209/227 migrations on production — 18 pending deploy (epic #920) |
| dep-audit | ✅ | 0 high/critical vulnerabilities |
| python-lint | ✅ | 0 ruff errors |
| quality-gate | ✅ | Passing — ReDoS hotspot resolved (PR #914) |
Expand All @@ -137,6 +135,7 @@
| #212 | Deferred | Infrastructure Cost Attribution Framework |

Issue #889 fully resolved and closed with PR #918 merge.
Epic #920 fully resolved and closed — all 12/12 issues shipped.

## Milestones Completed

Expand Down Expand Up @@ -193,7 +192,7 @@ These are documented follow-ups, not active work items. Address opportunisticall

- **Products (local DB):** 2,602 active (1,380 PL + 1,222 DE across 21 active + 1 deactivated category)
- **Deprecated products:** 58
- **QA checks:** 756 total (48 suites) — 47 pass, 1 pre-existing failure (Suite 11 NutriRange), 1 warning (local DB)
- **QA checks:** 759 total (48 suites) — view_consistency +3 checks for cross-country analytics views
- **Negative tests:** 23/23 caught
- **EAN coverage:** 2,261/2,264 with EAN (99.9%) — local DB
- **Ingredient refs:** 3,100 (local, after orphan cleanup from 6,279)
Expand All @@ -205,9 +204,9 @@ These are documented follow-ups, not active work items. Address opportunisticall
- **Nutrition coverage (production):** 2,438/2,438 (100%)
- **Frontend test coverage:** ~92% lines (SonarCloud Quality Gate passing)
- **ESLint warnings:** 23 (React Compiler rules — 5 rules downgraded to warn, see follow-ups)
- **Open issues:** 1 | **Open PRs:** 0
- **Vitest:** 5,733 tests passing across 348 test files
- **DB migrations:** 209 append-only (all 209 applied to production)
- **Open issues:** 1 | **Open PRs:** 1 (Dependabot #941)
- **Vitest:** 5,755 tests passing across 348 test files
- **DB migrations:** 227 append-only (209 applied to production, 18 pending from epic #920)
- **pgTAP test files:** 17
- **Ruff lint:** 0 errors
- **GitHub Ruleset:** strict_required_status_checks_policy = true
Expand Down
22 changes: 11 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,9 @@

<p align="center">
<a href="https://github.com/ericsocrat/tryvit/actions/workflows/pr-gate.yml"><img src="https://img.shields.io/github/actions/workflow/status/ericsocrat/tryvit/pr-gate.yml?style=flat-square&label=build" alt="Build Status" /></a>
<img src="https://img.shields.io/badge/QA%20checks-747%20passing-brightgreen?style=flat-square" alt="QA Checks" />
<img src="https://img.shields.io/badge/QA%20checks-759%20passing-brightgreen?style=flat-square" alt="QA Checks" />
<img src="https://img.shields.io/badge/coverage-%E2%89%A588%25-brightgreen?style=flat-square" alt="Coverage" />
<img src="https://img.shields.io/badge/products-2%2C438-1DB954?style=flat-square" alt="Products" />
<img src="https://img.shields.io/badge/products-2%2C602-1DB954?style=flat-square" alt="Products" />
<img src="https://img.shields.io/badge/market-PL%20%2B%20DE-1DB954?style=flat-square" alt="Market" />
<img src="https://img.shields.io/badge/scoring-v3.3-7c3aed?style=flat-square" alt="Scoring Version" />
<a href="LICENSE"><img src="https://img.shields.io/github/license/ericsocrat/tryvit?style=flat-square" alt="License" /></a>
Expand Down Expand Up @@ -137,7 +137,7 @@ supabase db reset # Full rebuild (migrations + seed)
.\RUN_SEED.ps1 # Seed reference data only

# ── Testing ──
.\RUN_QA.ps1 # 747 QA checks across 48 suites
.\RUN_QA.ps1 # 759 QA checks across 48 suites
.\RUN_NEGATIVE_TESTS.ps1 # 23 constraint violation tests
.\RUN_SANITY.ps1 -Env local # Row-count + schema assertions
python validate_eans.py # EAN checksum validation
Expand Down Expand Up @@ -168,7 +168,7 @@ echo "SELECT * FROM v_master LIMIT 5;" | docker exec -i supabase_db_tryvit psql
```
┌─────────────────┐ ┌──────────────────┐ ┌─────────────────────────┐
│ Open Food Facts │────▶│ Python Pipeline │────▶│ PostgreSQL (Supabase) │
│ API v2 │ │ sql_generator │ │ 199 migrations │
│ API v2 │ │ sql_generator │ │ 227 migrations │
│ (category tags, │ │ validator │ │ 43 pipeline folders │
│ countries=PL,DE│ │ off_client │ │ products + nutrition │
└─────────────────┘ └──────────────────┘ │ + ingredients + scores │
Expand Down Expand Up @@ -231,18 +231,18 @@ Every score is fully explainable via `api_score_explanation()` — returns the 9

<table>
<tr>
<td align="center" width="16%"><strong>2,438</strong><br />Active Products</td>
<td align="center" width="16%"><strong>2,602</strong><br />Active Products</td>
<td align="center" width="16%"><strong>43</strong><br />Categories</td>
<td align="center" width="16%"><strong>PL + DE</strong><br />Markets</td>
<td align="center" width="16%"><strong>2,995</strong><br />Ingredients</td>
<td align="center" width="16%"><strong>99.9%</strong><br />EAN Coverage</td>
<td align="center" width="16%"><strong>199</strong><br />Migrations</td>
<td align="center" width="16%"><strong>227</strong><br />Migrations</td>
</tr>
</table>

<table>
<tr>
<td align="center" width="16%"><strong>747</strong><br />QA Checks</td>
<td align="center" width="16%"><strong>759</strong><br />QA Checks</td>
<td align="center" width="16%"><strong>48</strong><br />Test Suites</td>
<td align="center" width="16%"><strong>23</strong><br />Negative Tests</td>
<td align="center" width="16%"><strong>≥88%</strong><br />Line Coverage</td>
Expand Down Expand Up @@ -296,11 +296,11 @@ tryvit/
│ │ ├── chips-pl/ # Reference PL implementation
│ │ ├── chips-de/ # DE Chips (51 products)
│ │ └── ... (21 more PL + 20 DE) # Variable product counts per category
│ ├── qa/ # 48 test suites (747 checks)
│ ├── qa/ # 48 test suites (759 checks)
│ └── views/ # Reference view definitions
├── supabase/
│ ├── migrations/ # 199 append-only schema migrations
│ ├── migrations/ # 227 append-only schema migrations
│ ├── seed/ # Reference data seeds
│ ├── tests/ # pgTAP integration tests
│ └── functions/ # Edge Functions (API gateway, push notifications, CAPTCHA)
Expand All @@ -327,7 +327,7 @@ tryvit/
├── monitoring/ # Alert definitions
├── RUN_LOCAL.ps1 # Pipeline runner (idempotent)
├── RUN_QA.ps1 # QA test runner (747 checks)
├── RUN_QA.ps1 # QA test runner (759 checks)
├── RUN_NEGATIVE_TESTS.ps1 # Negative test runner (23 tests)
├── RUN_SANITY.ps1 # Sanity checks
├── CHANGELOG.md # Structured changelog
Expand Down Expand Up @@ -400,7 +400,7 @@ Every change is validated against **747 automated checks** across 48 QA suites p

1. **PR Gate** — Typecheck → Lint → Build → Unit tests → Playwright smoke E2E
2. **Main Gate** — Above + Coverage → SonarCloud Quality Gate
3. **QA Gate** — Schema → Pipelines → 747 QA checks → Sanity → Confidence threshold
3. **QA Gate** — Schema → Pipelines → 759 QA checks → Sanity → Confidence threshold
4. **Nightly** — Full Playwright (all projects) + Data Integrity Audit

---
Expand Down
Loading
Loading