Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Task Management

Django、React、Next.js、PostgreSQL、docker compose を利用したタスク管理サイトの実装リポジトリです。

Local Development

環境変数の例は .env.example を参照してください。local の初期値は docker-compose.yml にも定義済みです。

docker compose up --build

起動後、以下を確認できます。

health check は以下を返します。

{
  "status": "ok"
}

Services

service port description
frontend 3000 Next.js
backend 8000 Django REST Framework
db 5432 PostgreSQL 16

Backend API Foundation

Backend は Django REST Framework を利用し、API は JSON response を返します。認証方式は Cookie ベースの session 認証を標準とし、状態変更 API では CSRF token を必須にします。

Environment

Backend は以下の環境変数で設定します。

DJANGO_SECRET_KEY=local-secret
DJANGO_DEBUG=true
DATABASE_URL=postgres://app:app@db:5432/app
ALLOWED_HOSTS=localhost,127.0.0.1,backend
CSRF_TRUSTED_ORIGINS=http://localhost:3000
CORS_ALLOWED_ORIGINS=http://localhost:3000
SESSION_COOKIE_SECURE=false
CSRF_COOKIE_SECURE=false
SESSION_COOKIE_AGE=28800
LOGIN_RATE_LIMIT_ATTEMPTS=5
LOGIN_RATE_LIMIT_WINDOW_SECONDS=300

Common Error Response

API error は以下の形式に揃えます。

{
  "code": "VALIDATION_ERROR",
  "message": "入力内容を確認してください",
  "details": {
    "email": ["メールアドレスを正しく入力してください"]
  }
}

主な error code は以下です。

HTTP status code 用途
400 VALIDATION_ERROR 入力値不正
401 UNAUTHENTICATED 未ログイン
403 FORBIDDEN 権限不足
403 CSRF_FAILED CSRF 検証失敗
404 NOT_FOUND 対象リソースなし
405 METHOD_NOT_ALLOWED 許可されていない HTTP method
500 INTERNAL_SERVER_ERROR 予期しない server error

500 response には stack trace、SQL、内部 path を含めません。

Security Defaults

  • session cookie は HttpOnly / SameSite=Lax です。
  • session 有効期限の初期値は 8 時間です。
  • local CORS は http://localhost:3000 のみ許可します。
  • password、session id、CSRF token は log に出力しない方針です。

Logs

Backend API access log は methodpathstatusduration_ms を stdout に出力します。request body や Cookie header は access log に出力しません。

Test

docker compose run --rm backend python manage.py test

Auth API

認証 API は Cookie ベースの session 認証を利用します。状態変更 API のため、POST /api/auth/login/POST /api/auth/logout/ では CSRF token が必須です。

CSRF Token

GET /api/auth/csrf/

CSRF cookie を発行し、以下を返します。

{
  "csrfToken": "..."
}

Login

POST /api/auth/login/
Content-Type: application/json
X-CSRFToken: {csrfToken}
{
  "email": "user@example.com",
  "password": "password123"
}

成功時は session cookie を発行し、以下を返します。

{
  "user": {
    "id": "usr_xxx",
    "email": "user@example.com",
    "displayName": "山田 太郎"
  }
}

認証失敗時は 401 INVALID_CREDENTIALS を返します。ログイン失敗は初期値として 5 回 / 5 分 で rate limit し、超過時は 429 RATE_LIMITED を返します。

Current User

GET /api/auth/me/

ログイン中のユーザー情報を返します。未ログイン時は 401 UNAUTHENTICATED です。

Logout

POST /api/auth/logout/
X-CSRFToken: {csrfToken}

成功時は session を破棄し、204 No Content を返します。

Database

MVP の永続化は Django custom user model と task model で構成します。

ID 方針

  • API 上の ID は string として扱います。
  • users.idusr_ prefix の string primary key です。
  • tasks.idtsk_ prefix の string primary key です。
  • Frontend では ID を数値変換しません。

Tables

table description
users ログインユーザー
django_session Django 標準 session
tasks タスク本体

tasks は MVP ではユーザー個人所有モデルです。削除方式は deleted_at を使う論理削除を前提にし、一覧・詳細・summary API では deleted_at IS NULL のタスクのみ扱います。

Migration

docker compose run --rm backend python manage.py migrate

開発用ユーザー作成

docker compose run --rm backend python manage.py createsuperuser

対話式で emaildisplay_namepassword を入力してください。

Frontend API Client

Frontend の API 呼び出しは frontend/src/lib/api/ 以下の共通クライアントを使います。

環境変数

NEXT_PUBLIC_API_BASE_URL=http://localhost:8000

使い方

import { login, logout, getCurrentUser } from "@/lib/api/auth";
import { getHomeSummary } from "@/lib/api/home";
import { listTasks, createTask, updateTask, deleteTask } from "@/lib/api/tasks";
import { isApiError } from "@/lib/api/errors";

// 認証
const { user } = await login("user@example.com", "password");
await logout();
const { user: me } = await getCurrentUser();

// ホーム summary
const summary = await getHomeSummary();
// summary.taskTotal / summary.taskOpen / summary.taskOverdue

// タスク
const { results, count } = await listTasks({ status: "todo" });
const task = await createTask({ title: "新しいタスク", dueDate: "2026-06-01" });
await updateTask(task.id, { status: "done" });
await deleteTask(task.id);

// エラーハンドリング
try {
  await login("user@example.com", "wrong");
} catch (e) {
  if (isApiError(e)) {
    if (e.isUnauthenticated()) { /* 401 */ }
    if (e.isValidationError()) { /* 400 + e.details */ }
    if (e.isCsrfFailed())      { /* 403 CSRF_FAILED */ }
  }
}

CSRF

POST / PUT / PATCH / DELETE では X-CSRFToken を自動付与します。
token は csrftoken cookie から取得し、未設定の場合は GET /api/auth/csrf/ にフォールバックします。

テスト

cd frontend && npm test

Notes

  • local DB は named volume postgres_data に保存されます。
  • volume を削除すると local DB のデータは消えます。
  • production 用の secrets 管理、TLS、監視、CI/CD は MVP 基盤 issue の対象外です。

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages