Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Portal.C Documentation

Portal.Cプロジェクトのドキュメントへようこそ!

プロジェクト概要

Portal.Cは、Tech.C Ventureのメンバー管理とイベント管理を行うWebアプリケーションです。技育プロジェクトVol.16で開発される、Tech.C Venture初の基盤システムです。

主要機能

  • 認証・ログイン機能: ZITADEL認証基盤を使用した認証システム
  • メンバープロフィール機能: 学年自動計算、24時間限定ステータス、スキルタグ管理
  • 時間割閲覧機能: 学年・専攻でフィルタリング可能なメンバー時間割
  • イベント管理機能: イベント一覧表示と参加表明
  • 管理者画面: イベント登録、参加者管理

技術スタック

  • フロントエンド: Next.js 15 (App Router), React 19, TypeScript 5.6+
  • バックエンド: TypeScript
  • データベース: Supabase (PostgreSQL)
  • 認証基盤: ZITADEL (NextAuth.js経由)
  • スタイリング: Tailwind CSS
  • UIコンポーネント: @openameba/spindle-ui
  • ホスティング: Vercel

ドキュメント構成

Getting Started

開発を始めるための基本的な情報

Architecture

プロジェクトのアーキテクチャ設計

Development Guide

開発時のガイドライン

Specification (SDD)

プロジェクトの仕様書とガイドライン

  • Steering: プロジェクト全体のガイドライン
    • Product, Tech, Structure
  • Specs: 機能仕様書
    • Clean Architecture Refactor

クイックスタート

  1. 開発者向けオンボーディングを読む
  2. アーキテクチャ設計でプロジェクト構造を理解
  3. AGENTS設定でAI開発支援を設定

リンク

Portal.C 開発者向けオンボーディングガイド

Portal.Cプロジェクトへようこそ!このガイドでは、新しい開発メンバーがスムーズにプロジェクトに参加できるよう、必要な情報をまとめています。

目次

  1. プロジェクト概要
  2. 前提知識
  3. 開発環境のセットアップ
  4. プロジェクト構造の理解
  5. 開発ワークフロー
  6. コーディング規約
  7. よくある問題とトラブルシューティング
  8. 参考資料

プロジェクト概要

Portal.Cは、Tech.C Ventureのメンバー管理とイベント管理を行うWebアプリケーションです。技育プロジェクトVol.16で開発される、Tech.C Venture初の基盤システムです。

主要機能

  • 認証・ログイン機能: ZITADEL認証基盤を使用した認証システム
  • メンバープロフィール機能: 学年自動計算、24時間限定ステータス、スキルタグ管理
  • 時間割閲覧機能: 学年・専攻でフィルタリング可能なメンバー時間割
  • イベント管理機能: イベント一覧表示と参加表明
  • 管理者画面: イベント登録、参加者管理

技術スタック

  • フロントエンド: Next.js 15 (App Router), React 19, TypeScript 5.6+
  • バックエンド: TypeScript
  • データベース: Supabase (PostgreSQL)
  • 認証基盤: ZITADEL (NextAuth.js経由)
  • スタイリング: Tailwind CSS
  • UIコンポーネント: @openameba/spindle-ui
  • ホスティング: Vercel

前提知識

開発に参加する前に、以下の技術についての基礎知識があることが望ましいです:

必須

  • TypeScript: プロジェクト全体がTypeScriptで書かれています
  • React: React 19の基本的な理解
  • Next.js: App Routerの基本(Server Components / Client Components)
  • Git: バージョン管理の基本操作

あると良い

  • Clean Architecture: プロジェクトのアーキテクチャパターン
  • PostgreSQL: データベース設計とクエリ
  • Tailwind CSS: ユーティリティファーストCSSフレームワーク
  • Supabase: BaaS(Backend as a Service)の概念

学習リソース


開発環境のセットアップ

1. 前提条件

以下のツールをインストールしてください:

  • Node.js 18+: nvmの使用を推奨
  • npm: Node.jsに同梱(プロジェクトではnpmを使用)
  • Git: バージョン管理
  • エディタ: VSCode推奨(プロジェクトには設定ファイルが含まれています)

2. リポジトリのクローン

git clone https://github.com/Tech-C-Venture/Portal.C.git
cd Portal.C

3. 依存関係のインストール

npm install

4. 環境変数の設定

.env.exampleをコピーして.envファイルを作成:

cp .env.example .env

.envファイルを編集し、以下の値を設定してください:

# ZITADEL認証
ZITADEL_ISSUER=https://your-zitadel-instance.zitadel.cloud
ZITADEL_CLIENT_ID=your_client_id

# NextAuth
NEXTAUTH_SECRET=your_secret_key_here  # openssl rand -base64 32 で生成
NEXTAUTH_URL=http://localhost:3000

# Supabase
NEXT_PUBLIC_SUPABASE_URL=https://your-project.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your_anon_key
SUPABASE_SERVICE_ROLE_KEY=your_service_role_key

注意: 環境変数の実際の値は、プロジェクトリードまたは運営メンバーから入手してください。

5. Supabaseのセットアップ

  1. Supabase ダッシュボードにアクセス
  2. プロジェクトを作成または既存のプロジェクトに接続
  3. SQL Editorでsupabase/migrations/内のマイグレーションファイルを順番に実行:
    • 20241216000001_create_members_table.sql
    • 20241216000002_create_tags_table.sql
    • 20241216000003_create_events_table.sql
    • 20241216000004_create_timetables_table.sql

6. 開発サーバーの起動

npm run dev

ブラウザで http://localhost:3000 を開いて動作を確認してください。

7. ビルドとリントの確認

# ビルド確認
npm run build

# リント実行
npm run lint

# テスト実行
npm run test

プロジェクト構造の理解

Portal.CはClean Architectureパターンを採用しています。以下の4層構造で設計されています。

ディレクトリ構造

Portal.C/
├── src/                      # Clean Architecture実装
│   ├── domain/              # ドメイン層(ビジネスロジック)
│   │   ├── entities/       # エンティティ(Member, Event, Timetable)
│   │   └── value-objects/  # 値オブジェクト(Email, StudentId等)
│   ├── application/         # アプリケーション層(ユースケース)
│   │   ├── use-cases/      # ビジネスロジック実行単位
│   │   ├── ports/          # インターフェース定義(リポジトリ等)
│   │   ├── dtos/           # データ転送オブジェクト
│   │   └── mappers/        # Entity ↔ DTO変換
│   └── infrastructure/      # インフラストラクチャ層
│       ├── repositories/   # データアクセス実装
│       ├── database/       # Supabaseクライアント
│       └── di/             # 依存性注入コンテナ
├── app/                     # プレゼンテーション層(Next.js App Router)
│   ├── events/             # イベント関連ページ
│   ├── members/            # メンバー関連ページ
│   ├── profile/            # プロフィールページ
│   ├── timetable/          # 時間割ページ
│   ├── admin/              # 管理画面
│   └── api/                # API Routes
├── components/              # Reactコンポーネント
│   ├── layout/             # レイアウトコンポーネント
│   └── ui/                 # UIコンポーネント
├── lib/                     # ユーティリティ関数
├── types/                   # TypeScript型定義
├── supabase/                # Supabase設定とマイグレーション
└── .kiro/                   # Kiro開発フレームワーク
    ├── steering/           # プロジェクト全体のガイドライン
    └── specs/              # 機能仕様書

Clean Architectureの層構造

┌─────────────────────────────────────────────┐
│          Presentation Layer                 │
│  (app/, components/ - Next.js App Router)   │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│         Application Layer                   │
│   (use-cases/, ports/, dtos/, mappers/)     │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│          Infrastructure Layer               │
│ (repositories/, database/, auth/, di/)      │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│            Domain Layer                     │
│       (entities/, value-objects/)           │
└─────────────────────────────────────────────┘

依存性ルール: 内側の層は外側の層に依存しません。

  • Domain Layer: ビジネスロジック、外部依存なし
  • Application Layer: ユースケース、Domainのみに依存
  • Infrastructure Layer: 外部サービス統合(DB、認証等)
  • Presentation Layer: UI、Application/Domainに依存

重要なファイル

ファイル説明
README.mdプロジェクト概要とセットアップ手順
CLAUDE.mdAI開発支援用の指示(Kiro Spec-Driven Development)
docs/ARCHITECTURE.mdClean Architectureの詳細設計
.kiro/steering/プロジェクト全体のガイドライン(product.md, tech.md, structure.md)
package.json依存関係とスクリプト定義
tsconfig.jsonTypeScript設定(パスエイリアス含む)

開発ワークフロー

Kiro Spec-Driven Development

Portal.CではKiroスタイルのSpec-Driven Developmentを採用しています。これにより、要件定義→設計→実装の流れが明確になり、AI支援開発が効率化されます。

基本フロー

  1. Phase 0(オプション): プロジェクトガイドラインの準備

    • /kiro:steering: ガイドライン管理
    • /kiro:steering-custom: カスタムガイドライン作成
  2. Phase 1(仕様策定):

    # 1. 仕様初期化
    /kiro:spec-init "新機能の説明"
    
    # 2. 要件定義
    /kiro:spec-requirements {feature-name}
    
    # 3. ギャップ分析(オプション、既存コードベースとの整合性確認)
    /kiro:validate-gap {feature-name}
    
    # 4. 設計
    /kiro:spec-design {feature-name} [-y]
    
    # 5. 設計レビュー(オプション)
    /kiro:validate-design {feature-name}
    
    # 6. タスク生成
    /kiro:spec-tasks {feature-name} [-y]
    
  3. Phase 2(実装):

    # タスク実装
    /kiro:spec-impl {feature-name} [task-numbers]
    
    # 実装検証(オプション)
    /kiro:validate-impl {feature-name}
    
  4. 進捗確認:

    /kiro:spec-status {feature-name}
    

実例:新機能追加の流れ

# 例:通知機能の追加
/kiro:spec-init "メンバーへのプッシュ通知機能"
/kiro:spec-requirements notification-feature
/kiro:spec-design notification-feature -y
/kiro:spec-tasks notification-feature -y
/kiro:spec-impl notification-feature 1-3

Gitワークフロー

  1. ブランチ作成:

    git checkout -b feature/your-feature-name
    
  2. 開発とコミット:

    git add .
    git commit -m "feat: 機能の説明"
    
  3. プッシュ:

    git push -u origin feature/your-feature-name
    
  4. プルリクエスト作成:

    • GitHubでPRを作成
    • レビューを依頼
    • CI/CDが通ることを確認

コミットメッセージ規約

Conventional Commitsに準拠:

  • feat: 新機能の追加
  • fix: バグ修正
  • docs: ドキュメント更新
  • style: コードフォーマット変更
  • refactor: リファクタリング
  • test: テスト追加・修正
  • chore: ビルドプロセス・ツール変更

コーディング規約

TypeScript

  • 型安全性: any型は使用禁止、適切な型定義を使用
  • strict mode: TypeScript strict modeを有効化
  • 命名規則:
    • ファイル名: PascalCase(コンポーネント)、camelCase(ユーティリティ)
    • 関数/変数: camelCase
    • 型/インターフェース: PascalCase
    • 定数: UPPER_SNAKE_CASE

React / Next.js

  • Server Components優先: デフォルトでServer Componentsを使用
  • Client Components: 'use client'が必要な場合のみ使用
  • コンポーネント設計: 単一責任の原則に従う
  • Hooks: カスタムフックはuseプレフィックスを付ける

Clean Architectureルール

  1. 依存性の方向:

    • Domain → (依存なし)
    • Application → Domain
    • Infrastructure → Application, Domain
    • Presentation → Application, Domain
  2. レイヤー間通信:

    • Use Caseを通じてビジネスロジックを実行
    • Repositoryインターフェース(ports)を定義し、実装(Infrastructure)を注入
  3. データフロー:

    // NG: Presentationから直接Repository実装を参照
    import { SupabaseMemberRepository } from '@/infrastructure/repositories/SupabaseMemberRepository';
    
    // OK: DIコンテナ経由でインターフェースを取得
    import { container } from '@/infrastructure/di/setup';
    import { REPOSITORY_KEYS } from '@/infrastructure/di/keys';
    const repository = container.resolve<IMemberRepository>(REPOSITORY_KEYS.MEMBER);
    

コードレビューチェックリスト

  • 型安全性が保たれているか(anyを使っていないか)
  • Clean Architectureの依存性ルールに違反していないか
  • テストが追加されているか
  • ESLintエラーがないか
  • コミットメッセージが規約に従っているか

よくある問題とトラブルシューティング

1. npm installでエラーが出る

原因: Node.jsのバージョンが古い

解決方法:

# Node.jsバージョン確認
node -v

# nvmでNode.js 18+をインストール
nvm install 18
nvm use 18

2. 環境変数が読み込まれない

原因: .envファイルが正しく設定されていない

