Skip to content

Instantly share code, notes, and snippets.

@drillan
Created November 22, 2025 13:52
Show Gist options
  • Select an option

  • Save drillan/c3ccd2fddd51da330b7986eb71903b1f to your computer and use it in GitHub Desktop.

Select an option

Save drillan/c3ccd2fddd51da330b7986eb71903b1f to your computer and use it in GitHub Desktop.
ポモドーロタイマープロジェクトの code_plan.md - Amplifier(AI駆動開発ツール)で生成

Code Implementation Plan - Pomodoro Timer

Generated: 2025-11-22T22:40:00+09:00 Based on: Phase 1 plan + Phase 2 documentation Project: Pomodoro Timer - Simple productivity tool


Summary

これは完全な新規実装プロジェクトです。現在、ドキュメントファイル(README.md, DESIGN.md, pyproject.toml, .gitignore)のみが存在し、コードファイルは一切存在しません。

Phase 2で作成したDESIGN.mdの仕様に基づき、すべてのコードファイルとディレクトリ構造を一から構築します。

実装スコープ:

  • Core modules: 6ファイル(models, storage, timer, stats, notifications, + init.py)
  • UI layer: 5ファイル(app, components × 2, + init.py × 2)
  • Tests: 5ファイル(unit tests × 4 + init.py)
  • Configuration: 1ファイル(data/.gitkeep)
  • Total: 17ファイル + 4ディレクトリ

Files to Create

Directory Structure

まず、以下のディレクトリ構造を作成します:

pomodoro-timer/
├── pomodoro/              # Core business logic
│   └── __init__.py
├── ui/                    # Streamlit UI
│   ├── components/
│   │   └── __init__.py
│   └── __init__.py
├── tests/                 # Test suite
│   └── __init__.py
└── data/                  # Session storage (gitignored)
    └── .gitkeep

File: pomodoro/__init__.py

Current State: 存在しない

Required Changes: パッケージ初期化ファイルを作成

Implementation:

"""Pomodoro Timer - Core business logic package.

This package contains the core functionality for the Pomodoro Timer application:
- Data models (models.py)
- Timer logic (timer.py)
- Storage persistence (storage.py)
- Statistics calculation (stats.py)
- OS notifications (notifications.py)
"""

__version__ = "0.1.0"

Dependencies: なし Agent Suggestion: modular-builder Tests: なし(パッケージマーカーのみ)


File: pomodoro/models.py

Current State: 存在しない

Required Changes: データモデルを定義(DESIGN.md lines 131-164参照)

Specific Implementation:

"""Data models for Pomodoro Timer.

Defines the core data structures used throughout the application.
"""

from dataclasses import dataclass
from datetime import datetime


@dataclass
class Session:
    """Represents a completed Pomodoro session.

    Attributes:
        id: Unique session identifier (UUID string)
        type: Session type - "work", "short_break", or "long_break"
        start_time: When the session started
        end_time: When the session completed
        completed: Whether session was completed (vs interrupted)
        duration_seconds: Actual duration in seconds
    """
    id: str
    type: str  # "work", "short_break", "long_break"
    start_time: datetime
    end_time: datetime
    completed: bool
    duration_seconds: int


@dataclass
class TimerConfig:
    """Configuration for timer durations and behavior.

    Default values follow classic Pomodoro Technique:
    - 25 minute work sessions
    - 5 minute short breaks
    - 15 minute long breaks every 4 pomodoros
    """
    work_duration: int = 1500  # 25 minutes
    short_break: int = 300  # 5 minutes
    long_break: int = 900  # 15 minutes
    pomodoros_until_long_break: int = 4
    sound_enabled: bool = True
    notification_enabled: bool = True

Dependencies: 標準ライブラリのみ Agent Suggestion: modular-builder Tests: tests/test_models.py


File: pomodoro/storage.py

Current State: 存在しない

Required Changes: JSONファイル永続化を実装(DESIGN.md lines 166-206参照)

