2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.js 16 × Prisma 7 × PostgreSQL で個人開発したAI業務管理秘書(プロジェクト管理も担う)の技術スタック全貌

2
Last updated at Posted at 2026-05-14

この記事は約7分で読めます。

筆者プロフィール: ソフトウェアエンジニア。「知った気にならない。いつまでも学び続ける」を信条に、業務と個人開発の両輪で技術を磨いています。AI 駆動開発で複数の個人開発アプリを構築・運用中。
👉 ポートフォリオ: 筆者ホームページ

個人開発した AI業務管理秘書 「たすきば Knowledge Relay」(過去の業務資産の管理を AI 秘書が手伝い、プロジェクト管理も担う)の技術スタックと設計判断を、運用中の実装ベースで整理した記事です。Next.js 16 / Prisma 7 / PostgreSQL を中核に、認証・認可・監査・自動テスト・CI セキュリティ をどう組み上げたかを公開します。

サービスの機能紹介・画面イメージ・コンセプトは公式プロダクトページをご覧ください。
👉 たすきば Knowledge Relay — 公式プロダクトページ

サービスの技術的ポジション

「プロジェクトの知見を蓄積し、次の判断を強くする」ことをテーマにした運営プラットフォームです。ナレッジ管理を中核に据え、見積もり・WBS・ガントチャート・リスク課題管理・振り返りが相互にリンクする構造になっています。

本記事では機能よりどう作ったかに焦点を当てます。

1. 技術スタック(全レイヤー)

実際に package.json に入っているバージョンで記載します。

レイヤー 採用技術・バージョン
フロントエンド Next.js 16.2.3 (App Router) / React 19.2.4 / TypeScript 5
UI shadcn/ui / Tailwind CSS v4 / @base-ui/react 1.4.0
バックエンド Next.js API Routes / Server Actions / Server Components (RSC)
ORM Prisma 7.7.0 (@prisma/adapter-pg 経由)
DB PostgreSQL 16 (Supabase Pooler)
全文検索 pg_trgm (PostgreSQL 標準拡張)
認証 NextAuth.js (Auth.js) 5.0.0-beta.31
MFA otplib 13.4.0 (TOTP / RFC 6238)
バリデーション zod 4.3.6
ハッシュ bcryptjs 3.0.3 (cost=12)
テスト (ユニット) Vitest 4.1.4
テスト (E2E) Playwright 1.59.1 (Chromium + 視覚回帰)
デプロイ Vercel + Supabase (PostgreSQL Pooler)

技術選定のポイント

  • 外部検索エンジンを入れない — pg_trgm で PostgreSQL だけで全文検索を完結させる
  • Edge Runtime 対応 — 認証ミドルウェアは Edge で高速化
  • @prisma/adapter-pg 方式 — Prisma 7 推奨の pg ドライバ直結構成
  • ゼロランタイムコスト — Vercel Hobby + Supabase Free でプレリリースまで運用

2. アーキテクチャとレイヤー構成

レイヤー 責務
Middleware 認証チェック、MFA 未検証時の誘導。Edge で高速実行
Route Handlers / Server Components リクエスト受付、認可、DTO 変換
Service Layer ビジネスロジック(DB 操作はここに集約)
Prisma + pg adapter 型安全な DB アクセス、PostgreSQL Pooler 経由

DB 操作は Service Layer に集約しており、Route Handler や Server Component から Prisma を直接叩くことは禁止しています。ルール違反は ESLint カスタムルールで検知します。

3. データベースと pg_trgm による全文検索

State Machine によるプロジェクト状態遷移

プロジェクトは 7 状態の線形フローで管理しています。

planning → estimating → scheduling → executing → completed → retrospected → closed

状態遷移は state-machine.ts に集約し、遷移可否テーブルを唯一の Source of Truth にしています。画面側で遷移可否ボタンを出し分ける際も、テスト時も、同じテーブルを参照します。

pg_trgm での全文検索

PostgreSQL 標準拡張の pg_trgm(トライグラム検索)を使って、外部検索エンジンなしで類似検索を実装しています。

-- Prisma migration で拡張を有効化
CREATE EXTENSION IF NOT EXISTS pg_trgm;

-- GIN インデックスをタイトル・本文に付与
CREATE INDEX idx_knowledge_title_trgm
  ON knowledges USING GIN (title gin_trgm_ops);

利用シーン:

  • ナレッジ全文検索 — タイトル・本文の部分一致+類似度順ソート
  • 提案型サービス(核心機能) — 業務ドメインタグ・工程タグ・技術スタックをキーに、過去プロジェクトから関連ナレッジ・リスク・振り返りを自動提案

