Skip to content

Session notes — claude-2026-10-15 ​

One person's notes, never rewritten by anyone else. docs/state/HANDOFF.md §18g holds what is NOT done, and STATE.md holds what is true now (the deployed sha's only home is its ✅ DEPLOYED line). This file is WHY each thing was done, and how it was checked.

▶ HANDOFF — SAMO Shop admin: ยอดขาย tab, ต้องจัดการ row, slip queue rebuilt, order ประวัติ ​

All on production, every deploy <== exit 0 — ran to the end, read back from the VM's HEAD, and the served bundle grepped for a string from code that runs unconditionally. No migration, no Apps Script change, no new read path. Four user-visible notes are staged in PENDING (src/data/changelog.js).

Read these before touching the same code ​

If you touch…Read first
any shop revenue numberisRevenueOrder (data.js) is the ONE rule — รายรับสะสม, ยอดขาย and 0206's shop_order_totals (Discord) all ask it; data.test.js holds the SQL to the JS list
a line's stage anywhererowDisplayStatus (data.js): the order status before payment, the item status after. The orders table, the handover bar and the history share it — it was a private copy in admin.js until today
sales.jsproduct rows must sum EXACTLY to the KPI (a test says so); a fee is an adjustment line, never folded into a product; a DELETED product's lines still count
order-facts.jscompare timestamps as instants (Date.parse), never as strings: a slip's at is …606Z, Postgres writes …555207+00:00
the ต้องจัดการ tilesa tile's count = the predicate of the filter its click applies, within แหล่งที่มา (lineInScope: itemMatchesSource). Change one, change both
a global key handlerwireVerifyKeys checks pane.getClientRects().length — an ancestor hides the shop on other admin pages, so class checks lie (docs/mistakes/frontend-ui.md)
any stylesheetsrc/js/css-parses.test.js parses every file. Never delete CSS by matching line (sed /x/d orphaned a rule body today)
the shop admin UInode tools/browser/shop-admin-tour.mjs — screenshots every tab signed in, both widths (skills/drive-the-browser.md §11)

What happened, in order ​

  1. "Shouldn't samoshop see how much we sell per product?" Production had 44 orders / 53 lines / 3 products / ฿12,785, all paid, fee 0, subtotal equal to the line sum on every order. The admin had money only as one total. Planned, ran /scrutinize on the plan (it caught: a deleted product's sales would vanish; switching รายรับสะสม to a line sum would part it from Discord; a third copy of the stage rule), then built sales.js + admin-sales.js. Rejected alternative: extending พรีออเดอร์ — it counts UNPAID demand and shows no money. The handover bar's first palette FAILED the dataviz CVD validator (gray beside green); stages are ordinal, so it is a one-hue green ramp with red only for มีปัญหา.

  2. Admin polish on the owner's prompt: the tab strip wrapped into five rows on a phone (a third of the screen) → one scrolling row; the orders table was a 900px table cut off at the right on a phone → one card per order (CSS grid over the same cells); shop_admin badge → ผู้ดูแลร้าน; uppercase tracking off Thai labels.

  3. "Revenue by size, colour?" The grid tracked money per cell already; it now switches ชิ้น / บาท, and its margins (per size / per colour) are computed in sales.js from the lines. Per-size prices mean a size's money is not pieces × one price; a test has the dearer size earning more than its share.

  4. "Make the admin work better" — toured all 10 tabs + the order popup first. Found: the slip was a ~38px thumbnail in the slip queue (the daily task) and the popup; the popup had no phone, order time, pickup or history; nothing said what needed attention. Built the ต้องจัดการ row, rebuilt the queue (big slip beside the amount, oldest first, wait time, A/R/←/→ incl. Thai ฟ/พ), added the popup summary + ประวัติ + a "slip will not load" state.

  5. Bug scans. Mine found string-compared timestamps. A /code-review high found 10, all real, all fixed — worst: A/R stayed live on OTHER admin pages (verified red with the old check restored). Fixing it, a line-based sed delete orphaned a CSS rule body that would have eaten the orders phone layout; npm test and the build were green — hence css-parses.test.js. A last independent review covered the ยอดขาย commits (see the end of this file).

  6. Independent review of the ยอดขาย commits found six, all fixed with a test each (mutation-checked): the "waiting for slip check" note counted no-slip and rejected-slip orders and its button opened an EMPTY queue — now review vs ยังไม่ชำระ are split; "ดูคำสั่งซื้อของสินค้านี้" kept the orders tab's own แหล่งที่มา and could open an empty list — it now clears every filter; a row's แหล่งที่มา came from the product's CURRENT source, not the lines it counted; an old line carrying a colour LABEL made a second grid row; the chart's readout sat inside role="img" (never announced); plus CSV fee row, margin %s summing to 100, clamped partial weeks, no "after today" cut, the source default re-seeded per account, whole-piece gridlines.

  7. The tour itself wrote once. Its "no-write" key check trapped only the approve button; in the run that restored the bug, R rejected SH9349 on samo-dev. Repaired (exact-timestamp UPDATE), both buttons trapped, a before/after snapshot is byte-identical — docs/mistakes/tooling-proofs.md.

How each thing was checked ​

  • Unit: sales.test.js, order-facts.test.js, css-rules.test.js (every emitted sales- / oc- / attn- / verify- / om- class has a rule in what /admin/ loads), css-parses.test.js. Mutations: review counted as revenue → 6 red; string sort → red; a removed .sales-tip-label → red; the orphan body re-injected → red.
  • Browser: shop-admin-tour.mjs on samo-dev, throwaway samoshop account, cleaned up every run (accounts: 0). Its own two instrument bugs (a \S that a template literal turned into S; toggling an already-open row shut) are in docs/mistakes/tooling-proofs.md.
  • Production: the served admin chunk greps "ส่งออกยอดขาย", "ไซส์ × สี แสดงเป็น", "รอลูกค้าส่งสลิปใหม่", "เรียงจากส่งสลิปก่อน"; the CSS greps sales-hero-value, sales-matrix-pct, attn-tile, om-history.

Not seen ​

A real slip at full size (samo-dev has no slip files), and ยอดขาย on real data — both HANDOFF §18g.

Working docs. STATE.md is the status file and lives at the repo root, not here.