Specific Implementation:

  • save_session(session: Session) -> None: アトミックライトパターンで保存
  • load_sessions(start_date, end_date) -> list[Session]: 日付範囲でフィルタリング
  • get_sessions_today() -> list[Session]: 今日のセッションを取得
  • 内部ヘルパー: _load_all_sessions(), _deserialize_session()

Key Patterns:

  1. Atomic Write:

    temp_path = DATA_PATH.with_suffix('.json.tmp')
    with open(temp_path, 'w') as f:
        json.dump(data, f, indent=2)
    temp_path.rename(DATA_PATH)  # Atomic on POSIX
  2. Incremental Save: セッション完了ごとに即座に保存

  3. Date Filtering: datetime.date() で日付比較

Dependencies: models.py, 標準ライブラリ(json, pathlib, datetime) Agent Suggestion: modular-builder Tests: tests/test_storage.py


File: pomodoro/timer.py

Current State: 存在しない

Required Changes: タイマーコアロジックを実装(DESIGN.md lines 208-250参照)

Specific Implementation:

Classes:

  • TimerState(Enum): IDLE, WORKING, SHORT_BREAK, LONG_BREAK, PAUSED
  • PomodoroTimer: メインタイマークラス

Methods:

  • start() -> None: タイマー開始(IDLE → WORKING)
  • pause() -> int: 一時停止、残り秒数を返す
  • resume() -> None: 再開(PAUSED → WORKING)
  • stop() -> None: 停止してリセット(Any → IDLE)
  • get_state() -> TimerState: 現在の状態を取得
  • get_remaining() -> int: 残り秒数を取得
  • is_complete() -> bool: セッション完了判定

Key Implementation Details:

  1. Drift-Free Timer:

    end_time = time.time() + duration_seconds
    while time.time() < end_time:
        remaining = int(end_time - time.time())
        # Update display
        time.sleep(0.1)  # Check frequently
  2. State Machine: 明示的な状態遷移ログ

  3. Auto-Save: セッション完了時に storage.save_session() 呼び出し

  4. Pomodoro Counting: 作業セッション完了数をカウント、4回目で長休憩

Dependencies: models.py, storage.py, notifications.py Agent Suggestion: modular-builder Tests: tests/test_timer.py


File: pomodoro/stats.py

Current State: 存在しない

Required Changes: 統計計算を実装(DESIGN.md lines 252-284参照)

Specific Implementation:

Functions:

  • calculate_today_stats() -> dict: 今日の集中時間と完了ポモドーロ数
  • calculate_streak() -> int: 連続日数計算
  • calculate_weekly_overview() -> dict[str, int]: 過去7日間の日別ポモドーロ数

Algorithm Notes:

  1. Today Stats:

    • storage.get_sessions_today() でセッション取得
    • type == "work" のみカウント
    • duration_seconds を合計して分に変換
  2. Streak Calculation:

    • 各日付の作業セッション数を集計
    • 今日から遡って連続日数をカウント
    • 0ポモドーロの日でストリーク終了
  3. Weekly Overview:

    • 過去7日間のセッションを読み込み
    • 日付別にグループ化
    • 作業セッション数をカウント

Dependencies: models.py, storage.py Agent Suggestion: modular-builder Tests: tests/test_stats.py


File: pomodoro/notifications.py

Current State: 存在しない

Required Changes: OS通知システムを実装(DESIGN.md lines 286-324参照)

Specific Implementation:

Functions:

  • notify_session_complete(session_type: str) -> None
  • notify_break_complete() -> None

Key Details:

from plyer import notification

def notify_session_complete(session_type: str) -> None:
    """セッション完了通知を表示。

    Args:
        session_type: "work", "short_break", "long_break"
    """
    if session_type == "work":
        title = "ポモドーロ完了!"
        message = "よくできました!5分休憩しましょう。"
    elif session_type == "short_break":
        title = "休憩完了!"
        message = "さあ、次のポモドーロを始めましょう。"
    else:  # long_break
        title = "長休憩完了!"
        message = "リフレッシュできましたか?作業を再開しましょう。"

    notification.notify(
        title=title,
        message=message,
        app_name="Pomodoro Timer",
        timeout=10
    )

Dependencies: plyer Agent Suggestion: modular-builder Tests: 手動テスト(OS通知が実際に表示されるか)


