@mohasinac/appkit 4.41.10 → 4.41.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -40,6 +40,33 @@ import { withOrderSearchTxt } from "./_helpers/search-txt-wrappers";
40
40
  import { seedPhoto } from "./_helpers/media";
41
41
  const NOW = new Date();
42
42
  const daysAgo = (n) => new Date(NOW.getTime() - n * 86400000);
43
+ /**
44
+ * The anchor the order IDs are built from — fixed, never `NOW`.
45
+ *
46
+ * 🛑 An ID may not contain a value that moves. `generateOrderId` embeds a
47
+ * `yyyymmdd` derived from its anchor, so with `NOW` every order's id changed on
48
+ * every calendar day: `appkit-seed load` CREATED 50 fresh documents instead of
49
+ * upserting the same 50, and `status`/`delete` computed ids that had never been
50
+ * written.
51
+ *
52
+ * Measured immediately after a successful `load --collections orders` that
53
+ * reported "created 50, errors 0": `appkit-seed status` answered
54
+ * **`orders 50 seed / 0 in db`**. Both numbers were right; they were about
55
+ * different sets of ids.
56
+ *
57
+ * This is exactly the case Recurrent Root Cause #25 names — "`Date.now()` used
58
+ * as an ID component (as opposed to just a display timestamp)". The
59
+ * distinction is the whole fix:
60
+ *
61
+ * - **IDs** anchor to `SEED_EPOCH`, so they are reproducible forever.
62
+ * - **Display timestamps** (`orderDate`, `createdAt`, shipping dates) keep
63
+ * using `daysAgo()` off `NOW`, so a reseeded catalogue still looks recent
64
+ * and time-bound fixtures re-arm, which is what the tester window needs.
65
+ *
66
+ * It also broke every checklist case that names an order by id: they were
67
+ * authored against one day's ids and could never resolve afterwards.
68
+ */
69
+ const SEED_EPOCH = new Date("2026-01-01T00:00:00.000Z");
43
70
  // Deterministic per-product thumbnail — picsum.photos returns a stable image
44
71
  // for any seed string, so this doesn't need to match the real product seed's
45
72
  // own image, just be present and consistent across reseeds. Backfills the
@@ -64,7 +91,9 @@ function seededSuffix(seed) {
64
91
  return (hash >>> 0).toString(36).padStart(6, "0").slice(0, 6);
65
92
  }
66
93
  const generateOrderId = (itemCount, daysBack, seed) => {
67
- const date = new Date(NOW.getTime() - daysBack * 86400000);
94
+ // SEED_EPOCH, not NOW — see the block comment on SEED_EPOCH. An id that
95
+ // moves with the calendar is an id that never upserts.
96
+ const date = new Date(SEED_EPOCH.getTime() - daysBack * 86400000);
68
97
  const yyyymmdd = date.toISOString().split("T")[0].replace(/-/g, "");
69
98
  const rand = seededSuffix(`${itemCount}-${daysBack}-${seed}`);
70
99
  return `order-${itemCount}-${yyyymmdd}-${rand}`;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "4.41.10",
3
+ "version": "4.41.11",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"