解決方法:

  • .envファイルがプロジェクトルートに存在するか確認
  • サーバーを再起動(npm run dev
  • ブラウザのキャッシュをクリア

3. Supabaseへの接続エラー

原因: Supabase認証情報が間違っている、またはマイグレーションが未実行

解決方法:

# 環境変数を確認
echo $NEXT_PUBLIC_SUPABASE_URL
echo $NEXT_PUBLIC_SUPABASE_ANON_KEY

# Supabaseダッシュボードでマイグレーションが実行されているか確認
# SQL Editorでテーブルの存在を確認
SELECT * FROM members LIMIT 1;

4. 型エラーが出る

原因: 型定義が古い、または間違った型を使用している

解決方法:

# 型定義を再生成(Supabaseの場合)
npx supabase gen types typescript --project-id YOUR_PROJECT_ID > types/database.types.ts

# TypeScriptキャッシュをクリア
rm -rf .next
npm run build

5. ZITADELログインエラー

原因: ZITADEL設定が間違っている

解決方法:

  • ZITADEL_ISSUERZITADEL_CLIENT_IDが正しいか確認
  • ZITADELダッシュボードでリダイレクトURIがhttp://localhost:3000/api/auth/callback/zitadelに設定されているか確認

6. Clean Architectureの依存性エラー

原因: 誤った方向の依存性

解決方法:

  • Domainレイヤーで外部ライブラリをインポートしていないか確認
  • Presentationレイヤーから直接Infrastructure実装をインポートしていないか確認
  • Use Caseを通じてビジネスロジックを実行しているか確認

参考資料

プロジェクト内ドキュメント

技術スタック公式ドキュメント

アーキテクチャ・設計パターン

学習リソース


サポート

質問や問題がある場合は、以下の方法でサポートを受けられます:

  1. GitHub Issues: バグ報告や機能リクエスト
  2. プルリクエストレビュー: コードレビューで質問
  3. Tech.C Venture内部チャット: プロジェクトメンバーに直接質問
  4. プロジェクトリード: 木戸(認証基盤担当)

開発を楽しんでください! 🎉

何か困ったことがあれば、遠慮なくチームメンバーに質問してください。

Clean Architecture 設計ドキュメント

アーキテクチャ概要

Portal.CはClean Architectureパターンを採用し、以下の4層構造で設計されています。

┌─────────────────────────────────────────────┐
│          Presentation Layer                 │
│  (app/, components/ - Next.js App Router)   │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│         Application Layer                   │
│   (use-cases/, ports/, dtos/, mappers/)     │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│          Infrastructure Layer               │
│ (repositories/, database/, auth/, di/)      │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│            Domain Layer                     │
│       (entities/, value-objects/)           │
└─────────────────────────────────────────────┘

レイヤー構成

1. Domain Layer (src/domain/)

責務: ビジネスロジックとエンティティ定義 依存: なし(外部ライブラリ・フレームワーク不使用)

  • entities/: Member, Event, Timetable
  • value-objects/: Email, StudentId, EventCapacity, CurrentStatus

特徴:

  • イミュータブル設計
  • バリデーションロジック内包
  • 純粋なTypeScript(フレームワーク非依存)

2. Application Layer (src/application/)

責務: ユースケースとアプリケーションロジック 依存: Domain Layer のみ

  • use-cases/: GetMemberProfile, RegisterForEvent等
  • ports/: IMemberRepository, IEventRepository等(インターフェース定義)
  • dtos/: MemberDTO, EventDTO等(データ転送オブジェクト)
  • mappers/: Entity ↔ DTO変換

特徴:

  • 依存性逆転の原則(ポートインターフェース定義)
  • Result型によるエラーハンドリング
  • トランザクション境界の定義

3. Infrastructure Layer (src/infrastructure/)

責務: 外部サービスとの統合 依存: Application Layer, Domain Layer

  • repositories/: SupabaseMemberRepository等(ポート実装)
  • database/: Supabaseクライアント設定
  • di/: 依存性注入コンテナ

特徴:

  • リポジトリパターン
  • データマッパー(DB型 ↔ ドメインエンティティ)
  • PostgreSQL関数によるトランザクション処理

4. Presentation Layer (app/, components/)

責務: UI表示とユーザーインタラクション 依存: Application Layer, Domain Layer

  • app/: Next.js App Router(Server Components)
  • components/: Reactコンポーネント(Client Components)

特徴:

  • Server Components: データ取得、ユースケース呼び出し
  • Client Components: インタラクティブUI
  • Server Actions: フォーム送信等

依存性ルール

Domain ← Application ← Infrastructure
  ↑                        ↑
  └────── Presentation ────┘

原則: 内側の層は外側の層に依存しない

依存性注入(DI)

軽量DIコンテナを使用:

import { container } from '@/infrastructure/di/setup';
import { REPOSITORY_KEYS } from '@/infrastructure/di/keys';

// リポジトリの解決
const memberRepository = container.resolve<IMemberRepository>(
  REPOSITORY_KEYS.MEMBER
);

登録: モジュールファクトリーパターン

  • memberModule: メンバー関連の依存性
  • eventModule: イベント関連の依存性
  • timetableModule: 時間割関連の依存性

データフロー

Server Component → Repository

// 1. Server Componentでデータ取得
async function getMembers() {
  const repository = container.resolve<IMemberRepository>(REPOSITORY_KEYS.MEMBER);
  const result = await repository.findAll();

  // 2. Entity → DTO変換
  return MemberMapper.toDTOList(result.value);
}

// 3. Client Componentに渡す
<MemberList members={members} />

ユースケース実行

// 1. ユースケース取得
const useCase = new RegisterForEventUseCase(eventRepository);

// 2. 実行
const result = await useCase.execute(eventId, memberId);

// 3. Result型でエラーハンドリング
if (!result.success) {
  console.error(result.error);
}

トランザクション処理

Supabase(PostgreSQL)の関数を使用:

CREATE FUNCTION register_for_event(p_event_id UUID, p_member_id UUID)
RETURNS void AS $$
BEGIN
  -- 定員チェック + 参加登録を原子的に実行
  ...
END;
$$ LANGUAGE plpgsql;

テスト戦略

  • Domain Layer: ユニットテスト(外部依存なし)
  • Application Layer: ユニットテスト(モックリポジトリ)
  • Infrastructure Layer: 統合テスト(Supabase接続)
  • Presentation Layer: E2Eテスト(Playwright/Cypress)

ディレクトリ構造

Portal.C/
├── src/
│   ├── domain/               # ドメイン層
│   │   ├── entities/
│   │   └── value-objects/
│   ├── application/          # アプリケーション層
│   │   ├── use-cases/
│   │   ├── ports/
│   │   ├── dtos/
│   │   └── mappers/
│   └── infrastructure/       # インフラストラクチャ層
│       ├── repositories/
│       ├── database/
│       └── di/
├── app/                      # プレゼンテーション層(Server Components)
└── components/               # プレゼンテーション層(Client Components)

パスエイリアス

{
  "@/domain/*": ["./src/domain/*"],
  "@/application/*": ["./src/application/*"],
  "@/infrastructure/*": ["./src/infrastructure/*"]
}

開発ワークフロー

  1. 新機能追加時:

    • Domain Entityを定義
    • Application Use Caseを実装
    • Infrastructure Repositoryを実装
    • DI登録
    • Presentation統合
  2. 変更時:

    • 影響範囲を層で限定
    • 依存性ルールを守る
    • テストで担保

参考資料

  • Clean Architecture (Robert C. Martin)
  • Hexagonal Architecture (Ports & Adapters)
  • Domain-Driven Design

マイグレーション計画

AI-DLC and Spec-Driven Development

Kiro-style Spec Driven Development implementation on AI-DLC (AI Development Life Cycle)

Project Memory

Project memory keeps persistent guidance (steering, specs notes, component docs) so Codex honors your standards each run. Treat it as the long-lived source of truth for patterns, conventions, and decisions.

  • Use .kiro/steering/ for project-wide policies: architecture principles, naming schemes, security constraints, tech stack decisions, api standards, etc.
  • Use local AGENTS.md files for feature or library context (e.g. src/lib/payments/AGENTS.md): describe domain assumptions, API contracts, or testing conventions specific to that folder. Codex auto-loads these when working in the matching path.
  • Specs notes stay with each spec (under .kiro/specs/) to guide specification-level workflows.

Project Context

Paths

  • Steering: .kiro/steering/
  • Specs: .kiro/specs/

Steering vs Specification

Steering (.kiro/steering/) - Guide AI with project-wide rules and context Specs (.kiro/specs/) - Formalize development process for individual features

Active Specifications

  • Check .kiro/specs/ for active specifications
  • Use /prompts:kiro-spec-status [feature-name] to check progress

Development Guidelines

  • Think in English, generate responses in English. All Markdown content written to project files (e.g., requirements.md, design.md, tasks.md, research.md, validation reports) MUST be written in the target language configured for this specification (see spec.json.language).

Minimal Workflow

  • Phase 0 (optional): /prompts:kiro-steering, /prompts:kiro-steering-custom
  • Phase 1 (Specification):
    • /prompts:kiro-spec-init "description"
    • /prompts:kiro-spec-requirements {feature}
    • /prompts:kiro-validate-gap {feature} (optional: for existing codebase)
    • /prompts:kiro-spec-design {feature} [-y]
    • /prompts:kiro-validate-design {feature} (optional: design review)
    • /prompts:kiro-spec-tasks {feature} [-y]
  • Phase 2 (Implementation): /prompts:kiro-spec-impl {feature} [tasks]
    • /prompts:kiro-validate-impl {feature} (optional: after implementation)
  • Progress check: /prompts:kiro-spec-status {feature} (use anytime)

Development Rules

  • 3-phase approval workflow: Requirements → Design → Tasks → Implementation
  • Human review required each phase; use -y only for intentional fast-track
  • Keep steering current and verify alignment with /prompts:kiro-spec-status
  • Follow the user’s instructions precisely, and within that scope act autonomously: gather the necessary context and complete the requested work end-to-end in this run, asking questions only when essential information is missing or the instructions are critically ambiguous.

Steering Configuration

  • Load entire .kiro/steering/ as project memory
  • Default files: product.md, tech.md, structure.md
  • Custom files are supported (managed via /prompts:kiro-steering-custom)

Steering

Steeringは、プロジェクト全体のガイドラインとルールを定義します。AI開発支援において、これらのガイドラインがプロジェクトの一貫性を保つための基盤となります。

ファイル構成

  • Product - プロダクト要件とビジネスルール
  • Tech - 技術スタックと技術的な制約
  • Structure - プロジェクト構造とアーキテクチャ原則

Steeringの役割

Steeringファイルは、以下の目的で使用されます:

  1. AI開発支援の指針: Claude CodeやCodexなどのAI開発ツールが、プロジェクトの標準に沿った提案を行うための参照情報
  2. 開発者のオンボーディング: 新規メンバーがプロジェクトの方針を理解するための資料
  3. 一貫性の維持: プロジェクト全体で統一された設計思想を保つためのガイドライン

更新方法

Steeringファイルは、プロジェクトの成長に伴って更新されます:

# Steeringファイルの更新
/kiro:steering

# カスタムSteeringファイルの作成
/kiro:steering-custom

詳細はルートディレクトリのCLAUDE.mdAGENTS.mdを参照してください。

Product Overview

Portal.C is a member and event management web application for Tech.C Venture, developed as part of the Giiku Project Vol.16. It serves as Tech.C Venture’s first foundational system, providing event bulletin board and participant management capabilities.

Core Capabilities

  • Member Profile Management: Comprehensive member information including automatic grade calculation from enrollment year, retention flags, skill/interest tags, and time-limited status updates
  • Event Management: Event listing, registration, participation tracking, and capacity management
  • Timetable System: Grade and department-based filtering for member schedules
  • Authentication & Authorization: ZITADEL-based authentication with role-based access control (admin roles for administrative functions)
  • Administrative Functions: Event creation, participation tracking by ID, and member management

Target Use Cases

  • Tech.C Venture members discovering and participating in events
  • Administrators creating and managing events
  • Members viewing each other’s profiles and timetables for collaboration
  • Tracking member participation and engagement metrics
  • Sharing current status (24-hour limited, Discord-like status feature)

Value Proposition

Portal.C provides Tech.C Venture with a centralized platform for community engagement, replacing fragmented communication channels with a unified system that tracks member activities, facilitates event participation, and strengthens community bonds through profile discovery and shared schedules.


Focus on patterns and purpose, not exhaustive feature lists

Technology Stack

Architecture

Currently: Standard Next.js application structure with direct database access from UI components. Target: Clean Architecture with proper layer separation (Domain, Application, Infrastructure, Presentation).

Core Technologies

  • Language: TypeScript 5.6+
  • Framework: Next.js 15 (App Router)
  • Runtime: Node.js 18+
  • Database: Supabase (PostgreSQL)
  • Authentication: ZITADEL via NextAuth.js 4.24
  • Styling: Tailwind CSS 3.4
  • UI Components: @openameba/spindle-ui 3.1.4

Key Libraries

  • @supabase/ssr: Server-side rendering support for Supabase
  • @supabase/supabase-js: Supabase client library
  • next-auth: Authentication for Next.js
  • date-fns: Date manipulation utilities
  • matter-js: Physics engine for hero animations
  • clsx: Utility for constructing className strings

Development Standards

Type Safety

  • TypeScript strict mode enabled
  • No any types - use proper type definitions
  • Database types generated from Supabase schema

Code Quality

  • ESLint with Next.js configuration
  • Consistent file naming and structure
  • Component-based architecture

Testing

  • Testing infrastructure to be established during clean architecture migration

Development Environment

Required Tools

  • Node.js 18+
  • npm or yarn
  • Supabase CLI (for type generation)
  • Git

Common Commands

# Dev: npm run dev
# Build: npm run build
# Start: npm start
# Lint: npm run lint
# Type generation: npx supabase gen types typescript --project-id YOUR_PROJECT_ID > types/database.types.ts

Key Technical Decisions

  1. Next.js 15 App Router: Modern React architecture with server components
  2. Supabase: Managed PostgreSQL with built-in auth, real-time, and storage capabilities
  3. ZITADEL for Auth: Enterprise-grade authentication separate from application logic
  4. Spindle UI: Consistent design system for UI components
  5. Clean Architecture Migration: Planned refactoring to separate concerns and improve testability

Infrastructure

  • Hosting: Vercel (optimized for Next.js)
  • Database: Supabase-managed PostgreSQL
  • Auth Provider: ZITADEL instance

Document standards and patterns, not every dependency

Project Structure

Organization Philosophy

Current: Standard Next.js structure with pages, components, and lib utilities.

Target (Clean Architecture): Layer-based organization with clear dependency rules:

  • Domain Layer: Business logic and entities (no external dependencies)
  • Application Layer: Use cases and application services
  • Infrastructure Layer: External services (database, auth, APIs)
  • Presentation Layer: UI components and pages (Next.js App Router)

Directory Patterns

Current Structure

Pages and Routing

Location: /app/ Purpose: Next.js App Router pages and API routes Example: /app/events/page.tsx, /app/api/auth/[...nextauth]/route.ts

UI Components

Location: /components/ Purpose: Reusable React components Example: /components/layout/Navigation.tsx, /components/MatterHero.tsx

Utilities and Clients

Location: /lib/ Purpose: Utility functions and external service clients Example: /lib/supabase/client.ts, /lib/auth.ts

Type Definitions

Location: /types/ Purpose: TypeScript type definitions Example: /types/database.types.ts, /types/index.ts

Target Structure (Clean Architecture)

Domain Layer

Location: /src/domain/ Purpose: Core business entities, value objects, and business rules. No framework dependencies. Example: /src/domain/entities/Member.ts, /src/domain/value-objects/Email.ts

Application Layer

Location: /src/application/ Purpose: Use cases, DTOs, and interfaces for external dependencies Example: /src/application/use-cases/RegisterForEvent.ts, /src/application/ports/MemberRepository.ts

Infrastructure Layer

Location: /src/infrastructure/ Purpose: Implementations of external dependencies (DB, auth, external APIs) Example: /src/infrastructure/repositories/SupabaseMemberRepository.ts, /src/infrastructure/auth/ZitadelAuthProvider.ts

Presentation Layer

Location: /src/presentation/ (or keep in /app/ and /components/) Purpose: Next.js pages, components, controllers Example: /app/events/page.tsx with controller separation

Naming Conventions

  • Files:
    • Components: PascalCase (e.g., MemberCard.tsx)
    • Utilities: camelCase (e.g., formatDate.ts)
    • Pages: kebab-case or lowercase (Next.js convention)
  • Components: PascalCase
  • Functions: camelCase
  • Types/Interfaces: PascalCase

Import Organization

// External dependencies
import { createBrowserClient } from "@supabase/ssr";

// Internal absolute imports (current)
import { MatterHero } from "@/components/MatterHero";
import type { Event } from "@/types";

// Target (Clean Architecture)
import { Member } from "@/domain/entities/Member";
import { RegisterForEvent } from "@/application/use-cases/RegisterForEvent";
import { SupabaseMemberRepository } from "@/infrastructure/repositories/SupabaseMemberRepository";

Path Aliases:

  • @/: Maps to project root (configured in tsconfig.json)

Code Organization Principles

Current State

  • UI components directly import and use Supabase clients
  • Business logic mixed with presentation logic
  • No clear separation of concerns

Target State (Clean Architecture)

  1. Dependency Rule: Inner layers don’t depend on outer layers

    • Domain → (no dependencies)
    • Application → Domain
    • Infrastructure → Application, Domain
    • Presentation → Application, Domain
  2. Dependency Inversion: Application layer defines interfaces, infrastructure implements them

  3. Use Case Driven: Each feature is a use case in the application layer

  4. Testability: Business logic can be tested without UI or database


Document patterns, not file trees. New files following patterns shouldn’t require updates

Specs

Specsは、個別の機能や変更に対する仕様書を管理します。各機能の要件定義、設計、タスク、実装状況を追跡します。

アクティブな仕様

Spec-Driven Development (SDD)

Portal.CではKiro-style Spec-Driven Developmentを採用しています。これにより、要件定義→設計→実装の流れが明確になり、AI支援開発が効率化されます。

基本フロー

  1. 要件定義 (/kiro:spec-requirements)

    • 機能の要件を詳細に記述
    • EARS形式での要件記述
  2. ギャップ分析 (/kiro:validate-gap) - オプション

    • 既存コードベースとの整合性確認
  3. 設計 (/kiro:spec-design)

    • アーキテクチャ設計
    • 技術選定
    • インターフェース定義
  4. タスク生成 (/kiro:spec-tasks)

    • 実装タスクの分解
    • 優先順位付け
  5. 実装 (/kiro:spec-impl)

    • TDD方式での実装
    • タスク単位での進捗管理
  6. 検証 (/kiro:validate-impl) - オプション

    • 要件との整合性確認

詳細はルートディレクトリのCLAUDE.mdAGENTS.mdを参照してください。

新しい仕様の作成

# 新しい機能の仕様初期化
/kiro:spec-init "機能の説明"

# 要件定義
/kiro:spec-requirements {feature-name}

# 設計
/kiro:spec-design {feature-name}

# タスク生成
/kiro:spec-tasks {feature-name}

# 実装
/kiro:spec-impl {feature-name} [task-numbers]

Clean Architecture Refactor

Portal.CをClean Architectureパターンに基づいてリファクタリングするための仕様書です。

概要

既存のコードベースを、保守性と拡張性に優れたClean Architectureパターンに移行します。これにより、ビジネスロジックと外部依存を明確に分離し、テスタビリティを向上させます。

ドキュメント

  • Requirements - 要件定義(EARS形式)
  • Design - アーキテクチャ設計の詳細
  • Tasks - 実装タスクの一覧
  • Research - 技術調査とアーキテクチャ分析
  • Gap Analysis - 既存コードとのギャップ分析

進捗確認

/kiro:spec-status clean-architecture-refactor

アーキテクチャ構造

┌─────────────────────────────────────────────┐
│          Presentation Layer                 │
│  (app/, components/ - Next.js App Router)   │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│         Application Layer                   │
│   (use-cases/, ports/, dtos/, mappers/)     │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│          Infrastructure Layer               │
│ (repositories/, database/, auth/, di/)      │
└─────────────────────────────────────────────┘
                    ↓
┌─────────────────────────────────────────────┐
│            Domain Layer                     │
│       (entities/, value-objects/)           │
└─────────────────────────────────────────────┘

依存性ルール

内側の層は外側の層に依存しません:

  • Domain Layer: ビジネスロジック、外部依存なし
  • Application Layer: ユースケース、Domainのみに依存
  • Infrastructure Layer: 外部サービス統合(DB、認証等)
  • Presentation Layer: UI、Application/Domainに依存

詳細はDesignを参照してください。

Requirements Document

導入

本ドキュメントは、Portal.CをスタンダードなNext.jsアーキテクチャからClean Architectureへリファクタリングするための要件を定義します。このリファクタリングの目的は、レイヤーの適切な分離により、テスタビリティ、保守性、関心の分離を向上させながら、既存のすべての機能を維持することです。

Portal.Cは、Tech.C Venture向けのメンバー・イベント管理Webアプリケーションであり、Next.js 15、Supabase、ZITADELを使用しています。現在の構造(app/, components/, lib/, types/)から、ドメイン駆動設計の原則に基づいた明確なレイヤー構造(src/domain/, src/application/, src/infrastructure/, src/presentation/)へ移行します。

Requirements

Requirement 1: ディレクトリ構造とレイヤー分離

Objective: 開発者として、Clean Architectureの原則に従った明確なレイヤー構造を持つことで、各レイヤーの責務を理解し、保守性の高いコードベースを実現したい。

Acceptance Criteria

  1. The Portal.C shall プロジェクトルートにsrc/ディレクトリを作成し、すべてのアプリケーションコードを格納する
  2. The Portal.C shall src/配下にdomain/, application/, infrastructure/, presentation/の4つのレイヤーディレクトリを作成する
  3. The Portal.C shall 各レイヤーディレクトリ内に、機能別のサブディレクトリを配置する(例:domain/entities/, domain/value-objects/, application/use-cases/, application/ports/)
  4. The Portal.C shall 既存のapp/ディレクトリをNext.js App Router用に保持し、プレゼンテーション層のページルーティングとして使用する
  5. The Portal.C shall 既存のcomponents/ディレクトリをUIコンポーネント用に保持し、プレゼンテーション層の一部として使用する
  6. The Portal.C shall lib/およびtypes/ディレクトリから適切なレイヤーへコードを移行する
  7. The Portal.C shall tsconfig.jsonにパスエイリアスを設定し、各レイヤーへの絶対パスインポートを可能にする(例:@/domain/, @/application/, @/infrastructure/, @/presentation/)

Requirement 2: ドメインレイヤーの設計

Objective: 開発者として、外部依存を持たないビジネスロジックとエンティティを明確に定義することで、ビジネスルールの純粋性を保ち、テストしやすいコアロジックを実現したい。

Acceptance Criteria

  1. The Portal.C shall src/domain/entities/にビジネスエンティティを定義する(Member, Event, Timetable等)
  2. The Portal.C shall ドメインエンティティは外部ライブラリやフレームワークに依存しないプレーンなTypeScriptクラスまたはインターフェースとして実装する
  3. The Portal.C shall src/domain/value-objects/に値オブジェクトを定義する(Email, StudentId, EventCapacity等)
  4. The Portal.C shall 値オブジェクトはイミュータブルであり、バリデーションロジックを内包する
  5. The Portal.C shall src/domain/services/にドメインサービスを配置し、複数のエンティティにまたがるビジネスロジックを実装する
  6. The Portal.C shall ドメインレイヤーはアプリケーション層、インフラストラクチャ層、プレゼンテーション層のいずれにも依存しない
  7. When ドメインエンティティを作成または変更する際、the Portal.C shall ビジネスルールのバリデーションを実行し、不正な状態を防ぐ

Requirement 3: アプリケーションレイヤーの設計

Objective: 開発者として、ユースケースごとにアプリケーションロジックを整理し、ドメインとインフラストラクチャを橋渡しすることで、機能の実装と変更を容易にしたい。

Acceptance Criteria

  1. The Portal.C shall src/application/use-cases/にユースケースクラスを配置する(RegisterForEvent, CreateMember, UpdateProfile等)
  2. The Portal.C shall 各ユースケースは単一の責務を持ち、execute()メソッドまたは同等のエントリーポイントを提供する
  3. The Portal.C shall src/application/ports/にリポジトリインターフェースとサービスインターフェースを定義する(IMemberRepository, IEventRepository, IAuthService等)
  4. The Portal.C shall src/application/dtos/にデータ転送オブジェクトを配置し、レイヤー間のデータ受け渡しに使用する
  5. The Portal.C shall アプリケーション層はドメイン層のみに依存し、インフラストラクチャ層やプレゼンテーション層には依存しない
  6. When ユースケースを実行する際、the Portal.C shall ポートインターフェースを通じてインフラストラクチャ層の実装を呼び出す(依存性逆転の原則)
  7. If ユースケース実行中にビジネスルール違反が発生した場合、then the Portal.C shall 適切なドメインエラーまたはアプリケーションエラーをスローする
  8. The Portal.C shall 各ユースケースにトランザクション境界を定義し、データ整合性を保証する

Requirement 4: インフラストラクチャレイヤーの設計

Objective: 開発者として、外部サービス(データベース、認証、API)との統合を抽象化し、技術的な実装詳細をビジネスロジックから分離したい。

Acceptance Criteria

  1. The Portal.C shall src/infrastructure/repositories/にリポジトリの具体的実装を配置する(SupabaseMemberRepository, SupabaseEventRepository等)
  2. The Portal.C shall リポジトリ実装はアプリケーション層で定義されたポートインターフェースを実装する
  3. The Portal.C shall src/infrastructure/database/にSupabaseクライアント設定とデータベース接続ロジックを配置する
  4. The Portal.C shall src/infrastructure/auth/にZITADEL認証プロバイダーとNextAuth設定を配置する
  5. The Portal.C shall インフラストラクチャ層の実装はドメインエンティティとDTOの変換ロジックを含む
  6. When リポジトリメソッドを呼び出す際、the Portal.C shall データベース固有の型(Supabase型)をドメインエンティティに変換する
  7. If データベースクエリがエラーを返した場合、then the Portal.C shall アプリケーション層で処理可能な標準化されたエラーに変換する
  8. The Portal.C shall src/infrastructure/external/に外部API連携ロジックを配置する(必要に応じて)
  9. The Portal.C shall インフラストラクチャ層の各実装は、依存性注入によりアプリケーション層に提供される

Requirement 5: プレゼンテーションレイヤーの設計

Objective: 開発者として、UIロジックとビジネスロジックを分離し、Next.jsのApp Router機能を活用しながら、Clean Architectureの原則に従った実装を実現したい。

Acceptance Criteria

  1. The Portal.C shall app/ディレクトリをNext.js App Routerのページルーティング用に保持する
  2. The Portal.C shall components/ディレクトリをプレゼンテーション層のUIコンポーネント用に保持する
  3. The Portal.C shall ページコンポーネント(app/*/page.tsx)はサーバーコンポーネントとして実装し、ユースケースを直接呼び出す
  4. The Portal.C shall クライアントコンポーネントはuse clientディレクティブを使用し、インタラクティブなUIロジックのみを含む
  5. The Portal.C shall プレゼンテーション層のコンポーネントはユースケースまたはDTOを通じてアプリケーション層と通信する
  6. The Portal.C shall UIコンポーネントは直接データベースクライアント(Supabase)や認証クライアント(ZITADEL)を呼び出さない
  7. When フォーム送信やユーザーアクションが発生した際、the Portal.C shall 対応するユースケースを呼び出し、ビジネスロジックを実行する
  8. If ユースケース実行がエラーを返した場合、then the Portal.C shall ユーザーに適切なエラーメッセージを表示する
  9. The Portal.C shall Server ActionsをNext.js 15の推奨パターンに従って実装し、ユースケースへの橋渡しを行う

Requirement 6: 依存性ルールの遵守

Objective: 開発者として、Clean Architectureの依存性ルール(内側のレイヤーは外側のレイヤーに依存しない)を厳格に守ることで、アーキテクチャの整合性と変更容易性を維持したい。

Acceptance Criteria

  1. The Portal.C shall ドメイン層は他のいずれのレイヤー(アプリケーション、インフラストラクチャ、プレゼンテーション)にも依存しない
  2. The Portal.C shall アプリケーション層はドメイン層のみに依存し、インフラストラクチャ層やプレゼンテーション層には依存しない
  3. The Portal.C shall インフラストラクチャ層はアプリケーション層とドメイン層に依存可能だが、プレゼンテーション層には依存しない
  4. The Portal.C shall プレゼンテーション層はアプリケーション層とドメイン層に依存可能だが、インフラストラクチャ層の具体的実装には依存しない
  5. When アプリケーション層が外部サービスとの統合を必要とする際、the Portal.C shall ポートインターフェースを定義し、インフラストラクチャ層がそれを実装する(依存性逆転の原則)
  6. The Portal.C shall TypeScriptのコンパイラオプションやリンターを設定し、依存性ルール違反を検出する
  7. If レイヤー間の不正な依存が検出された場合、then the Portal.C shall ビルドまたはリント時にエラーを報告する

Requirement 7: 既存機能の保持

Objective: ユーザーおよび管理者として、リファクタリング後も既存のすべての機能が正常に動作し、ユーザー体験が損なわれないことを確認したい。

Acceptance Criteria

  1. The Portal.C shall メンバープロフィール管理機能(プロフィール表示、編集、入学年度からの学年自動計算、在籍フラグ、スキル/興味タグ、24時間限定ステータス更新)をリファクタリング後も提供する
  2. The Portal.C shall イベント管理機能(イベント一覧、登録、参加追跡、定員管理)をリファクタリング後も提供する
  3. The Portal.C shall タイムテーブルシステム機能(学年・学部フィルタリング、メンバースケジュール表示)をリファクタリング後も提供する
  4. The Portal.C shall ZITADEL認証とロールベースアクセス制御(管理者ロール)をリファクタリング後も提供する
  5. The Portal.C shall 管理機能(イベント作成、ID別参加追跡、メンバー管理)をリファクタリング後も提供する
  6. The Portal.C shall Spindle UIコンポーネントライブラリを使用したUIデザインをリファクタリング後も維持する
  7. When リファクタリング後のアプリケーションを起動した際、the Portal.C shall すべての既存ページとルートが正常にアクセス可能である
  8. When 既存のユーザーフローを実行した際、the Portal.C shall リファクタリング前と同一の結果と動作を提供する
  9. If リファクタリング中に機能の動作変更が必要な場合、then the Portal.C shall 事前に関係者に通知し、承認を得る

Requirement 8: テスタビリティの向上

Objective: 開発者として、ビジネスロジックとインフラストラクチャロジックを独立してテストできる環境を構築し、コードの品質と信頼性を向上させたい。

Acceptance Criteria

  1. The Portal.C shall ドメイン層のエンティティと値オブジェクトを外部依存なしでユニットテスト可能にする
  2. The Portal.C shall アプリケーション層のユースケースをモックリポジトリを使用してユニットテスト可能にする
  3. The Portal.C shall インフラストラクチャ層のリポジトリ実装をインテグレーションテスト可能にする
  4. The Portal.C shall src/配下の各レイヤーに対応する__tests__/ディレクトリまたは.test.tsファイルを配置する
  5. When ユースケースのテストを実行する際、the Portal.C shall リポジトリインターフェースのモック実装を注入し、データベースアクセスなしでテストを実行できる
  6. The Portal.C shall テストフレームワーク(Jest, Vitest等)とテストランナーを設定し、自動テスト実行環境を構築する
  7. The Portal.C shall テストカバレッジツールを導入し、コードカバレッジを測定可能にする
  8. When ドメインロジックに変更を加えた際、the Portal.C shall 既存のユニットテストが自動的に検証し、リグレッションを防ぐ

Requirement 9: マイグレーション戦略と段階的移行

Objective: 開発チームとして、リファクタリングを安全かつ段階的に実施し、開発速度を維持しながらリスクを最小化したい。

Acceptance Criteria

  1. The Portal.C shall リファクタリングを機能単位またはドメイン単位で段階的に実施する
  2. The Portal.C shall 新しいレイヤー構造と既存の構造が一時的に共存可能なマイグレーション計画を策定する
  3. When 新しいレイヤー構造への移行を開始する際、the Portal.C shall まず小規模な機能(例:メンバープロフィール表示)をパイロットとして移行する
  4. The Portal.C shall 各マイグレーション段階で既存機能のリグレッションテストを実施し、動作を検証する
  5. The Portal.C shall 既存のインポートパスを新しいレイヤー構造に段階的に更新するためのツールまたはスクリプトを用意する
  6. If マイグレーション中に重大な問題が発見された場合、then the Portal.C shall ロールバック可能な状態を維持する(Gitブランチ戦略)
  7. The Portal.C shall 各マイグレーション段階の完了基準(定義済みテストの通過、コードレビュー承認等)を明確にする
  8. When すべての機能が新しいレイヤー構造に移行完了した際、the Portal.C shall 古い構造のコードを削除し、クリーンな状態にする

Requirement 10: ドキュメントと開発者体験

Objective: 開発チームとして、新しいアーキテクチャの理解を促進し、開発者が効率的に作業できる環境を提供したい。

Acceptance Criteria

  1. The Portal.C shall Clean Architectureの各レイヤーの責務と依存性ルールを説明するドキュメントを提供する
  2. The Portal.C shall 新しいユースケースを追加する際の開発ガイドラインとコード例を提供する
  3. The Portal.C shall リポジトリインターフェースと実装の追加方法を説明するドキュメントを提供する
  4. The Portal.C shall ディレクトリ構造とファイル配置規則を説明するREADMEを各レイヤーディレクトリに配置する
  5. When 新しい開発者がプロジェクトに参加する際、the Portal.C shall オンボーディングドキュメントを通じてアーキテクチャの概要を理解できる
  6. The Portal.C shall コード生成スクリプトまたはテンプレートを提供し、新しいエンティティ、ユースケース、リポジトリの作成を支援する
  7. The Portal.C shall 既存のSteering Context(.kiro/steering/)を更新し、新しいアーキテクチャパターンを反映する

技術設計書: Clean Architecture リファクタリング

概要

本設計は、Portal.Cを標準的なNext.jsアーキテクチャからClean Architectureへリファクタリングするための技術的アプローチを定義します。このリファクタリングにより、レイヤーの適切な分離、テスタビリティの向上、保守性の改善を実現しながら、既存のすべての機能を維持します。

Portal.Cは、Tech.C Venture向けのメンバー・イベント管理Webアプリケーションであり、現在Next.js 15、Supabase、ZITADELを使用しています。現在の構造(app/, components/, lib/, types/)から、ドメイン駆動設計の原則に基づいた明確なレイヤー構造(src/domain/, src/application/, src/infrastructure/, src/presentation/)へ移行します。

ユーザー: 開発チーム、Tech.C Ventureのメンバーと管理者

影響: 既存のコードベース構造を根本的に変更しますが、ユーザー向け機能は完全に維持されます。開発者体験は、明確なレイヤー分離とテスト可能性の向上により大幅に改善されます。

目標

  • レイヤー分離の実現: Domain、Application、Infrastructure、Presentationの4層を明確に分離し、Clean Architectureの依存性ルールを遵守
  • テスタビリティの向上: ビジネスロジックとインフラストラクチャロジックを独立してテスト可能にする環境を構築
  • 既存機能の保持: リファクタリング後もすべての既存機能(メンバー管理、イベント管理、タイムテーブル、認証)が正常に動作
  • 段階的移行: 7段階の移行計画により、リスクを最小化しながら安全にリファクタリングを実施
  • 開発者体験の改善: 明確なアーキテクチャパターンとドキュメントにより、新しい開発者のオンボーディングと機能追加を容易化

非目標

  • 機能追加: 本リファクタリングは既存機能の再構築のみを対象とし、新機能追加は含まない
  • UIデザインの変更: Spindle UIコンポーネントとデザインシステムはそのまま維持
  • データベーススキーマの変更: 既存のSupabaseスキーマは変更せず、そのまま活用
  • 認証システムの変更: ZITADELとNextAuth.jsの統合はそのまま維持
  • パフォーマンス最適化: アーキテクチャ変更に伴う自然な改善は期待されるが、積極的な最適化は別途実施

アーキテクチャ

既存アーキテクチャ分析

現在のパターン

  • 標準的なNext.js構造: app/ディレクトリによるファイルベースルーティング
  • 直接的なデータアクセス: UIコンポーネントから直接Supabaseクライアントを呼び出す想定(現在はモックデータ)
  • 型定義とビジネスロジックの混在: types/index.tsにcalculateGrade(), isStatusValid()などのビジネスロジックが含まれる
  • レイヤー分離なし: プレゼンテーション、ビジネスロジック、データアクセスが明確に分離されていない

再利用可能な資産

  • データベーススキーマ完全構築済み: members, tags, events, timetablesテーブル、RLS設定済み
  • 認証基盤設定完了: ZITADEL OIDC統合、NextAuth.js設定、ロールベースアクセス制御
  • Supabaseクライアント: 4種類のクライアント(browser, server, admin, middleware)
  • 型定義システム: Supabase自動生成型、アプリケーション型
  • UIコンポーネント: Spindle UI統合、ページコンポーネント実装済み

技術的制約

  • Next.js 15 App Routerの使用が必須
  • Supabaseをデータベースとして使用
  • ZITADELを認証基盤として使用
  • TypeScript strict mode有効

アーキテクチャパターンと境界マップ

選択パターン: Clean Architecture(4層モデル)

根拠:

  • ドメインロジックとインフラストラクチャの明確な分離
  • 依存性逆転の原則により、ビジネスロジックが外部技術に依存しない
  • テスタビリティと保守性の大幅な向上
  • Next.js 15 App Routerとの互換性が高い(調査により実証済み)
graph TB
    subgraph Presentation["プレゼンテーション層 (Presentation)"]
        Pages["Pages<br/>app/"]
        Components["UI Components<br/>components/"]
        ServerActions["Server Actions"]
    end

    subgraph Application["アプリケーション層 (Application)"]
        UseCases["Use Cases"]
        Ports["Ports<br/>(Interfaces)"]
        DTOs["DTOs"]
    end

    subgraph Domain["ドメイン層 (Domain)"]
        Entities["Entities"]
        ValueObjects["Value Objects"]
        DomainServices["Domain Services"]
    end

    subgraph Infrastructure["インフラストラクチャ層 (Infrastructure)"]
        Repositories["Repositories<br/>(Implementations)"]
        Database["Database<br/>(Supabase)"]
        Auth["Auth<br/>(ZITADEL)"]
    end

    Pages --> ServerActions
    ServerActions --> UseCases
    Components --> ServerActions
    UseCases --> Ports
    UseCases --> DTOs
    UseCases --> Entities
    Repositories -.implements.-> Ports
    Repositories --> Database
    Repositories --> Auth
    Entities --> ValueObjects
    DomainServices --> Entities

ドメイン/機能境界:

  • Member管理: プロフィール、学年計算、ステータス管理、スキル/興味タグ
  • Event管理: イベント作成、参加登録、定員管理、参加追跡
  • Timetable管理: 時間割表示、学年/学部フィルタリング
  • 認証・認可: ZITADEL統合、ロールベースアクセス制御

既存パターンの保持:

  • Next.js 15 App Routerのファイルベースルーティング(app/ディレクトリ)
  • Spindle UIコンポーネントライブラリ
  • Tailwind CSSスタイリング
  • Supabaseデータベーススキーマ

新規コンポーネントの根拠:

  • Domain層: 外部依存のないビジネスロジックのカプセル化
  • Application層: ユースケース駆動の開発と依存性逆転の実現
  • Infrastructure層: 外部サービスとの統合を抽象化し、テスト可能性を向上
  • Presentation層の分離: UIロジックとビジネスロジックの明確な分離

Steering準拠:

  • TypeScript strict mode有効(Type Safety)
  • Clean Architectureへの移行(tech.mdで明記)
  • 既存の技術スタック保持(Next.js 15, Supabase, ZITADEL)
  • ドメイン駆動設計の原則に基づいたレイヤー構造(structure.md)

技術スタック

レイヤー選択/バージョン本機能での役割備考
LanguageTypeScript 5.6+全レイヤーで型安全性を確保strict mode有効、any型禁止
FrameworkNext.js 15 (App Router)プレゼンテーション層のフレームワークServer Components/Client Components、Server Actions
RuntimeNode.js 18+サーバーサイド実行環境Edge Functionsサポート
DatabaseSupabase (PostgreSQL)データ永続化RLS設定済み、型自動生成
ORM/Client@supabase/supabase-jsインフラストラクチャ層でのデータアクセスリポジトリパターン実装の基盤
AuthenticationZITADEL via NextAuth.js 4.24認証・認可OIDC統合、ロールベース制御
Dependency Injection軽量ファクトリーパターンアプリケーション層とインフラ層の接続ioctopus風のインターフェースバインディング
StylingTailwind CSS 3.4UIスタイリング既存スタイル保持
UI Components@openameba/spindle-ui 3.1.4UIコンポーネントライブラリ既存コンポーネント保持
TestingJest または Vitest(段階7で決定)ユニット/統合テストNext.js 15互換性を考慮

技術選択の根拠:

  • 軽量DIパターン: reflect-metadata不要でNext.js Server Componentsと互換性が高い(調査により実証)
  • Supabase継続: トランザクション処理はPostgreSQL関数+RPC経由で実現可能(公式ガイド
  • 既存スタック保持: データベーススキーマ、認証、UIコンポーネントは再利用可能な資産

詳細な調査結果はresearch.mdを参照。

システムフロー

メンバープロフィール取得フロー

sequenceDiagram
    participant User as ユーザー
    participant Page as Page Component<br/>(Server)
    participant Action as Server Action
    participant UseCase as GetMemberProfile<br/>UseCase
    participant Repo as IMemberRepository<br/>(Port)
    participant Impl as SupabaseMember<br/>Repository
    participant DB as Supabase DB

    User->>Page: ページアクセス
    Page->>Action: getMemberProfile(id)
    Action->>UseCase: execute(id)
    UseCase->>Repo: findById(id)
    Repo->>Impl: findById(id)
    Impl->>DB: SELECT * FROM members
    DB-->>Impl: Row data
    Impl->>Impl: mapToEntity(row)
    Impl-->>Repo: Member entity
    Repo-->>UseCase: Member entity
    UseCase->>UseCase: ビジネスルール適用
    UseCase-->>Action: MemberDTO
    Action-->>Page: MemberDTO
    Page->>Page: UIレンダリング
    Page-->>User: プロフィール表示

フロー決定事項:

  • Server ComponentsがデフォルトでServer Actionsを呼び出す
  • UseCaseがビジネスロジックを集約
  • リポジトリがDB型→ドメインエンティティへの変換を担当
  • DTOでレイヤー間のデータ転送を実施

イベント参加登録フロー(トランザクション)

sequenceDiagram
    participant User as ユーザー
    participant Client as Client Component
    participant Action as Server Action
    participant UseCase as RegisterForEvent<br/>UseCase
    participant Repo as IEventRepository<br/>(Port)
    participant Impl as SupabaseEvent<br/>Repository
    participant DB as Supabase<br/>(RPC Function)

    User->>Client: 参加ボタンクリック
    Client->>Action: registerForEvent(memberId, eventId)
    Action->>UseCase: execute({memberId, eventId})
    UseCase->>UseCase: ビジネスルール検証<br/>(定員チェック等)
    UseCase->>Repo: registerMember(memberId, eventId)
    Repo->>Impl: registerMember(memberId, eventId)
    Impl->>DB: rpc('register_for_event',<br/>{p_member_id, p_event_id})
    Note over DB: トランザクション内:<br/>1. participations INSERT<br/>2. events UPDATE<br/>3. COMMIT
    DB-->>Impl: Success/Error
    Impl-->>Repo: Result
    Repo-->>UseCase: Result
    UseCase-->>Action: DTO or Error
    Action-->>Client: Response
    Client->>Client: UI更新
    Client-->>User: 登録完了/エラー表示

フロー決定事項:

  • トランザクション処理はPostgreSQL関数をRPC経由で呼び出す(Supabase公式パターン
  • PostgRESTが自動的にrpc()をトランザクションでラップ
  • ビジネスルール検証はUseCaseで実施(定員チェック等)
  • エラーハンドリングはレイヤー間で標準化されたResult型を使用

要件トレーサビリティ

要件概要コンポーネントインターフェースフロー
1.1src/ディレクトリ作成ディレクトリ構造--
1.2domain/等4層作成Domain, Application, Infrastructure, Presentation--
1.3機能別サブディレクトリentities/, use-cases/, repositories/--
1.4app/ディレクトリ保持Pages (app/)--
1.5components/保持UI ComponentsBaseUIProps-
1.6lib/,types/移行全レイヤーに分散--
1.7tsconfig.jsonパスエイリアス---
2.1エンティティ定義Member, Event, TimetableEntity interfaces-
2.2外部依存なし実装Domain層全体--
2.3値オブジェクトEmail, StudentId, EventCapacityValueObject interfaces-
2.4イミュータビリティ値オブジェクト--
2.5ドメインサービスGradeCalculator(必要時)DomainService interfaces-
2.6レイヤー依存ルール依存性注入メカニズム--
2.7バリデーション実行Entity constructor/methods--
3.1ユースケースクラスGetMemberProfile, RegisterForEvent等IUseCaseプロフィール取得、イベント登録
3.2execute()メソッド全ユースケースIUseCase.execute()-
3.3ポートインターフェースIMemberRepository, IEventRepository等Repository interfaces-
3.4DTO定義MemberDTO, EventDTO等DTO interfaces全フロー
3.5Domain層のみ依存Application層--
3.6ポート経由呼び出しユースケース→リポジトリ-全フロー
3.7エラースローユースケースDomainError, AppError-
3.8トランザクション境界ユースケース-イベント登録
4.1リポジトリ実装SupabaseMemberRepository等IMemberRepository等全フロー
4.2ポート実装全リポジトリ--
4.3SupabaseクライアントDatabaseClient--
4.4ZITADEL認証AuthProviderIAuthService-
4.5型変換ロジックデータマッパー--
4.6DB型→ドメイン変換mapToEntity()-プロフィール取得
4.7エラー変換リポジトリ--
4.8外部API連携(該当なし)--
4.9依存性注入DIContainer--
5.1app/保持Pages--
5.2components/保持UI Components--
5.3サーバーコンポーネントPage components-プロフィール取得
5.4クライアントコンポーネントInteractive UI-イベント登録
5.5ユースケース通信Server Actions-全フロー
5.6直接呼び出し禁止アーキテクチャルール--
5.7ユースケース呼び出しServer Actions-全フロー
5.8エラー表示Error UI ComponentsErrorDTO全フロー
5.9Server Actions実装Server Actions-全フロー
6.1-6.7依存性ルール全レイヤー--
7.1-7.9既存機能保持全機能--
8.1-8.8テスタビリティテストフレームワーク、モック--
9.1-9.8マイグレーション7段階計画--
10.1-10.7ドキュメントREADMEs, ガイド--

コンポーネントとインターフェース

コンポーネント概要

コンポーネントドメイン/レイヤー目的要件カバレッジ主要依存関係 (優先度)契約
MemberDomain/Entitiesメンバービジネスロジック2.1, 2.2, 2.7ValueObjects (P0)State
Email, StudentIdDomain/ValueObjects値オブジェクト2.3, 2.4-State
IMemberRepositoryApplication/Portsリポジトリインターフェース3.3Member (P0)Service
GetMemberProfileApplication/UseCasesプロフィール取得ユースケース3.1, 3.2, 3.6IMemberRepository (P0), Member (P0)Service
RegisterForEventApplication/UseCasesイベント登録ユースケース3.1, 3.2, 3.8IEventRepository (P0), Event (P0)Service
MemberDTOApplication/DTOsデータ転送オブジェクト3.4-State
SupabaseMemberRepositoryInfrastructure/Repositoriesリポジトリ実装4.1, 4.2, 4.6Supabase Client (P0), IMemberRepository (P0)Service
DatabaseClientInfrastructure/DatabaseSupabaseクライアント4.3@supabase/supabase-js (P0)Service
AuthProviderInfrastructure/AuthZITADEL認証プロバイダー4.4NextAuth.js (P0), ZITADEL (P0)Service
DIContainerInfrastructure/DI依存性注入コンテナ4.9-Service
MemberProfilePagePresentation/Pagesメンバープロフィールページ5.1, 5.3GetMemberProfile (P0), MemberDTO (P0)-
EventRegistrationButtonPresentation/Componentsイベント登録ボタン5.2, 5.4RegisterForEvent (P0)-
Server ActionsPresentation/ActionsServer Actions5.5, 5.7, 5.9UseCases (P0)API

ドメイン層 (Domain Layer)

Member Entity

フィールド詳細
目的メンバーのビジネスロジックとルールをカプセル化
要件2.1, 2.2, 2.7
オーナー/レビュアー開発チーム

責務と制約

  • メンバーの状態管理とバリデーション
  • 学年計算ロジック(入学年度から自動計算)
  • ステータス有効性チェック(24時間限定)
  • 在籍フラグ管理
  • ドメイン境界: 単一のメンバーアグリゲート、他のエンティティに依存しない

依存関係

  • Outbound: Email (値オブジェクト) — メールアドレス検証 (P0)
  • Outbound: StudentId (値オブジェクト) — 学籍番号検証 (P0)

契約: State [x]

State Management

状態モデル:

interface Member {
  readonly id: string;
  readonly name: string;
  readonly email: Email;
  readonly studentId: StudentId;
  readonly enrollmentYear: number;
  readonly isActive: boolean;
  readonly status?: {
    readonly text: string;
    readonly expiresAt: Date;
  };
  readonly skills: readonly string[];
  readonly interests: readonly string[];
  readonly createdAt: Date;
  readonly updatedAt: Date;

  // ビジネスロジックメソッド
  calculateGrade(currentYear: number, currentMonth: number): number;
  isStatusValid(): boolean;
  updateStatus(text: string): Member;
  deactivate(): Member;
}

永続化と整合性:

  • イミュータブル: すべてのプロパティはreadonlyであり、更新は新しいインスタンスを返す
  • 整合性: コンストラクタでバリデーションを実施し、不正な状態を防ぐ

同時実行戦略:

  • エンティティ自体は状態を持たない(純粋関数型アプローチ)
  • 同時実行制御はリポジトリ層で実施(楽観的ロック等)

実装ノート

  • 統合: types/index.tsの既存ビジネスロジック(calculateGrade, isStatusValid)を移行
  • バリデーション: コンストラクタでEmail、StudentIdの値オブジェクトを使用した検証
  • リスク: イミュータブル実装によるパフォーマンス影響は軽微(調査結果より)

Email, StudentId (値オブジェクト)

フィールド詳細
目的ビジネスルールを持つ値のカプセル化とバリデーション
要件2.3, 2.4

責務と制約

  • 値のバリデーションと不変性の保証
  • ビジネスルールの実装(例: メールアドレス形式、学籍番号形式)
  • 等価性比較

契約: State [x]

State Management

Emailモデル:

interface Email {
  readonly value: string;

  // ファクトリーメソッド
  static create(value: string): Result<Email, ValidationError>;

  // 等価性
  equals(other: Email): boolean;
}

StudentIdモデル:

interface StudentId {
  readonly value: string;

  static create(value: string): Result<StudentId, ValidationError>;
  equals(other: StudentId): boolean;
}

永続化と整合性:

  • イミュータブル: 生成後は変更不可
  • バリデーション: ファクトリーメソッドで生成時に検証

実装ノート

  • バリデーション: 正規表現でメールアドレス形式、学籍番号形式を検証
  • リスク: バリデーションロジックの複雑性は低い

アプリケーション層 (Application Layer)

IMemberRepository (ポートインターフェース)

フィールド詳細
目的メンバーリポジトリの抽象化インターフェース
要件3.3

責務と制約

  • メンバーエンティティのCRUD操作インターフェースを定義
  • トランザクション境界なし(単一エンティティ操作)
  • ドメイン境界: Memberアグリゲート

依存関係

  • Inbound: GetMemberProfile UseCase — プロフィール取得 (P0)
  • Inbound: UpdateMemberProfile UseCase — プロフィール更新 (P0)
  • Outbound: Member Entity — ビジネスロジック (P0)

契約: Service [x]

Service Interface
interface IMemberRepository {
  findById(id: string): Promise<Result<Member | null, RepositoryError>>;
  findAll(params: QueryParams): Promise<Result<Member[], RepositoryError>>;
  findByEmail(email: Email): Promise<Result<Member | null, RepositoryError>>;
  create(member: Member): Promise<Result<Member, RepositoryError>>;
  update(id: string, member: Partial<Member>): Promise<Result<Member, RepositoryError>>;
  delete(id: string): Promise<Result<void, RepositoryError>>;
}

interface QueryParams {
  limit?: number;
  offset?: number;
  filters?: {
    isActive?: boolean;
    enrollmentYear?: number;
  };
}

事前条件:

  • findById, update, delete: idは有効なUUID形式
  • create: memberは有効なMemberエンティティ(バリデーション済み)

事後条件:

  • findById: 存在する場合はMemberエンティティ、存在しない場合はnull
  • create, update: 成功時は保存されたMemberエンティティを返す
  • delete: 成功時はvoid、エンティティは削除される

不変条件:

  • すべてのメソッドはResult型を返し、エラーハンドリングを明示的に

実装ノート

  • 統合: Infrastructure層のSupabaseMemberRepositoryが実装
  • バリデーション: エンティティレベルで実施済み、リポジトリは永続化のみ
  • リスク: Supabaseクエリビルダーとの型安全性を確保(TypeScript型生成)

IEventRepository (ポートインターフェース)

フィールド詳細
目的イベントリポジトリの抽象化インターフェース
要件3.3

責務と制約

  • イベントエンティティのCRUD操作インターフェース
  • イベント参加登録(トランザクション処理)
  • ドメイン境界: Eventアグリゲート、Participationアグリゲート

依存関係

  • Inbound: RegisterForEvent UseCase — イベント登録 (P0)
  • Inbound: GetEventList UseCase — イベント一覧取得 (P0)
  • Outbound: Event Entity — ビジネスロジック (P0)

契約: Service [x]

Service Interface
interface IEventRepository {
  findById(id: string): Promise<Result<Event | null, RepositoryError>>;
  findAll(params: EventQueryParams): Promise<Result<Event[], RepositoryError>>;
  create(event: Event): Promise<Result<Event, RepositoryError>>;
  update(id: string, event: Partial<Event>): Promise<Result<Event, RepositoryError>>;
  delete(id: string): Promise<Result<void, RepositoryError>>;

  // トランザクション処理(RPC経由)
  registerMember(memberId: string, eventId: string): Promise<Result<void, RepositoryError>>;
  unregisterMember(memberId: string, eventId: string): Promise<Result<void, RepositoryError>>;

  // 参加者取得
  getParticipants(eventId: string): Promise<Result<Member[], RepositoryError>>;
}

interface EventQueryParams {
  limit?: number;
  offset?: number;
  filters?: {
    startDateFrom?: Date;
    startDateTo?: Date;
  };
}

事前条件:

  • registerMember, unregisterMember: memberId, eventIdは有効なUUID
  • registerMember: イベントの定員に空きがある(ビジネスロジックで事前チェック)

事後条件:

  • registerMember: participationsテーブルにレコード追加、eventsのparticipant_count増加(トランザクション)
  • unregisterMember: participationsテーブルからレコード削除、eventsのparticipant_count減少(トランザクション)

不変条件:

  • トランザクション処理の原子性を保証(RPC経由でPostgreSQL関数実行)

実装ノート

  • 統合: Infrastructure層のSupabaseEventRepositoryが実装
  • バリデーション: PostgreSQL関数内でビジネスルール検証(定員チェック等)
  • リスク: RPC関数の型安全性を確保(TypeScript型生成とテスト)

GetMemberProfile UseCase

フィールド詳細
目的メンバープロフィール取得ユースケース
要件3.1, 3.2, 3.6

責務と制約

  • メンバープロフィールの取得とDTOへの変換
  • ビジネスルール適用(例: 学年計算、ステータス有効性チェック)
  • トランザクション境界: なし(読み取り専用)
  • ドメイン境界: Memberアグリゲート

依存関係

  • Inbound: Server Actions — プレゼンテーション層からの呼び出し (P0)
  • Outbound: IMemberRepository — データ取得 (P0)
  • Outbound: Member Entity — ビジネスロジック (P0)

契約: Service [x]

Service Interface
interface IUseCase<TInput, TOutput> {
  execute(input: TInput): Promise<Result<TOutput, UseCaseError>>;
}

interface GetMemberProfileUseCase extends IUseCase<GetMemberProfileInput, MemberDTO> {
  execute(input: GetMemberProfileInput): Promise<Result<MemberDTO, UseCaseError>>;
}

interface GetMemberProfileInput {
  memberId: string;
  currentYear: number;
  currentMonth: number;
}

事前条件:

  • memberIdは有効なUUID形式
  • currentYear, currentMonthは有効な日付

事後条件:

  • 成功時: MemberDTOを返す(学年計算済み、ステータス有効性チェック済み)
  • 失敗時: MemberNotFoundError または RepositoryError

不変条件:

  • ビジネスロジックは常にドメインエンティティ内で実行
  • DTOはシリアライズ可能な型のみ(Date→ISO文字列等)

実装ノート

  • 統合: Server Actionsから呼び出され、リポジトリを通じてデータ取得
  • バリデーション: エンティティのcalculateGrade(), isStatusValid()を使用
  • リスク: DTOシリアライゼーションでDate型の扱いに注意

RegisterForEvent UseCase

フィールド詳細
目的イベント参加登録ユースケース
要件3.1, 3.2, 3.8

責務と制約

  • イベント参加登録とビジネスルール検証
  • トランザクション境界: 定義あり(participations INSERT + events UPDATE)
  • ドメイン境界: Event, Member, Participationアグリゲート

依存関係

  • Inbound: Server Actions — プレゼンテーション層からの呼び出し (P0)
  • Outbound: IEventRepository — イベント登録 (P0)
  • Outbound: IMemberRepository — メンバー取得 (P1)
  • Outbound: Event Entity — ビジネスロジック (P0)

契約: Service [x]

Service Interface
interface RegisterForEventUseCase extends IUseCase<RegisterForEventInput, void> {
  execute(input: RegisterForEventInput): Promise<Result<void, UseCaseError>>;
}

interface RegisterForEventInput {
  memberId: string;
  eventId: string;
}

事前条件:

  • memberId, eventIdは有効なUUID
  • メンバーが存在し、アクティブである
  • イベントが存在し、定員に空きがある

事後条件:

  • 成功時: participationsテーブルにレコード追加、eventsのparticipant_count増加
  • 失敗時: EventFullError, MemberNotFoundError, EventNotFoundError

不変条件:

  • トランザクション処理の原子性を保証(RPC経由)
  • ビジネスルール違反時はロールバック

実装ノート

  • 統合: IEventRepository.registerMember()を呼び出し、RPC関数実行
  • バリデーション: PostgreSQL関数内で定員チェック、重複チェック
  • リスク: トランザクション失敗時のエラーハンドリングとユーザーへのフィードバック

MemberDTO, EventDTO (データ転送オブジェクト)

フィールド詳細
目的レイヤー間のデータ転送
要件3.4

責務と制約

  • シリアライズ可能なプレーンオブジェクト
  • ビジネスロジックを持たない
  • Server ComponentsとClient Components間のデータ転送

契約: State [x]

State Management
interface MemberDTO {
  id: string;
  name: string;
  email: string; // Email値オブジェクトから文字列に変換
  studentId: string; // StudentId値オブジェクトから文字列に変換
  enrollmentYear: number;
  grade: number; // 計算済み
  isActive: boolean;
  status?: {
    text: string;
    expiresAt: string; // Date → ISO文字列
    isValid: boolean; // 計算済み
  };
  skills: string[];
  interests: string[];
  createdAt: string; // Date → ISO文字列
  updatedAt: string; // Date → ISO文字列
}

interface EventDTO {
  id: string;
  title: string;
  description: string;
  startDate: string; // Date → ISO文字列
  endDate: string; // Date → ISO文字列
  capacity: number;
  participantCount: number;
  location: string;
  createdAt: string; // Date → ISO文字列
}

永続化と整合性:

  • DTOは一時的なデータ転送用のみ、永続化しない
  • ドメインエンティティ→DTO、DTO→ドメインエンティティの変換はユースケース層で実施

実装ノート

  • 統合: Server ActionsでDTOをJSON形式でシリアライズ
  • バリデーション: DTOからエンティティへの変換時にバリデーション再実施
  • リスク: Date型のシリアライゼーション(ISO文字列に統一)

インフラストラクチャ層 (Infrastructure Layer)

SupabaseMemberRepository (リポジトリ実装)

フィールド詳細
目的IMemberRepositoryの具体的実装
要件4.1, 4.2, 4.6

責務と制約

  • Supabaseクライアントを使用したCRUD操作
  • DB型(Database[‘public’][‘Tables’][‘members’][‘Row’])→Memberエンティティの変換
  • エラーハンドリングと標準化されたエラー型への変換
  • ドメイン境界: Memberアグリゲート

依存関係

  • Inbound: GetMemberProfile UseCase — データ取得 (P0)
  • Outbound: Supabase Client — データベースアクセス (P0)
  • Outbound: Member Entity — ドメインモデル (P0)
  • External: @supabase/supabase-js — Supabaseクライアントライブラリ (P0)

調査結果: Supabaseの型自動生成機能により、型安全性が確保される(公式ドキュメント

契約: Service [x]

Service Interface
class SupabaseMemberRepository implements IMemberRepository {
  constructor(private readonly client: SupabaseClient<Database>) {}

  async findById(id: string): Promise<Result<Member | null, RepositoryError>> {
    // 実装詳細は省略(インターフェース遵守)
  }

  async findAll(params: QueryParams): Promise<Result<Member[], RepositoryError>> {
    // 実装詳細は省略
  }

  async create(member: Member): Promise<Result<Member, RepositoryError>> {
    // 実装詳細は省略
  }

  // データマッパー(private)
  private mapToEntity(row: Database['public']['Tables']['members']['Row']): Member {
    // DB型 → ドメインエンティティへの変換
  }

  private mapToRow(member: Member): Database['public']['Tables']['members']['Insert'] {
    // ドメインエンティティ → DB型への変換
  }
}

事前条件:

  • Supabase clientが初期化済み
  • データベーススキーマがマイグレーション済み

事後条件:

  • すべてのメソッドは標準化されたResult型を返す
  • データベースエラーはRepositoryErrorに変換

不変条件:

  • データマッパーは純粋関数であり、副作用を持たない
  • RLS(Row Level Security)ポリシーを尊重

実装ノート

  • 統合: lib/supabase/server.tsのSupabaseクライアントを使用
  • バリデーション: エンティティコンストラクタで実施済み、リポジトリは永続化のみ
  • リスク: RLS設定によるクエリ失敗を適切にハンドリング

SupabaseEventRepository (リポジトリ実装)

フィールド詳細
目的IEventRepositoryの具体的実装
要件4.1, 4.2, 4.6

責務と制約

  • Supabaseクライアントを使用したCRUD操作
  • RPC経由でのトランザクション処理(registerMember, unregisterMember)
  • DB型→Eventエンティティの変換
  • ドメイン境界: Event, Participationアグリゲート

依存関係

  • Inbound: RegisterForEvent UseCase — イベント登録 (P0)
  • Outbound: Supabase Client — データベースアクセス、RPC (P0)
  • Outbound: Event Entity — ドメインモデル (P0)
  • External: @supabase/supabase-js — Supabaseクライアントライブラリ (P0)

調査結果: RPC関数はPostgRESTによって自動的にトランザクションでラップされる(調査結果

契約: Service [x], Batch [x]

Service Interface
class SupabaseEventRepository implements IEventRepository {
  constructor(private readonly client: SupabaseClient<Database>) {}

  async registerMember(memberId: string, eventId: string): Promise<Result<void, RepositoryError>> {
    const { data, error } = await this.client.rpc('register_for_event', {
      p_member_id: memberId,
      p_event_id: eventId
    });

    if (error) {
      return Result.err(this.mapError(error));
    }

    return Result.ok(undefined);
  }

  // 他のメソッドは省略
}
Batch / Job Contract

トリガー: RegisterForEvent UseCaseからの呼び出し

入力/バリデーション:

  • p_member_id: UUID形式
  • p_event_id: UUID形式
  • PostgreSQL関数内でビジネスルール検証(定員チェック、重複チェック)

出力/宛先:

  • 成功時: void(データベースに永続化)
  • 失敗時: RepositoryError(EventFull, AlreadyRegistered等)

冪等性と回復:

  • PostgreSQL関数内でトランザクション処理(原子性保証)
  • 重複登録はUNIQUE制約でエラー
  • リトライはアプリケーション層で実施(RPC呼び出しのリトライ)

実装ノート

  • 統合: PostgreSQL関数register_for_eventをRPC経由で呼び出し
  • バリデーション: PostgreSQL関数内でビジネスルール実施
  • リスク: RPC関数の型安全性(TypeScript型生成とテスト)

DatabaseClient (Supabaseクライアント)

フィールド詳細
目的Supabaseクライアントの初期化と提供
要件4.3

責務と制約

  • Server Components用のSupabaseクライアント初期化
  • 環境変数からの設定読み込み
  • RLS(Row Level Security)統合

依存関係

  • Inbound: 全リポジトリ実装 — データベースアクセス (P0)
  • External: @supabase/ssr — Server-side rendering support (P0)
  • External: @supabase/supabase-js — Supabaseクライアント (P0)

契約: Service [x]

Service Interface
interface IDatabaseClient {
  getServerClient(): SupabaseClient<Database>;
  getAdminClient(): SupabaseClient<Database>;
}

class DatabaseClient implements IDatabaseClient {
  getServerClient(): SupabaseClient<Database> {
    // lib/supabase/server.tsの既存実装を活用
  }

  getAdminClient(): SupabaseClient<Database> {
    // lib/supabase/admin.tsの既存実装を活用
  }
}

事前条件:

  • 環境変数(NEXT_PUBLIC_SUPABASE_URL, NEXT_PUBLIC_SUPABASE_ANON_KEY, SUPABASE_SERVICE_ROLE_KEY)が設定済み

事後条件:

  • 初期化されたSupabaseClientインスタンスを返す
  • RLSポリシーが適用される(ServerClient)またはバイパスされる(AdminClient)

実装ノート

  • 統合: 既存のlib/supabase/配下のクライアントを活用
  • バリデーション: 環境変数の検証(起動時)
  • リスク: AdminClientの誤用防止(使用箇所を限定)

AuthProvider (ZITADEL認証プロバイダー)

フィールド詳細
目的ZITADEL認証とNextAuth.jsの統合
要件4.4

責務と制約

  • ZITADEL OIDCプロバイダーの設定
  • NextAuth.jsコールバック設定
  • ロールベースアクセス制御(adminロール)
  • セッション管理

依存関係

  • Inbound: Server Components, Middleware — 認証状態取得 (P0)
  • External: NextAuth.js 4.24 — 認証フレームワーク (P0)
  • External: ZITADEL — 認証プロバイダー (P0)

契約: Service [x]

Service Interface
interface IAuthService {
  getCurrentUser(): Promise<User | null>;
  hasRole(role: string): Promise<boolean>;
  signIn(redirectUrl?: string): Promise<void>;
  signOut(redirectUrl?: string): Promise<void>;
}

class AuthProvider implements IAuthService {
  async getCurrentUser(): Promise<User | null> {
    // NextAuth.jsのgetServerSession()を使用
  }

  async hasRole(role: string): Promise<boolean> {
    // JWTからロール情報を抽出
  }
}

事前条件:

  • ZITADEL設定済み(Client ID, Client Secret, Issuer URL)
  • NextAuth.js設定完了

事後条件:

  • 認証済みユーザーのセッション情報を返す
  • ロール情報を含むJWTトークン

実装ノート

  • 統合: 既存のlib/auth-options.tsを活用
  • バリデーション: JWTトークンの検証(NextAuth.jsが自動実施)
  • リスク: ZITADELのダウンタイムやレート制限への対応

DIContainer (依存性注入コンテナ)

フィールド詳細
目的軽量DIメカニズムの提供
要件4.9

責務と制約

  • インターフェースベースの依存性登録
  • 型安全な依存性解決
  • ドメインモジュールによるファクトリーパターン

依存関係

  • Inbound: 全ユースケース — 依存性解決 (P0)
  • Inbound: Server Actions — 依存性注入 (P0)

契約: Service [x]

Service Interface
type DIKey<T> = symbol | string;

interface IDIContainer {
  register<T>(key: DIKey<T>, implementation: new (...args: any[]) => T): void;
  registerSingleton<T>(key: DIKey<T>, implementation: new (...args: any[]) => T): void;
  resolve<T>(key: DIKey<T>): T;
}

class DIContainer implements IDIContainer {
  private registry: Map<DIKey<any>, any> = new Map();
  private singletons: Map<DIKey<any>, any> = new Map();

  register<T>(key: DIKey<T>, implementation: new (...args: any[]) => T): void {
    this.registry.set(key, implementation);
  }

  registerSingleton<T>(key: DIKey<T>, implementation: new (...args: any[]) => T): void {
    if (!this.singletons.has(key)) {
      const instance = new implementation();
      this.singletons.set(key, instance);
    }
  }

  resolve<T>(key: DIKey<T>): T {
    if (this.singletons.has(key)) {
      return this.singletons.get(key);
    }

    const Implementation = this.registry.get(key);
    if (!Implementation) {
      throw new Error(`No implementation registered for key: ${String(key)}`);
    }

    return new Implementation();
  }
}

// ドメインモジュールファクトリー
function memberModule(di: IDIContainer): void {
  const MemberRepoKey = Symbol('IMemberRepository');
  di.registerSingleton(MemberRepoKey, SupabaseMemberRepository);
}

function eventModule(di: IDIContainer): void {
  const EventRepoKey = Symbol('IEventRepository');
  di.registerSingleton(EventRepoKey, SupabaseEventRepository);
}

事前条件:

  • すべての依存関係が登録済み(アプリケーション起動時)

事後条件:

  • 型安全な依存性解決
  • シングルトンインスタンスの再利用

実装ノート

  • 統合: Server Actions内でDIContainerを初期化し、ユースケースに注入
  • バリデーション: キーの重複登録を防止
  • リスク: 循環依存の検出と防止

調査結果: ioctopus風の軽量DIパターンはNext.js Server Componentsと互換性が高い(調査記事


プレゼンテーション層 (Presentation Layer)

MemberProfilePage (Server Component)

フィールド詳細
目的メンバープロフィールページのレンダリング
要件5.1, 5.3

責務と制約

  • Server Componentとしてサーバーサイドでレンダリング
  • GetMemberProfile UseCaseを呼び出してデータ取得
  • UIコンポーネントへのDTOの受け渡し

依存関係

  • Inbound: ユーザーアクセス — ページ表示 (P0)
  • Outbound: GetMemberProfile UseCase — データ取得 (P0)
  • Outbound: MemberProfileCard Component — UI表示 (P0)

実装ノート

  • 統合: app/members/[id]/page.tsxで実装
  • バリデーション: UseCaseからのエラーをエラーページで表示
  • リスク: Server Componentsでのエラーハンドリング(Next.js 15のerror.tsxを活用)

調査結果: Server Componentsはデフォルトでasync/awaitをサポート(Next.js公式ドキュメント


EventRegistrationButton (Client Component)

フィールド詳細
目的イベント参加登録ボタン
要件5.2, 5.4

責務と制約

  • Client Componentとしてインタラクティブ性を提供
  • Server Actionを呼び出してイベント登録
  • ローディング状態とエラー表示

依存関係

  • Inbound: ユーザークリック — イベント登録 (P0)
  • Outbound: registerForEvent Server Action — データ送信 (P0)

契約: State [x]

State Management
interface EventRegistrationButtonProps {
  eventId: string;
  memberId: string;
  isRegistered: boolean;
}

interface EventRegistrationButtonState {
  isLoading: boolean;
  error: string | null;
}

実装ノート

  • 統合: components/events/EventRegistrationButton.tsxで実装
  • バリデーション: Server Actionからのエラーをユーザーに表示
  • リスク: Server Action呼び出し時のネットワークエラーハンドリング

Server Actions

フィールド詳細
目的プレゼンテーション層とアプリケーション層の橋渡し
要件5.5, 5.7, 5.9

責務と制約

  • use serverディレクティブでServer Actionsを定義
  • UseCaseをDIContainerから解決して実行
  • Result型からHTTPレスポンスまたはDTOへの変換

依存関係

  • Inbound: Server Components, Client Components — データ送受信 (P0)
  • Outbound: UseCases — ビジネスロジック実行 (P0)
  • Outbound: DIContainer — 依存性解決 (P0)

契約: API [x]

API Contract
MethodEndpointRequestResponseErrors
POSTServer Action: getMemberProfile{ memberId: string }MemberDTOMemberNotFound, RepositoryError
POSTServer Action: registerForEvent{ memberId: string, eventId: string }voidEventFull, MemberNotFound, RepositoryError
POSTServer Action: updateMemberProfile{ memberId: string, data: Partial }MemberDTOValidationError, RepositoryError

実装例:

'use server';

export async function getMemberProfile(memberId: string): Promise<MemberDTO> {
  const di = initializeDI(); // DIContainer初期化
  const useCase = di.resolve<GetMemberProfileUseCase>(GetMemberProfileUseCaseKey);

  const result = await useCase.execute({
    memberId,
    currentYear: new Date().getFullYear(),
    currentMonth: new Date().getMonth() + 1
  });

  if (result.isErr()) {
    throw new Error(result.error.message); // Next.js 15がエラーをキャッチ
  }

  return result.value;
}

export async function registerForEvent(memberId: string, eventId: string): Promise<void> {
  const di = initializeDI();
  const useCase = di.resolve<RegisterForEventUseCase>(RegisterForEventUseCaseKey);

  const result = await useCase.execute({ memberId, eventId });

  if (result.isErr()) {
    throw new Error(result.error.message);
  }
}

実装ノート

  • 統合: app/actions/配下にドメイン別にファイル配置(member-actions.ts, event-actions.ts)
  • バリデーション: UseCaseからのエラーをNext.js 15のエラーハンドリングに委譲
  • リスク: Server Actionsのシリアライゼーション制約(DTOは常にシリアライズ可能)

調査結果: Server ActionsはNext.js 15の推奨パターン(公式ドキュメント


データモデル

ドメインモデル

アグリゲートとトランザクション境界

erDiagram
    MEMBER ||--o{ PARTICIPATION : registers
    EVENT ||--o{ PARTICIPATION : has
    MEMBER ||--o{ MEMBER_TAG : has
    TAG ||--o{ MEMBER_TAG : tagged
    MEMBER ||--o{ TIMETABLE : has

    MEMBER {
        uuid id PK
        string name
        string email
        string student_id
        int enrollment_year
        boolean is_active
        string status_text
        timestamp status_expires_at
        timestamp created_at
        timestamp updated_at
    }

    EVENT {
        uuid id PK
        string title
        text description
        timestamp start_date
        timestamp end_date
        int capacity
        int participant_count
        string location
        timestamp created_at
    }

    PARTICIPATION {
        uuid id PK
        uuid member_id FK
        uuid event_id FK
        timestamp registered_at
    }

    TAG {
        uuid id PK
        string name
        string category
    }

    MEMBER_TAG {
        uuid member_id FK
        uuid tag_id FK
    }

    TIMETABLE {
        uuid id PK
        uuid member_id FK
        int day_of_week
        int period
        string course_name
        string classroom
    }

エンティティ、値オブジェクト、ドメインイベント

  • Memberアグリゲート(ルート): id, name, email (値オブジェクト), studentId (値オブジェクト), enrollmentYear, isActive, status, skills, interests
  • Eventアグリゲート(ルート): id, title, description, startDate, endDate, capacity, participantCount, location
  • Participationエンティティ: id, memberId, eventId, registeredAt(EventアグリゲートとMemberアグリゲートの関連)
  • Timetableエンティティ: id, memberId, dayOfWeek, period, courseName, classroom(Memberアグリゲート配下)
  • 値オブジェクト: Email, StudentId, EventCapacity(バリデーションロジックを内包)

ビジネスルールと不変条件

  • Member:

    • emailはEmail値オブジェクトで検証済み
    • studentIdはStudentId値オブジェクトで検証済み
    • statusは24時間で無効化(isStatusValid()メソッド)
    • gradeはenrollmentYearから自動計算(calculateGrade()メソッド)
  • Event:

    • participantCountはcapacityを超えない(PostgreSQL関数で検証)
    • startDateはendDateより前
  • Participation:

    • member, eventの組み合わせは一意(UNIQUE制約)

論理データモデル

構造定義

既存のSupabaseスキーマを維持(supabase/migrations/配下):

  • membersテーブル: 主キー(id), UNIQUE(email, student_id), インデックス(enrollment_year, is_active)
  • eventsテーブル: 主キー(id), インデックス(start_date)
  • participationsテーブル: 主キー(id), 外部キー(member_id, event_id), UNIQUE(member_id, event_id)
  • tagsテーブル: 主キー(id), UNIQUE(name, category)
  • member_tagsテーブル: 複合主キー(member_id, tag_id)
  • timetablesテーブル: 主キー(id), 外部キー(member_id), インデックス(member_id)

整合性と完全性

  • トランザクション境界: イベント参加登録(participations INSERT + events UPDATE)はPostgreSQL関数で原子性保証
  • カスケーディングルール: members削除時、participations, member_tags, timetablesをCASCADE削除
  • 時間的側面: created_at, updated_atで監査ログ、status_expires_atで時間制限ステータス

物理データモデル

PostgreSQL(Supabase)

既存のデータベーススキーマを維持:

  • テーブル定義: supabase/migrations/配下のSQLマイグレーションファイル
  • インデックス: enrollment_year, is_active, start_date等にインデックス設定済み
  • 制約: PRIMARY KEY, FOREIGN KEY, UNIQUE, NOT NULL制約設定済み
  • 関数: calculate_grade()関数(入学年度から学年を自動計算)
  • RLS(Row Level Security): 認証済みユーザーのみアクセス可能、adminロールは全権限

パーティショニング戦略

現時点では不要(データ量が小規模)。将来的にeventsテーブルをstart_dateでパーティショニング可能。

データ契約と統合

APIデータ転送

  • リクエスト/レスポンススキーマ: MemberDTO, EventDTO等(TypeScriptインターフェース)
  • バリデーションルール: エンティティコンストラクタで実施
  • シリアライゼーション形式: JSON(Next.js Server Actions)

イベントスキーマ

現時点ではイベント駆動アーキテクチャは不採用。将来的にSupabase Realtimeを活用可能。

クロスサービスデータ管理

  • 分散トランザクションパターン: PostgreSQL関数によるローカルトランザクション
  • データ同期戦略: 同期的なRPC呼び出し
  • 結果整合性: リアルタイム要件なし、即時整合性

エラーハンドリング

エラー戦略

Result型パターン

すべてのレイヤーでResult型を使用し、エラーハンドリングを明示的に:

type Result<T, E = Error> =
  | { isOk: true; value: T; isErr: false; error: never }
  | { isOk: false; value: never; isErr: true; error: E };

class Result {
  static ok<T>(value: T): Result<T, never> {
    return { isOk: true, value, isErr: false, error: undefined as never };
  }

  static err<E>(error: E): Result<never, E> {
    return { isOk: false, value: undefined as never, isErr: true, error };
  }
}

エラーカテゴリとレスポンス

ドメインエラー(ビジネスルール違反)

  • InvalidEmailError: メールアドレス形式不正 → フィールドレベルバリデーションメッセージ
  • InvalidStudentIdError: 学籍番号形式不正 → フィールドレベルバリデーションメッセージ
  • StatusExpiredError: ステータス期限切れ → 警告メッセージとステータス更新促進

アプリケーションエラー(ユースケース実行失敗)

  • MemberNotFoundError: メンバーが存在しない → 404エラーページ
  • EventNotFoundError: イベントが存在しない → 404エラーページ
  • EventFullError: イベント定員超過 → ユーザーに定員超過メッセージ表示
  • AlreadyRegisteredError: 既に登録済み → ユーザーに登録済みメッセージ表示

インフラストラクチャエラー(外部サービス障害)

  • DatabaseConnectionError: データベース接続エラー → 5xxエラーページ、リトライ
  • AuthenticationError: 認証失敗 → ログインページへリダイレクト
  • AuthorizationError: 認可失敗 → 403エラーページ

システムエラー(予期しないエラー)

  • UnexpectedError: 予期しないエラー → 5xxエラーページ、ログ記録

モニタリング

  • エラー追跡: すべてのエラーをログ記録(console.error)、将来的にSentryなどの監視ツール統合
  • ヘルスモニタリング: Supabase接続状態、ZITADEL認証状態を定期的に監視
  • ログ: 構造化ログ(JSON形式)でエラー詳細、スタックトレース、ユーザーコンテキストを記録

テスト戦略

ユニットテスト

ドメイン層

  • MemberエンティティのcalculateGrade()メソッド
  • Memberエンティティのi sStatusValid()メソッド
  • Email値オブジェクトのバリデーション
  • StudentId値オブジェクトのバリデーション
  • Eventエンティティの定員チェックロジック

アプリケーション層

  • GetMemberProfile UseCaseの実行(モックリポジトリを使用)
  • RegisterForEvent UseCaseの実行(モックリポジトリを使用)
  • DTOからエンティティへの変換ロジック

統合テスト

インフラストラクチャ層

  • SupabaseMemberRepositoryのfindById()メソッド(実データベース使用)
  • SupabaseEventRepositoryのregisterMember()メソッド(実データベース、RPC関数)
  • データマッパーの変換ロジック(DB型↔ドメインエンティティ)

プレゼンテーション層

  • Server Actionsの呼び出しとレスポンス
  • Server ComponentsとClient Componentsの統合

E2E/UIテスト

クリティカルユーザーパス

  • メンバープロフィール表示フロー
  • イベント参加登録フロー
  • 管理者によるイベント作成フロー
  • メンバー一覧表示とフィルタリング
  • タイムテーブル表示とフィルタリング

パフォーマンステスト

負荷テスト

  • 同時100ユーザーのイベント参加登録
  • 1000件のメンバー一覧表示
  • タイムテーブルの複雑なフィルタリングクエリ

スケーラビリティテスト

  • Supabaseの接続プール上限テスト
  • Next.js Server Componentsのレンダリング時間計測

マイグレーション戦略

7段階マイグレーション計画

flowchart TB
    Start([開始]) --> Phase1[段階1: 基盤整備<br/>ディレクトリ構造、DI、設定]
    Phase1 --> Phase2[段階2: ドメイン層<br/>エンティティ、値オブジェクト]
    Phase2 --> Phase3[段階3: アプリケーション層<br/>ユースケース、ポート、DTO]
    Phase3 --> Phase4[段階4: インフラストラクチャ層<br/>リポジトリ、データマッパー]
    Phase4 --> Validation1{動作検証}
    Validation1 -->|OK| Phase5[段階5: プレゼンテーション統合<br/>パイロット機能]
    Validation1 -->|NG| Rollback1[ロールバック]
    Phase5 --> Validation2{動作検証}
    Validation2 -->|OK| Phase6[段階6: 全機能移行<br/>残機能の移行]
    Validation2 -->|NG| Rollback2[ロールバック]
    Phase6 --> Validation3{動作検証}
    Validation3 -->|OK| Phase7[段階7: テスト・ドキュメント<br/>ユニット/統合テスト]
    Validation3 -->|NG| Rollback3[ロールバック]
    Phase7 --> Complete([完了])
    Rollback1 --> Phase1
    Rollback2 --> Phase5
    Rollback3 --> Phase6

段階別詳細

段階1: 基盤整備(3日)

  • ディレクトリ作成(src/domain, application, infrastructure, presentation)
  • tsconfig.jsonパスエイリアス設定(@/domain, @/application等)
  • DIContainer実装(軽量ファクトリーパターン)
  • 完了基準: ビルドエラーなし、パスエイリアス動作確認

段階2: ドメイン層(5日)

  • Member, Event, Timetableエンティティ実装
  • Email, StudentId, EventCapacity値オブジェクト実装
  • types/index.tsのビジネスロジック移行
  • 完了基準: ドメインロジックのユニットテストパス

段階3: アプリケーション層(4日)

  • IMemberRepository, IEventRepository, ITimetableRepositoryポートインターフェース定義
  • MemberDTO, EventDTO, TimetableDTO定義
  • GetMemberProfile, RegisterForEventユースケース実装(パイロット)
  • 完了基準: ユースケースのユニットテスト(モックリポジトリ)パス

段階4: インフラストラクチャ層(5日)

  • SupabaseMemberRepository, SupabaseEventRepository実装
  • データマッパー実装(mapToEntity, mapToRow)
  • PostgreSQL関数作成(register_for_event, unregister_from_event)
  • 完了基準: リポジトリの統合テストパス

段階5: プレゼンテーション統合(4日)

  • パイロット機能(メンバー一覧ページ)をユースケース統合
  • Server Actions実装(getMemberProfile, registerForEvent)
  • エラーハンドリング統合
  • 完了基準: パイロット機能の動作確認、既存機能が破壊されていない

段階6: 全機能移行(5日)

  • 残機能の移行(イベント一覧、タイムテーブル、管理画面)
  • モックデータを実データに置き換え
  • 既存のlib/, types/ディレクトリから不要ファイル削除
  • 完了基準: すべての既存機能が新レイヤーで動作

段階7: テストとドキュメント(4日)

  • ユニットテスト完全実装
  • 統合テスト実装
  • E2Eテスト実装(クリティカルパス)
  • アーキテクチャドキュメント作成
  • 開発者オンボーディングガイド作成
  • 完了基準: テストカバレッジ80%以上、ドキュメント完成

ロールバック戦略

  • Gitブランチ戦略: 各段階ごとにブランチ作成(feature/phase-1等)
  • ロールバックトリガー: 重大なバグ、既存機能の破壊、パフォーマンス劣化
  • ロールバック手順: 前段階のブランチにマージ、問題修正後に再実施

検証チェックポイント

各段階で以下を検証:

  • ビルドエラーなし
  • TypeScript型エラーなし
  • 既存機能が破壊されていない
  • 新機能が期待通り動作
  • パフォーマンス劣化なし

セキュリティ考慮事項

脅威モデリング

  • SQLインジェクション: Supabaseクエリビルダーとパラメータ化クエリで防止
  • XSS: Next.jsのデフォルトエスケープ、Spindle UIコンポーネント使用
  • CSRF: Next.js Server ActionsのCSRFトークン自動生成
  • 認証バイパス: ZITADELとNextAuth.jsによる認証、RLSポリシーで二重チェック

認証と認可パターン

  • 認証: ZITADEL OIDC → NextAuth.js → セッション管理
  • 認可: ロールベースアクセス制御(adminロール)、RLSポリシー

データ保護とプライバシー

  • 個人情報: メールアドレス、学籍番号はRLSポリシーで保護
  • ステータス: 24時間で自動無効化
  • パスワード: ZITADELで管理(Portal.Cでは保存しない)

パフォーマンスとスケーラビリティ

目標メトリクス

  • ページロード時間: 初回ロード < 2秒、以降 < 1秒
  • APIレスポンス: メンバー一覧取得 < 500ms、イベント登録 < 1秒
  • 同時接続: 100同時ユーザー対応

スケーリングアプローチ

  • 水平スケーリング: Vercelの自動スケーリング、Supabaseの接続プール
  • 垂直スケーリング: 必要に応じてSupabaseプラン変更

キャッシング戦略

  • Next.js 15キャッシング: Server Componentsの自動キャッシュ
  • Supabaseキャッシング: メンバー一覧など頻繁にアクセスされるデータをNext.js側でキャッシュ
  • 再検証: 1時間ごとに再検証(revalidate: 3600)

サポートリファレンス

調査ソース

詳細な調査結果はresearch.mdを参照。

TypeScript型定義の詳細

詳細な型定義はSupporting Referencesセクションではなく、各コンポーネントのService Interface、State Managementセクションに記載しています。

PostgreSQL関数定義

-- register_for_event: イベント参加登録(トランザクション処理)
CREATE OR REPLACE FUNCTION register_for_event(
  p_member_id UUID,
  p_event_id UUID
)
RETURNS BOOLEAN AS $$
DECLARE
  v_capacity INT;
  v_participant_count INT;
BEGIN
  -- イベント情報取得
  SELECT capacity, participant_count INTO v_capacity, v_participant_count
  FROM events
  WHERE id = p_event_id;

  -- 定員チェック
  IF v_participant_count >= v_capacity THEN
    RAISE EXCEPTION 'Event is full';
  END IF;

  -- 参加登録
  INSERT INTO participations (member_id, event_id, registered_at)
  VALUES (p_member_id, p_event_id, NOW());

  -- 参加者数更新
  UPDATE events
  SET participant_count = participant_count + 1
  WHERE id = p_event_id;

  RETURN TRUE;
EXCEPTION
  WHEN unique_violation THEN
    RAISE EXCEPTION 'Already registered';
  WHEN OTHERS THEN
    RAISE;
END;
$$ LANGUAGE plpgsql SECURITY INVOKER;

-- unregister_from_event: イベント参加解除(トランザクション処理)
CREATE OR REPLACE FUNCTION unregister_from_event(
  p_member_id UUID,
  p_event_id UUID
)
RETURNS BOOLEAN AS $$
BEGIN
  -- 参加解除
  DELETE FROM participations
  WHERE member_id = p_member_id AND event_id = p_event_id;

  -- 参加者数更新
  UPDATE events
  SET participant_count = participant_count - 1
  WHERE id = p_event_id;

  RETURN TRUE;
END;
$$ LANGUAGE plpgsql SECURITY INVOKER;

設計完了日: 2025-12-16 バージョン: 1.0.0 ステータス: 設計承認待ち

実装計画

  • 1. レイヤー基盤を整備する

  • 1.1 (P) レイヤーディレクトリとパスエイリアスを確定する

    • src配下にドメイン、アプリケーション、インフラ、プレゼンテーションの境界を新設し、既存のApp RouterとUIコンポーネント領域をプレゼンテーションとして明示する
    • 各レイヤーのサブディレクトリ構成を合意し、依存方向を示すパスエイリアスをTypeScript設定に反映する
    • 新構成で型チェックとビルドが通ることを短いサンプルで確認し、逸脱時の検知方法を共有する
    • Requirements: 1.1,1.2,1.3,1.4,1.5,1.7
  • 1.2 (P) 既存資産のレイヤー配置計画を策定する

    • libやtypesの責務を洗い出し、ドメイン・アプリケーション・インフラへの移行先をマッピングする
    • 旧構成と新構成が一時共存する期間の参照ルールと移行順を決め、影響範囲を可視化する
    • インポート更新を自動化するスクリプトや手順を準備し、段階的移行で破綻しないようにする
    • Requirements: 1.6,9.2,9.5
  • 2. ドメイン層を純粋なビジネスロジックとして構築する

  • 2.1 (P) エンティティと値オブジェクトを定義する

    • Member・Event・Timetableの状態とふるまいを不変モデルで表現し、学年計算や定員チェックなどのビジネスルールを内包させる
    • Email・StudentId・EventCapacityの値オブジェクトを実装し、生成時にバリデーションを行う
    • 複数エンティティに跨るロジックをドメインサービスに集約し、外部依存を持たない形にする
    • Requirements: 2.1,2.2,2.3,2.4,2.5,2.7
  • 2.2 (P) ドメインの独立性と不変条件を検証する

    • ドメイン層が外部ライブラリや他レイヤーへ依存していないことを静的に確認する
    • 生成・更新時に不正状態を拒否するガードを用意し、例外やエラー型の扱いを決める
    • 既存ビジネスロジックを移行しても振る舞いが変わらないことをサンプルで確認する
    • Requirements: 2.6,2.7,6.1
  • 3. アプリケーション層でユースケース駆動のAPIを構築する

  • 3.1 (P) ポートとDTO契約を定義する

    • リポジトリや認証サービスのポートを整理し、依存性逆転を前提としたインターフェース契約を用意する
    • サーバー・クライアント間でシリアライズ可能なDTOを設計し、日付やIDの取り扱いルールを決める
    • アプリケーション層がドメインのみを参照することを確認し、境界外参照を検知する仕組みを組み込む
    • Requirements: 3.3,3.4,3.5,6.2
  • 3.2 (P) クエリ系ユースケースを実装する

    • プロフィール取得や一覧取得のユースケースでexecuteエントリーポイントを整備し、Resultベースのエラーハンドリングを適用する
    • ドメインエンティティからDTOへの変換責務を明確にし、ビジネスルールの評価順序を固定する
    • 失敗時の例外種別と呼び出し側への伝播方法を揃え、再利用しやすいレスポンス形に整える
    • Requirements: 3.1,3.2,3.6,3.7
  • 3.3 (P) コマンド系ユースケースを実装する

    • 参加登録やプロフィール更新などの書き込みユースケースにトランザクション境界を設定する
    • ポート経由でインフラ層を呼び出し、重複登録や定員超過などのビジネスルールを実行前に検証する
    • 例外とアプリケーションエラーを分類し、呼び出し元がUIに伝えやすい形で返す
    • Requirements: 3.1,3.2,3.6,3.8
  • 4. インフラストラクチャで外部サービス統合を実現する

  • 4.1 (P) データアクセス基盤を整える

    • Supabaseクライアントの初期化手順と資格情報検証を整理し、RLSを前提とした接続パターンを固める
    • 接続失敗や認証エラー時の標準化されたエラー構造を用意し、上位層が扱えるようにする
    • Requirements: 4.3,4.7
  • 4.2 (P) リポジトリ実装とデータマッピングを行う

    • Member・Event・Timetable向けのリポジトリでCRUDと検索を実装し、ポート契約に沿ったResultを返す
    • データベースの型とドメインモデルを相互に変換するマッパーを用意し、欠損値や不正値の扱いを定義する
    • 外部API連携が必要な場合の拡張ポイントを決め、依存注入で切り替えられるようにする
    • Requirements: 4.1,4.2,4.5,4.6,4.8
  • 4.3 (P) 認証基盤と依存性注入を統合する

    • 認証プロバイダーをポート契約に沿って実装し、ロール判定やセッション取得の流れを統一する
    • DIコンテナにリポジトリとサービスを登録し、シングルトン管理やテスト用差し替えの方針を決める
    • Requirements: 4.4,4.9,7.4
  • 4.4 (P) トランザクション処理をRPCで実装する

    • 参加登録・解除の処理をデータベース側のRPCで原子的に実行し、定員チェックを含むビジネスルールを担保する
    • RPCの結果とエラーをアプリケーション層で扱えるフォーマットに正規化する
    • Requirements: 3.8,4.1,4.2
  • 5. プレゼンテーション層でユースケースとUIを接続する

  • 5.1 Server Actionsを実装しユースケースを橋渡しする

    • サーバーコンテキストでユースケースを解決し、DTOを返却する標準フローを整える
    • エラーをユーザー向けメッセージや再入力案内に変換する規約を決める
    • Requirements: 5.5,5.7,5.9
  • 5.2 ページとUIをClean Architectureに合わせて再構成する

    • 主要ページをサーバーコンポーネント基調にし、ユースケース経由でデータ取得・操作を行う流れに統一する
    • クライアントコンポーネントはインタラクションに専念させ、サーバー経由の呼び出し境界を明文化する
    • 既存のプロフィール、イベント、タイムテーブル、管理機能が同等の体験で動作し、UIライブラリのデザインを維持することを確認する
    • Requirements: 5.1,5.2,5.3,5.4,5.6,5.8,7.1,7.2,7.3,7.5,7.6
  • 5.3 エラー体験と通知を統一する

    • ユースケースからの失敗理由をUIで一貫した表示や再試行導線に落とし込み、想定外エラーを捕捉する仕組みを入れる
    • 入力検証エラーと権限エラーで異なる挙動(再入力・リダイレクト等)を定義し、ユーザーが迷わないようにする
    • Requirements: 5.7,5.8
  • 6. 依存性ルールと静的検証を整備する

  • 6.1 (P) レイヤー依存性チェックを自動化する

    • ドメイン→アプリケーション→インフラ→プレゼンテーションの依存方向を守るための静的解析ルールを設定する
    • プレゼンテーションからインフラ実装へ直接依存しないようパス制約を導入し、違反時にビルドを止める
    • Requirements: 6.1,6.2,6.3,6.4
  • 6.2 (P) 開発フローでのガードを導入する

    • ポート未経由の依存や循環参照を検出するリンター/型設定を追加し、CIでも実行する
    • パスエイリアスの解決と型チェックを強化し、設定漏れや誤参照を早期に検知する
    • Requirements: 6.5,6.6,6.7
  • 7. 段階的移行で既存機能を保護する

  • 7.1 (P) パイロット移行を計画し実施する

    • 小規模な機能をパイロットとして新アーキテクチャに載せ、旧構成との共存ポリシーとロールバック手順を明確にする
    • パイロット完了時に関係者へ共有し、挙動変更があれば承認を取る
    • Requirements: 7.9,9.1,9.2,9.3
  • 7.2 全機能を新レイヤーへ移行しクリーンアップする

    • イベント、タイムテーブル、管理、プロフィール各機能を順次新レイヤーに移し、Spindle UIを維持したまま動作確認する
    • 旧インポートパスを新しいエイリアスへ更新し、移行済みコードの重複や未使用部分を除去する
    • 移行完了後に旧構成への依存を断ち、クリーンな状態を保証する
    • Requirements: 1.6,5.1,5.2,5.4,5.6,7.1,7.2,7.3,7.4,7.5,7.6,9.5,9.8
  • 7.3 リグレッションとロールバックの検証を行う

    • 主要ユーザーフロー(プロフィール、イベント登録、タイムテーブル、管理操作)がリファクタ前と同じ結果を返すことを確認する
    • すべてのページがアクセス可能であることと、性能劣化がないことを検証する
    • 段階ごとに戻せるブランチやタグを用意し、問題発生時に安全に戻せることを確認する
    • Requirements: 7.7,7.8,9.4,9.6,9.7
  • 8. テスト体系を整備し品質を担保する

  • 8.1 (P) テスト基盤とカバレッジ計測を準備する

    • Next.js 15と互換性のあるテストランナーとカバレッジツールを導入し、各レイヤーのテスト配置方針を決める
    • テストコマンドをCIに組み込み、閾値設定で品質ゲートを用意する
    • Requirements: 8.4,8.6,8.7
  • 8.2 (P) ドメインのユニットテストを追加する

    • 学年計算やステータス有効性などのビジネスロジックを外部依存なしで検証する
    • 値オブジェクトのバリデーションが期待通りに失敗するケースも網羅する
    • Requirements: 8.1,8.8
  • 8.3 (P) アプリケーションユースケースのテストを実装する

    • モックリポジトリを注入してユースケースの正常系・異常系を検証し、エラー分類が正しく返ることを確認する
    • DTO変換のシリアライズ性をチェックし、境界でのデータ欠損を防ぐ
    • Requirements: 8.2,8.5,8.8
  • 8.4 (P) インフラ統合テストを実施する

    • リポジトリ実装がデータソースと正しくやり取りできることを確認し、マッピングのずれを検出する
    • トランザクション系のRPCが期待通りにコミット/ロールバックされることを検証する
    • Requirements: 8.3
  • 8.5 (P) 重要フローのE2Eを整備する

    • プロフィール表示、イベント登録、管理操作、タイムテーブル表示などのクリティカルパスをE2Eでカバーする
    • UI上のエラー表示やフィルタリング結果が期待通りであることを確認し、リグレッションの早期検知を図る
    • Requirements: 7.7,7.8
  • 9. 開発者体験とナレッジを整備する

  • 9.1 (P) アーキテクチャガイドを整備する

    • レイヤー責務と依存性ルールを説明するガイドを用意し、新しいユースケース追加時の手順と例を示す
    • リポジトリ追加方法とディレクトリ配置規則をまとめ、各レイヤーに短いREADMEを配置する
    • Requirements: 10.1,10.2,10.3,10.4
  • 9.2 (P) 開発者オンボーディングを準備する

    • 新規参加者がセットアップから主要フロー実行まで辿れるオンボーディング資料を整える
    • 振る舞い変更が必要な場合の承認・通知プロセスを含め、運用上のガイドラインをまとめる
    • Requirements: 10.5,10.7
  • 9.3 (P) コード生成テンプレートとスクリプトを用意する

    • 新しいエンティティ・ユースケース・リポジトリを作成するためのテンプレートやスクリプトを提供し、開発手順を標準化する
    • Steering Contextを最新のアーキテクチャパターンに合わせて更新する
    • Requirements: 10.6,10.7

技術調査レポート: Clean Architecture リファクタリング

調査概要

本調査は、Portal.CをClean Architectureへリファクタリングするための技術的実現可能性と実装パターンを検証することを目的としています。

1. Clean Architecture for Next.js 15 App Router

調査ソース

主要な発見

レイヤー構造

  • src/domain/: ビジネスルール、エンティティ、値オブジェクト(外部依存なし)
  • src/application/: ユースケース、ポートインターフェース、DTO
  • src/infrastructure/: 外部サービスアダプター(DB、認証、API)
  • src/presentation/ または app/ + components/: Next.js App Routerエントリーポイント

Next.js 15統合パターン

  • Server Componentsがデフォルト: データ取得とレンダリングをサーバーで実行
  • Client Componentsは選択的: インタラクティブ性が必要な箇所のみ
  • Server Actions: レイヤー間通信の主要メカニズム(use serverディレクティブ)
  • 境界の明確化: use serveruse client ディレクティブがレイヤー分離を強制

依存性ルール

  • Server Componentsはデフォルトで、データベース操作や認証などをサーバーレイヤーで処理
  • コンポーネントは直接データベースを呼び出さず、Server Actionsを介して実行
  • 検証スキーマ(Zod)をクライアントとサーバー間で共有

ベストプラクティス

  • レイアウトツリーを最初にモデル化
  • Route Groupsを使用してURLをクリーンに保つ
  • Server vs Clientの境界を明示的に
  • クライアントJSを最小化し、データアクセスをサーバー(RSC)にプッシュ

推奨事項

  • app/ディレクトリをNext.js App Routerページとして保持
  • src/配下にClean Architectureレイヤーを作成
  • Server ActionsをApplication層とPresentation層の橋渡しとして使用
  • TypeScriptの厳密な型チェックを活用

2. 依存性注入 (Dependency Injection) パターン

調査ソース

主要な発見

Feature Layer(ビジネスロジック)のDI

  • UseCaseとRepositoryをインターフェースベースのバインディングで接続
  • Adapter Patternに従い、ビジネスロジックをデータソースから分離
  • 一意のDIキーを使用した型安全な依存性解決
export default interface UserRepository {
  create(params: CreateUserParams): ApiTask<true>;
  update(params: UpdateUserParams): ApiTask<true>;
  delete(ids: string[]): ApiTask<true>;
}

export const userRepoKey = "userRepoKey";

Application Layer(React/Next.js統合)のDI

  • MVVMパターンを実装
  • ViewModelとViewをBridge Patternで接続
  • Server ComponentからClient ComponentへのViewModel受け渡しに一意のVMキーを使用

モジュール登録ファクトリー

export default function userModule(di: DependencyContainer) {
  di.register(userRepoKey, UserRepositoryImpl);
  return di;
}

DIライブラリ選択肢

  • TSyringe: TypeScript専用、デコレータベース、reflect-metadata必要
  • Awilix: JavaScript/TypeScript両対応、軽量
  • InversifyJS: TypeScript専用、機能豊富
  • ioctopus: reflect-metadataなし、全ランタイム対応(推奨)

Next.js 15 Server Components対応

  • 環境変数ベースの設定(T3 Env + Zod)
  • 集中化されたORMインスタンス(Drizzle)
  • Server ActionsをコンポーネントへのケイパビリティとしてInject

推奨事項

  • 軽量DIアプローチ: ファクトリー関数パターン + インターフェースバインディング
  • ioctopusまたはAwilixを推奨(Next.js Server Componentsと互換性が高い)
  • インターフェースベースのDIキーを使用して型安全性を確保
  • ドメインモジュールをDIファクトリーとして組織化

3. Supabase トランザクション処理

調査ソース

主要な発見

トランザクションサポートの制約

  • supabase-jsクライアントはトランザクションをサポートしない
  • PostgRESTベースのため、クライアントサイドでのトランザクション境界は不可

推奨されるワークアラウンド

  1. PostgreSQL関数をRPC経由で呼び出す(推奨)
    • データベースに複数のクエリをトランザクション内で実行するSQL関数を作成
    • Edge FunctionまたはServer ActionからRPCで呼び出す
    • 重要: PostgRESTはrpc()呼び出しを自動的にトランザクションでラップする
CREATE OR REPLACE FUNCTION register_for_event(
  p_member_id UUID,
  p_event_id UUID
)
RETURNS BOOLEAN AS $$
BEGIN
  -- トランザクション内で複数操作を実行
  INSERT INTO participations (member_id, event_id) VALUES (p_member_id, p_event_id);
  UPDATE events SET participant_count = participant_count + 1 WHERE id = p_event_id;
  RETURN TRUE;
EXCEPTION
  WHEN OTHERS THEN
    RETURN FALSE;
END;
$$ LANGUAGE plpgsql SECURITY INVOKER;
const { data, error } = await supabase.rpc('register_for_event', {
  p_member_id: memberId,
  p_event_id: eventId
});
  1. Edge Functionsで直接データベースアクセス

    • Edge FunctionsはサーバーサイドのためPostgRESTを経由せず直接データベースアクセス可能
    • 純粋なSQLトランザクションを使用可能
  2. ORM使用(Prisma等)

    • トランザクションサポートが必要な場合、PrismaなどのORMを使用

TypeScript型サポート

  • Supabase CLIで型生成: supabase gen types typescript --project-id [id] > database.types.ts
  • RPC関数は戻り値型を自動的に推論
  • null制約、生成カラムを検出

セキュリティベストプラクティス

  • SECURITY INVOKERを使用(デフォルト、推奨)
  • SECURITY DEFINERを使用する場合、search_pathを明示的に設定

推奨事項

  • 複雑なユースケース: PostgreSQL関数をRPC経由で呼び出す
  • 単純なCRUD: Supabase標準クエリを使用
  • トランザクション境界はユースケースレベルで定義
  • RPC関数の型安全性を確保(TypeScript型生成)

4. Server Components と Client Components のデータフロー

調査ソース

主要な発見

コンポジションパターン(Server → Client)

  • Server ComponentはClient Componentを含むことができる
  • Client ComponentはServer Componentを直接含むことはできないが、childrenプロップを通じて受け取ることは可能
// ✅ 許可: Server Component → Client Component
<ClientModal>
  <ServerCart /> {/* childrenとして渡される */}
</ClientModal>

// ❌ 禁止: Client Component内で直接Server Componentをインポート
import ServerCart from './ServerCart'; // エラー

依存性フロールール

  • Server Component → Client Component: ✅ 一般的なパターン
  • Client Component → Server Component: ❌ 許可されない
  • Server Component → Server Component: ✅ 完全サポート
  • Client Component → Client Component: ✅ 完全サポート

Next.js 15のデータ取得

  • getServerSidePropsを非同期Server Componentパターンで置き換え
  • async/awaitを直接Server Component内で使用
  • 自動キャッシングと再検証(revalidateオプション)

アーキテクチャの特徴

  • ストリーミングファーストのHTMLとデータの段階的配信
  • コンポーネントレベルのコード分割(Server Componentsはクライアントに到達しない)
  • 並列データ取得(複数の非同期操作を同時実行)
  • コンポーネントおよびフェッチレベルの細粒度キャッシング

パフォーマンスの利点

  • デフォルトでServer Componentsを使用し、サーバーでUIをレンダリングしてキャッシュ
  • ブラウザの負荷を軽減し、パフォーマンスを向上

推奨事項

  • Server Componentsをデフォルトとして使用
  • データ取得はServer Components内で直接実行
  • Client Componentsはインタラクティブな要素のみに制限
  • childrenパターンでServer ComponentsをClient Componentsに渡す
  • async/await構文でデータフローを直感的に

5. Repository パターン TypeScript 実装

調査ソース

主要な発見

インターフェース設計戦略

  • エンティティインターフェース: データモデル構造を定義(ITask, IProject)
  • クエリパラメータインターフェース: ページネーションとフィルタリングロジックを処理
  • リポジトリインターフェース: 利用可能なデータ操作を指定(list, get, create, update)

データマッピングアプローチ

  • 各リポジトリにprivate mapEntity()メソッドを含む
  • ORM結果をドメインインターフェースに変換
  • レイヤー間の型一貫性を確保
interface IMemberRepository {
  findById(id: string): Promise<Member | null>;
  findAll(params: QueryParams): Promise<Member[]>;
  create(member: Member): Promise<Member>;
  update(id: string, member: Partial<Member>): Promise<Member>;
  delete(id: string): Promise<void>;
}

class SupabaseMemberRepository implements IMemberRepository {
  private mapToEntity(row: Database['public']['Tables']['members']['Row']): Member {
    return {
      id: row.id,
      name: row.name,
      // ... マッピングロジック
    };
  }

  async findById(id: string): Promise<Member | null> {
    const { data, error } = await this.client
      .from('members')
      .select('*')
      .eq('id', id)
      .single();

    if (error || !data) return null;
    return this.mapToEntity(data);
  }
}

Mixinパターンを使用したリポジトリ構造

  • BaseRepository: 共有されたクライアントアクセスとページネーションデフォルト
  • AddEntityRepository: エンティティ固有の操作をMixin関数として
  • ComposedRepository: Mixinを統一されたインスタンスに結合

Clean Architectureの利点

  • 関心の分離を促進
  • テスタビリティを向上
  • データレイヤーの交換を容易化

推奨事項

  • Application層でリポジトリインターフェースを定義
  • Infrastructure層で具体的な実装を提供
  • データマッパーメソッドでDB型↔ドメインエンティティ変換
  • 型安全性を確保(TypeScriptの厳密な型)
  • 汎用リポジトリよりも専用リポジトリパターンを優先

6. アーキテクチャ決定記録 (ADR)

ADR-001: レイヤー構造

決定: src/配下にdomain/, application/, infrastructure/, presentation/の4層を作成

根拠:

  • Clean Architectureの標準的なレイヤー分離
  • Next.js 15 App Routerとの互換性
  • テスタビリティと保守性の向上

代替案:

  • Hexagonal Architecture(ポート&アダプター): より複雑、オーバーエンジニアリングの懸念
  • 3層アーキテクチャ: レイヤー分離が不十分

ADR-002: 依存性注入メカニズム

決定: 軽量ファクトリーパターン + インターフェースバインディング(ioctopus または カスタム実装)

根拠:

  • Next.js 15 Server Componentsとの互換性
  • reflect-metadata不要(全ランタイム対応)
  • Tree-shaking対応でバンドルサイズ最小化
  • 学習曲線が緩やか

代替案:

  • TSyringe: reflect-metadata必要、Next.js Server Componentsと互換性の問題
  • InversifyJS: 重量級、複雑なセットアップ

ADR-003: トランザクション処理戦略

決定: PostgreSQL関数をRPC経由で呼び出す

根拠:

  • supabase-jsはトランザクション未サポート
  • PostgRESTがrpc()を自動的にトランザクションでラップ
  • RLS(Row Level Security)との統合が容易
  • 型安全性(TypeScript型生成)

代替案:

  • Edge Functionsで直接データベースアクセス: 複雑性増加、RLS統合が困難
  • ORMの追加(Prisma): 技術スタック増加、学習コスト

ADR-004: Server/Client Component 分離戦略

決定: Server Componentsをデフォルト、Client Componentsはuse clientで明示的に

根拠:

  • Next.js 15のベストプラクティス
  • パフォーマンス最適化(サーバーレンダリング)
  • データ取得の直感性(async/await)
  • バンドルサイズ削減

代替案:

  • すべてClient Components: パフォーマンス悪化、バンドルサイズ増大
  • 手動でのスプリット: 複雑性増加、一貫性の欠如

ADR-005: リポジトリパターン実装

決定: 専用リポジトリ(エンティティごと)+ データマッパー

根拠:

  • 明確な責務分離
  • 型安全性の確保
  • Supabaseクエリビルダーとの統合が容易
  • テストしやすい

代替案:

  • 汎用リポジトリ: 型安全性が低い、ビジネスロジックの表現が困難
  • Active Recordパターン: ドメイン層とインフラ層の混在

7. リスクと軽減策

技術的リスク

リスク 1: Next.js 15 Server ComponentsとDIの統合複雑性

  • 影響: 中
  • 軽減策:
    • パイロット機能(メンバー一覧)で最初に検証
    • ioctopusまたはシンプルなファクトリーパターンを使用
    • 公式ドキュメントとコミュニティパターンを参照

リスク 2: Supabaseトランザクション制約

  • 影響: 中
  • 軽減策:
    • PostgreSQL関数をRPC経由で呼び出す戦略を採用
    • 段階2で実装パターンを確立
    • 型安全性を確保(TypeScript型生成)

リスク 3: Server/Client Componentデータシリアライゼーション

  • 影響: 低〜中
  • 軽減策:
    • DTOを使用してシリアライズ可能な型のみを渡す
    • Date型はISO文字列に変換
    • Next.js公式ドキュメントのベストプラクティスに従う

プロジェクトリスク

リスク 4: チームの学習曲線

  • 影響: 中
  • 軽減策:
    • 段階的移行により各段階で学習
    • アーキテクチャドキュメントとガイドライン作成
    • コードレビューとペアプログラミング

リスク 5: 並行開発期間の複雑性

  • 影響: 中
  • 軽減策:
    • 既存コードを破壊しない
    • 新機能は新レイヤーで実装
    • 明確なマイグレーション計画(7段階)

8. 未解決の調査項目

実装段階での検証が必要な項目

  1. エンティティ実装方式

    • クラスベース vs インターフェース+純粋関数
    • テスタビリティと保守性のトレードオフ
    • 推奨: パイロット機能で両方を試し、チームの嗜好に基づいて決定
  2. キャッシング戦略

    • Next.js 15のキャッシング機能との統合
    • リポジトリレベルのキャッシング vs ユースケースレベルのキャッシング
    • 推奨: 段階5以降で性能要件に基づいて実装
  3. エラーハンドリング標準化

    • ドメインエラー、アプリケーションエラー、インフラエラーの分類
    • Result型 vs Exception
    • 推奨: 段階2-3でエラー型システムを確立
  4. テストフレームワーク選定

    • Jest vs Vitest
    • モックライブラリ選定
    • 推奨: 段階7で決定、Next.js 15との互換性を考慮

9. 推奨実装アプローチ

ハイブリッドアプローチ(Option C)

段階1: 基盤整備

  • ディレクトリ構造作成(src/domain, application, infrastructure)
  • tsconfig.jsonパスエイリアス設定
  • 軽量DIメカニズム実装(ファクトリーパターン)

段階2: ドメイン層

  • エンティティ実装(Member, Event, Timetable)
  • 値オブジェクト実装(Email, StudentId, EventCapacity)
  • 既存types/index.tsのビジネスロジックを移行

段階3: アプリケーション層

  • リポジトリインターフェース定義
  • DTO定義
  • パイロットユースケース実装(GetMemberProfile, ListMembers)

段階4: インフラストラクチャ層

  • リポジトリ実装(SupabaseMemberRepository)
  • データマッパー実装
  • RPC関数作成(必要に応じて)

段階5: プレゼンテーション層統合

  • パイロットページ(メンバー一覧)をユースケース統合
  • Server Actions実装
  • エラーハンドリング統合

段階6: 全機能移行

  • 残機能の移行(イベント、時間割、管理画面)
  • モックデータを実データに置き換え

段階7: テストとドキュメント

  • ユニットテスト実装
  • インテグレーションテスト
  • アーキテクチャドキュメント作成

10. まとめ

技術的実現可能性: ✅ 高い

根拠:

  • Next.js 15はClean Architectureパターンをサポート
  • 依存性注入の軽量実装パターンが確立
  • Supabaseトランザクションの実用的ワークアラウンド存在
  • Server/Client Componentsのデータフロー明確
  • リポジトリパターンのTypeScript実装パターン豊富

推奨技術スタック

  • レイヤー構造: Clean Architecture 4層(Domain, Application, Infrastructure, Presentation)
  • DI: 軽量ファクトリーパターン(ioctopusまたはカスタム)
  • トランザクション: PostgreSQL関数 + RPC
  • データフロー: Server Componentsデフォルト + Server Actions
  • リポジトリ: 専用リポジトリ + データマッパー

次のステップ

  1. 要件の最終承認
  2. 技術設計ドキュメント生成(design.md)
  3. タスク分解とマイルストーン設定
  4. パイロット機能の実装開始

ギャップ分析: Clean Architecture リファクタリング

1. 現状調査

1.1 既存コードベースの構造

ディレクトリレイアウト

Portal.C/
├── app/                    # Next.js 15 App Router ページ
│   ├── admin/             # 管理画面
│   ├── events/            # イベント一覧ページ
│   ├── members/           # メンバー一覧ページ
│   ├── profile/           # プロフィール編集ページ
│   ├── timetable/         # 時間割ページ
│   ├── layout.tsx         # ルートレイアウト
│   ├── page.tsx           # ホームページ
│   └── api/auth/          # NextAuth APIルート
├── components/            # UIコンポーネント
│   ├── layout/Navigation.tsx
│   └── MatterHero.tsx
├── lib/                   # ユーティリティとクライアント
│   ├── auth.ts            # 認証ヘルパー
│   ├── auth-options.ts    # NextAuth設定
│   ├── utils.ts           # 汎用ユーティリティ
│   └── supabase/          # Supabaseクライアント
│       ├── client.ts      # ブラウザクライアント
│       ├── server.ts      # サーバークライアント
│       ├── admin.ts       # 管理者クライアント
│       └── middleware.ts  # ミドルウェア
├── types/                 # 型定義
│   ├── database.types.ts  # Supabase自動生成型
│   └── index.ts           # アプリケーション型定義 + ビジネスロジック
└── supabase/migrations/   # データベーススキーマ
    ├── 20241216000001_create_members_table.sql
    ├── 20241216000002_create_tags_table.sql
    ├── 20241216000003_create_events_table.sql
    └── 20241216000004_create_timetables_table.sql

再利用可能な資産

1. データベーススキーマ(完全構築済み)

  • membersテーブル: ZITADEL ID統合、学年自動計算関数、RLS(Row Level Security)設定済み
  • tagsテーブル: スキル・興味タグ管理
  • eventsテーブル: イベント情報、参加者管理
  • timetablesテーブル: メンバーの時間割情報

2. 認証基盤(設定完了)

  • ZITADEL OIDC統合(lib/auth-options.ts)
  • NextAuth.js設定
  • ロールベースアクセス制御(admin ロール対応)
  • セッション管理

3. Supabaseクライアント(4種類)

  • ブラウザクライアント(lib/supabase/client.ts)
  • サーバークライアント(lib/supabase/server.ts)
  • 管理者クライアント(lib/supabase/admin.ts)
  • ミドルウェアクライアント(lib/supabase/middleware.ts)

4. 型定義システム

  • Supabase自動生成型(types/database.types.ts)
  • アプリケーション型(types/index.ts): Member, Event, Timetable, Participation

5. UIコンポーネント

  • Spindle UI統合(@openameba/spindle-ui)
  • Tailwind CSS設定
  • レイアウトコンポーネント(Navigation)
  • ページコンポーネント(会員、イベント、時間割、管理画面)

アーキテクチャパターンと制約

現在のパターン

  • 標準的なNext.js構造: app/ディレクトリによるファイルベースルーティング
  • 直接的なデータアクセス: UIコンポーネントから直接Supabaseクライアントを呼び出す想定(現在はモックデータ)
  • 型定義とビジネスロジックの混在: types/index.tsにcalculateGrade(), isStatusValid()などのビジネスロジックが含まれる
  • レイヤー分離なし: プレゼンテーション、ビジネスロジック、データアクセスが明確に分離されていない

技術的制約

  • Next.js 15 App Routerの使用が必須
  • Supabaseをデータベースとして使用
  • ZITADELを認証基盤として使用
  • TypeScript strict mode有効

命名規則

  • コンポーネント: PascalCase(Navigation.tsx, MatterHero.tsx)
  • ユーティリティ: camelCase(utils.ts, auth.ts)
  • 型定義: PascalCase(Member, Event)

インポートパターン

  • 絶対パスインポート: @/エイリアス使用
  • 例: import type { Member } from "@/types"

1.2 統合ポイント

データモデル/スキーマ

  • PostgreSQL(Supabase)スキーマ完全定義
  • 学年自動計算はデータベース関数で実装済み
  • Row Level Security(RLS)設定済み
  • TypeScript型は自動生成可能

認証メカニズム

  • ZITADEL OIDC provider
  • NextAuth.jsによるセッション管理
  • JWT内にロール情報を含む
  • RLSとの統合(auth.jwt())

外部API/サービス

  • Supabase API(データベース、認証、ストレージ)
  • ZITADEL(認証プロバイダー)

2. 要件実現可能性分析

2.1 技術的ニーズ(EARS要件からの抽出)

データモデル

  • Memberエンティティ: データベーススキーマ、型定義完備
  • Eventエンティティ: データベーススキーマ、型定義完備
  • Timetableエンティティ: データベーススキーマ、型定義完備
  • 値オブジェクト候補: Email, StudentId, EventCapacity(実装は未)

API/サービス

  • Supabaseクライアント: 4種類のクライアント実装済み
  • 認証サービス: ZITADEL統合完了
  • リポジトリインターフェース: 未実装
  • ユースケース: 未実装

UI/コンポーネント

  • ページコンポーネント: 全ページ実装済み(モックデータ使用)
  • UIライブラリ: Spindle UI導入済み
  • ⚠️ データバインディング: 現在はモックデータ、実データ統合が必要

ビジネスルール/バリデーション

  • ⚠️ 学年計算: データベース関数とTypeScript関数に重複実装
  • ⚠️ ステータス有効性チェック: TypeScript関数のみ(types/index.ts)
  • 値オブジェクトバリデーション: 未実装
  • ドメインルール: エンティティ内にカプセル化されていない

非機能要件

セキュリティ

  • ✅ Row Level Security設定済み
  • ✅ ロールベースアクセス制御
  • ⚠️ 入力バリデーション: フロントエンドのみ、サーバーサイド強化が必要

パフォーマンス

  • ✅ データベースインデックス設定済み
  • ❌ クエリ最適化: リポジトリパターンで実装予定
  • ❌ キャッシング: 未実装

スケーラビリティ

  • ✅ Supabase(PostgreSQL)でスケーラブル
  • ✅ Vercelホスティングでスケーラブル

信頼性

  • ⚠️ トランザクション境界: ユースケース層で定義予定
  • ❌ エラーハンドリング: 統一されたエラー処理が必要

2.2 ギャップと制約の特定

欠落機能

1. ドメイン層(完全欠如)

  • エンティティクラス/インターフェース
  • 値オブジェクト
  • ドメインサービス
  • ビジネスルールのカプセル化

2. アプリケーション層(完全欠如)

  • ユースケース実装
  • ポートインターフェース(リポジトリ、サービス)
  • DTO(データ転送オブジェクト)
  • アプリケーションサービス

3. インフラストラクチャ層(部分的実装)

  • ✅ Supabaseクライアント存在
  • ❌ リポジトリ実装
  • ❌ データマッパー(DB型 ↔ ドメインエンティティ変換)
  • ❌ 依存性注入メカニズム

4. プレゼンテーション層(部分的実装)

  • ✅ ページコンポーネント存在
  • ❌ ユースケース統合
  • ❌ Server Actions(Next.js 15推奨パターン)
  • ❌ 統一されたエラー表示

5. テスト基盤(未実装)

  • ユニットテストフレームワーク
  • インテグレーションテスト
  • モック/スタブ実装

調査が必要な項目

1. 依存性注入(DI)の実装方法

  • 選択肢:
    • ファクトリー関数パターン(軽量)
    • DIコンテナライブラリ(TSyringe, InversifyJS)
    • Next.js App Routerネイティブパターン
  • 調査ポイント: Next.js 15 Server Componentsとの相性、パフォーマンス影響

2. トランザクション処理

  • 調査ポイント: Supabaseでのトランザクション実装方法、ユースケース境界での実装パターン

3. Server ComponentsとClient Componentsのデータ転送

  • 調査ポイント: DTOのシリアライゼーション、Date型の扱い、エラー伝播

4. エンティティ実装方式

  • 選択肢:
    • クラスベース(メソッド含む)
    • インターフェース + 純粋関数
  • 調査ポイント: TypeScriptでの推奨パターン、テスタビリティ

5. リポジトリインターフェースの粒度

  • 調査ポイント: 汎用リポジトリ vs 専用リポジトリ、Supabaseクエリビルダーとの統合

既存アーキテクチャからの制約

1. Next.js App Routerの制約

  • ファイルベースルーティング(app/ディレクトリ)必須
  • Server ComponentsとClient Componentsの分離
  • Server Actionsの使用推奨

2. Supabaseの制約

  • PostgreSQL専用(NoSQL非対応)
  • RLSによるアクセス制御
  • リアルタイムサブスクリプション機能

3. ZITADEL統合

  • OIDC標準準拠
  • JWT内にロール情報を格納
  • NextAuth.jsとの統合

2.3 複雑性の指標

機能タイプ

  • ドメインロジック: 中程度(学年計算、ステータス有効性チェック、イベント参加管理)
  • データアクセス: 標準的CRUD + RLS統合
  • 外部統合: 認証(ZITADEL)、データベース(Supabase)
  • ワークフロー: シンプル(メンバー登録、イベント参加、プロフィール更新)

アーキテクチャの複雑性

  • レイヤー数: 4層(Domain, Application, Infrastructure, Presentation)
  • 抽象化レベル: 高(ポート/アダプター、依存性逆転)
  • 新規パターン: リポジトリパターン、ユースケースパターン、依存性注入

3. 実装アプローチオプション

Option A: 既存コンポーネントの拡張

該当しない理由: Clean Architectureへのリファクタリングは、既存の構造を根本的に変更する必要があり、単なる拡張では実現不可能。

評価: ❌ 適用不可


Option B: 新規コンポーネント作成

アプローチ: 既存コードを保持したまま、完全に新しいレイヤー構造(src/domain/, src/application/, src/infrastructure/)を作成し、段階的に機能を移行。

新規作成の根拠

  • Clean Architectureは既存の構造と根本的に異なる
  • レイヤー分離の原則に従うには、新しいディレクトリ構造が必須
  • 既存コードとの並行運用により、段階的移行が可能

統合ポイント

  • app/ディレクトリ: プレゼンテーション層として保持、新しいユースケースを呼び出す
  • lib/supabase/: 新しいリポジトリ実装のアダプターとして使用
  • types/: ドメインエンティティ定義に段階的に移行

責任境界

  • src/domain/: ビジネスルール、エンティティ、値オブジェクト(外部依存なし)
  • src/application/: ユースケース、ポートインターフェース、DTO
  • src/infrastructure/: リポジトリ実装、Supabase統合、ZITADEL統合
  • app/ + components/: プレゼンテーション層(ユースケースを呼び出す)

トレードオフ

  • ✅ クリーンな分離、テストしやすい
  • ✅ 段階的移行が可能
  • ✅ 既存機能を壊さない
  • ❌ ディレクトリ数増加、初期学習コスト
  • ❌ 並行期間中のコード重複

評価: ✅ 推奨される基本アプローチ


Option C: ハイブリッドアプローチ(推奨)

アプローチ: Option Bをベースに、既存の安定した資産(Supabaseクライアント、ZITADEL設定、UIコンポーネント)を活用しながら、段階的に新しいレイヤーを導入。

組み合わせ戦略

段階1: 基盤整備(Week 1)

  • 新しいディレクトリ構造作成(src/domain/, src/application/, src/infrastructure/)
  • tsconfig.jsonパスエイリアス設定
  • 依存性注入メカニズム選定・実装

段階2: ドメイン層(Week 1-2)

  • エンティティ実装(Member, Event, Timetable)
  • 値オブジェクト実装(Email, StudentId, EventCapacity)
  • ドメインサービス(必要に応じて)
  • 既存資産活用: types/index.tsのビジネスロジックを移行

段階3: アプリケーション層(Week 2)

  • ポートインターフェース定義(IMemberRepository, IEventRepository等)
  • DTO定義
  • 基本ユースケース実装(1-2個のパイロットユースケース)

段階4: インフラストラクチャ層(Week 2-3)

  • リポジトリ実装(SupabaseMemberRepository等)
  • データマッパー(DB型 ↔ ドメインエンティティ変換)
  • 既存資産活用: lib/supabase/クライアントをアダプターとして使用

段階5: プレゼンテーション層統合(Week 3)

  • パイロットページ(例: メンバー一覧)をユースケース統合
  • Server Actions実装
  • エラーハンドリング統合
  • 既存資産活用: 既存のUIコンポーネントとSpindle UI

段階6: 全機能移行(Week 3-4)

  • 残りの機能(イベント、時間割、管理画面)を移行
  • モックデータを実データに置き換え
  • 既存資産活用: 既存のページ構造とルーティング

段階7: テストとドキュメント(Week 4)

  • ユニットテスト実装
  • インテグレーションテスト
  • アーキテクチャドキュメント作成
  • 開発者オンボーディングガイド

段階的実装の詳細

パイロット機能選定: メンバー一覧ページ

  • シンプルなCRUD操作
  • 既存のUIコンポーネント活用可能
  • 学習曲線が緩やか

移行戦略:

  1. 新しいレイヤーでメンバー一覧機能を完全実装
  2. 既存のapp/members/page.tsxをリファクタリング
  3. 動作確認・フィードバック収集
  4. 他の機能に適用

リスク軽減策

技術的リスク:

  • DI実装の複雑性: パイロット機能で検証後、パターン確立
  • Server Components統合: Next.js 15公式ドキュメント参照、コミュニティパターン調査
  • トランザクション処理: Supabaseドキュメント参照、段階2で調査完了

プロジェクトリスク:

  • 段階的移行: 各段階で動作確認、必要に応じてロールバック可能
  • 並行開発: 既存コードを破壊しない、新機能追加は新レイヤーで実装
  • 知識共有: 段階ごとにドキュメント更新、チームレビュー実施

トレードオフ

  • ✅ バランスの取れたアプローチ
  • ✅ 既存資産を最大限活用
  • ✅ リスク分散(段階的移行)
  • ✅ 各段階でフィードバック可能
  • ❌ 計画の複雑性
  • ❌ 段階間の調整が必要

評価: ⭐ 強く推奨 - 最もバランスが取れた実装アプローチ

4. 実装の複雑性とリスク

工数見積もり

工数: XL (3-4週間、約26-41日)

内訳

  • 基盤整備: 2-3日(ディレクトリ構造、DI、設定)
  • ドメイン層: 5-7日(エンティティ、値オブジェクト、サービス)
  • アプリケーション層: 4-5日(ユースケース、ポート、DTO)
  • インフラストラクチャ層: 5-7日(リポジトリ、データマッパー、統合)
  • プレゼンテーション層: 4-5日(Server Actions、統合、エラーハンドリング)
  • 全機能移行: 3-5日(残機能の移行、モックデータ置き換え)
  • テストとドキュメント: 3-5日(ユニット/統合テスト、ドキュメント)
  • バッファ: 2-4日(予期しない問題対応)

合計: 26-41日(1人、フルタイム換算)

リスク評価

リスク: Medium

リスク要因

技術的未知数(Medium リスク):

  • Next.js 15 App Routerでの依存性注入パターン
  • Supabaseトランザクション処理
  • Server ComponentsとClient Componentsのデータ転送

軽減策:

  • 段階1で技術調査とパイロット実装
  • Next.js 15公式ドキュメントとコミュニティベストプラクティス参照
  • Supabaseドキュメントとサンプルコード調査

アーキテクチャ変更の影響(Medium リスク):

  • 既存コードとの共存期間
  • チームの学習曲線
  • パターンの一貫性

軽減策:

  • 段階的移行により影響を最小化
  • 各段階でコードレビューとペアプログラミング
  • アーキテクチャドキュメントとガイドライン作成

データ統合(Low リスク):

  • データベーススキーマ完全構築済み
  • Supabaseクライアント動作確認済み

軽減策:

  • 既存のデータベーススキーマとクライアントを活用
  • データマッパーで型安全性を確保

パフォーマンス(Low リスク):

  • レイヤー追加によるオーバーヘッド
  • 不適切なクエリパターン

軽減策:

  • リポジトリパターンでクエリ最適化
  • 必要に応じてキャッシング導入
  • パフォーマンステスト実施

成功のための鍵

  1. 段階的アプローチ: 各段階で動作確認とフィードバック
  2. 既存資産活用: データベーススキーマ、認証、UIコンポーネント
  3. 明確なドキュメント: アーキテクチャガイド、コーディング規約
  4. 継続的レビュー: コードレビュー、ペアプログラミング
  5. テスト駆動: ドメイン層とアプリケーション層のユニットテスト

5. 要件-資産マッピング

Requirement 1: ディレクトリ構造とレイヤー分離

受入基準既存資産ギャップタグ
src/ディレクトリ作成なし新規作成が必要Missing
domain/, application/, infrastructure/, presentation/作成なし新規作成が必要Missing
app/ディレクトリ保持✅ 既存プレゼンテーション層として再定義Refactor
components/ディレクトリ保持✅ 既存プレゼンテーション層として再定義Refactor
lib/, types/から移行✅ 既存適切なレイヤーへ移行が必要Refactor
tsconfig.jsonパスエイリアス⚠️ 部分的(@/のみ)レイヤー別エイリアス追加Extend

推奨アプローチ: Option C - 新規ディレクトリ作成 + 既存ディレクトリ活用


Requirement 2: ドメインレイヤーの設計

受入基準既存資産ギャップタグ
エンティティ定義(Member, Event, Timetable)⚠️ types/index.ts(型定義のみ)クラス/インターフェース実装が必要Missing
外部依存なしの実装❌ 現在ビジネスロジック混在純粋なドメインロジックに分離Missing
値オブジェクト(Email, StudentId等)❌ なし新規実装が必要Missing
イミュータビリティとバリデーション❌ なし値オブジェクトに実装Missing
ドメインサービス❌ なし必要に応じて実装Missing
レイヤー依存ルール❌ 現在制約なしTypeScript設定で強制Missing
ビジネスルールバリデーション⚠️ calculateGrade, isStatusValid存在エンティティ内にカプセル化Refactor

推奨アプローチ: Option B - 新規作成(既存のビジネスロジックを移行)


Requirement 3: アプリケーションレイヤーの設計

受入基準既存資産ギャップタグ
ユースケースクラス❌ なし新規実装が必要Missing
単一責務とexecute()メソッド❌ なしパターン確立が必要Missing
ポートインターフェース❌ なし新規定義が必要Missing
DTO定義❌ なし新規定義が必要Missing
ドメイン層のみに依存❌ 現在制約なしレイヤールール強制Missing
依存性逆転の原則❌ なしDI実装が必要Unknown
エラーハンドリング⚠️ 部分的統一されたエラー型が必要Missing
トランザクション境界❌ なし実装パターン調査が必要Unknown

推奨アプローチ: Option B - 新規作成(調査項目あり)

調査項目:

  • Next.js 15での依存性注入パターン
  • Supabaseトランザクション処理方法

Requirement 4: インフラストラクチャレイヤーの設計

受入基準既存資産ギャップタグ
リポジトリ実装❌ なし新規実装が必要Missing
ポートインターフェース実装❌ なしアプリケーション層定義後に実装Missing
Supabaseクライアント設定✅ lib/supabase/(4種類)アダプターとして活用Extend
ZITADEL認証プロバイダー✅ lib/auth-options.tsアダプターとして活用Extend
DB型↔ドメインエンティティ変換❌ なしデータマッパー実装が必要Missing
エラー変換⚠️ 部分的標準化されたエラー型に変換Missing
外部API統合⚠️ 必要に応じて現時点では不要N/A
依存性注入❌ なしDI実装が必要Unknown

推奨アプローチ: Option C - 既存Supabaseクライアント活用 + 新規リポジトリ実装


Requirement 5: プレゼンテーションレイヤーの設計

受入基準既存資産ギャップタグ
app/ディレクトリ保持✅ 既存ユースケース統合が必要Refactor
components/ディレクトリ保持✅ 既存UIロジックのみに制限Refactor
サーバーコンポーネント⚠️ 一部実装ユースケース呼び出しに変更Refactor
クライアントコンポーネント⚠️ 一部実装インタラクティブUIのみに制限Refactor
ユースケース/DTO通信❌ 現在直接データアクセス統合が必要Missing
データベース/認証直接呼び出し禁止❌ 現在想定パターン変更が必要Constraint
Server Actions❌ なしNext.js 15推奨パターン実装Missing
エラー表示⚠️ 部分的統一されたエラーUIMissing

推奨アプローチ: Option C - 既存ページ/コンポーネント活用 + ユースケース統合


Requirement 6: 依存性ルールの遵守

受入基準既存資産ギャップタグ
ドメイン層独立性❌ 現在制約なしレイヤー分離が必要Missing
アプリケーション層依存ルール❌ 現在制約なしレイヤー分離が必要Missing
インフラストラクチャ層依存ルール❌ 現在制約なしレイヤー分離が必要Missing
プレゼンテーション層依存ルール❌ 現在制約なしレイヤー分離が必要Missing
依存性逆転の原則❌ なしポート/アダプターパターン実装Missing
TypeScript/リンター設定⚠️ 基本設定のみレイヤー依存ルール強制設定Missing
ビルド/リント時エラー検出❌ なし設定強化が必要Missing

推奨アプローチ: Option B - 新規実装(TypeScript設定とリンター強化)


Requirement 7: 既存機能の保持

受入基準既存資産ギャップタグ
メンバー管理機能✅ UI実装済み(モック)実データ統合が必要Refactor
イベント管理機能✅ UI実装済み(モック)実データ統合が必要Refactor
タイムテーブル機能✅ UI実装済み(モック)実データ統合が必要Refactor
認証機能✅ ZITADEL統合完了新レイヤーとの統合Extend
管理者機能✅ UI実装済み実データ統合が必要Refactor
データベーススキーマ✅ 完全構築済みそのまま使用✓ Ready
回帰テスト❌ なしテスト実装が必要Missing

推奨アプローチ: Option C - 既存UI活用 + 新レイヤー統合


Requirement 8-10(テスタビリティ、マイグレーション、ドキュメント)

要件エリア既存資産ギャップタグ
テストフレームワーク❌ なしJest/Vitest導入が必要Missing
ユニットテスト❌ なしドメイン/アプリケーション層実装Missing
統合テスト❌ なしリポジトリ/ユースケーステスト実装Missing
マイグレーション計画❌ なし7段階計画作成済み✓ Planned
アーキテクチャドキュメント❌ なし作成が必要Missing
開発者ガイド❌ なし作成が必要Missing
コード生成テンプレート❌ なし作成推奨Missing

推奨アプローチ: Option B - 新規作成(段階7で実装)

6. まとめ

現状とギャップの要約

Portal.Cは、データベーススキーマと認証システムが完全に構築されているものの、アーキテクチャ層の分離が存在しない標準的なNext.jsアプリケーションです。Clean Architectureへのリファクタリングには、以下の主要ギャップが存在します:

  • ドメイン層: 完全欠如(エンティティ、値オブジェクト、サービス)
  • アプリケーション層: 完全欠如(ユースケース、ポート、DTO)
  • インフラストラクチャ層: 部分的実装(クライアント存在、リポジトリなし)
  • プレゼンテーション層: 部分的実装(UI存在、統合なし)
  • テスト基盤: 未実装

一方で、以下の技術的資産が活用可能:

  • ✅ Supabaseデータベーススキーマ完全構築
  • ✅ ZITADEL認証統合完了
  • ✅ 型定義システム整備済み
  • ✅ UIコンポーネント実装済み

推奨アプローチ

Option C: ハイブリッドアプローチ(段階的移行)を強く推奨します。

理由:

  1. 既存の安定した資産(データベース、認証、UI)を最大限活用
  2. 段階的移行によりリスクを最小化
  3. 各段階で動作確認とフィードバックが可能
  4. チームの学習曲線を緩やか化

7段階の移行計画:

  1. 基盤整備(ディレクトリ、DI、設定)
  2. ドメイン層(エンティティ、値オブジェクト)
  3. アプリケーション層(ユースケース、ポート、DTO)
  4. インフラストラクチャ層(リポジトリ、データマッパー)
  5. プレゼンテーション層統合(パイロット機能)
  6. 全機能移行(残機能の移行)
  7. テストとドキュメント

工数とリスク

  • 工数: XL (3-4週間、約26-41日)
  • リスク: Medium(技術的未知数はあるが軽減策明確)

デザインフェーズでの優先調査項目

  1. 依存性注入: Next.js 15での実装パターン(ファクトリー vs DIコンテナ)
  2. トランザクション処理: Supabaseでの実装方法
  3. データ転送: Server Components ↔ Client Componentsのベストプラクティス
  4. エンティティ実装: クラスベース vs インターフェース+関数
  5. リポジトリ粒度: 汎用 vs 専用リポジトリパターン

成功のための鍵

  1. 段階的アプローチ: 各段階で検証とフィードバック
  2. 既存資産活用: データベース、認証、UIを最大限利用
  3. 明確なドキュメント: アーキテクチャガイド、規約
  4. 継続的レビュー: コードレビュー、ペアプログラミング
  5. テスト駆動: ドメイン層・アプリケーション層のユニットテスト

次のステップ: /kiro:spec-design clean-architecture-refactor を実行して、技術設計ドキュメントを生成してください。

Settings

.kiro/settings/は、Spec-Driven Development (SDD)フレームワークの設定ファイルを管理します。これらの設定は、AI開発エージェント(Claude Code、Cursor、Codex、Geminiなど)がプロジェクトの標準に沿った開発を行うためのルールとテンプレートを定義しています。

構成

Rules

開発プロセスにおける各フェーズのルールと原則を定義

Templates

仕様書やステアリング文書のテンプレート

Specs Templates

Steering Templates

Custom Steering Templates

使用方法

これらの設定ファイルは、以下のAI開発ツールで使用されます:

  • Claude Code (.claude/commands/kiro/, .claude/agents/kiro/)
  • Cursor IDE (.cursor/commands/kiro/)
  • Codex CLI (.codex/prompts/)
  • Gemini CLI (.gemini/commands/kiro/)
  • GitHub Copilot (.github/prompts/)

各ツールは、これらの設定を参照して一貫した開発プロセスを実現します。

Rules

SDDフレームワークにおける各フェーズのルールと原則を定義します。これらのルールは、AI開発エージェントが一貫性のある高品質な開発を行うためのガイドラインです。

Design Rules

Design Discovery (Full)

完全版の設計発見プロセス。既存コードベースの詳細な分析と、新機能との統合方法を検討します。

Design Discovery (Light)

軽量版の設計発見プロセス。小規模な変更や明確な要件に対して使用します。

Design Principles

設計の基本原則。SOLID原則、Clean Architecture、DRYなどの設計パターンを定義します。

Design Review

設計レビューのチェックリストとガイドライン。設計の品質を保証するためのレビュー項目です。

Requirements Rules

EARS Format

要件記述フォーマット(Easy Approach to Requirements Syntax)。明確で検証可能な要件を記述するためのルールです。

Gap Analysis

既存コードベースと新要件のギャップを分析する手法。影響範囲と実装戦略を明確にします。

Steering Rules

Steering Principles

ステアリング文書の作成原則。プロジェクト全体のガイドラインを定義する際のルールです。

Tasks Rules

Tasks Generation

実装タスクの生成ルール。要件と設計から具体的な実装タスクを分解する方法を定義します。

Tasks Parallel Analysis

タスクの並列実行可能性を分析するルール。依存関係を考慮した効率的なタスク実行計画を立てます。

Full Discovery Process for Technical Design

Objective

Conduct comprehensive research and analysis to ensure the technical design is based on complete, accurate, and up-to-date information.

Discovery Steps

1. Requirements Analysis

Map Requirements to Technical Needs

  • Extract all functional requirements from EARS format
  • Identify non-functional requirements (performance, security, scalability)
  • Determine technical constraints and dependencies
  • List core technical challenges

2. Existing Implementation Analysis

Understand Current System (if modifying/extending):

  • Analyze codebase structure and architecture patterns
  • Map reusable components, services, utilities
  • Identify domain boundaries and data flows
  • Document integration points and dependencies
  • Determine approach: extend vs refactor vs wrap

3. Technology Research

Investigate Best Practices and Solutions:

  • Use WebSearch to find:

    • Latest architectural patterns for similar problems
    • Industry best practices for the technology stack
    • Recent updates or changes in relevant technologies
    • Common pitfalls and solutions
  • Use WebFetch to analyze:

    • Official documentation for frameworks/libraries
    • API references and usage examples
    • Migration guides and breaking changes
    • Performance benchmarks and comparisons

4. External Dependencies Investigation

For Each External Service/Library:

  • Search for official documentation and GitHub repositories
  • Verify API signatures and authentication methods
  • Check version compatibility with existing stack
  • Investigate rate limits and usage constraints
  • Find community resources and known issues
  • Document security considerations
  • Note any gaps requiring implementation investigation

5. Architecture Pattern & Boundary Analysis

Evaluate Architectural Options:

  • Compare relevant patterns (MVC, Clean, Hexagonal, Event-driven)
  • Assess fit with existing architecture and steering principles
  • Identify domain boundaries and ownership seams required to avoid team conflicts
  • Consider scalability implications and operational concerns
  • Evaluate maintainability and team expertise
  • Document preferred pattern and rejected alternatives in research.md

6. Risk Assessment

Identify Technical Risks:

  • Performance bottlenecks and scaling limits
  • Security vulnerabilities and attack vectors
  • Integration complexity and coupling
  • Technical debt creation vs resolution
  • Knowledge gaps and training needs

Research Guidelines

Always search for:

  • External API documentation and updates
  • Security best practices for authentication/authorization
  • Performance optimization techniques for identified bottlenecks
  • Latest versions and migration paths for dependencies

Search if uncertain about:

  • Architectural patterns for specific use cases
  • Industry standards for data formats/protocols
  • Compliance requirements (GDPR, HIPAA, etc.)
  • Scalability approaches for expected load

Search Strategy

  1. Start with official sources (documentation, GitHub)
  2. Check recent blog posts and articles (last 6 months)
  3. Review Stack Overflow for common issues
  4. Investigate similar open-source implementations

Output Requirements

Capture all findings that impact design decisions in research.md using the shared template:

  • Key insights affecting architecture, technology alignment, and contracts
  • Constraints discovered during research
  • Recommended approaches and selected architecture pattern with rationale
  • Rejected alternatives and trade-offs (documented in the Design Decisions section)
  • Updated domain boundaries that inform Components & Interface Contracts
  • Risks and mitigation strategies
  • Gaps requiring further investigation during implementation

Light Discovery Process for Extensions

Objective

Quickly analyze existing system and integration requirements for feature extensions.

Focused Discovery Steps

1. Extension Point Analysis

Identify Integration Approach:

  • Locate existing extension points or interfaces
  • Determine modification scope (files, components)
  • Check for existing patterns to follow
  • Identify backward compatibility requirements

2. Dependency Check

Verify Compatibility:

  • Check version compatibility of new dependencies
  • Validate API contracts haven’t changed
  • Ensure no breaking changes in pipeline

3. Quick Technology Verification

For New Libraries Only:

  • Use WebSearch for official documentation
  • Verify basic usage patterns
  • Check for known compatibility issues
  • Confirm licensing compatibility
  • Record key findings in research.md (technology alignment section)

4. Integration Risk Assessment

Quick Risk Check:

  • Impact on existing functionality
  • Performance implications
  • Security considerations
  • Testing requirements

When to Escalate to Full Discovery

Switch to full discovery if you find:

  • Significant architectural changes needed
  • Complex external service integrations
  • Security-sensitive implementations
  • Performance-critical components
  • Unknown or poorly documented dependencies

Output Requirements

  • Clear integration approach (note boundary impacts in research.md)
  • List of files/components to modify
  • New dependencies with versions
  • Integration risks and mitigations
  • Testing focus areas

Technical Design Rules and Principles

Core Design Principles

1. Type Safety is Mandatory

  • NEVER use any type in TypeScript interfaces
  • Define explicit types for all parameters and returns
  • Use discriminated unions for error handling
  • Specify generic constraints clearly

2. Design vs Implementation

  • Focus on WHAT, not HOW
  • Define interfaces and contracts, not code
  • Specify behavior through pre/post conditions
  • Document architectural decisions, not algorithms

3. Visual Communication

  • Simple features: Basic component diagram or none
  • Medium complexity: Architecture + data flow
  • High complexity: Multiple diagrams (architecture, sequence, state)
  • Always pure Mermaid: No styling, just structure

4. Component Design Rules

  • Single Responsibility: One clear purpose per component
  • Clear Boundaries: Explicit domain ownership
  • Dependency Direction: Follow architectural layers
  • Interface Segregation: Minimal, focused interfaces
  • Team-safe Interfaces: Design boundaries that allow parallel implementation without merge conflicts
  • Research Traceability: Record boundary decisions and rationale in research.md

5. Data Modeling Standards

  • Domain First: Start with business concepts
  • Consistency Boundaries: Clear aggregate roots
  • Normalization: Balance between performance and integrity
  • Evolution: Plan for schema changes

6. Error Handling Philosophy

  • Fail Fast: Validate early and clearly
  • Graceful Degradation: Partial functionality over complete failure
  • User Context: Actionable error messages
  • Observability: Comprehensive logging and monitoring

7. Integration Patterns

  • Loose Coupling: Minimize dependencies
  • Contract First: Define interfaces before implementation
  • Versioning: Plan for API evolution
  • Idempotency: Design for retry safety
  • Contract Visibility: Surface API and event contracts in design.md while linking extended details from research.md

Documentation Standards

Language and Tone

  • Declarative: “The system authenticates users” not “The system should authenticate”
  • Precise: Specific technical terms over vague descriptions
  • Concise: Essential information only
  • Formal: Professional technical writing

Structure Requirements

  • Hierarchical: Clear section organization
  • Traceable: Requirements to components mapping
  • Complete: All aspects covered for implementation
  • Consistent: Uniform terminology throughout
  • Focused: Keep design.md centered on architecture and contracts; move investigation logs and lengthy comparisons to research.md

Section Authoring Guidance

Global Ordering

  • Default flow: Overview → Goals/Non-Goals → Requirements Traceability → Architecture → Technology Stack → System Flows → Components & Interfaces → Data Models → Optional sections.
  • Teams may swap Traceability earlier or place Data Models nearer Architecture when it improves clarity, but keep section headings intact.
  • Within each section, follow Summary → Scope → Decisions → Impacts/Risks so reviewers can scan consistently.

Requirement IDs

  • Reference requirements as 2.1, 2.3 without prefixes (no “Requirement 2.1”).
  • All requirements MUST have numeric IDs. If a requirement lacks a numeric ID, stop and fix requirements.md before continuing.
  • Use N.M-style numeric IDs where N is the top-level requirement number from requirements.md (for example, Requirement 1 → 1.1, 1.2; Requirement 2 → 2.1, 2.2).
  • Every component, task, and traceability row must reference the same canonical numeric ID.

Technology Stack

  • Include ONLY layers impacted by this feature (frontend, backend, data, messaging, infra).
  • For each layer specify tool/library + version + the role it plays; push extended rationale, comparisons, or benchmarks to research.md.
  • When extending an existing system, highlight deviations from the current stack and list new dependencies.

System Flows

  • Add diagrams only when they clarify behavior:
    • Sequence for multi-step interactions
    • Process/State for branching rules or lifecycle
    • Data/Event for pipelines or async patterns
  • Always use pure Mermaid. If no complex flow exists, omit the entire section.

Requirements Traceability

  • Use the standard table (Requirement | Summary | Components | Interfaces | Flows) to prove coverage.
  • Collapse to bullet form only when a single requirement maps 1:1 to a component.
  • Prefer the component summary table for simple mappings; reserve the full traceability table for complex or compliance-sensitive requirements.
  • Re-run this mapping whenever requirements or components change to avoid drift.

Components & Interfaces Authoring

  • Group components by domain/layer and provide one block per component.
  • Begin with a summary table listing Component, Domain, Intent, Requirement coverage, key dependencies, and selected contracts.
  • Table fields: Intent (one line), Requirements (2.1, 2.3), Owner/Reviewers (optional).
  • Dependencies table must mark each entry as Inbound/Outbound/External and assign Criticality (P0 blocking, P1 high-risk, P2 informational).
  • Summaries of external dependency research stay here; detailed investigation (API signatures, rate limits, migration notes) belongs in research.md.
  • design.md must remain a self-contained reviewer artifact. Reference research.md only for background, and restate any conclusions or decisions here.
  • Contracts: tick only the relevant types (Service/API/Event/Batch/State). Unchecked types should not appear later in the component section.
  • Service interfaces must declare method signatures, inputs/outputs, and error envelopes. API/Event/Batch contracts require schema tables or bullet lists covering trigger, payload, delivery, idempotency.
  • Use Integration & Migration Notes, Validation Hooks, and Open Questions / Risks to document rollout strategy, observability, and unresolved decisions.
  • Detail density rules:
    • Full block: components introducing new boundaries (logic hooks, shared services, external integrations, data layers).
    • Summary-only: presentational/UI components with no new boundaries (plus a short Implementation Note if needed).
  • Implementation Notes must combine Integration / Validation / Risks into a single bulleted subsection to reduce repetition.
  • Prefer lists or inline descriptors for short data (dependencies, contract selections). Use tables only when comparing multiple items.

Shared Interfaces & Props

  • Define a base interface (e.g., BaseUIPanelProps) for recurring UI components and extend it per component to capture only the deltas.
  • Hooks, utilities, and integration adapters that introduce new contracts should still include full TypeScript signatures.
  • When reusing a base contract, reference it explicitly (e.g., “Extends BaseUIPanelProps with onSubmitAnswer callback”) instead of duplicating the code block.

Data Models

  • Domain Model covers aggregates, entities, value objects, domain events, and invariants. Add Mermaid diagrams only when relationships are non-trivial.
  • Logical Data Model should articulate structure, indexing, sharding, and storage-specific considerations (event store, KV/wide-column) relevant to the change.
  • Data Contracts & Integration section documents API payloads, event schemas, and cross-service synchronization patterns when the feature crosses boundaries.
  • Lengthy type definitions or vendor-specific option objects should be placed in the Supporting References section within design.md, linked from the relevant section. Investigation notes stay in research.md.
  • Supporting References usage is optional; only create it when keeping the content in the main body would reduce readability. All decisions must still appear in the main sections so design.md stands alone.

Error/Testing/Security/Performance Sections

  • Record only feature-specific decisions or deviations. Link or reference organization-wide standards (steering) for baseline practices instead of restating them.

Diagram & Text Deduplication

  • Do not restate diagram content verbatim in prose. Use the text to highlight key decisions, trade-offs, or impacts that are not obvious from the visual.
  • When a decision is fully captured in the diagram annotations, a short “Key Decisions” bullet is sufficient.

General Deduplication

  • Avoid repeating the same information across Overview, Architecture, and Components. Reference earlier sections when context is identical.
  • If a requirement/component relationship is captured in the summary table, do not rewrite it elsewhere unless extra nuance is added.

Diagram Guidelines

When to include a diagram

  • Architecture: Use a structural diagram when 3+ components or external systems interact.
  • Sequence: Draw a sequence diagram when calls/handshakes span multiple steps.
  • State / Flow: Capture complex state machines or business flows in a dedicated diagram.
  • ER: Provide an entity-relationship diagram for non-trivial data models.
  • Skip: Minor one-component changes generally do not need diagrams.

Mermaid requirements

graph TB
    Client --> ApiGateway
    ApiGateway --> ServiceA
    ApiGateway --> ServiceB
    ServiceA --> Database
  • Plain Mermaid only – avoid custom styling or unsupported syntax.
  • Node IDs – alphanumeric plus underscores only (e.g., Client, ServiceA). Do not use @, /, or leading -.
  • Labels – simple words. Do not embed parentheses (), square brackets [], quotes ", or slashes /.
    • DnD[@dnd-kit/core] → invalid ID (@).
    • UI[KanbanBoard(React)] → invalid label (()).
    • DndKit[dnd-kit core] → use plain text in labels, keep technology details in the accompanying description.
    • ℹ️ Mermaid strict-mode will otherwise fail with errors like Expecting 'SQE' ... got 'PS'; remove punctuation from labels before rendering.
  • Edges – show data or control flow direction.
  • Groups – using Mermaid subgraphs to cluster related components is allowed; use it sparingly for clarity.

Quality Metrics

Design Completeness Checklist

  • All requirements addressed
  • No implementation details leaked
  • Clear component boundaries
  • Explicit error handling
  • Comprehensive test strategy
  • Security considered
  • Performance targets defined
  • Migration path clear (if applicable)

Common Anti-patterns to Avoid

❌ Mixing design with implementation ❌ Vague interface definitions ❌ Missing error scenarios ❌ Ignored non-functional requirements ❌ Overcomplicated architectures ❌ Tight coupling between components ❌ Missing data consistency strategy ❌ Incomplete dependency analysis

Design Review Process

Objective

Conduct interactive quality review of technical design documents to ensure they are solid enough to proceed to implementation with acceptable risk.

Review Philosophy

  • Quality assurance, not perfection seeking
  • Critical focus: Limit to 3 most important concerns
  • Interactive dialogue: Engage with designer, not one-way evaluation
  • Balanced assessment: Recognize strengths and weaknesses
  • Clear decision: Definitive GO/NO-GO with rationale

Scope & Non-Goals

  • Scope: Evaluate the quality of the design document against project context and standards to decide GO/NO-GO.
  • Non-Goals: Do not perform implementation-level design, deep technology research, or finalize technology choices. Defer such items to the design phase iteration.

Core Review Criteria

1. Existing Architecture Alignment (Critical)

  • Integration with existing system boundaries and layers
  • Consistency with established architectural patterns
  • Proper dependency direction and coupling management
  • Alignment with current module organization

2. Design Consistency & Standards

  • Adherence to project naming conventions and code standards
  • Consistent error handling and logging strategies
  • Uniform configuration and dependency management
  • Alignment with established data modeling patterns

3. Extensibility & Maintainability

  • Design flexibility for future requirements
  • Clear separation of concerns and single responsibility
  • Testability and debugging considerations
  • Appropriate complexity for requirements

4. Type Safety & Interface Design

  • Proper type definitions and interface contracts
  • Avoidance of unsafe patterns (e.g., any in TypeScript)
  • Clear API boundaries and data structures
  • Input validation and error handling coverage

Review Process

Step 1: Analyze

Analyze design against all review criteria, focusing on critical issues impacting integration, maintainability, complexity, and requirements fulfillment.

Step 2: Identify Critical Issues (≤3)

For each issue:

🔴 **Critical Issue [1-3]**: [Brief title]
**Concern**: [Specific problem]
**Impact**: [Why it matters]
**Suggestion**: [Concrete improvement]
**Traceability**: [Requirement ID/section from requirements.md]
**Evidence**: [Design doc section/heading]

Step 3: Recognize Strengths

Acknowledge 1-2 strong aspects to maintain balanced feedback.

Step 4: Decide GO/NO-GO

  • GO: No critical architectural misalignment, requirements addressed, clear implementation path, acceptable risks
  • NO-GO: Fundamental conflicts, critical gaps, high failure risk, disproportionate complexity

Traceability & Evidence

  • Link each critical issue to the relevant requirement(s) from requirements.md (ID or section).
  • Cite evidence locations in the design document (section/heading, diagram, or artifact) to support the assessment.
  • When applicable, reference constraints from steering context to justify the issue.

Output Format

Design Review Summary

2-3 sentences on overall quality and readiness.

Critical Issues (≤3)

For each: Issue, Impact, Recommendation, Traceability (e.g., 1.1, 1.2), Evidence (design.md section).

Design Strengths

1-2 positive aspects.

Final Assessment

Decision (GO/NO-GO), Rationale (1-2 sentences), Next Steps.

Interactive Discussion

Engage on designer’s perspective, alternatives, clarifications, and necessary changes.

Length & Focus

  • Summary: 2–3 sentences
  • Each critical issue: 5–7 lines total (including Issue/Impact/Recommendation/Traceability/Evidence)
  • Overall review: keep concise (~400 words guideline)

Review Guidelines

  1. Critical Focus: Only flag issues that significantly impact success
  2. Constructive Tone: Provide solutions, not just criticism
  3. Interactive Approach: Engage in dialogue rather than one-way evaluation
  4. Balanced Assessment: Recognize both strengths and weaknesses
  5. Clear Decision: Make definitive GO/NO-GO recommendation
  6. Actionable Feedback: Ensure all suggestions are implementable

Final Checklist

  • Critical Issues ≤ 3 and each includes Impact and Recommendation
  • Traceability: Each issue references requirement ID/section
  • Evidence: Each issue cites design doc location
  • Decision: GO/NO-GO with clear rationale and next steps

EARS Format Guidelines

Overview

EARS (Easy Approach to Requirements Syntax) is the standard format for acceptance criteria in spec-driven development.

EARS patterns describe the logical structure of a requirement (condition + subject + response) and are not tied to any particular natural language.
All acceptance criteria should be written in the target language configured for the specification (for example, spec.json.language / en).
Keep EARS trigger keywords and fixed phrases in English (When, If, While, Where, The system shall, The [system] shall) and localize only the variable parts ([event], [precondition], [trigger], [feature is included], [response/action]) into the target language. Do not interleave target-language text inside the trigger or fixed English phrases themselves.

Primary EARS Patterns

1. Event-Driven Requirements

  • Pattern: When [event], the [system] shall [response/action]
  • Use Case: Responses to specific events or triggers
  • Example: When user clicks checkout button, the Checkout Service shall validate cart contents

2. State-Driven Requirements

  • Pattern: While [precondition], the [system] shall [response/action]
  • Use Case: Behavior dependent on system state or preconditions
  • Example: While payment is processing, the Checkout Service shall display loading indicator

3. Unwanted Behavior Requirements

  • Pattern: If [trigger], the [system] shall [response/action]
  • Use Case: System response to errors, failures, or undesired situations
  • Example: If invalid credit card number is entered, then the website shall display error message

4. Optional Feature Requirements

  • Pattern: Where [feature is included], the [system] shall [response/action]
  • Use Case: Requirements for optional or conditional features
  • Example: Where the car has a sunroof, the car shall have a sunroof control panel

5. Ubiquitous Requirements

  • Pattern: The [system] shall [response/action]
  • Use Case: Always-active requirements and fundamental system properties
  • Example: The mobile phone shall have a mass of less than 100 grams

Combined Patterns

  • While [precondition], when [event], the [system] shall [response/action]
  • When [event] and [additional condition], the [system] shall [response/action]

Subject Selection Guidelines

  • Software Projects: Use concrete system/service name (e.g., “Checkout Service”, “User Auth Module”)
  • Process/Workflow: Use responsible team/role (e.g., “Support Team”, “Review Process”)
  • Non-Software: Use appropriate subject (e.g., “Marketing Campaign”, “Documentation”)

Quality Criteria

  • Requirements must be testable, verifiable, and describe a single behavior.
  • Use objective language: “shall” for mandatory behavior, “should” for recommendations; avoid ambiguous terms.
  • Follow EARS syntax: [condition], the [system] shall [response/action].

Gap Analysis Process

Objective

Analyze the gap between requirements and existing codebase to inform implementation strategy decisions.

Analysis Framework

1. Current State Investigation

  • Scan for domain-related assets:

    • Key files/modules and directory layout
    • Reusable components/services/utilities
    • Dominant architecture patterns and constraints
  • Extract conventions:

    • Naming, layering, dependency direction
    • Import/export patterns and dependency hotspots
    • Testing placement and approach
  • Note integration surfaces:

    • Data models/schemas, API clients, auth mechanisms

2. Requirements Feasibility Analysis

  • From EARS requirements, list technical needs:

    • Data models, APIs/services, UI/components
    • Business rules/validation
    • Non-functionals: security, performance, scalability, reliability
  • Identify gaps and constraints:

    • Missing capabilities in current codebase
    • Unknowns to be researched later (mark as “Research Needed”)
    • Constraints from existing architecture and patterns
  • Note complexity signals:

    • Simple CRUD / algorithmic logic / workflows / external integrations

3. Implementation Approach Options

Option A: Extend Existing Components

When to consider: Feature fits naturally into existing structure

  • Which files/modules to extend:

    • Identify specific files requiring changes
    • Assess impact on existing functionality
    • Evaluate backward compatibility concerns
  • Compatibility assessment:

    • Check if extension respects existing interfaces
    • Verify no breaking changes to consumers
    • Assess test coverage impact
  • Complexity and maintainability:

    • Evaluate cognitive load of additional functionality
    • Check if single responsibility principle is maintained
    • Assess if file size remains manageable

Trade-offs:

  • ✅ Minimal new files, faster initial development
  • ✅ Leverages existing patterns and infrastructure
  • ❌ Risk of bloating existing components
  • ❌ May complicate existing logic

Option B: Create New Components

When to consider: Feature has distinct responsibility or existing components are already complex

  • Rationale for new creation:

    • Clear separation of concerns justifies new file
    • Existing components are already complex
    • Feature has distinct lifecycle or dependencies
  • Integration points:

    • How new components connect to existing system
    • APIs or interfaces exposed
    • Dependencies on existing components
  • Responsibility boundaries:

    • Clear definition of what new component owns
    • Interfaces with existing components
    • Data flow and control flow

Trade-offs:

  • ✅ Clean separation of concerns
  • ✅ Easier to test in isolation
  • ✅ Reduces complexity in existing components
  • ❌ More files to navigate
  • ❌ Requires careful interface design

Option C: Hybrid Approach

When to consider: Complex features requiring both extension and new creation

  • Combination strategy:

    • Which parts extend existing components
    • Which parts warrant new components
    • How they interact
  • Phased implementation:

    • Initial phase: minimal viable changes
    • Subsequent phases: refactoring or new components
    • Migration strategy if needed
  • Risk mitigation:

    • Incremental rollout approach
    • Feature flags or configuration
    • Rollback strategy

Trade-offs:

  • ✅ Balanced approach for complex features
  • ✅ Allows iterative refinement
  • ❌ More complex planning required
  • ❌ Potential for inconsistency if not well-coordinated

4. Out-of-Scope for Gap Analysis

  • Defer deep research activities to the design phase.
  • Record unknowns as concise “Research Needed” items only.

5. Implementation Complexity & Risk

  • Effort:
    • S (1–3 days): existing patterns, minimal deps, straightforward integration
    • M (3–7 days): some new patterns/integrations, moderate complexity
    • L (1–2 weeks): significant functionality, multiple integrations or workflows
    • XL (2+ weeks): architectural changes, unfamiliar tech, broad impact
  • Risk:
    • High: unknown tech, complex integrations, architectural shifts, unclear perf/security path
    • Medium: new patterns with guidance, manageable integrations, known perf solutions
    • Low: extend established patterns, familiar tech, clear scope, minimal integration

Output Checklist

  • Requirement-to-Asset Map with gaps tagged (Missing / Unknown / Constraint)
  • Options A/B/C with short rationale and trade-offs
  • Effort (S/M/L/XL) and Risk (High/Medium/Low) with one-line justification each
  • Recommendations for design phase:
    • Preferred approach and key decisions
    • Research items to carry forward

Principles

  • Information over decisions: Provide analysis and options, not final choices
  • Multiple viable options: Offer credible alternatives when applicable
  • Explicit gaps and assumptions: Flag unknowns and constraints clearly
  • Context-aware: Align with existing patterns and architecture limits
  • Transparent effort and risk: Justify labels succinctly

Steering Principles

Steering files are project memory, not exhaustive specifications.


Content Granularity

Golden Rule

“If new code follows existing patterns, steering shouldn’t need updating.”

✅ Document

  • Organizational patterns (feature-first, layered)
  • Naming conventions (PascalCase rules)
  • Import strategies (absolute vs relative)
  • Architectural decisions (state management)
  • Technology standards (key frameworks)

❌ Avoid

  • Complete file listings
  • Every component description
  • All dependencies
  • Implementation details
  • Agent-specific tooling directories (e.g. .cursor/, .gemini/, .claude/)
  • Detailed documentation of .kiro/ metadata directories (settings, automation)

Example Comparison

Bad (Specification-like):

- /components/Button.tsx - Primary button with variants
- /components/Input.tsx - Text input with validation
- /components/Modal.tsx - Modal dialog
... (50+ files)

Good (Project Memory):

## UI Components (`/components/ui/`)
Reusable, design-system aligned primitives
- Named by function (Button, Input, Modal)
- Export component + TypeScript interface
- No business logic

Security

Never include:

  • API keys, passwords, credentials
  • Database URLs, internal IPs
  • Secrets or sensitive data

Quality Standards

  • Single domain: One topic per file
  • Concrete examples: Show patterns with code
  • Explain rationale: Why decisions were made
  • Maintainable size: 100-200 lines typical

Preservation (when updating)

  • Preserve user sections and custom examples
  • Additive by default (add, don’t replace)
  • Add updated_at timestamp
  • Note why changes were made

Notes

  • Templates are starting points, customize as needed
  • Follow same granularity principles as core steering
  • All steering files loaded as project memory
  • Light references to .kiro/specs/ and .kiro/steering/ are acceptable; avoid other .kiro/ directories
  • Custom files equally important as core files

File-Specific Focus

  • product.md: Purpose, value, business context (not exhaustive features)
  • tech.md: Key frameworks, standards, conventions (not all dependencies)
  • structure.md: Organization patterns, naming rules (not directory trees)
  • Custom files: Specialized patterns (API, testing, security, etc.)

Task Generation Rules

Core Principles

1. Natural Language Descriptions

Focus on capabilities and outcomes, not code structure.

Describe:

  • What functionality to achieve
  • Business logic and behavior
  • Features and capabilities
  • Domain language and concepts
  • Data relationships and workflows

Avoid:

  • File paths and directory structure
  • Function/method names and signatures
  • Type definitions and interfaces
  • Class names and API contracts
  • Specific data structures

Rationale: Implementation details (files, methods, types) are defined in design.md. Tasks describe the functional work to be done.

2. Task Integration & Progression

Every task must:

  • Build on previous outputs (no orphaned code)
  • Connect to the overall system (no hanging features)
  • Progress incrementally (no big jumps in complexity)
  • Validate core functionality early in sequence
  • Respect architecture boundaries defined in design.md (Architecture Pattern & Boundary Map)
  • Honor interface contracts documented in design.md
  • Use major task summaries sparingly—omit detail bullets if the work is fully captured by child tasks.

End with integration tasks to wire everything together.

3. Flexible Task Sizing

Guidelines:

  • Major tasks: As many sub-tasks as logically needed (group by cohesion)
  • Sub-tasks: 1-3 hours each, 3-10 details per sub-task
  • Balance between too granular and too broad

Don’t force arbitrary numbers - let logical grouping determine structure.

4. Requirements Mapping

End each task detail section with:

  • _Requirements: X.X, Y.Y_ listing only numeric requirement IDs (comma-separated). Never append descriptive text, parentheses, translations, or free-form labels.
  • For cross-cutting requirements, list every relevant requirement ID. All requirements MUST have numeric IDs in requirements.md. If an ID is missing, stop and correct requirements.md before generating tasks.
  • Reference components/interfaces from design.md when helpful (e.g., _Contracts: AuthService API)

5. Code-Only Focus

Include ONLY:

  • Coding tasks (implementation)
  • Testing tasks (unit, integration, E2E)
  • Technical setup tasks (infrastructure, configuration)

Exclude:

  • Deployment tasks
  • Documentation tasks
  • User testing
  • Marketing/business activities

Optional Test Coverage Tasks

  • When the design already guarantees functional coverage and rapid MVP delivery is prioritized, mark purely test-oriented follow-up work (e.g., baseline rendering/unit tests) as optional using the - [ ]* checkbox form.
  • Only apply the optional marker when the sub-task directly references acceptance criteria from requirements.md in its detail bullets.
  • Never mark implementation work or integration-critical verification as optional—reserve * for auxiliary/deferrable test coverage that can be revisited post-MVP.

Task Hierarchy Rules

Maximum 2 Levels

  • Level 1: Major tasks (1, 2, 3, 4…)
  • Level 2: Sub-tasks (1.1, 1.2, 2.1, 2.2…)
  • No deeper nesting (no 1.1.1)
  • If a major task would contain only a single actionable item, collapse the structure and promote the sub-task to the major level (e.g., replace 1.1 with 1.).
  • When a major task exists purely as a container, keep the checkbox description concise and avoid duplicating detailed bullets—reserve specifics for its sub-tasks.

Sequential Numbering

  • Major tasks MUST increment: 1, 2, 3, 4, 5…
  • Sub-tasks reset per major task: 1.1, 1.2, then 2.1, 2.2…
  • Never repeat major task numbers

Parallel Analysis (default)

  • Assume parallel analysis is enabled unless explicitly disabled (e.g. --sequential flag).
  • Identify tasks that can run concurrently when all conditions hold:
    • No data dependency on other pending tasks
    • No shared file or resource contention
    • No prerequisite review/approval from another task
  • Validate that identified parallel tasks operate within separate boundaries defined in the Architecture Pattern & Boundary Map.
  • Confirm API/event contracts from design.md do not overlap in ways that cause conflicts.
  • Append (P) immediately after the task number for each parallel-capable task:
    • Example: - [ ] 2.1 (P) Build background worker
    • Apply to both major tasks and sub-tasks when appropriate.
  • If sequential mode is requested, omit (P) markers entirely.
  • Group parallel tasks logically (same parent when possible) and highlight any ordering caveats in detail bullets.
  • Explicitly call out dependencies that prevent (P) even when tasks look similar.

Checkbox Format

- [ ] 1. Major task description
- [ ] 1.1 Sub-task description
  - Detail item 1
  - Detail item 2
  - _Requirements: X.X_

- [ ] 1.2 Sub-task description
  - Detail items...
  - _Requirements: Y.Y_

- [ ] 1.3 Sub-task description
  - Detail items...
  - _Requirements: Z.Z, W.W_

- [ ] 2. Next major task (NOT 1 again!)
- [ ] 2.1 Sub-task...

Requirements Coverage

Mandatory Check:

  • ALL requirements from requirements.md MUST be covered
  • Cross-reference every requirement ID with task mappings
  • If gaps found: Return to requirements or design phase
  • No requirement should be left without corresponding tasks

Use N.M-style numeric requirement IDs where N is the top-level requirement number from requirements.md (for example, Requirement 1 → 1.1, 1.2; Requirement 2 → 2.1, 2.2), and M is a local index within that requirement group.

Document any intentionally deferred requirements with rationale.

Parallel Task Analysis Rules

Purpose

Provide a consistent way to identify implementation tasks that can be safely executed in parallel while generating tasks.md.

When to Consider Tasks Parallel

Only mark a task as parallel-capable when all of the following are true:

  1. No data dependency on pending tasks.
  2. No conflicting files or shared mutable resources are touched.
  3. No prerequisite review/approval from another task is required beforehand.
  4. Environment/setup work needed by this task is already satisfied or covered within the task itself.

Marking Convention

  • Append (P) immediately after the numeric identifier for each qualifying task.
    • Example: - [ ] 2.1 (P) Build background worker for emails
  • Apply (P) to both major tasks and sub-tasks when appropriate.
  • If sequential execution is requested (e.g. via --sequential flag), omit (P) markers entirely.
  • Keep (P) outside of checkbox brackets to avoid confusion with completion state.

Grouping & Ordering Guidelines

  • Group parallel tasks under the same parent whenever the work belongs to the same theme.
  • List obvious prerequisites or caveats in the detail bullets (e.g., “Requires schema migration from 1.2”).
  • When two tasks look similar but are not parallel-safe, call out the blocking dependency explicitly.
  • Skip marking container-only major tasks (those without their own actionable detail bullets) with (P)—evaluate parallel execution at the sub-task level instead.

Quality Checklist

Before marking a task with (P), ensure you have:

  • Verified that running this task concurrently will not create merge or deployment conflicts.
  • Captured any shared state expectations in the detail bullets.
  • Confirmed that the implementation can be tested independently.

If any check fails, do not mark the task with (P) and explain the dependency in the task details.

Templates

SDDフレームワークで使用する各種ドキュメントテンプレートです。これらのテンプレートを使用することで、一貫性のある仕様書とステアリング文書を作成できます。

Specs Templates

新機能や変更の仕様書を作成するためのテンプレート群です。

Steering Templates

プロジェクト全体のガイドラインを定義するためのテンプレート群です。

  • Product Template: プロダクト要件とビジネスルールのテンプレート
  • Tech Template: 技術スタックと技術的制約のテンプレート
  • Structure Template: プロジェクト構造とアーキテクチャ原則のテンプレート

Custom Steering Templates

特定のドメインに特化したステアリングテンプレート群です。

使用方法

  1. 適切なテンプレートを選択
  2. プロジェクト固有の情報で埋める
  3. .kiro/steering/または.kiro/specs/に保存
  4. AI開発エージェントがこれらを参照して開発を進める

Specs Templates

新機能や変更の仕様書を作成するためのテンプレート群です。

Templates

  • Design: アーキテクチャ設計書のテンプレート
  • Requirements: 要件定義書のテンプレート
  • Requirements Init: 要件初期化のテンプレート
  • Research: 技術調査レポートのテンプレート
  • Tasks: 実装タスクリストのテンプレート

使用方法

  1. 適切なテンプレートを選択
  2. プロジェクト固有の情報で埋める
  3. .kiro/specs/{feature-name}/に保存
  4. AI開発エージェントがこれらを参照して開発を進める

Design Document Template


Purpose: Provide sufficient detail to ensure implementation consistency across different implementers, preventing interpretation drift.

Approach:

  • Include essential sections that directly inform implementation decisions
  • Omit optional sections unless critical to preventing implementation errors
  • Match detail level to feature complexity
  • Use diagrams and tables over lengthy prose

Warning: Approaching 1000 lines indicates excessive feature complexity that may require design simplification.

Sections may be reordered (e.g., surfacing Requirements Traceability earlier or moving Data Models nearer Architecture) when it improves clarity. Within each section, keep the flow Summary → Scope → Decisions → Impacts/Risks so reviewers can scan consistently.

Overview

2-3 paragraphs max Purpose: This feature delivers [specific value] to [target users]. Users: [Target user groups] will utilize this for [specific workflows]. Impact (if applicable): Changes the current [system state] by [specific modifications].

Goals

  • Primary objective 1
  • Primary objective 2
  • Success criteria

Non-Goals

  • Explicitly excluded functionality
  • Future considerations outside current scope
  • Integration points deferred

Architecture

Reference detailed discovery notes in research.md only for background; keep design.md self-contained for reviewers by capturing all decisions and contracts here. Capture key decisions in text and let diagrams carry structural detail—avoid repeating the same information in prose.

Existing Architecture Analysis (if applicable)

When modifying existing systems:

  • Current architecture patterns and constraints
  • Existing domain boundaries to be respected
  • Integration points that must be maintained
  • Technical debt addressed or worked around

Architecture Pattern & Boundary Map

RECOMMENDED: Include Mermaid diagram showing the chosen architecture pattern and system boundaries (required for complex features, optional for simple additions)

Architecture Integration:

  • Selected pattern: [name and brief rationale]
  • Domain/feature boundaries: [how responsibilities are separated to avoid conflicts]
  • Existing patterns preserved: [list key patterns]
  • New components rationale: [why each is needed]
  • Steering compliance: [principles maintained]

Technology Stack

LayerChoice / VersionRole in FeatureNotes
Frontend / CLI
Backend / Services
Data / Storage
Messaging / Events
Infrastructure / Runtime

Keep rationale concise here and, when more depth is required (trade-offs, benchmarks), add a short summary plus pointer to the Supporting References section and research.md for raw investigation notes.

System Flows

Provide only the diagrams needed to explain non-trivial flows. Use pure Mermaid syntax. Common patterns:

  • Sequence (multi-party interactions)
  • Process / state (branching logic or lifecycle)
  • Data / event flow (pipelines, async messaging)

Skip this section entirely for simple CRUD changes.

Describe flow-level decisions (e.g., gating conditions, retries) briefly after the diagram instead of restating each step.

Requirements Traceability

Use this section for complex or compliance-sensitive features where requirements span multiple domains. Straightforward 1:1 mappings can rely on the Components summary table.

Map each requirement ID (e.g., 2.1) to the design elements that realize it.

RequirementSummaryComponentsInterfacesFlows
1.1
1.2

Omit this section only when a single component satisfies a single requirement without cross-cutting concerns.

Components and Interfaces

Provide a quick reference before diving into per-component details.

  • Summaries can be a table or compact list. Example table:
    ComponentDomain/LayerIntentReq CoverageKey Dependencies (P0/P1)Contracts
    ExampleComponentUIDisplays XYZ1, 2GameProvider (P0), MapPanel (P1)Service, State
  • Only components introducing new boundaries (e.g., logic hooks, external integrations, persistence) require full detail blocks. Simple presentation components can rely on the summary row plus a short Implementation Note.

Group detailed blocks by domain or architectural layer. For each detailed component, list requirement IDs as 2.1, 2.3 (omit “Requirement”). When multiple UI components share the same contract, reference a base interface/props definition instead of duplicating code blocks.

[Domain / Layer]

[Component Name]

FieldDetail
Intent1-line description of the responsibility
Requirements2.1, 2.3
Owner / Reviewers(optional)

Responsibilities & Constraints

  • Primary responsibility
  • Domain boundary and transaction scope
  • Data ownership / invariants

Dependencies

  • Inbound: Component/service name — purpose (Criticality)
  • Outbound: Component/service name — purpose (Criticality)
  • External: Service/library — purpose (Criticality)

Summarize external dependency findings here; deeper investigation (API signatures, rate limits, migration notes) lives in research.md.

Contracts: Service [ ] / API [ ] / Event [ ] / Batch [ ] / State [ ] ← check only the ones that apply.

Service Interface
interface [ComponentName]Service {
  methodName(input: InputType): Result<OutputType, ErrorType>;
}
  • Preconditions:
  • Postconditions:
  • Invariants:
API Contract
MethodEndpointRequestResponseErrors
POST/api/resourceCreateRequestResource400, 409, 500
Event Contract
  • Published events:
  • Subscribed events:
  • Ordering / delivery guarantees:
Batch / Job Contract
  • Trigger:
  • Input / validation:
  • Output / destination:
  • Idempotency & recovery:
State Management
  • State model:
  • Persistence & consistency:
  • Concurrency strategy:

Implementation Notes

  • Integration:
  • Validation:
  • Risks:

Data Models

Focus on the portions of the data landscape that change with this feature.

Domain Model

  • Aggregates and transactional boundaries
  • Entities, value objects, domain events
  • Business rules & invariants
  • Optional Mermaid diagram for complex relationships

Logical Data Model

Structure Definition:

  • Entity relationships and cardinality
  • Attributes and their types
  • Natural keys and identifiers
  • Referential integrity rules

Consistency & Integrity:

  • Transaction boundaries
  • Cascading rules
  • Temporal aspects (versioning, audit)

Physical Data Model

When to include: When implementation requires specific storage design decisions

For Relational Databases:

  • Table definitions with data types
  • Primary/foreign keys and constraints
  • Indexes and performance optimizations
  • Partitioning strategy for scale

For Document Stores:

  • Collection structures
  • Embedding vs referencing decisions
  • Sharding key design
  • Index definitions

For Event Stores:

  • Event schema definitions
  • Stream aggregation strategies
  • Snapshot policies
  • Projection definitions

For Key-Value/Wide-Column Stores:

  • Key design patterns
  • Column families or value structures
  • TTL and compaction strategies

Data Contracts & Integration

API Data Transfer

  • Request/response schemas
  • Validation rules
  • Serialization format (JSON, Protobuf, etc.)

Event Schemas

  • Published event structures
  • Schema versioning strategy
  • Backward/forward compatibility rules

Cross-Service Data Management

  • Distributed transaction patterns (Saga, 2PC)
  • Data synchronization strategies
  • Eventual consistency handling

Skip subsections that are not relevant to this feature.

Error Handling

Error Strategy

Concrete error handling patterns and recovery mechanisms for each error type.

Error Categories and Responses

User Errors (4xx): Invalid input → field-level validation; Unauthorized → auth guidance; Not found → navigation help System Errors (5xx): Infrastructure failures → graceful degradation; Timeouts → circuit breakers; Exhaustion → rate limiting
Business Logic Errors (422): Rule violations → condition explanations; State conflicts → transition guidance

Process Flow Visualization (when complex business logic exists): Include Mermaid flowchart only for complex error scenarios with business workflows.

Monitoring

Error tracking, logging, and health monitoring implementation.

Testing Strategy

Default sections (adapt names/sections to fit the domain)

  • Unit Tests: 3–5 items from core functions/modules (e.g., auth methods, subscription logic)
  • Integration Tests: 3–5 cross-component flows (e.g., webhook handling, notifications)
  • E2E/UI Tests (if applicable): 3–5 critical user paths (e.g., forms, dashboards)
  • Performance/Load (if applicable): 3–4 items (e.g., concurrency, high-volume ops)

Optional Sections (include when relevant)

Security Considerations

Use this section for features handling auth, sensitive data, external integrations, or user permissions. Capture only decisions unique to this feature; defer baseline controls to steering docs.

  • Threat modeling, security controls, compliance requirements
  • Authentication and authorization patterns
  • Data protection and privacy considerations

Performance & Scalability

Use this section when performance targets, high load, or scaling concerns exist. Record only feature-specific targets or trade-offs and rely on steering documents for general practices.

  • Target metrics and measurement strategies
  • Scaling approaches (horizontal/vertical)
  • Caching strategies and optimization techniques

Migration Strategy

Include a Mermaid flowchart showing migration phases when schema/data movement is required.

  • Phase breakdown, rollback triggers, validation checkpoints

Supporting References (Optional)

  • Create this section only when keeping the information in the main body would hurt readability (e.g., very long TypeScript definitions, vendor option matrices, exhaustive schema tables). Keep decision-making context in the main sections so the design stays self-contained.
  • Link to the supporting references from the main text instead of inlining large snippets.
  • Background research notes and comparisons continue to live in research.md, but their conclusions must be summarized in the main design.

Requirements Document

Introduction

{{INTRODUCTION}}

Requirements

Requirement 1: {{REQUIREMENT_AREA_1}}

Objective: As a {{ROLE}}, I want {{CAPABILITY}}, so that {{BENEFIT}}

Acceptance Criteria

  1. When [event], the [system] shall [response/action]
  2. If [trigger], then the [system] shall [response/action]
  3. While [precondition], the [system] shall [response/action]
  4. Where [feature is included], the [system] shall [response/action]
  5. The [system] shall [response/action]

Requirement 2: {{REQUIREMENT_AREA_2}}

Objective: As a {{ROLE}}, I want {{CAPABILITY}}, so that {{BENEFIT}}

Acceptance Criteria

  1. When [event], the [system] shall [response/action]
  2. When [event] and [condition], the [system] shall [response/action]

Requirements Document

Project Description (Input)

{{PROJECT_DESCRIPTION}}

Requirements

Research & Design Decisions Template


Purpose: Capture discovery findings, architectural investigations, and rationale that inform the technical design.

Usage:

  • Log research activities and outcomes during the discovery phase.
  • Document design decision trade-offs that are too detailed for design.md.
  • Provide references and evidence for future audits or reuse.

Summary

  • Feature: <feature-name>
  • Discovery Scope: New Feature / Extension / Simple Addition / Complex Integration
  • Key Findings:
    • Finding 1
    • Finding 2
    • Finding 3

Research Log

Document notable investigation steps and their outcomes. Group entries by topic for readability.

[Topic or Question]

  • Context: What triggered this investigation?
  • Sources Consulted: Links, documentation, API references, benchmarks
  • Findings: Concise bullet points summarizing the insights
  • Implications: How this affects architecture, contracts, or implementation

Repeat the subsection for each major topic.

Architecture Pattern Evaluation

List candidate patterns or approaches that were considered. Use the table format where helpful.

OptionDescriptionStrengthsRisks / LimitationsNotes
HexagonalPorts & adapters abstraction around core domainClear boundaries, testable coreRequires adapter layer build-outAligns with existing steering principle X

Design Decisions

Record major decisions that influence design.md. Focus on choices with significant trade-offs.

Decision: <Title>

  • Context: Problem or requirement driving the decision
  • Alternatives Considered:
    1. Option A — short description
    2. Option B — short description
  • Selected Approach: What was chosen and how it works
  • Rationale: Why this approach fits the current project context
  • Trade-offs: Benefits vs. compromises
  • Follow-up: Items to verify during implementation or testing

Repeat the subsection for each decision.

Risks & Mitigations

  • Risk 1 — Proposed mitigation
  • Risk 2 — Proposed mitigation
  • Risk 3 — Proposed mitigation

References

Provide canonical links and citations (official docs, standards, ADRs, internal guidelines).

  • Title — brief note on relevance

Implementation Plan

Task Format Template

Use whichever pattern fits the work breakdown:

Major task only

  • {{NUMBER}}. {{TASK_DESCRIPTION}}{{PARALLEL_MARK}}
    • {{DETAIL_ITEM_1}} (Include details only when needed. If the task stands alone, omit bullet items.)
    • Requirements: {{REQUIREMENT_IDS}}

Major + Sub-task structure

  • {{MAJOR_NUMBER}}. {{MAJOR_TASK_SUMMARY}}
  • {{MAJOR_NUMBER}}.{{SUB_NUMBER}} {{SUB_TASK_DESCRIPTION}}{{SUB_PARALLEL_MARK}}
    • {{DETAIL_ITEM_1}}
    • {{DETAIL_ITEM_2}}
    • Requirements: {{REQUIREMENT_IDS}} (IDs only; do not add descriptions or parentheses.)

Parallel marker: Append (P) only to tasks that can be executed in parallel. Omit the marker when running in --sequential mode.

Optional test coverage: When a sub-task is deferrable test work tied to acceptance criteria, mark the checkbox as - [ ]* and explain the referenced requirements in the detail bullets.

Steering Templates

プロジェクト全体のガイドラインを定義するためのテンプレート群です。

Templates

  • Product: プロダクト要件とビジネスルールのテンプレート
  • Tech: 技術スタックと技術的制約のテンプレート
  • Structure: プロジェクト構造とアーキテクチャ原則のテンプレート

使用方法

  1. 適切なテンプレートを選択
  2. プロジェクト固有の情報で埋める
  3. .kiro/steering/に保存
  4. AI開発エージェントがこれらを参照して開発を進める

Product Overview

[Brief description of what this product does and who it serves]

Core Capabilities

[3-5 key capabilities, not exhaustive features]

Target Use Cases

[Primary scenarios this product addresses]

Value Proposition

[What makes this product unique or valuable]


Focus on patterns and purpose, not exhaustive feature lists

Technology Stack

Architecture

[High-level system design approach]

Core Technologies

  • Language: [e.g., TypeScript, Python]
  • Framework: [e.g., React, Next.js, Django]
  • Runtime: [e.g., Node.js 20+]

Key Libraries

[Only major libraries that influence development patterns]

Development Standards

Type Safety

[e.g., TypeScript strict mode, no any]

Code Quality

[e.g., ESLint, Prettier rules]

Testing

[e.g., Jest, coverage requirements]

Development Environment

Required Tools

[Key tools and version requirements]

Common Commands

# Dev: [command]
# Build: [command]
# Test: [command]

Key Technical Decisions

[Important architectural choices and rationale]


Document standards and patterns, not every dependency

Project Structure

Organization Philosophy

[Describe approach: feature-first, layered, domain-driven, etc.]

Directory Patterns

[Pattern Name]

Location: /path/
Purpose: [What belongs here]
Example: [Brief example]

[Pattern Name]

Location: /path/
Purpose: [What belongs here]
Example: [Brief example]

Naming Conventions

  • Files: [Pattern, e.g., PascalCase, kebab-case]
  • Components: [Pattern]
  • Functions: [Pattern]

Import Organization

// Example import patterns
import { Something } from '@/path'  // Absolute
import { Local } from './local'     // Relative

Path Aliases:

  • @/: [Maps to]

Code Organization Principles

[Key architectural patterns and dependency rules]


Document patterns, not file trees. New files following patterns shouldn’t require updates

Custom Steering Templates

特定のドメインに特化したステアリングテンプレート群です。

Templates

使用方法

  1. プロジェクトに必要なテンプレートを選択
  2. プロジェクト固有の情報で埋める
  3. .kiro/steering/にカスタムファイルとして保存
  4. AI開発エージェントがこれらを参照して開発を進める

カスタムステアリングの作成

/kiro:steering-custom

このコマンドでカスタムステアリングファイルを対話的に作成できます。

API Standards

[Purpose: consistent API patterns for naming, structure, auth, versioning, and errors]

Philosophy

  • Prefer predictable, resource-oriented design
  • Be explicit in contracts; minimize breaking changes
  • Secure by default (auth first, least privilege)

Endpoint Pattern

/{version}/{resource}[/{id}][/{sub-resource}]

Examples:

  • /api/v1/users
  • /api/v1/users/:id
  • /api/v1/users/:id/posts

HTTP verbs:

  • GET (read, safe, idempotent)
  • POST (create)
  • PUT/PATCH (update)
  • DELETE (remove, idempotent)

Request/Response

Request (typical):

{ "data": { ... }, "metadata": { "requestId": "..." } }

Success:

{ "data": { ... }, "meta": { "timestamp": "...", "version": "..." } }

Error:

{ "error": { "code": "ERROR_CODE", "message": "...", "field": "optional" } }

(See error-handling for rules.)

Status Codes (pattern)

  • 2xx: Success (200 read, 201 create, 204 delete)
  • 4xx: Client issues (400 validation, 401/403 auth, 404 missing)
  • 5xx: Server issues (500 generic, 503 unavailable) Choose the status that best reflects the outcome.

Authentication

  • Credentials in standard location
Authorization: Bearer {token}
  • Reject unauthenticated before business logic

Versioning

  • Version via URL/header/media-type
  • Breaking change → new version
  • Non-breaking → same version
  • Provide deprecation window and comms

Pagination/Filtering (if applicable)

  • Pagination: page, pageSize or cursor-based
  • Filtering: explicit query params
  • Sorting: sort=field:asc|desc Return pagination metadata in meta.

Focus on patterns and decisions, not endpoint catalogs.

Authentication & Authorization Standards

[Purpose: unify auth model, token/session lifecycle, permission checks, and security]

Philosophy

  • Clear separation: authentication (who) vs authorization (what)
  • Secure by default: least privilege, fail closed, short-lived tokens
  • UX-aware: friction where risk is high, smooth otherwise

Authentication

Method (choose + rationale)

  • Options: JWT, Session, OAuth2, hybrid
  • Choice: [our method] because [reason]

Flow (high-level)

1) User proves identity (credentials or provider)
2) Server verifies and issues token/session
3) Client sends token per request
4) Server verifies token and proceeds

