From 59be08a8f88e4d0f9d75fb6a2f5e6667e8c728cb Mon Sep 17 00:00:00 2001
From: th
Date: Thu, 16 Apr 2026 17:31:32 +0200
Subject: [PATCH] fix(shopping): filter out __inactive__ sentinel rows on relay
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The old single-list clearRemote wrote a dummy row with card_uid
'__inactive__' instead of deleting. After the multi-list migration
that row still exists alongside real lists, causing every list to
appear twice on the phone — once as "all done" (the empty sentinel)
and once with actual items. Filter it out in shoppingLoadAll and
delete it on bootstrap so it doesn't linger.
Co-Authored-By: Claude Opus 4.6 (1M context)
---
relay/inc/bootstrap.php | 2 ++
relay/inc/routes/shopping.php | 5 ++++-
2 files changed, 6 insertions(+), 1 deletion(-)
diff --git a/relay/inc/bootstrap.php b/relay/inc/bootstrap.php
index 150aeb5..c552a5c 100644
--- a/relay/inc/bootstrap.php
+++ b/relay/inc/bootstrap.php
@@ -271,6 +271,8 @@ if (count($shoppingPk) === 1) {
} elseif (!in_array('position', $shoppingColNames)) {
$db->exec('ALTER TABLE shopping_state ADD COLUMN position INTEGER NOT NULL DEFAULT 0');
}
+// Clean up __inactive__ sentinel rows from the old single-list era.
+$db->exec("DELETE FROM shopping_state WHERE card_uid = '__inactive__'");
// Sync-event notifications: replaces the old bot-chat mechanism. When a
// client syncs a card they received, they POST here; the sender polls
diff --git a/relay/inc/routes/shopping.php b/relay/inc/routes/shopping.php
index 8116363..0974a7c 100644
--- a/relay/inc/routes/shopping.php
+++ b/relay/inc/routes/shopping.php
@@ -14,7 +14,10 @@ $clientTenant = $clientTenant ?? authClient($db);
$tenant = $sessionTenant ?: $clientTenant;
function shoppingLoadAll(PDO $db, int $tenantId): array {
- $stmt = $db->prepare('SELECT card_uid, title, body, position, updated_at_client, updated_at_server FROM shopping_state WHERE tenant_id = :t ORDER BY position, title');
+ // Exclude __inactive__ sentinel rows left over from the old
+ // single-list era (clearRemote used to write a dummy row instead
+ // of deleting).
+ $stmt = $db->prepare("SELECT card_uid, title, body, position, updated_at_client, updated_at_server FROM shopping_state WHERE tenant_id = :t AND card_uid != '__inactive__' ORDER BY position, title");
$stmt->execute(['t' => $tenantId]);
return $stmt->fetchAll() ?: [];
}
|