初めてのサーバ基盤フルスタックウェブアプリ完成
Photo by Ilya Pavlov on Unsplash
https://vimeo.com/1112232760?share=copy
目的と方針
- 日本人大学生向けのタスク管理を、軽快な操作性と見やすさで提供
- ローカライズ(日本語 UI、日付の日本語表示)と、モダンな UI/UX(ガラスモーフィズム、ネオン星空)を両立
- まずは「タスク」機能に集中し、検索/並び替え/ステータス管理/期限などのコア体験を磨く
フロントエンド(Next.js + Tailwind)
src/types/task.tsにTask/TaskStatusを集約し、重複定義を排除- 日付処理は
src/lib/date.tsに統一(parseLocalDateTime,formatDateTimeJa)
- 一目で把握できる色と階層(未着手/進行中/完了で背景色・不透明度を変化)
- 「緊急(24h以内)」セクションを上部に配置し、期限の可視性を向上
- リスト/グリッド切替ボタンで閲覧性を状況に応じて最適化
- 6つのコントロール(タイトル/詳細/日付/時間/優先度/追加ボタン)の高さ・角丸を統一(
h-12/rounded-lg) ModernDropdownを共通化し、buttonClassNameで高さを揃えやすく- 星のアニメーションは控えめな発光に調整しつつ、雰囲気を演出
- 端末依存性の高い
datetime-localを避け、SimpleDateTimePickerを実装 - 日付はネイティブ
date、時間はカスタムドロップダウン(5分刻み) - クリックで必ずドロップダウンが開くように制御(外側クリックで閉じる)
- 値はローカル時刻の文字列(
YYYY-MM-DDTHH:MM)として保持
- 日付はネイティブ
- 表示は常に
formatDateTimeJa経由で日本語ロケールに統一
- スワイプ削除(左へドラッグ→しきい値超えで削除、途中で戻せばスナップバック)
- クリック伝播の抑止(ステータス変更ボタンがスワイプと競合しないよう
stopPropagation) - ドロワー(ハンバーガー)に検索/フィルタ/並び順/新規追加を集約
TaskListClientが検索条件を保持し、必要時にフェッチ- 初回描画時にバックエンドの
/tasksをno-storeで取得(常に最新) - エラーはユーザーに簡潔に通知(今後はトースト導入を検討)
- 軽量な CSS と Tailwind ユーティリティ中心で実装
- 不要な再レンダリングを避けるため、集計や緊急抽出は
useMemoでメモ化
バックエンド(FastAPI + SQLAlchemy + Alembic)
tasksテーブル:title/description/status/priority/due_date/created_at/updated_at- SQLite 互換性のため
statusはStringとし、Enum はアプリ側で制約
GET /tasks検索(q)、フィルタ(status_in)、並び替え(sort)POST /tasks作成、PATCH /tasks/{id}更新、DELETE /tasks/{id}削除- CORS はフロント開発ドメインを許可
- ローカル開発は SQLite、将来の本番運用では Postgres を想定
- マイグレーションは Alembic で管理
- 期限は「ローカル時刻の文字列」を受け取り、サーバー側で
DateTimeに変換(本番ではタイムゾーン戦略を明確化予定)
エラーハンドリング / メッセージ
- フロント:
Failed to ...形式で簡潔に通知(今後は日本語トーストに統一) - バック:404/422 を厳密化(将来は詳細メッセージとフィールドエラーの整備)
再利用性と責務分離
- 共通 UI:
ModernDropdown,SimpleDateTimePicker - ドメイン型:
src/types/task.ts - 日付ユーティリティ:
src/lib/date.ts - 画面ロジックは
TaskListClientに集約、詳細は[id]/page.tsxに分離
テスト/品質
- 目視 E2E を優先、後続で Playwright 導入予定(緊急カード/スワイプ/作成→表示の一連)
- 型とユーティリティの共通化でレビュー負荷を削減
既知の課題と改善計画
- タイムゾーン戦略の明確化(本番での TZ 揃え、サーバー/クライアントの変換)
- 入力検証(zod 導入と UI でのフィードバック強化)
- API クライアントの薄いラッパを導入してエラー整形を統一
- モバイル最適化(タッチ領域/レイアウトの最終調整)
- CI で Lint/TypeCheck/E2E を自動化