Token/Session Lifecycle

  • Storage: httpOnly cookie or Authorization header
  • Expiration: short-lived access, longer refresh (if used)
  • Refresh: rotate tokens; respect revocation
  • Revocation: blacklist/rotate on logout/compromise

Security Pattern

  • Enforce TLS; never expose tokens to JS when avoidable
  • Bind token to audience/issuer; include minimal claims
  • Consider device binding and IP/risk checks for sensitive actions

Authorization

Permission Model

  • Choose one: RBAC / ABAC / ownership-based / hybrid
  • Define roles/attributes centrally; avoid hardcoding across codebase

Checks (where to enforce)

  • Route/middleware: coarse-grained gate
  • Domain/service: fine-grained decisions
  • UI: conditional rendering (no security reliance)

Example pattern:

requirePermission('resource:action'); // route
if (!user.can('resource:action')) throw ForbiddenError(); // domain

Ownership

  • Pattern: owner OR privileged role can act
  • Verify on entity boundary before mutation

Passwords & MFA

  • Passwords: strong policy, hashed (bcrypt/argon2), never plaintext
  • Reset: time-limited token, single-use, notify user
  • MFA: step-up for risky operations (policy-driven)

API-to-API Auth

  • Use API keys or OAuth client credentials
  • Scope keys minimally; rotate and audit usage
  • Rate limit by identity (user/key)

