Skip to content

EngineerCafeJP/worktrace

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

13 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

workTrace — 解説ドキュメント

アプリ概要

作業時間の記録・分析を行う Web アプリ。 後から入力した記録が既存の時間を自動的に上書き・分割する「後出し優先ロジック」が核心機能。 日またぎ(深夜作業など)にも対応し、直近 20 件の記録をタイムラインで一覧できる。


ファイル構成

worktrace/
├── backend/
│   ├── main.py            # FastAPI アプリ本体(DBモデル・重複処理・全エンドポイント)
│   └── requirements.txt   # Python 依存ライブラリ
└── frontend/
    ├── index.html
    ├── package.json
    ├── vite.config.js
    ├── tailwind.config.js
    ├── postcss.config.js
    └── src/
        ├── main.jsx
        ├── index.css
        ├── App.jsx                      # メイン UI・状態管理
        └── components/
            ├── Timeline.jsx             # タイムライン表示
            └── Analytics.jsx           # アナリティクスダッシュボード

技術スタック

レイヤー 技術
Backend Python / FastAPI
DB SQLite(SQLAlchemy ORM)
Frontend React 18 / Vite
スタイリング Tailwind CSS
グラフ Recharts
HTTP クライアント Axios

起動方法

Backend(ポート 8000)

Debian/Ubuntu 系の Python 3.12 以降は externally-managed-environment のため、 システム全体への pip install が禁止されている。 仮想環境(venv)を作成してからインストールする。

cd backend

# 初回のみ: 仮想環境を作成
python3 -m venv .venv

# 仮想環境を有効化(プロンプトが (.venv) になる)
source .venv/bin/activate

# 依存ライブラリをインストール
pip install -r requirements.txt

# サーバー起動
uvicorn main:app --reload

2回目以降は仮想環境の作成・pip install は不要。 source .venv/bin/activate してから uvicorn main:app --reload だけでよい。

仮想環境を抜けるときは deactivate

Frontend(ポート 5173)

cd frontend
npm install
npm run dev

ブラウザで http://localhost:5173 を開く。 Vite のプロキシ設定により、フロントエンドからの API リクエストは自動的に localhost:8000 へ転送される。


機能詳細

1. 入力フォーム

