Skip to content

program-student-2/smart-shift

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

146 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

スマート・シフト

塾向けのシフト管理 Web アプリ。Google OR-Tools の制約充足ソルバーで講師と生徒を最適にマッチングし、AWS にフルマネージドでデプロイされます。

Built with React TypeScript AWS Amplify FastAPI OR-Tools


概要

塾の講師シフト作成は「講師の出勤可否・担当科目・生徒の希望コマ・1対1指定」など多数の制約が絡み、手作業では数時間かかる組合せ最適化問題です。本アプリは Google OR-Tools (CP-SAT) で数秒で解き、ドラッグ&ドロップ編集・公開フォーム受付・監査ログまでを フルサーバーレス (AWS Amplify Gen 2) で提供します。

  • 🧩 最適化エンジン — 希望コマ充足を最大化しつつ講師の負荷を平準化
  • ☁️ フルマネージド — AppSync + DynamoDB + Docker Lambda、スケールゼロで運用レス
  • 🔐 セキュリティ重視 — Cognito 認証 / 公開APIキー非露出 / append-only / SSRF・CSP 対策
  • CI/CD — セキュリティ監査と認証テストを通過したコードのみ自動デプロイ

主な機能

管理者向け

  • 講師・生徒の登録/編集
  • OR-Tools CP-SAT による自動シフト生成(最大化目標:希望コマ充足、最小化目標:講師偏り)
  • ドラッグ&ドロップによるシフト編集
  • 公開フォームから受信した申請の承認/却下
  • 操作監査ログ
  • Excel エクスポート

講師・生徒向け(公開)

  • ID 入力でシフト確認(ログイン不要)
  • スマホからのシフト希望提出フォーム
  • 二重送信防止(DynamoDB の Conditional Write)
  • 月別カレンダー表示

セキュリティ

  • 管理画面:Cognito User Pool(管理者作成のみ/自己登録不可)
  • 公開エンドポイント:Lambda 経由でのみ AppSync にアクセス、API キーはフロントに含まれない
  • CSP / X-Frame-Options / HSTS ヘッダー
  • 監査ログによる操作履歴記録
  • フォーム送信は append-only(漏洩しても削除・列挙不可)

アーキテクチャ

┌──────────────────────────────────────────────────────────────────┐
│  React フロントエンド (Vite + TypeScript)                          │
│  ・ /admin    管理画面 (Cognito 認証)                              │
│  ・ /view     シフト確認 (ID ベース)                                │
│  ・ /form     公開フォーム                                          │
└──────────┬─────────────────────┬────────────────────────────────┘
           │ Cognito JWT         │ Lambda Function URL
           ▼                     ▼
   AppSync GraphQL       FastAPI Lambda (Docker, OR-Tools)
           │                     │ x-api-key
           ▼                     ▼
       DynamoDB           AppSync GraphQL → DynamoDB

技術スタック

レイヤー 技術
フロントエンド React 19, TypeScript, Vite, TailwindCSS, Framer Motion
状態管理 Zustand, React hooks
認証 Amazon Cognito (User Pool), Amplify UI Authenticator
API AWS AppSync (GraphQL), AWS Lambda Function URL
データベース Amazon DynamoDB
計算エンジン Python 3.12, FastAPI, Google OR-Tools (CP-SAT)
パッケージング Docker (linux/amd64), Amazon ECR
CI/CD GitHub Actions, AWS Amplify Hosting
インフラ as Code AWS CDK (Amplify Gen 2)

技術的ハイライト・設計判断

1. 組合せ最適化を実用時間で 講師×生徒×コマの割当は制約が多く、手作業では非効率。OR-Tools の CP-SAT ソルバーで「希望コマ充足の最大化」と「講師偏りの最小化」を同時に扱う多目的最適化として定式化し、数秒で解いています。

2. 「公開フォーム」を安全に晒す設計 生徒は認証なしで希望を提出できる必要がある一方、データ流出は許されません。公開エンドポイントは Lambda 経由でのみ AppSync にアクセスし、API キーをフロントへ一切出しません。送信は append-only 設計で、万一漏洩しても既存データの削除・列挙は不可能です。

3. キーレスな CI/CD GitHub Actions は OIDC で AWS STS と連携し、長期アクセスキーを保持しません。pip-audit / npm audit(本番依存の高深刻度は必ず失敗)と認証テストスイート (pytest) をデプロイ前ゲートにしています。

4. 実運用で踏んだ罠を記録 AWS Lambda は docker buildx が生成する OCI manifest を拒否するため、あえて通常の docker build(Manifest v2 Schema 2)でビルドしています。こうした知見はコード中のコメントに残しています。


ローカル開発

前提

  • Node.js 20+
  • Python 3.12+
  • AWS アカウント(Amplify Gen 2 のサンドボックス用)
  • AWS CLI 認証済み

セットアップ

# 依存インストール
npm install
pip install -r python/requirements.txt

# Amplify サンドボックス起動(バックエンドが立ち上がる)
npx ampx sandbox

# 別ターミナルでフロント + Python API を同時起動
npm run dev

ブラウザで http://localhost:5173 にアクセス。

環境変数(ローカル開発時のみ)

.env.example.env.local にコピーし、必要に応じて設定。

APPSYNC_API_URL=...     # Lambda 経由テスト時
APPSYNC_API_KEY=...     # 同上

通常の管理画面開発ではこれらは不要です(管理画面は Cognito 経由)。


デプロイ

本番環境(main ブランチ)へのデプロイは GitHub への push で自動実行されます。

main へ push
  ├─→ GitHub Actions: Docker ビルド → ECR push(python/** 変更時)
  └─→ Amplify Hosting: CDK 適用 → フロント配信

初回セットアップ(ECR / IAM OIDC ロール / Amplify サービスロール)が必要です。 GitHub Actions の VariablesAWS_ACCOUNT_ID を設定してください(.github/workflows/deploy.yml がロール ARN の組み立てに使用します)。


ディレクトリ構成

test2/
├── src/                       # React フロントエンド
│   ├── components/             #   UI コンポーネント
│   ├── pages/                  #   ルーティング先のページ
│   ├── services/               #   AppSync / Lambda クライアント
│   ├── store/                  #   Zustand ストア
│   ├── utils/                  #   マッチングロジック等
│   └── main.tsx                #   ルーター
├── python/                    # Lambda (FastAPI + OR-Tools)
│   ├── api.py                  #   エンドポイント定義
│   ├── shift_generator.py      #   CP-SAT ソルバー
│   ├── auth.py                 #   Cognito JWT 検証
│   └── Dockerfile
├── amplify/                   # AWS CDK バックエンド定義
│   ├── auth/                   #   Cognito 設定
│   ├── data/                   #   AppSync + DynamoDB スキーマ
│   └── backend.ts              #   Lambda Function URL 等
├── scripts/                   # デプロイ用シェルスクリプト
└── .github/workflows/         # GitHub Actions

ライセンス

MIT License で公開しています。


作者

@program-student-2

技術相談・コードレビュー:Claude (Anthropic) との協同開発

About

塾向けシフト自動生成アプリ — Google OR-Tools(CP-SAT)による割当最適化 × フルサーバーレス(AWS Amplify Gen 2 / AppSync / Lambda / DynamoDB)

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors