sisters-book-cafe
WIP(現在進行中)
Work In Progress
このプロジェクトで現在進行中の作業と、過去のスナップショットを記録する。
現在の状況
直近のフェーズ
本番稼働中 + 姉への引き渡し完了。フィードバック待ちフェーズ。
本番情報
- URL: https://bookcafe.ikapps.com
- 配置先:
/home/ubuntu/apps/sisters-book-cafe/(多目的 Lightsail サーバー) - 環境変数:
/etc/bookcafe.env(root:root 0600、内容はサーバー上にのみ) - DB:
/var/lib/bookcafe/bookcafe.db(ubuntu:ubuntu、空の状態で姉に引き渡し済み) - systemd:
bookcafe-web.service(enabled, active、メモリ ~37MB) - Nginx:
/etc/nginx/sites-available/bookcafe.ikapps.com、SSL は certbot 自動更新 - ブランド名:
make smile bookcafe(UI 表記のみ。リポジトリ名・サービス名はsisters-*のまま)
今回 (2026-05-24 後半) のセッションで終わったこと
- 多目的サーバーへのデプロイ一式(rsync / venv / systemd / Nginx / Let's Encrypt)
- 本番 E2E(ログイン → 本登録 → CSV ダウンロード)全パス確認
- 本番 DB をクリーンに初期化
multi-purpose-lightsail-server1README 更新 + push (6c4983b)- ブランド名を「make smile bookcafe」に統一(templates 3 ファイル + rsync + restart)
- 姉に案内文面(URL / パスワード / 使い方 / Square 取り込み手順)を送付
次にやること
- 姉からの動作報告 / フィードバック待ち
- (必要に応じて)UI ブラッシュアップ
- バッチ切り替えセレクタ
- 未ヒット(
pending)行を上に集めるソート - Windows ブラウザでの表示確認
- Phase 3 (画像つき操作マニュアル) は、姉から「分からない画面」が出てきた時に該当画面だけ作る方針(最初から全画面マニュアルは作らない)
- (クリーンアップ)Square 上のテスト 2 冊(『太平洋の試練』『1Q84』)の削除 — You が手動で実施予定
ブロッカー / 未決事項
- なし(姉のリアクション待ち)
- 開店予定日は依然未確認だが、ツール本体は稼働状態にある
過去のWIPアーカイブ
2026-05-24 17:18 時点のスナップショット
- Phase 2 完了。姉の Square 実アカウントへの取り込みテストまで通り、書名・著者・出版社・価格・SKU・GTIN・在庫数すべて正しく反映されることを実機検証済み
- 残るは「デプロイ準備 → 姉への引き渡し」
- 主な実装変更:
config.pyにSQUARE_LOCATION_NAME追加square_csv.pyを実テンプレ 27 列に完全準拠(ヘッダ自動一致確認)- 在庫列の出力先を「現在の数量」→「新規の数量」へ修正
- 次にやること: テスト 2 冊削除 / デプロイ / 姉に引き渡し / UI ブラッシュアップ
- ブロッカー: なし(クリティカルパスは全部解消済み)
2026-05-24 13:17 時点のスナップショット
- Phase 1 完了。ローカルで openBD 連携・SQLite 保存・CSV 出力・簡易ログインまで E2E 動作確認済み
- 次の動きは「Square テンプレ CSV 待ち」と「多目的サーバーへのデプロイ準備」の並行進行
- 主な実装: FastAPI 雛形(main / config / isbn / openbd / database / schema / square_csv / auth)+ テンプレート + 静的アセット
- ISBN 正規化テスト 11/11 PASS、実 openBD API での書誌情報取得確認、E2E スモーク全パス
- 次にやること:
- Square テンプレ CSV を姉から受領 ← クリティカルパス
- 多目的 Lightsail サーバーへのデプロイ(systemd + Nginx + Let's Encrypt)
- UI ブラッシュアップ
- 姉に渡す案内
- ブロッカー: Square テンプレ CSV 未入手 / 姉 PC の USB ポート形状未確認 / 開店予定日未確認
2026-05-19 13:00 時点のスナップショット
- Phase 1 着手中(openBD クライアント + ISBN 正規化 + 中間モデル + 最小 UI)
- 直近で決まったこと(2026-05-19):
- アプリ形態: Web アプリ、多目的 Lightsail サーバーにホスト
- URL:
bookcafe.ikapps.com - 認証: 簡易ログイン(パスワード1個)
- スタック: Python + FastAPI + 素の HTML/JS
- データ: サーバー側 SQLite
- ポート 8002 / systemd
bookcafe-web予定
- 次にやること: 雛形 → ISBN 正規化 → openBD → 中間モデル → UI → ログイン → スモーク
- ブロッカー: Square テンプレ CSV 未入手
ROADMAP(計画)
ロードマップ
今週
- Phase 1: openBD クライアント + ISBN 正規化 + 中間モデル + 最小 UI(ローカル動作)
- 簡易ログイン実装
- ローカルでスモークテスト
- Phase 2: Square テンプレ列マッピングアダプタ実装
- 姉の Square 実アカウントへの取り込み実機テスト(在庫数まで反映確認)
- 多目的 Lightsail サーバーへのデプロイ(systemd + Nginx + Let's Encrypt)
-
bookcafe.ikapps.comで姉が触れる状態にする - 姉に URL / パスワード + 使い方案内を送付
- テスト用2冊を Square から削除(クリーンアップ、You が手動で実施)
今月
- 姉からの動作報告 / フィードバックに対応
- 実機での運用テスト(姉が実際に複数冊登録 → Square 取り込み往復)
- UI ブラッシュアップ(バッチ切り替え、未ヒット行ソート、Windows ブラウザ表示確認)
- Windows 向け簡易ガイドの拡充(姉が詰まった画面が出てきたらスクショ付きで作る)
今四半期
- 開店日に間に合わせる(開店日は未確認、確認後にスケジュール調整)
- Phase 3: 画像つき操作マニュアル — 姉が実際に詰まった画面だけ、必要に応じて作成
いつか
- BASE 取り込み用 CSV 生成(引き継ぎ.md §4 の将来拡張)
- Square API 直叩きでの商品登録(CSV インポートからのアップグレード)
- 登録履歴の検索 UI(過去にいつ・どの本を登録したか)
- サーバー側に deploy key 仕込みで git pull デプロイ化(現状は rsync)
DECISIONS(意思決定)
意思決定記録
このプロジェクトで下した重要な意思決定を記録する。 最新が上に来る。
2026-05-24: プロダクト名を「make smile bookcafe」に確定
背景: 開発当初はリポジトリ名 sisters-book-cafe に合わせて UI 上のブランド名も「sisters book cafe」としていたが、姉の店舗運営元の社名が「(株)make smile」であり、Square 上の店舗名にも全角で「(株)make smile」が使われていることが Phase 2 で判明。本番デプロイ後に姉に渡す前のタイミングで、ブランド表記をどちらに揃えるか決定する必要があった。
決定: UI 上の表記 (タブタイトル + 左上ヘッダ) を 「make smile bookcafe」 に統一する。リポジトリ名・コード上の識別子 (bookcafe-web 等) は sisters-* のまま維持する。
理由:
- 店舗運営元の社名と整合させたほうが、姉が「自分の店のツール」と認識しやすい
- Square テンプレ列名に埋め込まれる店舗名と語感が揃う
- リポジトリ名・systemd サービス名まで変えるのはコストに見合わない (URL とサーバー設定一式の書き換えが発生する)。ユーザー向け表記だけ差し替える方針が最小コストで最大効果
- 反映は templates の 3 ファイル (base.html / index.html / login.html) を rsync +
systemctl restartで完了
2026-05-24: 在庫数は「新規の数量」列に出力する(「現在の数量」ではない)
背景: 姉の Square アカウントで実機取り込みテストを実施したところ、商品名・価格・SKU・GTIN・説明・カテゴリは全て正しく入ったが、在庫数だけ反映されなかった。商品編集画面に在庫数を直接入力する UI も存在しない(「在庫を管理」セクションの「アクション」は「在庫履歴」リンクのみ)。
決定: square_csv.py の出力で quantity を「新規の数量」列に出す。「現在の数量」列は常に空にする。
理由:
- Square 取り込みのマッピング画面で「Squareの属性」側に「現在の数量」が存在せず「新規の数量」だけが存在することを観測。Square は新規取り込み時には「新規の数量」しか読まない仕様
- Square 無料プランは在庫を「在庫の動き」(入庫・出庫・棚卸し)として管理する設計で、「新規の数量」列が 初回入庫として在庫を作る唯一の入り口
- 修正後の再取り込みで在庫数が「1点提供可能」「3点提供可能」と意図通り反映され仮説確定
- 代替案として「現在の数量」と「新規の数量」両方に同じ値を入れる手もあったが、Square 仕様上の役割が異なるため将来の更新インポート時の挙動が読めず、片方に絞った
2026-05-19: アプリ形態・スタック・配備方針を確定
決定内容
| 項目 | 決定 |
|---|---|
| アプリ形態 | Web アプリ |
| ホスト先 | 多目的 Lightsail サーバー(multi-purpose-lightsail-server1) |
| ドメイン | bookcafe.ikapps.com(サブドメイン構成) |
| 認証 | 簡易ログイン(姉用1アカウント・パスワードはサーバー環境変数) |
| 技術スタック | Python + FastAPI + 素の HTML/JS |
| データ永続化 | サーバー側 SQLite |
| 想定ポート | 8002(既存 7channel=8001、aix=5001 と衝突しないように) |
| systemd サービス名 | bookcafe-web(既存 7channel-web に倣う) |
| DB 配置先 | /var/lib/bookcafe/bookcafe.db(サーバー側) |
| SSL | Let's Encrypt(certbot、既存パターンに倣う) |
理由
- Web アプリ採用: 姉 PC に Python/Node ランタイムを入れる手間を回避。多目的サーバーがすでに稼働中で実質コスト 0。Win/Mac 非依存になる副次効果も大きい。
- クラウドWebサービスとして外に置く意味も成立: 姉 PC からのスキャナ入力は HID(キーボードエミュレーション)なのでブラウザの入力欄にそのまま流れる。サーバーがリモートでも UX は変わらない。
- SQLite + サーバー側保存(C 案): 未ヒット本の手入力フォローを「後でまとめてやる」運用に対応できる。バッチが残るので中断・再開が自然。実装コストは A/B 案との差が小さく、運用での効きが大きい。
- FastAPI: 既存サーバー上で稼働実績あり(7channel-server-v2)。流儀を踏襲できる。
- 素の HTML/JS: 画面が少ない(スキャン欄 + 一覧 + 手入力フォーム + CSV ダウンロードボタン)ので、フレームワーク導入のコストに見合わない。
影響
- 引き継ぎ.md §8 の「案 A 推奨(単一実行ファイル or 簡易ローカル Web)」に対し、多目的サーバー上の Web アプリで確定。姉 PC への配布物は不要。
- 引き継ぎ.md §10「姉に PC の OS / USB ポート形状を確認」のうち OS 確認の優先度が下がる(ブラウザだけ動けば OK)。USB ポート形状はスキャナ用なので引き続き必要。
- 引き継ぎ.md §6 の「画像つき操作マニュアル」は、Square へのアップロード手順は引き続き必要(ツール側は CSV ダウンロードまで)。加えて bookcafe.ikapps.com の使い方説明も必要になる。
暫定で残る論点
- Square テンプレ CSV 未入手の論点(引き継ぎ.md §5)は不変。中間データを汎用スキーマで持ち、Square 列へのマッピング層を差し替え可能なアダプタとして分離する方針で先行実装する。
DEVLOG(作業ログ)
開発日誌
このプロジェクトでの作業を時系列で記録する。 最新のエントリが上に来る。
2026-05-24
17:43 - 本番デプロイ + 姉への引き渡し
やったこと:
- DNS 確認 (
bookcafe.ikapps.com→ 13.230.63.19) + SSH 接続テスト + サーバー Python 3.10.12 動作確認 - 既存サービス流儀の調査:
- 実体は
aix-manager(Flask + gunicorn) のみ稼働。README に書かれている 7channel-server-v2 は実体なし - 配置流儀:
/home/ubuntu/apps/<app>/、venv は.venv/、systemd User=ubuntu、Nginx は sites-available にドメイン名ファイル
- 実体は
- 多目的 Lightsail サーバーへのデプロイ:
- rsync で
/home/ubuntu/apps/sisters-book-cafe/に同期 (venv / data / pycache / .git 等除外) - サーバー側で
python3 -m venv .venv && pip install -r requirements.txt /var/lib/bookcafe/を ubuntu:ubuntu 0755 で作成/etc/bookcafe.envを root:root 0600 で配置 (scp → sudo mv 経由、ローカル一時ファイルは shred 削除)/etc/systemd/system/bookcafe-web.service作成 →daemon-reload→enable→start- uvicorn を 127.0.0.1:8002 で常駐、
EnvironmentFile=/etc/bookcafe.env - 起動メモリ ~37MB、CPU ほぼゼロ
- uvicorn を 127.0.0.1:8002 で常駐、
/etc/nginx/sites-available/bookcafe.ikapps.com作成 → symlink →nginx -t→ reloadcertbot --nginx -d bookcafe.ikapps.com --redirectで SSL 化 (有効期限 2026-08-22、自動更新設定)
- rsync で
- 本番 E2E: ログイン → 本登録 (openBD 取得) → CSV ダウンロード (27 列ヘッダ) 全パス
- 本番 DB を一度クリーンに削除 → サービス再起動で空 DB 自動再作成、
books=0 / batches=0確認 multi-purpose-lightsail-server1の README にサービス追加 → commit & push (6c4983b)- ブランド名を
sisters book cafe→make smile bookcafeに変更 (templates/base.html + login.html + index.html) → rsync +systemctl restart bookcafe-webで反映確認 - 姉に渡す案内文面 (URL / パスワード / 使い方 / Square 取り込み手順 / トラブル時の問い合わせ) を作成、姉に送信済み
決めたこと (詳細は .devnotes/DECISIONS.md の 2026-05-24 エントリ):
- プロダクト名を 「make smile bookcafe」 に確定 (店舗運営元の社名と一致させる)
詰まったこと / 気づき:
- 既存サーバー上の
sqlite3CLI が未インストール。apt installするより.venv/python -c "import sqlite3; ..."で十分なので入れず - 一度 curl で
-w '%{redirect_url}'が空表示 → 一瞬「200 が返ってる?」と誤読しかけた。ヘッダ取得 (-D -) で正しく303 See Otherを確認するのが安全 EnvironmentFile=形式は全角文字 (例: 店舗名) もクォートなしでそのまま読まれる- パスワードを含むファイルは scp → sudo mv → 0600 root:root + 双方の一時ファイルを shred、の流れでログ / 履歴に値を残さない
次回やること:
- 姉のフィードバック待ち。動作報告 or 「ここが分からん」が来たら個別対応
- UI ブラッシュアップ (バッチ切り替え、未ヒット行ソート、Windows ブラウザ表示確認) は姉の使用感を見てから優先度判断
- Phase 3 (画像つき操作マニュアル) は姉から「困った画面」が出てから該当画面だけ作る方針
17:18 - Phase 2 完了(Square テンプレ準拠 + 実機取り込み検証)
やったこと:
- 姉からの追加情報を取り込み:
- バーコードリーダー: BUSICOM
BC-BR1000U-W(引き継ぎ.md 記載のBC-BR1000Uの色違い)→ HID 型確定 - PC: Windows + USB Type-A 対応 → 変換アダプタ不要、Phase 3 マニュアルは Windows スクショで作る
- バーコードリーダー: BUSICOM
- 姉から Square テンプレ CSV (
MLQ65KJ6YDV8R_商品マスタ-2026-05-24-0752.csv) を受領、列構成を解析- テンプレは「指示・説明」「サンプル」など冒頭5論理行 + 27列ヘッダ + データ行の構造
- 在庫4列の列名には店舗名(『(株)make smile』)が動的に埋め込まれる
config.pyにSQUARE_LOCATION_NAME環境変数を追加(デフォルトは姉の店舗名、コピペ可能なまま全角で保持)square_csv.pyを実テンプレ 27 列に完全差し替え:_FIXED_COLUMNS23 列 + 在庫4列を_INVENTORY_COL_TEMPLATESで店舗名差し込み生成row_for_bookを 27 列全部埋める形に再実装
- 自動検証スクリプトで「テンプレ列ヘッダ vs 生成CSVヘッダ」を
==比較 → 27/27 完全一致 - ローカル E2E: 2 冊 (『太平洋の試練』『1Q84』) を openBD 経由で登録 → CSV 出力 → 列数・データ確認
- 姉の Square アカウントでの実機取り込みテスト:
- 1 回目: 全データ正しく入ったが在庫数だけ反映されず
- 商品編集画面に在庫数入力フィールドが見当たらない(「在庫を管理」セクションの「アクション」は「在庫履歴」のみ)
- → Square 無料プランは編集画面から在庫数を直接入れる UI がない、CSV の「新規の数量」列が初回入庫の唯一の入り口、と仕様確定
square_csv.pyを修正: 「現在の数量」を空に、quantityを「新規の数量」列へ- 2 回目: 1Q84「3点提供可能」/太平洋の試練「1点提供可能」完全一致 ✓
決めたこと (詳細は .devnotes/DECISIONS.md の 2026-05-24 エントリ):
- 在庫数は「現在の数量」ではなく**「新規の数量」列**に出力する(Square 無料プランの仕様)
詰まったこと / 気づき:
- Square のテンプレ CSV を
csv.readerで読むと論理行5行になる(クォート内改行のため 4-5 行目のサンプル行が1論理行に統合される)。物理行ベースでrows[5]を取ると IndexError。論理行ベースでrows[-1]を見ること - Square 自動マッピング画面の「Squareの属性」側に「現在の数量」が存在せず「新規の数量」だけ存在 → これが在庫が入らない原因のサインだった。次回マッピング画面を見るときは「属性側に存在しない列名」を観察すれば仕様が読める
- 「重量(キログラム)」(うちのテンプレ通り) vs 「重量(kg)」(Square 表示) で表記揺れがあり自動マッピングに失敗するが、書籍では使わないので影響なし
- 商品編集画面で GTIN が「有効なGTIN-13」と認識される= ISBN-13 と GTIN-13 のチェックデジット仕様が同じことを Square 側も理解している
次回やること:
- テスト用2冊 (太平洋の試練 / 1Q84) を姉の Square から削除(クリーンアップ)
- 多目的 Lightsail サーバーへのデプロイ(systemd
bookcafe-webポート 8002 / Nginxbookcafe.ikapps.com/ Let's Encrypt) - 姉に URL とパスワード共有 + 使い方案内
2026-05-19
13:17 - アーキ確定 + Phase 1 実装完了
やったこと:
引き継ぎ.mdを起点に方針詰め。アプリ形態・スタック・配備方針を一気に確定- 多目的 Lightsail サーバー (
multi-purpose-lightsail-server1) の流儀を確認- 7channel-server-v3 のフラット構成 (
main.py/config.py/database.py/schema.sql/templates/+requirements.txt) を踏襲
- 7channel-server-v3 のフラット構成 (
- FastAPI 雛形構築:
requirements.txt,.env.example,.gitignoreに DB 関連除外を追加config.py(環境変数読み込み)isbn.py(ISBN-10/13 正規化 + チェックデジット検証 + 10→13 変換)openbd.py(httpx 非同期クライアント、fetch/fetch_many/ 価格抽出)database.py+schema.sql(batches / books テーブル、WAL モード)square_csv.py(Square テンプレ未確定なので差し替え可能アダプタとして分離)auth.py(itsdangerous の署名 Cookie で 1 パスワード認証)main.py(FastAPI 本体、/login /logout / / /books CRUD /batches /export)templates/3 ファイル +static/style.css+static/app.jstests/test_isbn.py(11 ケース)
- 動作確認:
- pytest 11/11 PASS
- 実 openBD API: 9784163904238 で書名・著者・出版社・価格(¥1900)取得成功
- E2E (curl + cookie jar): /login → / → POST /books (実 ISBN / 不正 / 未収録) → PATCH /books/{id} → GET /batches/1/export → DELETE すべて成功
- 未収録 ISBN は source='pending', completed=0 で DB に入ることを確認
- CSV は BOM 付き UTF-8 + CRLF で出力されることを確認
決めたこと (詳細は .devnotes/DECISIONS.md の 2026-05-19 エントリ):
- 形態: Web アプリ(多目的 Lightsail サーバーにホスト、
bookcafe.ikapps.com) - 認証: 簡易ログイン(パスワード1個)
- スタック: Python + FastAPI + 素の HTML/JS
- データ: サーバー側 SQLite(C 案 = 中断・再開に強く、過去登録履歴も残る)
- ポート 8002 / systemd
bookcafe-web予定
気づき:
- 当初テストコメントに書いていた「9784163904238 = コンビニ人間」は誤り(実際は「太平洋の試練」)。 ロジック自体に影響なし。コメントの書名は無理に当てない方が安全。
- openBD の
summary.coverは実 API では空文字が返ることがある (上記 ISBN でも未取得)。 画像 URL は使うとき None チェック必須。 - Python 3.14.5 環境では
BookInfoの dataclass +int | Noneがそのまま通った。 - ファイル名「引き継ぎ.md」(日本語) は git で
\345\274\225...とエスケープ表記されるが操作上は問題なし。
次回やること:
- Square テンプレ CSV 待ち(姉のクリティカルパス)
- 多目的サーバーへのデプロイ準備(systemd / Nginx / Let's Encrypt)
- UI 改善余地: バッチ切り替え UI、未ヒット行を上に集めるソート、ヘッダ列固定
最近のコミット
README
sisters-book-cafe
概要
(記入予定)
セットアップ
(記入予定)
使い方
(記入予定)