Skip to content

Instantly share code, notes, and snippets.

@drillan
Last active November 23, 2025 00:23
Show Gist options
  • Select an option

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

Select an option

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

DDD Plan: Pomodoro Timer

Problem Statement

What We're Solving

ポモドーロテクニックを実装したタイマーアプリケーションを構築します。ユーザーが集中力を維持し、生産性を向上させるための時間管理ツールです。

Why It Matters

  • 集中力の維持: 25分の作業セッションで持続可能な集中を促進
  • 作業履歴の追跡: セッション記録により自己改善を支援
  • 生産性の可視化: 統計により定量的なフィードバックを提供

User Value

  • シンプルで使いやすいタイマーインターフェース
  • 作業パターンの可視化
  • 邪魔にならない通知システム
  • ローカルデータ保存(プライバシー重視)

Proposed Solution

High-Level Approach

Streamlitを使用したPython製のシンプルなデスクトップアプリケーションとして実装します。

Core Features:

  1. タイマー機能: 25分作業、5分休憩、15分長休憩
  2. セッション記録: 各完了セッションをローカルJSONファイルに保存
  3. 統計表示: 今日の集中時間、完了ポモドーロ数、連続日数、週間概要
  4. 通知システム: セッション完了時のOS標準通知

Key Design Decisions:

  • Frontend: Streamlit(迅速な開発、Pythonのみ)
  • Storage: JSON files(シンプル、人間が読める)
  • State Management: Streamlit session state
  • Timer Precision: 秒単位表示(MM:SS形式)
  • Notifications: OS-native desktop notifications

Alternatives Considered

Alternative 1: HTML/CSS/JavaScript Frontend

Pros:

  • 高度なアニメーションとUI制御
  • より洗練されたビジュアル表現
  • ブラウザベースでクロスプラットフォーム

Cons:

  • 開発時間が長い(4-6時間)
  • JavaScriptの知識が必要
  • バックエンド/フロントエンド間の複雑な通信
  • 技術スタックの分散(Python + JavaScript)

Why We Chose Streamlit:

  • 学習プロジェクトとして1-2時間で完成可能
  • 統一された技術スタック(Pythonのみ)
  • 十分なUI機能性
  • Ruthless Simplicity原則に最も適合

Alternative 2: Database Storage (SQLite)

Pros:

  • より高速なクエリ
  • 複雑な集計が可能
  • データ整合性の保証

Cons:

  • セットアップの複雑さ
  • オーバーエンジニアリング(データ量は小規模)
  • 人間が直接読めない

Why We Chose JSON:

  • セッションデータは小規模(1日あたり10-20セッション程度)
  • 人間が読み書き可能
  • バックアップとデバッグが容易
  • Ruthless Simplicity原則に適合

Architecture & Design

System Architecture

┌─────────────────────────────────────────────┐
│           Streamlit UI Layer                │
│         (app.py / components/)              │
└─────────────┬───────────────────────────────┘
              │
              │ Uses
              ↓
┌─────────────────────────────────────────────┐
│         Business Logic Layer                │
│                                             │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐ │
│  │  Timer   │  │  Stats   │  │  Notify  │ │
│  │ (timer.py)│  │(stats.py)│  │(notif.py)│ │
│  └────┬─────┘  └────┬─────┘  └──────────┘ │
│       │             │                       │
│       │             │                       │
│       ↓             ↓                       │
│  ┌─────────────────────────────┐           │
│  │    Storage Layer            │           │
│  │    (storage.py)             │           │
│  └──────────┬──────────────────┘           │
└─────────────┼──────────────────────────────┘
              │
              ↓
      ┌───────────────┐
      │ sessions.json │
      │ (data/)       │
      └───────────────┘

Key Interfaces (Studs)

Timer Module (timer.py)

class TimerState(Enum):
    IDLE = "idle"
    WORKING = "working"
    SHORT_BREAK = "short_break"
    LONG_BREAK = "long_break"
    PAUSED = "paused"

class PomodoroTimer:
    def start() -> None
    def pause() -> int  # Returns remaining seconds
    def stop() -> None
    def get_state() -> TimerState
    def get_remaining() -> int  # Seconds remaining
    def is_complete() -> bool