Focus on patterns and decisions. No library-specific code.

Database Standards

[Purpose: guide schema design, queries, migrations, and integrity]

Philosophy

  • Model the domain first; optimize after correctness
  • Prefer explicit constraints; let database enforce invariants
  • Query only what you need; measure before optimizing

Naming & Types

  • Tables: snake_case, plural (users, order_items)
  • Columns: snake_case (created_at, user_id)
  • FKs: {table}_id referencing {table}.id
  • Types: timezone-aware timestamps; strong IDs; precise money types

Relationships

  • 1:N: FK in child
  • N:N: join table with compound key
  • 1:1: FK + UNIQUE

Migrations

  • Immutable migrations; always add rollback
  • Small, focused steps; test on non-prod first
  • Naming: {seq}_{action}_{object} (e.g., 002_add_email_index)

Query Patterns

  • ORM for simple CRUD and safety; raw SQL for complex/perf-critical
  • Avoid N+1 (eager load/batching); paginate large sets
  • Index FKs and frequently filtered/sorted columns

Connection & Transactions

  • Use pooling (size/timeouts based on workload)
  • One connection per unit of work; close/return promptly
  • Wrap multi-step changes in transactions

Data Integrity

  • Use NOT NULL/UNIQUE/CHECK/FK constraints
  • Validate at DB when appropriate (defense in depth)
  • Prefer generated columns for consistent derivations

