Skip to content

Repository files navigation

JAN Sync

English

小売の棚前作業を想定した、JANコードのスキャン・整理・出力をスマートフォンで行うオフライン対応PWAです。

カメラでEAN-8 / EAN-13を読み取り、商品名・個数・定価・売価をブラウザのIndexedDBへ保存します。保存したデータは横断検索し、CSV / TSVとして表計算へ渡したり、JANバーコードを画面上にまとめて生成したりできます。

公開デモを開く

架空の商品データを表示したJAN Syncの一覧・CSV TSV出力画面

スクリーンショットは、GS1 Japanがインストアマーキング用と説明する 02 開始の店内デモ用コードと合成データで構成し、実在の商品・店舗情報は使用していません。

想定した業務上の問題

  • 棚前で確認したJANを別のメモへ転記する手間を減らしたい
  • 同じ商品の連続読取りを個数として数えたい
  • JANの先頭0を表計算へ渡すときに失いにくくしたい
  • 専用端末やバックエンドを用意せず、スマートフォンだけで作業を始めたい
  • 古い作業リストを見分け、用途ごとに整理したい

実装済みの範囲

作業 JAN Syncでできること
棚前での収集 背面カメラによるEAN-8 / EAN-13の単発・連続スキャン
棚卸し補助 同一JANを個数へ加算し、短時間の重複読取りを抑制
商品情報の整理 名前・個数・定価・売価をリスト単位で保存・編集
検索 すべてのリストをJAN・名前で横断検索
データ受け渡し 検索結果をCSV / TSVでダウンロード
バーコード確認 履歴または手入力したJANをCanvas上に一括生成
PWA アプリシェルのキャッシュ、ホーム画面への追加、更新通知

現場を想定して調整した点

  • 棚卸しモード — 同じ商品を繰り返し読んだとき、行を増やさず個数へ反映
  • 重複読取り防止 — 50〜2,000msの範囲で待ち時間を調整可能
  • 読取フィードバック — 音とバイブレーションをそれぞれ4段階で設定
  • 端末機能への配慮 — 非対応端末ではバイブ設定やライト操作を表示しない
  • 表計算向け出力 — JANの数値化を抑えやすい形式、TSV、個数の行展開を用意
  • 古いリストの可視化 — 作成から7日を超えたリストに警告を表示

CSV / TSV出力

出力はUTF-8(BOM付き)で、検索欄が空なら全件、検索中なら表示中の結果だけを対象にします。

プリセット 出力列
すべて JAN、名前、個数、リスト、定価(税抜)、定価(税込)、売価(税抜)、売価(税込)、スキャン日時
JANと名前 JAN、名前
JANのみ JAN

数字だけのJANには先頭タブを付け、表計算ソフトによる数値化と先頭0の消失を起こりにくくしています。ソフトや取込方法によるため、完全な保証ではありません。

CSV / TSVは出力専用です。JAN Syncへ再取込する機能はなく、アプリのリストや設定を復元するバックアップにはなりません。

データ保存・通信・プライバシー

  • スキャンデータは外部サーバーへ自動アップロードせず、現在のブラウザ・オリジンのIndexedDBに保存します。
  • 初回アクセスとアプリ更新には通信が必要です。読み込み後はService Workerがキャッシュしたアプリシェルを利用できます。
  • 端末の紛失・変更、ブラウザのサイトデータ削除、ストレージ消去などで保存データは失われます。サーバー同期や復元機能はありません。
  • Google / Yahoo検索ボタンを押すと、対象のJANと商品名が検索サービスへ送られます。
  • Cloudflare Pagesはアプリの静的ファイルをHTTPS配信します。

現在の制約

  • 対応コードはEAN-8 / EAN-13です。QRコード、UPCなどは対象外です。
  • 手入力時は8桁または13桁の数字かだけを確認し、JANのチェックデジットは検証しません。
  • バーコード生成は画面上のCanvas表示です。専用の印刷レイアウト、PDF / 画像保存、ラベルプリンター連携はありません。
  • 税込表示は税率10%固定・四捨五入です。軽減税率や個別税率には対応しません。
  • データはブラウザごと・端末ごとに分かれます。アカウント、共有、複数端末同期はありません。
  • カメラ、ライト、バイブレーション、クリップボードの対応状況はブラウザと端末に依存します。カメラ利用にはHTTPSなどのsecure contextが必要です。

公開可能な利用実績の範囲

JAN Syncは棚前作業を想定して設計し、読取音などを実機テスト後に調整した公開デモです。v1.0.0からv1.2.1まで機能追加と修正を重ねています。

現時点の公開情報は、実店舗への導入社数・利用者数・継続運用期間・業務改善効果を示すものではありません。

アーキテクチャ

graph TD
    Hosting["Cloudflare Pages\nHTTPSによる静的配信"] --> Browser["ブラウザ / PWA"]
    SW["Service Worker\nアプリシェルのキャッシュ"] --> Browser
    Browser --> Scanner["zxing-wasm\nEAN-8 / EAN-13読取り"]
    Browser --> Generator["bwip-js\nCanvasへのバーコード生成"]
    Browser --> DB["IndexedDB\nlists / scans"]
    Browser --> Export["CSV / TSV\nブラウザ内で生成"]
Loading

バックエンドAPIやユーザー認証はありません。Cloudflare Pagesがアプリを配信し、スキャンデータの保存・検索・出力はブラウザ内で処理します。

技術スタック

領域 技術
UI SolidJS、TypeScript、Tailwind CSS v4
Build Vite
JAN読取り zxing-wasm
バーコード生成 bwip-js
保存 IndexedDB(idb)
PWA vite-plugin-pwa、Workbox
Hosting Cloudflare Pages
Test Vitest

ローカル実行

Node.js 24とpnpm 11を使用します。packageManagerとlockfileに合わせて依存をインストールしてください。

corepack enable
pnpm install --frozen-lockfile
pnpm dev

pnpm devはデスクトップでのUI確認用です。スマートフォンのカメラを試す場合は、HTTPSで配信された環境を使用してください。

検証コマンド

pnpm test
pnpm test:coverage
pnpm build

データ構造

IndexedDB: jan-sync (version 2)
├── lists   { id, name, createdAt }
└── scans   { id, listId, jan, name, quantity?, retailPrice?, salePrice?, scannedAt }

操作方法は日本語の導入ガイドでも確認できます。

About

小売の棚前作業を、スマホのJANスキャン・端末内保存・CSV/TSV出力で支えるオフライン対応PWA。

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Contributors

Languages