File: ui/__init__.py

Current State: 存在しない

Required Changes: UIパッケージ初期化

Implementation:

"""Pomodoro Timer - User Interface package.

Streamlit-based UI for the Pomodoro Timer application.
"""

Dependencies: なし Agent Suggestion: modular-builder Tests: なし


File: ui/app.py

Current State: 存在しない

Required Changes: メインStreamlitアプリケーションを実装(DESIGN.md lines 326-355参照)

Specific Implementation:

Structure:

import streamlit as st
from pomodoro.timer import PomodoroTimer, TimerState
from pomodoro import stats
from ui.components import timer_display, stats_display

def main():
    """メインアプリケーション。"""
    st.set_page_config(page_title="Pomodoro Timer", layout="wide")

    # セッション状態の初期化
    initialize_session_state()

    # タイマー表示
    timer_display.render()

    # コントロールボタン
    render_controls()

    # 統計表示
    stats_display.render()

    # 設定パネル(サイドバー)
    render_settings()

def initialize_session_state():
    """Streamlitセッション状態を初期化。"""
    if 'timer' not in st.session_state:
        st.session_state.timer = PomodoroTimer()
    # その他の状態変数...

def render_controls():
    """タイマーコントロールボタンを表示。"""
    col1, col2, col3 = st.columns(3)
    with col1:
        if st.button("Start", key="start_btn"):
            st.session_state.timer.start()
    # ...

def render_settings():
    """設定パネルをサイドバーに表示。"""
    with st.sidebar:
        st.header("設定")
        # TimerConfigの編集UI
        # ...

if __name__ == "__main__":
    main()

