推しアイデア
タスクの重要度を設定できるようにしたこと。
タスクの重要度を設定できるようにしたこと。
3年になり課題に追われる毎日。課題の提出を忘れることも何度かあり、タスク管理アプリを作成したくなった。
期限が近いものから順に表示させ、期限が1日を切る重要度が高く変化する点。
慶應義塾大学「実践のためのWebプログラミング」(2026年春学期) 最終課題として制作した, タスク管理 Web アプリである。フロントエンド・バックエンド・データベースの三層構成をとり, 締切の近いタスクの重要度をサーバ側で自動的に引き上げて色分け表示する。
設計.txt (第10回 設計演習) で決めた三層構成に対応する。
[ フロントエンド ] <--JSON--> [ バックエンド ] <--Prisma--> [ PostgreSQL ] HTML / CSS / TypeScript Node.js + Express Render 上
fetch で JSON API を叩くroutes/, 処理を controllers/, DB アクセスを models/ に分けた MVC 寄りの構成| 層 | 技術 |
|---|---|
| フロントエンド | HTML, CSS, TypeScript (バンドラ無し, tsc で app.js を生成) |
| バックエンド | Node.js, Express 5, express-session |
| ORM | Prisma 7 (driver adapter 方式, @prisma/adapter-pg) |
| データベース | PostgreSQL |
| デプロイ | Render (Blueprint / render.yaml) |
task-app/ ├── backend/ │ ├── server.ts # Express の起動, ミドルウェア設定, 静的配信 │ ├── routes/ # ルーティング (auth.ts, tasks.ts, categories.ts) │ ├── controllers/ # リクエスト処理 (authController.ts, tasksController.ts, categoriesController.ts) │ ├── models/prisma.ts # Prisma クライアントの初期化 │ ├── middleware/requireAuth.ts # 未ログインを 401 で弾く │ ├── auth/password.ts # パスワードの scrypt ハッシュ化と照合 │ ├── importance.ts # 締切接近による重要度の算出 │ └── penalty.ts # 期限切れタスクのペナルティ点の算出 ├── frontend/ │ ├── index.html │ ├── style.css │ └── app.ts # 画面のロジック (ビルドすると app.js) ├── prisma/ │ ├── schema.prisma # DB スキーマ定義 │ ├── migrations/ # マイグレーション │ └── seed.ts # サンプルデータ投入 ├── render.yaml # Render の Blueprint (Web + PostgreSQL) └── package.json
tasks から users と categories へそれぞれ 1 対多の外部キーを張る。
id, name, email, password_hash (email は一意。password_hash は scrypt の "salt:derivedKey" hex 形式で, 平文は保存しない)id, name, colorid, title, deadline, importance_level, is_completed, user_id, category_idタスク系とカテゴリ系のエンドポイントはすべてログイン必須で, 未ログインだと 401 を返す。
| メソッド | パス | 説明 |
|---|---|---|
POST | /register | name, email, password を受け取り, ユーザを新規作成してログイン状態にする |
POST | /login | email と password を受け取り, 照合が通ればセッションに記録する |
POST | /logout | セッションを破棄する |
GET | /me | ログイン中のユーザを返す |
GET | /tasks | ログイン中ユーザのタスク一覧を返す (重要度の自動引き上げとペナルティ点を付けて返す) |
POST | /tasks | タスクを新規作成する |
PATCH | /tasks/:id | タスクを部分更新する |
DELETE | /tasks/:id | タスクを削除する |
GET | /categories | カテゴリ一覧を返す |
POST | /categories | カテゴリを新規作成する (color は #rrggbb 形式) |
このアプリの中心的な仕組みである。ユーザが設定した重要度 (importance_level) はそのまま DB に保存するが, 締切が近いタスクは GET /tasks の応答を組み立てるときに, より高い重要度へ引き上げてから返す。引き上げた値は DB に書き戻さない。
ユーザ設定値と締切由来の値のうち高い方を採用するため, 引き上げは行っても引き下げはしない。フロントエンドはこの実効重要度を見て色を変えるだけであり, 判定ロジックはバックエンドに一本化されている。これは importance_level を Single Source of Truth とし, 「期限まであと何時間か」から導ける値を DB に二重に持たないための設計である (第09回 DBとORM)。
重要度の自動引き上げと同じ方針で, 未完了のまま期限を過ぎたタスクにペナルティ点を与える。この値も DB には持たず, GET /tasks の応答時に deadline と現在時刻から算出して返す。
isOverdue と penaltyPoints を含め, フロントエンドは期限切れの件数とペナルティ合計を表示する「期限からどれだけ過ぎたか」は deadline から導けるため, ペナルティ点を DB に二重に持たせない (第09回 DBとORM)。点数の配分は暫定値である。
前提として, ローカルに PostgreSQL が動いており, .env に DATABASE_URL と SESSION_SECRET が設定されていること。.env は .gitignore 済みで, リポジトリには含めない。
npm install # 依存のインストール (postinstall で prisma generate も走る) npx prisma migrate deploy # マイグレーションの適用 npx tsx prisma/seed.ts # サンプルデータの投入 npm run build:frontend # frontend/app.ts を app.js にビルド npm run dev # バックエンドを起動 (tsx watch)
起動後, ブラウザで http://localhost:3000 を開く。backend/ を編集すると自動再起動する。フロントエンド (frontend/app.ts) を変更したときは npm run build:frontend で app.js を作り直す。
render.yaml を Blueprint として使い, Web サービスと PostgreSQL をまとめて作成する。
npm ci --include=dev && npm run build && npx prisma migrate deploynpm start (node dist/server.js)DATABASE_URL は Render の DB から自動注入し, SESSION_SECRET は自動生成する。秘密情報は .env をコミットせず, すべて環境変数で渡すapp.set("trust proxy", 1) を有効にし, secure Cookie が送出されるようにしている本番 DB は初回デプロイ後に, ローカルから外部接続 URL 経由で一度だけ seed.ts を実行して投入する。
新規登録から作成することもできるが, 動作確認には seed で投入済みの下記アカウントが使える。いずれもパスワードは password123 である。
aoiogawa0814@example.com (タスク 3 件)taro@example.com (別ユーザ。認証分離の確認用)