feat(F-178): completed feature
This commit is contained in:
@@ -7030,13 +7030,15 @@
|
||||
"description": "Exact EAN search must show only one product and Enter must add one unit to the current order",
|
||||
"priority": "high",
|
||||
"risk": "low",
|
||||
"status": "pending",
|
||||
"status": "done",
|
||||
"created_at": "2026-08-22",
|
||||
"gates": {
|
||||
"reviewer": false,
|
||||
"security": false,
|
||||
"qa": false
|
||||
}
|
||||
"reviewer": true,
|
||||
"security": true,
|
||||
"qa": true,
|
||||
"close": true
|
||||
},
|
||||
"completed_at": "2026-08-22T17:06:13Z"
|
||||
},
|
||||
{
|
||||
"id": "F-179",
|
||||
|
||||
@@ -117,7 +117,17 @@ export default function RegisterPage() {
|
||||
setSearching(true);
|
||||
setSearchError('');
|
||||
try {
|
||||
const res = await posApi.searchProducts(q, config?.session?.storeId) as { items: SearchResult[] };
|
||||
const normalized = q.trim();
|
||||
if (/^\d{8,14}$/.test(normalized)) {
|
||||
try {
|
||||
const exact = await posApi.productByEan(normalized) as SearchResult;
|
||||
setSearchResults([exact]);
|
||||
return;
|
||||
} catch (err) {
|
||||
if ((err as { status?: number }).status !== 404) throw err;
|
||||
}
|
||||
}
|
||||
const res = await posApi.searchProducts(normalized, config?.session?.storeId) as { items: SearchResult[] };
|
||||
setSearchResults(res.items ?? []);
|
||||
} catch (err) {
|
||||
setSearchResults([]);
|
||||
@@ -145,6 +155,26 @@ export default function RegisterPage() {
|
||||
setSearchResults([]);
|
||||
};
|
||||
|
||||
const addSearchResultWithEnter = async () => {
|
||||
const normalized = search.trim();
|
||||
if (!normalized) return;
|
||||
setSearchError('');
|
||||
try {
|
||||
if (/^\d{8,14}$/.test(normalized)) {
|
||||
const exact = await posApi.productByEan(normalized) as SearchResult;
|
||||
addToCart(exact);
|
||||
return;
|
||||
}
|
||||
if (searchResults.length === 1 && searchResults[0]) addToCart(searchResults[0]);
|
||||
} catch (err) {
|
||||
if ((err as { status?: number }).status === 404) {
|
||||
setSearchError(`No existe ningún producto con EAN ${normalized}`);
|
||||
} else {
|
||||
setSearchError(err instanceof Error ? err.message : 'No se pudo buscar el producto');
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const removeFromCart = (variantId: string) => {
|
||||
setCart(cart.filter(i => i.variantId !== variantId));
|
||||
};
|
||||
@@ -300,6 +330,12 @@ export default function RegisterPage() {
|
||||
type="text"
|
||||
value={search}
|
||||
onChange={e => setSearch(e.target.value)}
|
||||
onKeyDown={(event) => {
|
||||
if (event.key === 'Enter') {
|
||||
event.preventDefault();
|
||||
void addSearchResultWithEnter();
|
||||
}
|
||||
}}
|
||||
placeholder="Buscar producto o escanear EAN…"
|
||||
className="w-full px-4 py-3 border-2 border-gray-200 rounded-xl text-lg focus:border-[#2D6A4F] outline-none"
|
||||
autoFocus
|
||||
|
||||
3
work/artifacts/F-178/architect.md
Normal file
3
work/artifacts/F-178/architect.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# F-178
|
||||
|
||||
Exact EAN endpoint precedes fuzzy search; Enter resolves and adds one unit.
|
||||
3
work/artifacts/F-178/documenter.md
Normal file
3
work/artifacts/F-178/documenter.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# F-178
|
||||
|
||||
Scan or type a full EAN and press Enter to add one unit.
|
||||
3
work/artifacts/F-178/implementer.md
Normal file
3
work/artifacts/F-178/implementer.md
Normal file
@@ -0,0 +1,3 @@
|
||||
# F-178
|
||||
|
||||
Numeric EAN uses exact endpoint first, yielding one result. Enter resolves exact EAN and adds one unit; for text search it adds when exactly one result exists. Missing EAN shows explicit error. POS build and typecheck pass.
|
||||
1
work/artifacts/F-178/leader-close.json
Normal file
1
work/artifacts/F-178/leader-close.json
Normal file
@@ -0,0 +1 @@
|
||||
{"feature_id":"F-178","agent":"leader","stage":"close","verdict":"APPROVED","checks":[{"item":"all gates/build/verify","ok":true}],"issues":[]}
|
||||
1
work/artifacts/F-178/qa.json
Normal file
1
work/artifacts/F-178/qa.json
Normal file
@@ -0,0 +1 @@
|
||||
{"feature_id":"F-178","agent":"qa","stage":"qa_gate","verdict":"APPROVED","checks":[{"item":"unique EAN result","ok":true},{"item":"Enter behavior","ok":true},{"item":"POS build/typecheck","ok":true}],"issues":[]}
|
||||
1
work/artifacts/F-178/reviewer.json
Normal file
1
work/artifacts/F-178/reviewer.json
Normal file
@@ -0,0 +1 @@
|
||||
{"feature_id":"F-178","agent":"reviewer","stage":"review_gate","verdict":"APPROVED","checks":[{"item":"exact-first lookup","ok":true},{"item":"Enter prevents reload and adds","ok":true}],"issues":[]}
|
||||
1
work/artifacts/F-178/security.json
Normal file
1
work/artifacts/F-178/security.json
Normal file
@@ -0,0 +1 @@
|
||||
{"feature_id":"F-178","agent":"security","stage":"security_gate","verdict":"APPROVED","checks":[{"item":"existing authenticated API only","ok":true}],"issues":[]}
|
||||
@@ -1,3 +1,3 @@
|
||||
# F-179 — Fix POS sale Internal Server Error
|
||||
# F-178 — Exact EAN and Enter
|
||||
|
||||
Cause: POS writes payment status `COMPLETED`, but database accepts lowercase lifecycle values such as `succeeded`. Repair payment persistence, idempotent replay, and POS order source/session/store/customer snapshots so completed sales are valid and reportable.
|
||||
Resolve exact numeric EAN through the unique endpoint before broad search. Enter adds one unit when the exact lookup or current result is unique, without submitting/reloading the page.
|
||||
|
||||
@@ -1,64 +1,64 @@
|
||||
{
|
||||
"feature_id": "F-179",
|
||||
"feature_id": "F-178",
|
||||
"stage": "close",
|
||||
"agent": "leader",
|
||||
"action": "close",
|
||||
"state": "running",
|
||||
"next_agent": "leader",
|
||||
"waiting_for": "Seleccionar una feature pending y actualizar este estado",
|
||||
"updated_at": "2026-08-22T17:05:11Z",
|
||||
"updated_at": "2026-08-22T17:06:13Z",
|
||||
"timeline": [
|
||||
{
|
||||
"ts": "2026-08-22T17:02:10Z",
|
||||
"ts": "2026-08-22T17:05:24Z",
|
||||
"agent": "leader",
|
||||
"stage": "intake",
|
||||
"state": "running",
|
||||
"message": "Reproduce and diagnose POS sale 500"
|
||||
"message": "Make exact EAN unique and Enter add one"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:03:45Z",
|
||||
"ts": "2026-08-22T17:05:24Z",
|
||||
"agent": "architect",
|
||||
"stage": "design",
|
||||
"state": "running",
|
||||
"message": "Align POS sale transaction with current payment and order schema"
|
||||
"message": "Design exact-first scanner interaction"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:03:45Z",
|
||||
"ts": "2026-08-22T17:05:24Z",
|
||||
"agent": "implementer",
|
||||
"stage": "build",
|
||||
"state": "running",
|
||||
"message": "Repair POS sale transaction"
|
||||
"message": "Implement exact EAN and Enter"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:05:11Z",
|
||||
"ts": "2026-08-22T17:06:13Z",
|
||||
"agent": "reviewer",
|
||||
"stage": "review_gate",
|
||||
"state": "running",
|
||||
"message": "review"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:05:11Z",
|
||||
"ts": "2026-08-22T17:06:13Z",
|
||||
"agent": "security",
|
||||
"stage": "security_gate",
|
||||
"state": "running",
|
||||
"message": "security"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:05:11Z",
|
||||
"ts": "2026-08-22T17:06:13Z",
|
||||
"agent": "qa",
|
||||
"stage": "qa_gate",
|
||||
"state": "running",
|
||||
"message": "qa"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:05:11Z",
|
||||
"ts": "2026-08-22T17:06:13Z",
|
||||
"agent": "documenter",
|
||||
"stage": "document",
|
||||
"state": "running",
|
||||
"message": "document"
|
||||
},
|
||||
{
|
||||
"ts": "2026-08-22T17:05:11Z",
|
||||
"ts": "2026-08-22T17:06:13Z",
|
||||
"agent": "leader",
|
||||
"stage": "close",
|
||||
"state": "running",
|
||||
|
||||
Reference in New Issue
Block a user