Key Features:

  • セッション状態によるタイマー永続化
  • 0.1秒ごとの自動リフレッシュ(st.rerun()
  • キーボードショートカット(Space, Esc, B, S)
  • 設定の編集と保存

Dependencies: すべてのビジネスロジックモジュール、Streamlit Agent Suggestion: modular-builder Tests: 手動テスト(UIの動作確認)


File: ui/components/__init__.py

Current State: 存在しない

Required Changes: コンポーネントパッケージ初期化

Implementation:

"""UI components for Pomodoro Timer."""

Dependencies: なし Agent Suggestion: modular-builder Tests: なし


File: ui/components/timer_display.py

Current State: 存在しない

Required Changes: タイマー表示コンポーネントを実装

Specific Implementation:

"""Timer display component."""

import streamlit as st
from pomodoro.timer import TimerState

def render():
    """タイマー表示をレンダリング。

    大きく読みやすいフォントで残り時間を表示。
    - 7:1コントラスト比(アクセシビリティ)
    - MM:SS形式
    - 状態に応じた色分け(作業=青、休憩=緑)
    """
    timer = st.session_state.timer
    remaining = timer.get_remaining()
    state = timer.get_state()

    # MM:SS形式に変換
    minutes = remaining // 60
    seconds = remaining % 60
    time_str = f"{minutes:02d}:{seconds:02d}"

    # 状態に応じた色とメッセージ
    if state == TimerState.WORKING:
        st.markdown(f"<h1 style='color: #1E3A8A;'>{time_str}</h1>", unsafe_allow_html=True)
        st.write("作業中...")
    elif state == TimerState.SHORT_BREAK:
        st.markdown(f"<h1 style='color: #166534;'>{time_str}</h1>", unsafe_allow_html=True)
        st.write("短い休憩")
    # ...

Dependencies: Streamlit, pomodoro.timer Agent Suggestion: modular-builder Tests: 手動テスト(表示の確認)


File: ui/components/stats_display.py

Current State: 存在しない

Required Changes: 統計表示コンポーネントを実装

Specific Implementation:

"""Statistics display component."""

import streamlit as st
from pomodoro import stats

def render():
    """統計をレンダリング。

    表示内容:
    - 今日の集中時間(分)
    - 完了ポモドーロ数
    - 連続日数
    - 週間概要(バーチャート)
    """
    st.header("統計")

    # 今日の統計
    today = stats.calculate_today_stats()
    col1, col2 = st.columns(2)
    with col1:
        st.metric("今日の集中時間", f"{today['focus_time']}分")
    with col2:
        st.metric("完了ポモドーロ", today['completed_pomodoros'])

    # 連続日数
    streak = stats.calculate_streak()
    st.metric("連続日数", f"{streak}日")

    # 週間概要
    weekly = stats.calculate_weekly_overview()
    st.bar_chart(weekly)

Dependencies: Streamlit, pomodoro.stats Agent Suggestion: modular-builder Tests: 手動テスト(統計の正確性)


File: tests/__init__.py

Current State: 存在しない

Required Changes: テストパッケージ初期化

Implementation:

"""Test suite for Pomodoro Timer."""

Dependencies: なし Agent Suggestion: modular-builder Tests: なし


File: tests/test_models.py

Current State: 存在しない

Required Changes: データモデルのユニットテスト

Specific Tests:

"""Unit tests for data models."""

from datetime import datetime
from pomodoro.models import Session, TimerConfig

def test_session_creation():
    """Sessionデータクラスが正しく作成されるか。"""
    session = Session(
        id="test-123",
        type="work",
        start_time=datetime.now(),
        end_time=datetime.now(),
        completed=True,
        duration_seconds=1500
    )
    assert session.id == "test-123"
    assert session.type == "work"
    assert session.completed is True

def test_timer_config_defaults():
    """TimerConfigのデフォルト値が正しいか。"""
    config = TimerConfig()
    assert config.work_duration == 1500
    assert config.short_break == 300
    assert config.long_break == 900
    assert config.pomodoros_until_long_break == 4

def test_session_serialization():
    """Sessionをdictにシリアライズできるか。"""
    # dataclasses.asdict()を使用
    # ...

Dependencies: pomodoro.models, pytest Agent Suggestion: test-coverage Tests: 自己テスト


File: tests/test_storage.py

Current State: 存在しない

Required Changes: ストレージ永続化のユニットテスト

Specific Tests:

"""Unit tests for storage persistence."""

import pytest
from datetime import datetime, date
from pathlib import Path
from pomodoro.models import Session
from pomodoro import storage

@pytest.fixture
def temp_data_file(tmp_path):
    """一時的なデータファイルを作成。"""
    data_file = tmp_path / "sessions.json"
    # storage.DATA_PATHを一時的に置き換え
    # ...
    return data_file

def test_save_and_load_session(temp_data_file):
    """セッションを保存して読み込めるか。"""
    session = Session(
        id="test-1",
        type="work",
        start_time=datetime.now(),
        end_time=datetime.now(),
        completed=True,
        duration_seconds=1500
    )

    storage.save_session(session)
    sessions = storage.load_sessions()

    assert len(sessions) == 1
    assert sessions[0].id == "test-1"

def test_date_filtering(temp_data_file):
    """日付フィルタリングが正しく動作するか。"""
    # 異なる日付のセッションを作成
    # load_sessions(start_date, end_date)で取得
    # フィルタリング結果を検証
    # ...

def test_atomic_write(temp_data_file):
    """アトミックライトが正しく動作するか。"""
    # 保存中にクラッシュしても既存データが破損しないことを確認
    # ...

Dependencies: pomodoro.models, pomodoro.storage, pytest Agent Suggestion: test-coverage Tests: 自己テスト


File: tests/test_timer.py

Current State: 存在しない

Required Changes: タイマーロジックのユニットテスト

Specific Tests:

"""Unit tests for timer logic."""

import pytest
from unittest.mock import Mock, patch
from pomodoro.timer import PomodoroTimer, TimerState

def test_initial_state():
    """初期状態がIDLEであるか。"""
    timer = PomodoroTimer()
    assert timer.get_state() == TimerState.IDLE

def test_start_timer():
    """タイマーを開始できるか。"""
    timer = PomodoroTimer()
    timer.start()
    assert timer.get_state() == TimerState.WORKING

def test_pause_resume():
    """一時停止と再開が正しく動作するか。"""
    timer = PomodoroTimer()
    timer.start()
    remaining = timer.pause()
    assert timer.get_state() == TimerState.PAUSED
    assert remaining > 0

    timer.resume()
    assert timer.get_state() == TimerState.WORKING

def test_state_transitions():
    """状態遷移が正しく動作するか。"""
    # IDLE → WORKING → SHORT_BREAK → WORKING → ...
    # 4回目のWORKING完了後に LONG_BREAK
    # ...

@patch('pomodoro.storage.save_session')
def test_session_auto_save(mock_save):
    """セッション完了時に自動保存されるか。"""
    # タイマー完了をシミュレート
    # mock_save が呼ばれたことを確認
    # ...

Dependencies: pomodoro.timer, pomodoro.models, pytest Agent Suggestion: test-coverage Tests: 自己テスト


File: tests/test_stats.py

Current State: 存在しない

Required Changes: 統計計算のユニットテスト

Specific Tests:

"""Unit tests for statistics calculation."""

import pytest
from datetime import datetime, timedelta, date
from pomodoro.models import Session
from pomodoro import stats, storage

@pytest.fixture
def sample_sessions():
    """テスト用のサンプルセッションを作成。"""
    sessions = []
    # 今日の作業セッション3つ
    for i in range(3):
        sessions.append(Session(
            id=f"today-{i}",
            type="work",
            start_time=datetime.now() - timedelta(hours=i),
            end_time=datetime.now() - timedelta(hours=i) + timedelta(minutes=25),
            completed=True,
            duration_seconds=1500
        ))
    return sessions

def test_today_stats(sample_sessions):
    """今日の統計が正しく計算されるか。"""
    # sample_sessionsを一時的に保存
    # stats.calculate_today_stats()を呼び出し
    # focus_time = 75分(25×3)
    # completed_pomodoros = 3
    # ...

def test_streak_calculation():
    """連続日数が正しく計算されるか。"""
    # 過去5日間、毎日1ポモドーロのセッションを作成
    # calculate_streak()が5を返すことを確認
    # ...

def test_weekly_overview():
    """週間概要が正しく計算されるか。"""
    # 過去7日間のセッションを作成
    # calculate_weekly_overview()の結果を検証
    # 日付キーとポモドーロ数のマッピング
    # ...

Dependencies: pomodoro.models, pomodoro.stats, pomodoro.storage, pytest Agent Suggestion: test-coverage Tests: 自己テスト


File: data/.gitkeep

Current State: 存在しない

Required Changes: データディレクトリを保持するための空ファイル

Implementation: 空ファイル

Purpose: data/ ディレクトリをGitで追跡するが、sessions.jsonは除外(.gitignoreに記載)

Dependencies: なし Agent Suggestion: modular-builder Tests: なし


Implementation Chunks

実装を論理的で独立してテスト可能なチャンクに分割します。

Chunk 1: Data Foundation (データ基盤)

Files:

  • pomodoro/__init__.py
  • pomodoro/models.py
  • tests/__init__.py
  • tests/test_models.py

Description: 基本的なデータモデルを定義し、テストを作成

Why First: 他のすべてのモジュールがこれらのデータ構造に依存

Test Strategy:

  • pytest tests/test_models.py -v
  • データクラスの作成、デフォルト値、シリアライゼーション

Dependencies: なし

Commit Point: すべてのユニットテストがパスした後


Chunk 2: Persistence Layer (永続化層)

Files:

  • pomodoro/storage.py
  • tests/test_storage.py
  • data/.gitkeep

Description: JSONファイル永続化を実装

Why Second: タイマーとstatsがストレージに依存

Test Strategy:

  • pytest tests/test_storage.py -v
  • 保存/読み込み、日付フィルタリング、アトミックライト

Dependencies: Chunk 1(models)

Commit Point: すべてのストレージテストがパスした後


Chunk 3: Notifications (通知システム)

Files:

  • pomodoro/notifications.py

Description: OS通知システムを実装

Why Third: タイマーが通知に依存するが、他のモジュールには依存しない

Test Strategy: 手動テスト(OS通知が実際に表示されるか)

Dependencies: なし(plyerライブラリのみ)

Commit Point: 手動テストで通知が確認された後


Chunk 4: Timer Core Logic (タイマーコアロジック)

Files:

  • pomodoro/timer.py
  • tests/test_timer.py

Description: タイマー状態マシンとカウントダウンロジックを実装

Why Fourth: storage と notifications が完成している必要がある

Test Strategy:

  • pytest tests/test_timer.py -v
  • 状態遷移、pause/resume、セッション完了、自動保存

Dependencies: Chunk 1(models)、Chunk 2(storage)、Chunk 3(notifications)

Commit Point: すべてのタイマーテストがパスした後


Chunk 5: Statistics (統計計算)

Files:

  • pomodoro/stats.py
  • tests/test_stats.py

Description: セッションデータから統計を計算

Why Fifth: storage が完成している必要があるが、UI には依存しない

Test Strategy:

  • pytest tests/test_stats.py -v
  • 今日の統計、連続日数、週間概要

Dependencies: Chunk 1(models)、Chunk 2(storage)

Commit Point: すべての統計テストがパスした後


Chunk 6: UI Components (UIコンポーネント)

Files:

  • ui/__init__.py
  • ui/components/__init__.py
  • ui/components/timer_display.py
  • ui/components/stats_display.py

Description: Streamlit UIコンポーネントを実装

Why Sixth: すべてのビジネスロジックが完成している必要がある

Test Strategy: 手動テスト(UIの表示確認)

Dependencies: すべての前チャンク(models, timer, stats)

Commit Point: UIコンポーネントが正しく表示された後


Chunk 7: Main Application (メインアプリケーション)

Files:

  • ui/app.py

Description: メインStreamlitアプリケーションを実装

Why Last: すべてのコンポーネントを統合

Test Strategy: 手動エンドツーエンドテスト

  • タイマーの開始/停止
  • セッション完了時の通知
  • 統計の表示
  • 設定の編集

Dependencies: すべての前チャンク

Commit Point: エンドツーエンドテストが成功した後


Agent Orchestration Strategy

Primary Agents

modular-builder - すべてのモジュール実装:

Task modular-builder: "Implement pomodoro/models.py according to
code_plan.md and DESIGN.md specification"

test-coverage - テスト計画とレビュー:

Task test-coverage: "Review test coverage for pomodoro package
and suggest additional test cases"

bug-hunter - 問題発生時:

Task bug-hunter: "Debug issue with timer drift after 25 minutes"

Sequential Implementation

このプロジェクトは完全に順次的に実装します:

Chunk 1 → Chunk 2 → Chunk 3 → Chunk 4 → Chunk 5 → Chunk 6 → Chunk 7

Rationale: 各チャンクが前のチャンクに依存しているため

Parallel Implementation: なし(依存関係が強い)


Testing Strategy

Unit Tests to Add

tests/test_models.py

  • test_session_creation() - Sessionデータクラスの作成
  • test_timer_config_defaults() - デフォルト値の検証
  • test_session_serialization() - dict変換

tests/test_storage.py

  • test_save_and_load_session() - 保存/読み込み
  • test_date_filtering() - 日付範囲フィルタリング
  • test_atomic_write() - アトミックライトパターン
  • test_get_sessions_today() - 今日のセッション取得

tests/test_timer.py

  • test_initial_state() - 初期状態IDLE
  • test_start_timer() - タイマー開始
  • test_pause_resume() - 一時停止と再開
  • test_state_transitions() - 完全な状態遷移サイクル
  • test_session_auto_save() - セッション完了時の自動保存
  • test_pomodoro_counting() - 4回目で長休憩

tests/test_stats.py

  • test_today_stats() - 今日の集中時間と完了数
  • test_streak_calculation() - 連続日数計算
  • test_weekly_overview() - 週間概要
  • test_empty_sessions() - セッションなしの場合

Integration Tests

timer + storage:

  • セッション完了時の自動保存
  • 保存されたセッションの読み込み

timer + notifications:

  • セッション完了時の通知トリガー

stats + storage:

  • 保存されたセッションからの統計計算

Manual Tests

User Testing Plan:

# アプリケーション起動
uv run streamlit run ui/app.py

# テストシナリオ1: 基本的なタイマー動作
1. "Start"ボタンをクリック
2. タイマーが25:00からカウントダウン開始
3. "Pause"で一時停止
4. "Resume"で再開
5. "Stop"でリセット

# テストシナリオ2: セッション完了
1. タイマー開始
2. 25分待つ(または duration を短縮してテスト)
3. OS通知が表示されることを確認
4. 自動的に休憩に移行することを確認

# テストシナリオ3: 統計表示
1. 複数のポモドーロを完了
2. 統計ビューを開く
3. 今日の集中時間が正しく表示されるか
4. 完了ポモドーロ数が正しいか

# テストシナリオ4: キーボードショートカット
1. Spaceキーでタイマー開始/停止
2. Escキーでリセット
3. Bキーで手動休憩開始
4. Sキーで統計表示切り替え

Expected Behavior:

  • タイマーがドリフトなく正確にカウント
  • 通知がセッション完了時に表示
  • 統計が正しく計算され表示
  • キーボードショートカットが機能

Philosophy Compliance

Ruthless Simplicity

適用箇所:

  • JSONストレージ(データベース不要)
  • Streamlit UI(フロントエンドフレームワーク不要)
  • 基本統計のみ(高度な分析なし)
  • シンプルな状態マシン(複雑なライブラリなし)

実装しないもの:

  • ✗ クラウド同期
  • ✗ タスク管理統合
  • ✗ カスタムアニメーション
  • ✗ 高度なレポート
  • ✗ チーム機能

各モジュールで:

  • 最小限の抽象化
  • 明確な責任
  • 直接的なAPI

Modular Design (Bricks & Studs)

Bricks(自己完結モジュール):

  1. models.py - データ定義のみ、依存なし
  2. storage.py - ファイルI/O、modelsのみ依存
  3. notifications.py - OS統合、依存なし
  4. timer.py - タイマーロジック、明確な依存
  5. stats.py - 計算ロジック、明確な依存
  6. app.py - UI統合、すべてに依存

Studs(接続ポイント):

  • Session, TimerConfig - データインターフェース
  • save_session(), load_sessions() - 永続化インターフェース
  • start(), pause(), stop() - タイマー制御インターフェース
  • calculate_*() - 統計インターフェース
  • notify_*() - 通知インターフェース

再生成可能性: 各モジュールは以下から完全に再構築可能:

  • code_plan.mdの仕様
  • DESIGN.mdの詳細設計
  • テストスイート

Zero-BS Principle

実装すること:

  • ✓ 完全に動作するコード
  • ✓ 即座に実行可能
  • ✓ すべてのテストがパス
  • ✓ 実際のファイルI/O(モック最小限)

実装しないこと:

  • ✗ TODOコメント
  • NotImplementedError
  • ✗ プレースホルダーテキスト
  • ✗ 将来の機能のスタブ

Design for Humans

アクセシビリティ:

  • タイマーテキスト: 7:1コントラスト比
  • ボタン: 44×44px最小サイズ
  • キーボードナビゲーション: 完全サポート
  • スクリーンリーダー: 意味のあるHTML

ユーザビリティ:

  • 明確な状態表示
  • 予測可能な動作
  • 役立つエラーメッセージ
  • 設定可能な通知

Commit Strategy

詳細なコミット計画:

Commit 1: Data Foundation

git add pomodoro/__init__.py pomodoro/models.py tests/__init__.py tests/test_models.py
git commit -m "feat(models): Add core data models

- Add Session dataclass for completed pomodoros
- Add TimerConfig with classic Pomodoro defaults
- Add comprehensive unit tests

Tests:
- test_session_creation
- test_timer_config_defaults
- test_session_serialization

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Commit 2: Persistence Layer

git add pomodoro/storage.py tests/test_storage.py data/.gitkeep
git commit -m "feat(storage): Implement JSON file persistence

- Add atomic write pattern (temp file + rename)
- Add save_session() with incremental processing
- Add load_sessions() with date filtering
- Add get_sessions_today() convenience function

Tests:
- test_save_and_load_session
- test_date_filtering
- test_atomic_write

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Commit 3: Notifications

git add pomodoro/notifications.py
git commit -m "feat(notifications): Add OS-native desktop notifications

- Add notify_session_complete() for work/break completion
- Add notify_break_complete() for break completion
- Use plyer for cross-platform support

Manual testing confirms notifications work on current platform.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Commit 4: Timer Core Logic

git add pomodoro/timer.py tests/test_timer.py
git commit -m "feat(timer): Implement Pomodoro timer core logic

- Add TimerState enum (IDLE, WORKING, SHORT_BREAK, LONG_BREAK, PAUSED)
- Add PomodoroTimer class with drift-free countdown
- Add state machine with explicit transitions
- Add auto-save on session completion
- Add pomodoro counting (long break every 4)

Tests:
- test_initial_state
- test_start_timer
- test_pause_resume
- test_state_transitions
- test_session_auto_save

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Commit 5: Statistics

git add pomodoro/stats.py tests/test_stats.py
git commit -m "feat(stats): Add statistics calculation

- Add calculate_today_stats() for focus time and pomodoro count
- Add calculate_streak() for consecutive days
- Add calculate_weekly_overview() for last 7 days

Tests:
- test_today_stats
- test_streak_calculation
- test_weekly_overview
- test_empty_sessions

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Commit 6: UI Components

git add ui/__init__.py ui/components/__init__.py ui/components/timer_display.py ui/components/stats_display.py
git commit -m "feat(ui): Add Streamlit UI components

- Add timer_display.py for countdown visualization
- Add stats_display.py for statistics dashboard
- 7:1 contrast ratio for accessibility
- Color-coded state indication

Manual testing confirms correct display.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Commit 7: Main Application

git add ui/app.py
git commit -m "feat(ui): Add main Streamlit application

- Add session state management
- Add timer controls (start, pause, stop)
- Add keyboard shortcuts (Space, Esc, B, S)
- Add settings panel in sidebar
- Add 0.1s auto-refresh for smooth countdown

End-to-end testing confirms all features working.

🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)

Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>"