Backup & Recovery

  • Regular backups with retention; test restores
  • Document RPO/RTO targets; monitor backup jobs

Focus on patterns and decisions. No environment-specific settings.

Deployment Standards

[Purpose: safe, repeatable releases with clear environment and pipeline patterns]

Philosophy

  • Automate; test before deploy; verify after deploy
  • Prefer incremental rollout with fast rollback
  • Production changes must be observable and reversible

Environments

  • Dev: fast iteration; debugging enabled
  • Staging: mirrors prod; release validation
  • Prod: hardened; monitored; least privilege

CI/CD Flow

Code → Test → Build → Scan → Deploy (staged) → Verify

Principles:

  • Fail fast on tests/scans; block deploy
  • Artifact builds are reproducible (lockfiles, pinned versions)
  • Manual approval for prod; auditable trail

Deployment Strategies

  • Rolling: gradual instance replacement
  • Blue-Green: switch traffic between two pools
  • Canary: small % users first, expand on health Choose per risk profile; document default.

Zero-Downtime & Migrations

  • Health checks gate traffic; graceful shutdown
  • Backwards-compatible DB changes during rollout
  • Separate migration step; test rollback paths

Rollback

  • Keep previous version ready; automate revert
  • Rollback faster than fix-forward; document triggers

Configuration & Secrets

  • 12-factor config via env; never commit secrets
  • Secret manager; rotate; least privilege; audit access
  • Validate required env vars at startup