フィールド 内容
開始日 デフォルトは日付ナビの選択日。日付ナビ変更時に自動同期
開始時間 HH:MM 形式
終了日 開始日〜開始日の翌日まで選択可能(翌日以降は不可)
終了時間 HH:MM 形式
プロジェクト 過去の入力履歴をサジェスト(<datalist>
作業種別 過去の入力履歴をサジェスト(デフォルト候補あり)
作業メモ 任意のメモ。タイムラインにも表示される
  • 日付ナビ(ヘッダーの ← → ボタン)で日付を変えると、開始日・終了日が自動的にその日に合わせて更新される
  • 送信時に後出し優先ロジックを自動実行

2. 後出し優先ロジック(Core Logic)

backend/main.pyresolve_overlaps() 関数が実装している。 新しいエントリ [n_start, n_end] に対し、既存の全エントリを 4 ケースで処理する。 日またぎエントリも含め、datetime 単位で全期間を対象に重複を検出する。

ケース1: 完全内包(既存が新規の中にすっぽり収まる)
  既存:     [──e──]
  新規: [────────────]
  → 既存を削除

ケース2: 完全包含(既存が新規を丸ごと包む)
  既存: [──────────────]
  新規:     [──n──]
  → 既存を前後 2 つに分割
    前半: [e_start, n_start]
    後半: [n_end,   e_end  ]  ※後半セグメントの date は n_end の実日付

ケース3: 左側重複(既存が左にはみ出す)
  既存: [────]
  新規:   [────────]
  → 既存の終端を n_start に短縮

ケース4: 右側重複(既存が右にはみ出す)
  既存:         [────]
  新規: [────────]
  → 既存の始端を n_end に短縮(date フィールドも n_end の実日付に更新)

処理フロー:

  1. POST /entries でリクエストを受信
  2. 新エントリを DB に INSERT し ID を確定(db.flush()
  3. resolve_overlaps() で重複を解決
  4. db.commit() で一括確定

3. 日またぎ対応

  • 開始日と終了日を個別に指定できる(例:2/28 22:00 〜 3/1 02:00)
  • 終了日は開始日の翌日までに制限(それ以上はフロント・バック両方で弾く)
  • タイムラインの 24h バーでは、日またぎエントリの終端を 24:00 でカットして表示
  • エントリリストでは日またぎを「」ラベルで表示(例:22:00 – 翌 02:00

4. タイムライン表示(Timeline.jsx)

24時間ビジュアルバー(選択日)

  • ヘッダーの日付ナビで選択した日のエントリを表示
  • 横幅全体 = 24時間(1440分)
  • 日またぎエントリは 24:00 でカット
  • 未記録の隙間は破線ボーダーで視覚化

直近 20 件リスト

  • 全日付を対象に start_time 降順で直近 20 件を表示
  • 各エントリに日付(M/D)・時間・期間・プロジェクト・作業種別・メモを表示
  • ホバーで「複製」「削除」ボタンが表示される

複製機能

  • 「複製」ボタンをクリックすると、そのエントリの内容をフォームに展開する
  • 日付は日付ナビの選択日、時間・プロジェクト・種別・メモはそのままセット
  • 日またぎエントリは終了日も自動調整(選択日 + 1 日)
  • フォームに展開後、内容を確認・修正してから「記録する」で保存

5. アナリティクスダッシュボード(Analytics.jsx)

グラフ 内容
ドーナツチャート(左) プロジェクト別合計時間の内訳
ドーナツチャート(右) 作業種別(設計/実装/MTG…)の比率
棒グラフ 日次作業時間のサマリー
稼働率バー 作業種別ごとのパーセンテージをプログレスバーで表示

分析期間は「今日 / 7日間 / 30日間」で切り替え可能。

6. タグサジェスト

  • GET /tags で過去に使用したプロジェクト名・作業種別を取得
  • フォームの <datalist> に反映し、入力補完を提供
  • エントリ追加のたびに自動更新

API エンドポイント一覧

メソッド パス 説明
GET /entries?date=YYYY-MM-DD 指定日のエントリを時刻順で取得
POST /entries 新規エントリ追加(重複自動解決)
DELETE /entries/{id} エントリ削除
GET /entries/recent?limit=20 直近 N 件のエントリを新しい順で取得
POST /entries/{id}/clone 指定エントリを target_date にクローン
GET /analytics?start_date=...&end_date=... 期間集計データ取得
GET /tags 過去のプロジェクト名・作業種別を取得

リクエスト / レスポンス例

POST /entries

{
  "start_date": "2026-02-28",
  "start_time": "09:00",
  "end_date": "2026-02-28",
  "end_time": "10:30",
  "project": "ProjectA",
  "task_type": "実装",
  "memo": "認証まわりの実装"
}

GET /entries レスポンス

[
  {
    "id": 1,
    "start_date": "2026-02-28",
    "start_time": "09:00",
    "end_date": "2026-02-28",
    "end_time": "10:30",
    "project": "ProjectA",
    "task_type": "実装",
    "memo": "認証まわりの実装",
    "date": "2026-02-28",
    "duration_minutes": 90
  }
]

POST /entries/{id}/clone

{ "target_date": "2026-03-01" }

DB スキーマ

CREATE TABLE time_entries (
  id         INTEGER PRIMARY KEY AUTOINCREMENT,
  start_time DATETIME NOT NULL,
  end_time   DATETIME NOT NULL,
  project    VARCHAR  NOT NULL,
  task_type  VARCHAR  NOT NULL,
  date       VARCHAR  NOT NULL,  -- YYYY-MM-DD(start_time の日付、検索フィルタ用)
  memo       VARCHAR             -- 作業メモ(任意)
);

SQLite ファイルは初回起動時に backend/worktrace.db として自動生成される。 memo カラムは起動時に自動マイグレーションで追加されるため、既存 DB への手動変更は不要。


UI レイアウト

┌─────────────────────────────────────────────┐
│ ヘッダー: workTrace ロゴ    ← 日付ナビ →    │
├─────────────────────────────────────────────┤
│ 入力フォーム                                 │
│  [開始日][開始時間] [終了日][終了時間]        │
│  [プロジェクト] [種別] [記録する]            │
│  [作業メモ(任意・全幅)]                    │
├─────────────────────────────────────────────┤
│ タイムライン          直近 N 件              │
│  選択日 合計 Xh  隙間 Y箇所                 │
│  ████░░░████████░░░░████  ← 24h バー        │
│  00   06  09  12  15  18  21  24            │
│  2/27  09:00–10:30  90分  ProjectA  実装    │
│  2/27  翌 22:00–02:00  4h  ProjectB  調査  │
│  2/28  11:00–12:00  60分  ProjectC  MTG    │
│        ↑ ホバーで [複製] [削除] 表示         │
├─────────────────────────────────────────────┤
│ アナリティクス          [今日|7日|30日]      │
│  [合計時間] [件数] [平均時間]                │
│  ドーナツ(PJ別)   ドーナツ(種別)             │
│  日次棒グラフ                                │
│  稼働率プログレスバー                        │
└─────────────────────────────────────────────┘

About

バイブコーディングクラブより

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages

  • JavaScript 72.3%
  • Python 24.3%
  • CSS 2.6%
  • HTML 0.8%