🔍 OpenChair — Codex コードレビュー結果と修正計画

対象: 採用版A案 openchair_A_sqlite | レビュー: Codex | 日付: 2026-06-30

① レビュー結果サマリー

0CRITICAL
1HIGH
3MEDIUM
1LOW
5/5修正完了
結論: 重大度 CRITICAL は0件。Codex が検出した 5件(HIGH 1 / MEDIUM 3 / LOW 1)を全件修正し、回帰テストを追加。ユニットテストは 47 → 51 passed、selftest OK。

レビューはCodex(OpenAI)に委譲。観点は「スタイル指摘より実害のあるバグ」。本ページは指摘原文と、それに対する修正方針・実装状況をまとめたものです。

② 指摘 → 修正の対応表

重大度指摘内容(Codex)修正方針 / 実装状態
HIGH スキーマ未移行クラッシュ
src/storage.py
既存DBには CREATE TABLE IF NOT EXISTS しか走らないため、列追加後に旧DBを使うと add_screenshot()no such column で落ちる。
_init_db()_migrate_columns() を追加。PRAGMA table_info で不足列を検出し ALTER TABLE ADD COLUMN(既定値つき)で後付け。冪等。
for col, decl in expected:
  if col not in existing:
    ALTER TABLE t ADD COLUMN col decl
✅ 完了
MED ゼロ秒セッションが進行中扱い
src/app.py _today_total_sec
duration_sec==0 が falsy で elif start_ts に落ち、now-開始 を加算 → 残業合計が膨らむ。
end_ts の有無で「終了済み/着席中」を判定。終了済みは dur is not None なら 0 も加算、着席中のみ now-開始 ✅ 完了
MED 初回 diff 0.0 でアラート早発火
src/app.py _on_tick
比較元がない初回の diff_score=0.0diff_buf に積むため、無変化アラートが1ティック早く出る。
diff_computed=None 初期化。実際に前フレームと比較できたティックのみ diff_buf に追記。DB格納は初回 0.0 のまま。 ✅ 完了
MED 着席中セッションがゼロ幅
src/dashboard.py timeline
end_ts is Nonee_min=s_min となり、現在も着席中なのにタイムライン上で実績ゼロに見える。
_build_timeline_section(now=) を追加。撮影日と now が同日なら now までブロックを伸ばし、合計時間にも now-開始 を反映。 ✅ 完了
LOW タイムライン右端はみ出し
src/dashboard.py
max(0.4, min(100-left, width)) の順序だと left 大で left+width>100% になりうる。
先に available=100-left を求め、available<=0 はスキップ、width=min(available, max(0.4, raw)) に修正。 ✅ 完了

③ 修正計画(実行順)と結果

手順内容結果
1HIGH: storage に列マイグレーション実装(旧DB救済)
2MEDIUM×3: 残業集計の None/0 区別・初回diffのバッファ除外・着席中の now 反映
3LOW: タイムライン幅クランプの順序修正
4回帰テスト追加(マイグレーション/ゼロ秒/着席中幅/はみ出し)✅ 51 passed
5selftest 実行(DRY_RUN 一気通貫)✅ SELFTEST OK
6README 更新履歴へ追記 → コミット → プッシュ
追加した回帰テスト: TestSchemaMigration.test_adds_missing_columns_on_open, TestOvertime.test_zero_duration_finished_not_counted_as_ongoing, TestTimelineFixes.test_ongoing_session_uses_now_width, TestTimelineFixes.test_block_never_overflows_right_edge