Storage Module (storage.py)

def save_session(session: Session) -> None
def load_sessions(start_date: date = None, end_date: date = None) -> list[Session]
def get_sessions_today() -> list[Session]

Statistics Module (stats.py)

def calculate_today_stats() -> dict
    # Returns: {focus_time: int, completed_pomodoros: int}
def calculate_streak() -> int
    # Returns: consecutive days with at least 1 pomodoro
def calculate_weekly_overview() -> dict
    # Returns: {date: pomodoro_count} for last 7 days

Notifications Module (notifications.py)

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

Module Boundaries

models.py (Data Structures)

  • Purpose: Define core data models
  • Dependencies: None (pure data)
  • Exports: Session, TimerConfig, Statistics

storage.py (Persistence)

  • Purpose: Handle JSON file I/O
  • Dependencies: models.py
  • Exports: save_session(), load_sessions()

timer.py (Core Logic)

  • Purpose: Manage timer state and countdown
  • Dependencies: models.py, storage.py, notifications.py
  • Exports: PomodoroTimer class

stats.py (Statistics)

  • Purpose: Calculate metrics from session data
  • Dependencies: models.py, storage.py
  • Exports: Statistics calculation functions

notifications.py (System Integration)

  • Purpose: Trigger OS notifications
  • Dependencies: None
  • Exports: Notification functions

app.py (UI)

  • Purpose: Streamlit interface
  • Dependencies: All above modules
  • Exports: None (entry point)

Data Models

Session

@dataclass
class Session:
    id: str  # UUID
    type: str  # "work", "short_break", "long_break"
    start_time: datetime
    end_time: datetime
    completed: bool
    duration_seconds: int

TimerConfig

@dataclass
class TimerConfig:
    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

Files to Change

Non-Code Files (Phase 2: /ddd:2-docs)

  • pomodoro-timer/README.md - ユーザー向けドキュメント(インストール、使用方法、設定)
  • pomodoro-timer/DESIGN.md - アーキテクチャ決定、状態マシン図、データフロー
  • pomodoro-timer/.gitignore - data/ディレクトリの除外設定
  • pomodoro-timer/pyproject.toml - プロジェクト設定と依存関係

Code Files (Phase 4: /ddd:4-code)

Core Modules

  • pomodoro-timer/pomodoro/__init__.py - パッケージ初期化
  • pomodoro-timer/pomodoro/models.py - データモデル定義
  • pomodoro-timer/pomodoro/storage.py - JSON永続化ロジック
  • pomodoro-timer/pomodoro/timer.py - タイマーコアロジック
  • pomodoro-timer/pomodoro/stats.py - 統計計算
  • pomodoro-timer/pomodoro/notifications.py - 通知システム

UI Layer

  • pomodoro-timer/ui/__init__.py - UIパッケージ初期化
  • pomodoro-timer/ui/app.py - メインStreamlitアプリケーション
  • pomodoro-timer/ui/components/__init__.py - コンポーネント初期化
  • pomodoro-timer/ui/components/timer_display.py - タイマー表示コンポーネント
  • pomodoro-timer/ui/components/stats_display.py - 統計表示コンポーネント

Tests

  • pomodoro-timer/tests/__init__.py - テストパッケージ初期化
  • pomodoro-timer/tests/test_models.py - データモデルのテスト
  • pomodoro-timer/tests/test_storage.py - ストレージのテスト
  • pomodoro-timer/tests/test_timer.py - タイマーロジックのテスト
  • pomodoro-timer/tests/test_stats.py - 統計計算のテスト

Configuration

  • pomodoro-timer/data/.gitkeep - データディレクトリの保持(sessions.jsonは.gitignore)

Philosophy Alignment

Ruthless Simplicity

Start minimal:

  • 基本的なポモドーロ機能のみ(25/5/15分)
  • 最小限の統計(今日、連続、週間のみ)
  • シンプルなJSONストレージ