4. 認証設計(NextAuth v5 + MFA)

セッション暗号化

NextAuth.js v5 の JWE 暗号化セッション をそのまま採用しています。NextAuth v5 の既定アルゴリズムは A256CBC-HS512(AES-256-CBC + HMAC-SHA-512)で、鍵は NEXTAUTH_SECRET から派生します。セッション Cookie は maxAge 未指定のブラウザセッション Cookie とし、ブラウザを閉じた時点で失われる運用です。

TOTP MFA + 復旧コード

  • TOTP 実装は otplib ベース
  • TOTP シークレットは AES-256-CBC で暗号化して DB 保存(NEXTAUTH_SECRET を鍵に流用)
  • 復旧コードは 10 個、紛らわしい文字(0/O, 1/I/L)を除外した文字集合で生成
  • 管理者ロールは MFA 必須 — MFA 未設定だとシステム管理機能にアクセス不可
// src/services/mfa.service.ts 抜粋
const ENCRYPTION_KEY = process.env.NEXTAUTH_SECRET?.slice(0, 32).padEnd(32, '0');
const ALGORITHM = 'aes-256-cbc';

function encrypt(text: string): string {
  const iv = randomBytes(16);
  const cipher = createCipheriv(ALGORITHM, Buffer.from(ENCRYPTION_KEY, 'utf-8'), iv);
  let encrypted = cipher.update(text, 'utf-8', 'hex');
  encrypted += cipher.final('hex');
  return iv.toString('hex') + ':' + encrypted;
}

パスワードポリシー(src/config/security.ts に集約)

項目 定数名
最小文字数 10 PASSWORD_MIN_LENGTH
最大文字数 128 PASSWORD_MAX_LENGTH (DoS 対策)
文字種最低数 3 種類(英大・英小・数字・記号のうち) PASSWORD_REQUIRED_CHAR_TYPE_COUNT
同一文字連続禁止 4 文字まで PASSWORD_MAX_CONSECUTIVE_SAME_CHARS
履歴保持件数 5 回 PASSWORD_HISTORY_COUNT
bcrypt コスト 12(OWASP 推奨) BCRYPT_COST

アカウントロック

トリガー 挙動
ログイン失敗 5 回 30 分間の一時ロック(時間経過で自動解除)
管理者 MFA 未設定 システム管理機能にアクセス不可
30 日未ログイン 日次 cron が /api/admin/users/cleanup-inactive で論理削除

論理削除時は ProjectMember も同時に物理削除されるため、管理者が手動で消し忘れても DB 整合性が保たれます。

5. 認可設計(RBAC 2 軸マトリクス)

  • システムロール: admin / general
  • プロジェクトロール: pm_tl / member / viewer

認可判定は「アクション × ロール × プロジェクト状態」の 3 次元マトリクスで厳密に制御します。「見積もり確定後は PM/TL でも WBS を編集できない」といった状態依存の制約も同一のマトリクスで表現できます。

IDOR(他プロジェクトの不正アクセス)対策は共通関数に切り出し、各 API の冒頭で必ず呼び出す設計にしています。

6. 監査ログ(3 テーブル分離)

用途別に 3 テーブルへ分離しています。

テーブル 記録対象
audit_logs 全データ変更(誰が・いつ・何を・どう変えたか)
auth_event_logs 認証イベント(成功・失敗・ロック・MFA 検証)
role_change_logs 権限変更(システムロール/プロジェクトロールの変更)

管理者は専用画面から検索・閲覧が可能です。

7. テスト戦略(自動 3 層)

テスト件数(2026-04-23 時点の実測値)

ツール 規模
ユニットテスト Vitest 641 テストsrc/**/*.test.ts
E2E テスト Playwright 9 spec ファイル(smoke / setup / detail / 個人機能 / WBS / ガント / 見積もり 等)
視覚回帰 Playwright toHaveScreenshot 10 テーマ × 主要画面 の pixel 比較