Health & Monitoring

  • Endpoints: /health, /health/live, /health/ready
  • Monitor latency, error rate, throughput, saturation
  • Alerts on SLO breaches/spikes; tune to avoid fatigue

Incident Response & DR

  • Standard playbook: detect → assess → mitigate → communicate → resolve → post-mortem
  • Backups with retention; test restore; defined RPO/RTO

Focus on rollout patterns and safeguards. No provider-specific steps.

Error Handling Standards

[Purpose: unify how errors are classified, shaped, propagated, logged, and monitored]

Philosophy

  • Fail fast where possible; degrade gracefully at system boundaries
  • Consistent error shape across the stack (human + machine readable)
  • Handle known errors close to source; surface unknowns to a global handler

Classification (decide handling by source)

  • Client: Input/validation/user action issues → 4xx
  • Server: System failures/unexpected exceptions → 5xx
  • Business: Rule/state violations → 4xx (e.g., 409)
  • External: 3rd-party/network failures → map to 5xx or 4xx with context

Error Shape (single canonical format)

{
  "error": {
    "code": "ERROR_CODE",
    "message": "Human-readable message",
    "requestId": "trace-id",
    "timestamp": "ISO-8601"
  }
}

Principles: stable code enums, no secrets, include trace info.

Propagation (where to convert)

  • API layer: Convert domain errors → HTTP status + canonical body
  • Service layer: Throw typed business errors, avoid stringly-typed errors
  • Data/external layer: Wrap provider errors with safe, actionable codes
  • Unknown errors: Bubble to global handler → 500 + generic message

