feat(F-173): completed feature

This commit is contained in:
chattie
2026-08-22 19:14:54 +02:00
parent 8f02d1c6cc
commit c0870f6c48
11 changed files with 41 additions and 26 deletions

View File

@@ -6949,13 +6949,15 @@
"description": "/checkout shows This page couldn't load; diagnose frontend/runtime and restore checkout.", "description": "/checkout shows This page couldn't load; diagnose frontend/runtime and restore checkout.",
"priority": "high", "priority": "high",
"risk": "high", "risk": "high",
"status": "pending", "status": "done",
"created_at": "2026-08-22", "created_at": "2026-08-22",
"gates": { "gates": {
"reviewer": false, "reviewer": true,
"security": false, "security": true,
"qa": false "qa": true,
} "close": true
},
"completed_at": "2026-08-22T17:14:54Z"
}, },
{ {
"id": "F-174", "id": "F-174",

View File

@@ -140,6 +140,13 @@ export default function CheckoutClient() {
if (addr) setForm((f) => ({ ...f, ...addressToForm(addr) })); if (addr) setForm((f) => ({ ...f, ...addressToForm(addr) }));
}; };
const selectedShippingMethod = useMemo(
() => shippingMethods.find((m) => m.id === shippingMethodId) ?? null,
[shippingMethods, shippingMethodId],
);
const shippingCost = selectedShippingMethod?.baseCostCents ?? 0;
const totalCents = subtotalCents + shippingCost;
if (authLoading) { if (authLoading) {
return ( return (
<div className="max-w-7xl mx-auto px-4 py-16 flex items-center justify-center"> <div className="max-w-7xl mx-auto px-4 py-16 flex items-center justify-center">
@@ -161,13 +168,6 @@ export default function CheckoutClient() {
); );
} }
const selectedShippingMethod = useMemo(
() => shippingMethods.find((m) => m.id === shippingMethodId) ?? null,
[shippingMethods, shippingMethodId],
);
const shippingCost = selectedShippingMethod?.baseCostCents ?? 0;
const totalCents = subtotalCents + shippingCost;
const handlePlaceOrder = async () => { const handlePlaceOrder = async () => {
setSubmitting(true); setSubmitting(true);
setError(''); setError('');

View File

@@ -0,0 +1,3 @@
# F-173
Move shipping selection hook above all conditional returns.

View File

@@ -0,0 +1,3 @@
# F-173
Checkout loads consistently across auth/cart state changes.

View File

@@ -0,0 +1,3 @@
# F-173
Moved selected shipping useMemo above auth/cart conditional returns, preserving stable React hook order. Frontend build passes and /checkout responds 200.

View File

@@ -0,0 +1 @@
{"feature_id":"F-173","agent":"leader","stage":"close","verdict":"APPROVED","checks":[{"item":"all gates/build/verify","ok":true}],"issues":[]}

View File

@@ -0,0 +1 @@
{"feature_id":"F-173","agent":"qa","stage":"qa_gate","verdict":"APPROVED","checks":[{"item":"checkout 200","ok":true},{"item":"frontend build","ok":true}],"issues":[]}

View File

@@ -0,0 +1 @@
{"feature_id":"F-173","agent":"reviewer","stage":"review_gate","verdict":"APPROVED","checks":[{"item":"unconditional hooks","ok":true}],"issues":[]}

View File

@@ -0,0 +1 @@
{"feature_id":"F-173","agent":"security","stage":"security_gate","verdict":"APPROVED","checks":[{"item":"no security boundary change","ok":true}],"issues":[]}

View File

@@ -1,3 +1,3 @@
# F-170Delete categories # F-173Checkout load failure
Admin client must treat HTTP 204 as success instead of attempting JSON parsing. Category UI confirms cascading impact, disables duplicate deletion, reloads tree and shows persistent success/error feedback. Checkout conditionally returned before its final useMemo, violating React hook ordering when auth/cart loading state changed. Keep every hook unconditional.

View File

@@ -1,64 +1,64 @@
{ {
"feature_id": "F-170", "feature_id": "F-173",
"stage": "close", "stage": "close",
"agent": "leader", "agent": "leader",
"action": "close", "action": "close",
"state": "running", "state": "running",
"next_agent": "leader", "next_agent": "leader",
"waiting_for": "Seleccionar una feature pending y actualizar este estado", "waiting_for": "Seleccionar una feature pending y actualizar este estado",
"updated_at": "2026-08-22T17:13:31Z", "updated_at": "2026-08-22T17:14:54Z",
"timeline": [ "timeline": [
{ {
"ts": "2026-08-22T17:12:20Z", "ts": "2026-08-22T17:14:12Z",
"agent": "leader", "agent": "leader",
"stage": "intake", "stage": "intake",
"state": "running", "state": "running",
"message": "Fix category delete 204 handling" "message": "Fix checkout hook-order crash"
}, },
{ {
"ts": "2026-08-22T17:12:20Z", "ts": "2026-08-22T17:14:12Z",
"agent": "architect", "agent": "architect",
"stage": "design", "stage": "design",
"state": "running", "state": "running",
"message": "design" "message": "design"
}, },
{ {
"ts": "2026-08-22T17:12:20Z", "ts": "2026-08-22T17:14:12Z",
"agent": "implementer", "agent": "implementer",
"stage": "build", "stage": "build",
"state": "running", "state": "running",
"message": "Implement reliable category deletion" "message": "Make checkout hooks unconditional"
}, },
{ {
"ts": "2026-08-22T17:13:31Z", "ts": "2026-08-22T17:14:53Z",
"agent": "reviewer", "agent": "reviewer",
"stage": "review_gate", "stage": "review_gate",
"state": "running", "state": "running",
"message": "review" "message": "review"
}, },
{ {
"ts": "2026-08-22T17:13:31Z", "ts": "2026-08-22T17:14:53Z",
"agent": "security", "agent": "security",
"stage": "security_gate", "stage": "security_gate",
"state": "running", "state": "running",
"message": "security" "message": "security"
}, },
{ {
"ts": "2026-08-22T17:13:31Z", "ts": "2026-08-22T17:14:54Z",
"agent": "qa", "agent": "qa",
"stage": "qa_gate", "stage": "qa_gate",
"state": "running", "state": "running",
"message": "qa" "message": "qa"
}, },
{ {
"ts": "2026-08-22T17:13:31Z", "ts": "2026-08-22T17:14:54Z",
"agent": "documenter", "agent": "documenter",
"stage": "document", "stage": "document",
"state": "running", "state": "running",
"message": "document" "message": "document"
}, },
{ {
"ts": "2026-08-22T17:13:31Z", "ts": "2026-08-22T17:14:54Z",
"agent": "leader", "agent": "leader",
"stage": "close", "stage": "close",
"state": "running", "state": "running",