Avoid future-proofing:

  • クラウド同期なし(将来の拡張)
  • 高度な分析なし(将来の拡張)
  • カスタムテーマなし(将来の拡張)
  • タスク統合なし(将来の拡張)

Clear over clever:

  • 明示的な状態遷移(ログ付き)
  • シンプルなデータ構造
  • 直接的なAPI設計

What we're NOT building:

  • タスク管理機能
  • チーム/共有機能
  • 高度なレポート
  • カスタマイズ可能なテーマ
  • モバイルアプリ

Modular Design

Bricks (self-contained modules):

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

Studs (connection points):

  • Timer.start/pause/stop - UIがタイマーを制御
  • Storage.save/load - タイマーがセッションを保存
  • Stats.calculate_* - UIが統計を取得
  • Notifications.notify_* - タイマーが通知をトリガー

Regeneratable: 各モジュールは仕様から完全に再生成可能:

  • 明確な入力/出力
  • 明示的な依存関係
  • 包括的なテスト

Zero-BS Principle

No stubs or placeholders:

  • 各モジュールは完全に機能する実装
  • TODOコメントなし
  • NotImplementedErrorなし
  • プレースホルダーテキストなし

Immediate runnability:

  • 各モジュールは単独でテスト可能
  • すべてのコード例は動作する
  • モックは最小限(実際のファイルI/Oをテスト)

Design for Humans

Accessibility:

  • タイマーテキストの最小コントラスト比 7:1
  • キーボードショートカット(Space, Esc, B, S)
  • 色だけに依存しない(アイコン + テキスト)
  • スクリーンリーダー対応

Usability:

  • 大きなタッチターゲット(44×44px)
  • 明確な状態表示
  • 予測可能な動作
  • 設定可能な通知

Test Strategy

Unit Tests (60%)

models.py:

  • データクラスの検証
  • デフォルト値のテスト
  • シリアライゼーション/デシリアライゼーション

storage.py:

  • セッションの保存/読み込み
  • 日付範囲フィルタリング
  • ファイル破損の処理
  • アトミックライト(一時ファイル → リネーム)

timer.py:

  • 状態遷移ロジック
  • 時間計算(ドリフト防止)
  • pause/resume機能
  • セッション完了検出

stats.py:

  • 今日の統計計算
  • 連続日数計算
  • 週間概要集計
  • エッジケース(セッションなし、日付境界)

Integration Tests (30%)

timer + storage:

  • セッション完了時の自動保存
  • 保存されたセッションの読み込み
  • 増分処理パターン(セッションごとに保存)

timer + notifications:

  • セッション完了時の通知トリガー
  • 通知の設定可能性

stats + storage:

  • 保存されたセッションからの統計計算
  • 大量データでのパフォーマンス(1000+セッション)

Manual Testing (10%)

Timer accuracy:

  • 25分が実際に25分か確認
  • ドリフトの確認(長時間実行)

Notification delivery:

  • OS通知が表示されるか
  • 音が再生されるか(有効時)

UI responsiveness:

  • タイマー更新がスムーズか
  • ボタンクリックが100ms以内に反応するか

Cross-platform:

  • Windows, macOS, Linux での動作確認

Test Coverage Goals

  • クリティカルパス: 100%(タイマーロジック、データ永続化)
  • 全体: 80%+(pytest-covで測定)

Implementation Approach

Phase 2: Documentation (Docs)