Example pattern:

try { return await useCase(); }
catch (e) {
  if (e instanceof BusinessError) return respondMapped(e);
  logError(e); return respondInternal();
}

Logging (context over noise)

Log: operation, userId (if available), code, message, stack, requestId, minimal context. Do not log: passwords, tokens, secrets, full PII, full bodies with sensitive data. Levels: ERROR (failures), WARN (recoverable/edge), INFO (key events), DEBUG (diagnostics).

Retry (only when safe)

Retry when: network/timeouts/transient 5xx AND operation is idempotent. Do not retry: 4xx, business errors, non-idempotent flows. Strategy: exponential backoff + jitter, capped attempts; require idempotency keys.

Monitoring & Health

Track: error rates by code/category, latency, saturation; alert on spikes/SLI breaches. Expose health: /health (live), /health/ready (ready). Link errors to traces.


Focus on patterns and decisions. No implementation details or exhaustive lists.

Security Standards

[Purpose: define security posture with patterns for validation, authz, secrets, and data]

Philosophy

  • Defense in depth; least privilege; secure by default; fail closed
  • Validate at boundaries; sanitize for context; never trust input
  • Separate authentication (who) and authorization (what)

Input & Output

  • Validate at API boundaries and UI forms; enforce types and constraints
  • Sanitize/escape based on destination (HTML, SQL, shell, logs)
  • Prefer allow-lists over block-lists; reject early with minimal detail