カバレッジ閾値(vitest.config.ts

thresholds: {
  lines: 80,
  statements: 80,
  functions: 80,
  branches: 70,
}

閾値未達は CI で fail させています。閾値達成のために品質の低いテストを量産するのを避けるため、対象ディレクトリを src/lib/**src/services/** に限定しています(UI コンポーネントは視覚回帰で担保)。

E2E の罠を knowledge として蓄積

router.refresh race、next-auth session 更新 race、Suspense hydration race など、E2E 実装で詰まった 25 パターンdocs/developer/E2E_LESSONS_LEARNED.md に集約しています。新しい E2E を書く前・失敗をデバッグする前に一読するワークフローで、同じ罠に二度引っ掛からない体制にしました。

8. CI/CD — 6 層セキュリティスキャン

開発工程に以下の 6 層を組み込んでいます。

ツール 検知対象
1 gitleaks コミット履歴への機密情報混入
2 pnpm audit(日次実行) 依存パッケージの既知脆弱性
3 Semgrep SAST(静的セキュリティ解析)
4 CodeQL(GitHub 標準) 高度な SAST
5 Dependency Review PR 時の差分脆弱性検知(GitHub Advisory DB 照合)
6 独自 hook block-dangerous-edit eval / innerHTML / SQL 文字列連結 等の危険パターン編集をブロック

日次 Security Scan Workflow

# .github/workflows/security.yml 抜粋
on:
  schedule:
    - cron: '0 3 * * *'   # 毎日 03:00 UTC
  pull_request:

加えて、四半期ごとに STRIDE 脅威モデリング/threat-model スキル経由で自動化しています。

9. AI 駆動開発の仕組み(Claude Code 運用)

本リポジトリは AI 支援前提で設計されており、以下を .claude/ ディレクトリに制度化しています。

仕組み 件数 内容
Hooks 4 SessionStart(日次ブランチ自動化)/ PreToolUse(危険コード検知)/ PostToolUse(自動整形)/ Stop(機密スキャン + lint + test + 自動コミット)
Skills 5 /threat-model / /check-deploy / /fix-issue / /release / /update-labels
Agents 7 認証 / インジェクション / XSS / 機密情報 / 依存脆弱性 / パフォーマンス / ラベル検出 の観点別並列レビュー

Stop Hook が毎コミット前に検証する 5 点

  1. 横展開 — 同一パターンが他ファイルに残っていないか
  2. セキュリティ — ユーザー入力サニタイズ / 生 SQL / 機密情報ハードコード
  3. パフォーマンス — ループ内 DB 問い合わせ / 不要な再描画 / N+1
  4. テスト整合性 — 旧文言残留 / テスト数の不自然な増減
  5. ドキュメント更新 — 仕様変更時の関連ドキュメント更新漏れ

main / master / develop / release/* / hotfix/* への直接コミットは自動ブロックしています。

10. ドキュメント体系(役割別 3 ディレクトリ)

ディレクトリ 対象 内容
docs/beginner/ 初見開発者 開発環境構築 → PR 作成までの 30 分 onboarding
docs/developer/ 開発者 要件 / 仕様 / 設計 / テスト戦略 / E2E 罠集 / 知見・改修履歴
docs/administrator/ 運用管理者 デプロイ / 環境変数 / migration / 障害対応 / ロールバック

開発過程で得たナレッジは docs/developer/knowledge/ に KNW-NNN 形式で体系化して蓄積しています(例: KNW-001: 設計文書の質と開発速度 / KNW-002: Next.js App Router のパフォーマンス最適化パターン)。

11. デプロイ形態と今後のロードマップ

形態 対応状況
Vercel + Supabase(クラウド SaaS) ✅ 稼働中
PC / ローカル(Docker Compose) Phase 2 対応予定
オンプレミス(Nginx + Docker Compose) Phase 2 対応予定
クラウド(AWS ECS / Azure App Service) 将来対応
  • プレリリース: 2026-05-01 — 紹介記事としての公開(招待制)
  • 正式リリース: 2026-06-01 — 3 環境対応の手順書完備

まとめ

たすきば Knowledge Relay の技術スタックをまとめると:

  • Next.js 16 / React 19 / Prisma 7 / PostgreSQL を中核に、外部検索エンジン不要の設計
  • NextAuth v5 JWE(A256CBC-HS512)+ TOTP MFA + RBAC 2 軸 で認証・認可を構築
  • Vitest 641 テスト + E2E 9 spec + 視覚回帰 10 テーマ を CI で閾値強制
  • CI セキュリティ 6 層 + 四半期 STRIDE で脅威を継続監視
  • Claude Code 運用の制度化(Hooks 4 / Skills 5 / Agents 7)で少人数でも品質を維持

サービスの機能・画面イメージ・利用シーンを見たい方はこちらへ 👉 たすきば Knowledge Relay — 公式プロダクトページ

本記事で触れていない設計判断の詳細(E2E 実装で詰まった罠集・設計文書の構成 等)は、プレリリース後に順次公開予定です。

参考

関連記事

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?