Documents to create/update:

  1. README.md

    • プロジェクト概要
    • インストール手順(pip install -r requirements.txt
    • 使用方法(streamlit run ui/app.py
    • キーボードショートカット
    • 設定オプション
    • トラブルシューティング
  2. DESIGN.md

    • アーキテクチャ決定記録
    • 状態マシン図
    • データフロー図
    • モジュール責任
    • なぜStreamlitを選んだか
    • なぜJSONストレージか
    • タイマードリフト防止の実装
  3. pyproject.toml

    • プロジェクトメタデータ
    • 依存関係:
      • streamlit>=1.30.0
      • plyer>=2.1.0(クロスプラットフォーム通知)
      • pytest>=7.0(テスト)
      • pytest-cov>=4.0(カバレッジ)
  4. .gitignore

    • data/sessions.json(ユーザーデータを除外)
    • __pycache__/
    • .pytest_cache/
    • .coverage

Phase 3: Code Planning (Detailed Implementation Plan)

Implementation Order:

Chunk 1: Data Foundation

  1. pomodoro/models.py - データモデル定義
  2. tests/test_models.py - モデルテスト

Chunk 2: Persistence Layer 3. pomodoro/storage.py - JSONストレージ実装 4. tests/test_storage.py - ストレージテスト

Chunk 3: Core Logic 5. pomodoro/timer.py - タイマー実装 6. tests/test_timer.py - タイマーテスト

Chunk 4: Statistics 7. pomodoro/stats.py - 統計計算 8. tests/test_stats.py - 統計テスト

Chunk 5: Notifications 9. pomodoro/notifications.py - 通知システム

Chunk 6: UI Components 10. ui/components/timer_display.py - タイマー表示 11. ui/components/stats_display.py - 統計表示

Chunk 7: Main Application 12. ui/app.py - メインアプリケーション

Rationale:

  • データ → ロジック → プレゼンテーション(内側から外側へ)
  • 各チャンクは独立してテスト可能
  • 依存関係の順序を尊重

Phase 4: Implementation (Code)

Per-module validation:

  • モジュール実装後、即座にテスト実行
  • make checkでリント/型チェック
  • pyproject.tomlの仕様と照合

Incremental commits:

  • 各モジュール完成後にコミット
  • テストと一緒にコミット
  • コミットメッセージ規約:
    feat(timer): Implement Pomodoro countdown logic
    
    🤖 Generated with [Amplifier](https://github.com/microsoft/amplifier)
    
    Co-Authored-By: Amplifier <240397093+microsoft-amplifier@users.noreply.github.com>
    

Success Criteria

Functional Requirements

  • タイマーが25分正確にカウントダウンする
  • 休憩が自動的に開始または手動開始可能
  • 完了したセッションがsessions.jsonに保存される
  • 統計が正しく計算される(今日、連続、週間)
  • OS通知がセッション完了時に表示される
  • キーボードショートカットが機能する

Quality Requirements

  • テストカバレッジ80%以上
  • make checkが成功(リント、型チェック)
  • すべてのテストが通過
  • タイマー更新がスムーズ(視覚的に)
  • UIが100ms以内に応答

Documentation Requirements

  • README.mdが完全(インストール、使用方法)
  • DESIGN.mdがアーキテクチャを説明
  • コード例がすべて動作する
  • インラインコメントが意図を説明

Philosophy Compliance

  • 不要な抽象化なし
  • 将来の仮説的機能なし
  • TODOやプレースホルダーなし
  • 各モジュールが仕様から再生成可能

Next Steps

Immediate Actions

Phase 1 Complete: 計画が承認されました

➡️ Phase 2: ドキュメントの更新

/ddd:2-docs

これにより以下が更新されます:

  • README.md(ユーザーガイド)
  • DESIGN.md(アーキテクチャ)
  • pyproject.toml(依存関係)
  • .gitignore(データ除外)

Subsequent Phases

  1. Phase 3 (/ddd:3-code-plan): 詳細なコード実装計画
  2. Phase 4 (/ddd:4-code): コード実装
  3. Phase 5 (/ddd:5-finish): クリーンアップと最終検証

Questions or Concerns

Potential Risks

  1. タイマードリフト: sleep()の累積誤差

    • 対策: ターゲット終了時刻を計算、それに対してチェック
  2. UI ブロッキング: タイマーがUIスレッドをブロック

    • 対策: Streamlitのsession stateとauto-refresh
  3. クラッシュ時のデータ損失: アプリ終了時のみ保存

    • 対策: セッション完了ごとに即座に保存(増分処理パターン)
  4. クロスプラットフォーム通知: OS間での動作差異

    • 対策: plyerライブラリ使用(クロスプラットフォーム対応)

Open Questions

  • なし(すべて承認済み)

Document Metadata

Created: 2025-11-22 Status: Approved ✅ Next Phase: /ddd:2-docs Estimated Completion Time: 1-2 hours total

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