Authentication & Authorization

  • Authentication: verify identity; issue short-lived tokens/sessions
  • Authorization: check permissions before actions; deny by default
  • Centralize policies; avoid duplicating checks across code

Pattern:

if (!user.hasPermission('resource:action')) throw ForbiddenError();

Secrets & Configuration

  • Never commit secrets; store in secret manager or env
  • Rotate regularly; audit access; scope minimal
  • Validate required env vars at startup; fail fast on missing

Sensitive Data

  • Minimize collection; mask/redact in logs; encrypt at rest and in transit
  • Restrict access by role/need-to-know; track access to sensitive records

Session/Token Security

  • httpOnly + secure cookies where possible; TLS everywhere
  • Short expiration; rotate on refresh; revoke on logout/compromise
  • Bind tokens to audience/issuer; include minimal claims

Logging (security-aware)

  • Log auth attempts, permission denials, and sensitive operations
  • Never log passwords, tokens, secrets, full PII; avoid full bodies
  • Include requestId and context to correlate events

Headers & Transport

  • Enforce TLS; HSTS
  • Set security headers (CSP, X-Frame-Options, X-Content-Type-Options)
  • Prefer modern crypto; disable weak protocols/ciphers

Vulnerability Posture

  • Prefer secure libraries; keep dependencies updated
  • Static/dynamic scans in CI; track and remediate
  • Educate team on common classes; encode as patterns above

Focus on patterns and principles. Link concrete configs to ops docs.

Testing Standards

[Purpose: guide what to test, where tests live, and how to structure them]

Philosophy

  • Test behavior, not implementation
  • Prefer fast, reliable tests; minimize brittle mocks
  • Cover critical paths deeply; breadth over 100% pursuit

Organization

Options:

  • Co-located: component.tsx + component.test.tsx
  • Separate: /src/... and /tests/... Pick one as default; allow exceptions with rationale.

Naming:

  • Files: *.test.* or *.spec.*
  • Suites: what is under test; Cases: expected behavior

Test Types

  • Unit: single unit, mocked dependencies, very fast
  • Integration: multiple units together, mock externals only
  • E2E: full flows, minimal mocks, only for critical journeys

Structure (AAA)

it('does X when Y', () => {
  // Arrange
  const input = setup();
  // Act
  const result = act(input);
  // Assert
  expect(result).toEqual(expected);
});

Mocking & Data

  • Mock externals (API/DB); never mock the system under test
  • Use factories/fixtures; reset state between tests
  • Keep test data minimal and intention-revealing

Coverage

  • Target: [% overall]; higher for critical domains
  • Enforce thresholds in CI; exceptions require review rationale

Focus on patterns and decisions. Tool-specific config lives elsewhere.