Risk Assessment

High Risk Changes

Risk 1: Timer Drift

  • Problem: sleep() accumulation could cause drift
  • Mitigation: Target end time approach (lines 476-482 in DESIGN.md)
  • Test: Manual test with 25-minute session

Risk 2: UI Thread Blocking

  • Problem: Countdown loop might block Streamlit UI
  • Mitigation: 0.1s sleep + st.rerun() for responsive updates
  • Test: Check UI responsiveness during countdown

Risk 3: Data Corruption on Crash

  • Problem: Partial writes could corrupt sessions.json
  • Mitigation: Atomic write pattern (temp file + rename)
  • Test: Simulate crash during save

Dependencies to Watch

plyer (notifications):

  • Version: >=2.1.0
  • Constraint: クロスプラットフォーム動作
  • Fallback: 通知失敗時は静かにログ

streamlit:

  • Version: >=1.30.0
  • Constraint: セッション状態API
  • Risk: Streamlit更新によるAPI変更

Breaking Changes

なし - 新規プロジェクトのため既存APIなし


Success Criteria

コードが準備完了の条件:

  • すべてのドキュメント化された動作が実装されている
  • すべてのテストがパス(uv run pytest
  • コード品質チェックがパス(make check
  • ユーザーテストが正常に動作(タイマー、通知、統計)
  • 既存機能の退行なし(新規プロジェクトなのでN/A)
  • コードが哲学原則に従っている
  • Phase 4実装準備完了

Next Steps

Code plan complete and detailed

➡️ Get user approval

このコード計画を確認してください。すべてのファイル、実装の詳細、テスト戦略、コミット計画が含まれています。

➡️ When approved, run: /ddd:4-code

Phase 4では、この計画に基づいて実際のコード実装を行います。各チャンクを順次実装し、テストし、コミットします。


Document Metadata

Created: 2025-11-22T22:40:00+09:00 Based on: plan.md (Phase 1), DESIGN.md (Phase 2) Status: Ready for User Approval Next Phase: /ddd:4-code Estimated Implementation Time: 1-2 hours

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment