AI にレジ締めを作らせてみた — 「過不足」を3回見たので、ついに primitive を起こす(やってみた #44)
/register-close375px のビューポートで撮影。縦長のページはフレーム内をスクロールします。
解説記事
AI にレジ締めを作らせてみた — 「過不足」を3回見たので、ついに primitive を起こす(やってみた #44)
やってみたシリーズ: 自作のデザインシステム
@gunjo/ui(群青)を、文脈ゼロの cold な AI に実 UI で作らせる連載。小売3枚目——レジ締め / 日次精算(金種別現金実査 × 理論残高照合 × 過不足 × 支払区分別内訳 × 釣銭繰越)。
「1業界は最低3〜5枚・可能な限り違う内容・業界特有UIを最優先」という方針。#42 レジ会計(売る)、#43 実地棚卸(数える)に続いて、今回は 締める——一日の終わり、ドロワーを数えて理論残高と突き合わせ、レジを締める作法。売上を立てる画面でも、在庫を数える画面でもない、現金照合の画面。
結果 — 4/5
tsc/build 緑・console 0・375px(レジ脇のハンディ/タブレット想定)・金種実査→実査現金が即再計算・過不足が符号+矢印+語+色+読み上げ・±¥1,000 超で理由 Reveal+締めブロック・締め完了で read-only・h1 1個・支払区分別内訳が総売上に一致。
育てた primitive は、また真逆の画面でも全採用
小売 #42 レジ会計(売る) : カート / 釣銭 / ¥%割引
小売 #43 実地棚卸(数える): 理論在庫 / 実地カウント / 差異
小売 #44 レジ締め(締める): 金種実査 / 理論残高 / 過不足
内容は三者三様でも、横断 primitive はそのまま効いた——cold AI の所見:
EditableDataTable(#199) — USED, strong fit. 金種×枚数→金額の実査グリッド。renderFooterCellで「実査現金合計」行が無料、rowLabel+自動ctx.ariaLabelで全枚数セルがラベル付きコントロール、table→card 自動化で 375px 横スクロール0。「この画面で一番効いた単一コンポーネント」。RevealSection(#213) — USED, perfect fit. 過不足が ±¥1,000 を超えたときだけ「過不足の理由」Select がrole=regionで出現+読み上げ、理由を選ぶまで締めをブロック。NumberInput— USED. 枚数・繰越。min/max・draft 文字列(クリアして打ち直せる)・read-only 状態でdisabled。CurrencyInput/formatCurrency {signed}(#180) — USED, 12回連続. 過不足・入出金に符号付き ±¥(+¥930/-¥1,280)。「JPY/ja-JP 既定で設定ゼロ・本当に良い」。
そして今回の本題 — 「過不足」を3回見たので primitive を起こした
cold AI が最大の穴に挙げたのは、過不足(over/short)の表示だった:
Missing higher-order primitive: a signed-variance / over-short display. Every reconciliation screen (cash 過不足, stock 差異, budget variance) needs "signed amount + status word + sign-driven icon + semantic tone, announced."
Statisticwon't self-format a signed ¥ value or carry a status word. I hand-rolledVarianceDisplay. A<Variance value={-930} … />would be the highest-leverage addition.
これで 3回目だった——損益(#33)・棚卸差異(#43)・レジ過不足(#44)。毎回 cold AI が「符号付き数値+方向矢印+符号駆動のトーン+読み上げラベル」を手で書き直していた。Statistic はカード型でセルに入らないから。
「3回見たら起こす」ルールに従って、Delta(#221・PR #223)を出荷した:
// 損益 — 既定トーン(正=success / 負=destructive)
<Delta value={12500} format={yen} labels={{ positive: "増加", negative: "減少" }} />
// 現金過不足 — 正が「良い」とは限らないのでトーンを差し替える
<Delta value={-930} format={yen}
tones={{ positive: "warning", negative: "destructive", zero: "success" }}
labels={{ positive: "過剰", negative: "不足", zero: "一致" }} showLabel />
valueの符号が矢印(↑/↓/–)・トーン・ラベルを駆動する、<span>の inline atom。Statisticと違いセルに収まる。format既定は符号付きグループ ja-JP。formatCurrencyを渡せば ¥。tonesを符号ごとに上書き可能——損益は正=緑が既定、現金過不足は「過剰」を警告色に差し替える。「正=良い」が普遍でないのが reconciliation の肝。labelsは常に読み上げ(sr-only かshowLabelで可視)。意味が色や矢印だけに乗らない。- 純表示なので RSC 安全(client 境界なし)。
起票だけした穴(3回ルール未達)
- 🟠 支払区分別内訳 / 集計テーブル primitive——現金/クレジット/電子マネー/QR/商品券の「ラベル→金額→構成比+合計行」を素の
<table>で手組み。#178(DescriptionList/サマリリスト)の領域。レビュー系で再々確認、閾値接近(#32 振込確認・#37 請求書・#44 ここ)。 - 🟠 現金照合 / 台帳サマリ primitive——開始釣銭+現金売上±入出金=理論 vs 実査の「符号付きラベル→値スタック+強い合計」も手組み(
ReconRow)。同じく #178 寄り。 - 🟠 金種カウントのヘルパ——
EditableDataTableが良いホストだが、金種行・金額=金種×枚数・実査合計フッタは毎回再発明。POS 特有。1回目。 - 🟡
EditableDataTableがデスクトップ表とモバイルカードを両方 DOM に出す(md:で隠す)ので、9 金種で枚数 input が18個存在。スクリプト/テスト/フォーム送信で要注意。 - 🟡
ctx.ariaLabelがrowLabel + headerを既に合成している旨が JSDoc に無く、cold AI が二重前置きした(修正済)。
学び — "違う内容を3〜5枚" は、primitive を起こすための回し方だった
横断 primitive(金額・グリッド・reveal)は内容が真逆でも効く。そのうえで同じ穴が3画面で再発したら、それは個別画面のグルーではなく primitive 不在のサイン。今回その閾値に届いたのが「符号付き差分の表示」だった。1業界を3〜5枚・内容を散らして回すのは、業界判断を立体化すると同時に、"3回ルール" を発火させて DS を1つ太らせるための設計でもある。次は #178(サマリリスト)が同じ閾値に近づいている。
次回予告(やってみた #45)
- 小売をもう1枚(返品/レジ開け or スキャン入力 #220 を3回目へ)か、別業界へ。
Delta(#221) が次の fresh な cold AI に発見・使用されるかも観測する。
試す
まだ alpha。同じ業界の3枚目で、ついに「3回見た穴」を primitive に起こした回。
<!-- 公開前: 相互URL差込/スクショ確定/EN(dev.to)ミラー -->
使用した @gunjo/ui コンポーネント
この画面のソースが直接 import している部品です。
cold AI が組み上げた実コード
ファイル名をクリックでソースを展開できます。