store を node:sqlite に刷新(差し替え可能なストア層の背後で)#78
Merged
Conversation
The receiver kept all feedback in a single JSON array and rewrote the whole file on every change, with queries and deletes scanning the array in memory — fine for a prototype, but it degrades by the hundreds of items. Persistence now lives in server/store.js behind a small async interface (init/insert/get/list/update/delete/count) with a node:sqlite implementation; a future backend like MySQL implements the same contract without touching the receiver. The interface is async so a network-backed driver fits the same shape. A minimal portable schema (id + project/demo/status/received_at columns for filtering, the full object in a JSON column) keeps payload growth schema-free and maps cleanly to other SQL engines. On startup a legacy feedback.json is migrated once and archived; a corrupt one is set aside, preserving the old crash-safe behavior. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
🔍 レビュー依頼(→ Codex)
|
- Reject duplicate ids with 409 instead of INSERT OR REPLACE silently overwriting an existing row - Make update/delete atomic by reading synchronously (no await between read and write), closing the lost-update window - Treat empty query filter values as "no filter" so NULL-column rows still match, matching the inbox "all" option - Wrap the legacy migration in a transaction so an interruption rolls back and the next startup retries instead of stranding rows - Restore process.emitWarning right after requiring node:sqlite Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Owner
Author
📋 レビュー結果(by Codex / GPT-5.5)判定: ⛔ 要対応(must 2 件)→ 対応済み、再検証パス Codex が must 2・should 3 を指摘。いずれも今回導入したコードの正当な指摘で、全件対応しました。 🔴 must(対応済み)
🟡 should(対応済み)
⚪ nitなし 検証
修正コミットをこの後 push します。 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #74
路線 2 の最後。事前に方式を相談し、node:sqlite + 差し替え可能なストア層で合意。
設計
server/store.jsの小さな非同期インターフェースの背後に隔離:init / insert / get / list / update / delete / count / close。receiver はこの契約だけを呼ぶcreateSqliteStore(node:sqliteのDatabaseSync)。createStore({ backend })ファクトリ経由で、将来createMysqlStore等を同契約で足せば receiver は無変更。インターフェースは async なのでネットワーク系ドライバもそのまま乗る(要件: 後で MySQL 等に差し替え可能)id+ フィルタ用project_id / demo_id / status / received_at列 + 全文を JSON 列data。payload にフィールドが増えてもスキーマ変更不要、他の SQL エンジンへも素直にマップfeedback.jsonは起動時に一度だけ sqlite へ移行しfeedback.json.migrated-<ts>に退避。壊れていればfeedback.json.corrupt-<ts>に退避して空起動(feedback.json の破損で全データが黙って消える(非アトミック書き込み) #47 のクラッシュセーフ挙動を踏襲)node:sqliteの ExperimentalWarning はその 1 行だけ抑止FEEDBACK_DB_PATH(db パス)/FEEDBACK_STORE_PATH(移行元 JSON)外から見た振る舞いは不変
widget の payload、
GET /feedback.jsonの応答、inbox の見た目は変わりません。全書き換え→INSERT/UPDATE/DELETE、メモリ全走査→WHEREで索引、になっただけです。検証
npm run check全パス(テスト 61 件。旧 corrupt-store テストを「起動時に corrupt legacy を退避」に書き換え、「valid legacy → sqlite 移行 + archive」テストを追加。既存の post/import/status/github/delete/filter は sqlite 実装に対して green)レビュー観点(依頼するなら)