Skip to content

feat(scanner): pass user region through api_record_scan and api_submit_product (#923)#935

Merged
ericsocrat merged 1 commit intomainfrom
feat/923-country-aware-scanner-rpcs
Mar 17, 2026
Merged

feat(scanner): pass user region through api_record_scan and api_submit_product (#923)#935
ericsocrat merged 1 commit intomainfrom
feat/923-country-aware-scanner-rpcs

Conversation

@ericsocrat
Copy link
Owner

Summary

Implements issue #923 — the third issue in epic #920 (Country-Aware Scanner).

Modifies api_record_scan and api_submit_product RPC functions to accept explicit country parameters, resolve country from user preferences when not provided, and return country information in their responses.

Depends on: PR #933 (issue #921) and PR #934 (issue #922) — both merged into this branch.


Changes

Migration: 20260320000300_country_aware_scanner_rpcs.sql

api_record_scan(p_ean text, p_scan_country text DEFAULT NULL)

Aspect Before After
Signature (text) — 1 param (text, text) — 2 params
Country input None p_scan_country DEFAULT NULL
Country resolution None COALESCE(p_scan_country, user_preferences.country)
scan_history INSERT No country Writes scan_country column
Found response No country keys Adds scan_country, product_country
Not-found response No country keys Adds scan_country

Country resolution order:

  1. Explicit p_scan_country parameter (if provided)
  2. user_preferences.country (if user is authenticated and has preferences)
  3. NULL (anonymous users or no preference set)

api_submit_product(p_ean, p_product_name, p_brand, p_category, p_photo_url, p_notes, p_scan_country, p_suggested_country)

Aspect Before After
Signature (text ×6) — 6 params (text ×8) — 8 params
Country input None p_scan_country, p_suggested_country DEFAULT NULL
Country resolution None scan_country from param or prefs; suggested_country from param or defaults to resolved scan_country
INSERT No country cols Writes scan_country, suggested_country
Response No country keys Adds scan_country, suggested_country

Old function signatures are dropped via DROP FUNCTION IF EXISTS.

Tests

  • scanner_functions.test.sql — plan 6470 (+6 tests):

    • Section 2: scan_country and product_country keys exist in found response
    • Section 5: scan_country key exists in not-found response
    • Section 6b (new): explicit scan_country parameter returns correct value; backward compat (no param → NULL)
  • schema_contracts.test.sql — plan 303305 (+2 assertions):

    • has_function for api_record_scan(text, text) — 2-param signature
    • has_function for api_submit_product(text ×8) — 8-param signature

Documentation

  • docs/API_CONTRACTS.md — new subsections under §8 (Barcode Scanner):
    • api_record_scan — PostgREST call, parameters table, country resolution, response examples (found/not-found/error)
    • api_submit_product — 8-param signature, parameters table, country resolution, response examples (success/error)

Backward Compatibility

All new parameters have DEFAULT NULL. Existing callers that pass only the original parameters continue to work identically — country fields return null when not provided and user has no preferences.

Response keys are additive only. No existing keys were removed or renamed.


Verification

supabase db reset                → All 3 migrations apply cleanly (000100 + 000200 + 000300)
pg_proc signature check          → api_record_scan(text,text) ✅, api_submit_product(text×8) ✅, old sigs GONE ✅

supabase test db:
  schema_contracts.test.sql      → 304/305 pass (1 pre-existing: test 294 trg_record_score_change)
  scanner_functions.test.sql     → 41/41 ran PASS (29 skipped: pre-existing trust trigger bug at section 10)
  All 6 new #923 tests           → PASS ✅

Direct function calls:
  api_record_scan('5901234123457', 'PL') → scan_country: "PL" ✅
  api_record_scan('5901234123457')       → scan_country: null  ✅ (backward compat)

.\RUN_QA.ps1:
  49 suites, 0 new failures ✅
  Pre-existing (post-reset, no pipeline data): suites 6, 16, 20, 21, 32

File Impact

4 files changed, +428 / -2 lines:

  • 1 new DB migration (267 lines)
  • 2 modified pgTAP test files (+8 assertions)
  • 1 modified doc file (API_CONTRACTS.md, +153 lines)

Acceptance Criteria (from issue #923)

Copilot AI review requested due to automatic review settings March 17, 2026 10:29
@vercel
Copy link

vercel bot commented Mar 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
tryvit Ready Ready Preview, Comment Mar 17, 2026 11:02am

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds country context capture to the scanner + submission RPCs by introducing optional country parameters, persisting resolved country into the new schema columns, and documenting/testing the updated contracts as part of the “Country-Aware Scanner” epic.

Changes:

  • Add scan_country / suggested_country columns (with FKs + indexes) to scan_history and product_submissions.
  • Update api_record_scan and api_submit_product RPCs to accept country params, resolve from user_preferences when absent, persist to tables, and return country keys in JSON responses.
  • Expand pgTAP coverage and update API contracts documentation for the new signatures/response fields.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
supabase/migrations/20260320000100_scan_history_country.sql Adds scan_history.scan_country (FK to country_ref) + partial index and column comment.
supabase/migrations/20260320000200_submissions_country.sql Adds product_submissions.scan_country + suggested_country (FKs), partial indexes, and comments.
supabase/migrations/20260320000300_country_aware_scanner_rpcs.sql Updates api_record_scan / api_submit_product signatures + response shape and persists resolved country values.
supabase/tests/schema_contracts.test.sql Adds schema + function signature contract assertions and adjusts plan count.
supabase/tests/scanner_functions.test.sql Adds tests for new scan_country / product_country response keys and explicit param behavior.
docs/API_CONTRACTS.md Documents new RPC params, country resolution, and response examples.

Comment on lines +62 to +68
v_scan_country := p_scan_country;
IF v_scan_country IS NULL AND v_user_id IS NOT NULL THEN
SELECT up.country INTO v_scan_country
FROM public.user_preferences up
WHERE up.user_id = v_user_id;
END IF;

Comment on lines +251 to +261
-- Resolve scan_country: explicit param → user_preferences → NULL
v_scan_country := p_scan_country;
IF v_scan_country IS NULL THEN
SELECT up.country INTO v_scan_country
FROM public.user_preferences up
WHERE up.user_id = v_uid;
END IF;

-- Resolve suggested_country: explicit param → scan_country → NULL
v_suggested_country := COALESCE(p_suggested_country, v_scan_country);


| Name | Type | Default | Description |
| ---------------- | ---- | ------- | --------------------------------------------------------------------------------------------------------------- |
| `p_ean` | text | — | Barcode (EAN-8 or EAN-13). Validated via `is_valid_ean()`. |
}
```

**Error cases:** invalid EAN checksum, rate limit (100/24h per user).
Comment on lines 195 to +218
-- ─── 7. Whitespace trimming ────────────────────────────────────────────────

-- ─── 6b. Explicit scan_country parameter (#923) ───────────────────────────

SELECT is(
(public.api_record_scan('5901234123457', 'PL'))->>'scan_country',
'PL',
'explicit p_scan_country=PL is returned in response (#923)'
);

SELECT is(
(public.api_record_scan('5901234123457', 'PL'))->>'product_country',
'XX',
'product_country reflects fixture product country XX (#923)'
);

SELECT is(
(public.api_record_scan('5901234123457'))->>'scan_country',
NULL,
'scan_country is NULL when no param and no auth (#923)'
);

-- ─── 7 (cont). Whitespace trimming ────────────────────────────────────────

…t_product (#923)

- api_record_scan: new p_scan_country text DEFAULT NULL param
  Country resolution: p_scan_country > user_preferences.country
  Response adds: scan_country, product_country keys
- api_submit_product: new p_scan_country, p_suggested_country params
  Country resolution: scan_country from param or prefs
  suggested_country from param or defaults to resolved scan_country
  Response adds: scan_country, suggested_country keys
- DROP old 1-param api_record_scan and 6-param api_submit_product
- All new params DEFAULT NULL for backward compatibility
- 6 new pgTAP tests in scanner_functions.test.sql (plan 64->70)
- 2 new schema contract assertions (plan 303->305)
- API_CONTRACTS.md: document both RPC signatures under §8
@ericsocrat ericsocrat force-pushed the feat/923-country-aware-scanner-rpcs branch from 342f19f to ac0de76 Compare March 17, 2026 11:00
@ericsocrat ericsocrat merged commit f4df249 into main Mar 17, 2026
14 of 15 checks passed
@ericsocrat ericsocrat deleted the feat/923-country-aware-scanner-rpcs branch March 17, 2026 11:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants