Files
opengroupware/docs/architecture.md
Ken Yasue 80e195b3dc chore: initialize repository with project docs and tooling
- Add persistent docs: PRD, functional design, architecture, repository structure, development guidelines, milestones

- Add brainstorming notes (docs/ideas/)

- Configure tooling: package.json, tsconfig, eslint, prettier, vitest

- Add opencode configuration (commands, skills, agents)

- Add .gitignore for node_modules, .env, data/, backups/, build outputs
2026-06-24 23:31:06 +02:00

17 KiB
Raw Permalink Blame History

アーキテクチャ設計書 (Architecture Design Document)

本書は docs/product-requirements.mddocs/functional-design.md を技術的に実現するためのシステム構造・技術選定・インフラ要件を定義する。

技術スタック

言語・ランタイム

技術 バージョン 選定理由
Node.js v24.11.0 開発環境(devcontainer)と同一。better-sqlite3の同期APIを直接扱える。LTS保証下で本番運用が安定
TypeScript 5.x 静的型付けによりコンパイル時バグ検出。Repository/Service/Entity間の型共有で保守性向上。IDE補完により開発効率向上
npm 11.x Node.js v24.11.0にバンドル。package-lock.jsonによる厳密な依存管理。workspaces対応

フレームワーク・ライブラリ

技術 バージョン 目的 選定理由
Next.js 15 Webフレームワーク App Router・Server Components・Route Handlers・Server Actionsを統合利用。Node.js Runtime選択可能でSQLite直接操作に適合
better-sqlite3 最新安定 SQLiteドライバ 同期APIで扱いやすく高速。トランザクション・プリペアドステートメント・pragma制御が直接可能
react-markdown 最新安定 Markdownレンダリング GFM拡張と連携可能。プラグインでサニタイズパイプラインを構築できる
remark-gfm 最新安定 GFM対応 テーブル・チェックリスト・取り消し線等のGFM記法を有効化
rehype-sanitize 最新安定 HTMLサニタイズ Markdown表示時のXSS対策。危険なHTML・URLスキームを除去
Tailwind CSS 最新安定 スタイリング ユーティリティファーストでUI構築が高速。カスタムCSS削減
bcrypt 最新安定 パスワードハッシュ ソルト付きハッシュで平文保存を回避。適切なコスト係数でブルートフォース耐性
FullCalendar系 または独自実装 - カレンダーUI 月/週/日/リスト表示・ドラッグ操作・イベントフィルタ要件を満たす

開発ツール

技術 バージョン 目的 選定理由
Vitest 最新安定 Unit Test Viteベースで高速。TypeScriptネイティブ対応。better-sqlite3等のネイティブモジュールも扱える
Playwright 最新安定 E2E Test 実ブラウザChromium/Firefox/WebKit操作で主要ユーザーフローを検証。SSEのリアルタイム挙動も検証可能
ESLint 最新安定 リンタ コード品質・一貫性維持。TypeScriptルールと連携
TypeScripttsc 5.x 型チェック 型エラーをCIで検出

アーキテクチャパターン

レイヤードアーキテクチャ

┌─────────────────────────────────────────────┐
│  UI層 (Next.js)                              │ ← Server Components / Client Components
│   Route Handler / Server Action / SSE        │   入力受付・表示・認証・認可
├─────────────────────────────────────────────┤
│  Service層                                   │ ← 業務ロジック・権限チェック・トランザクション
│   AuthService / ProjectService / ...         │   通知生成・アクティビティログ・SSE配信
├─────────────────────────────────────────────┤
│  Repository層                                │ ← SQL保持・データアクセス・論理削除フィルタ
│   UserRepository / ProjectRepository / ...   │
├─────────────────────────────────────────────┤
│  Data層                                      │ ← SQLite接続・SQL実行・Migration
│   lib/db/sqlite.ts / migrator.ts / SQLite    │
└─────────────────────────────────────────────┘

レイヤ責務と依存規則

依存は一方向UI → Service → Repository → Dataのみ許可する。逆方向依存・層飛ばしを禁止する。

UI層Route Handler / Server Action / Server Components / SSEエンドポイント

  • 責務: 入力受付・バリデーション・認証・認可・結果表示
  • 許可操作: Service層の呼び出し
  • 禁止操作: Repository層・Data層への直接アクセス、SQLの直接記述

Service層

  • 責務: 業務ロジック・権限チェック(isMember/ロール・トランザクション境界・副作用通知生成・アクティビティログ記録・SSE配信
  • 許可操作: Repository層の呼び出し・FileStorageServiceによるファイル操作・SseHubへの配信依頼
  • 禁止操作: UI層への依存、SQLの直接記述、SQLiteライブラリの直接操作

Repository層

  • 責務: SQLの保持・パラメータバインド実行・論理削除deleted_at IS NULL)の確実な付与・プロジェクト分離の担保
  • 許可操作: SQLラッパーlib/db/sqlite.ts経由のDBアクセス
  • 禁止操作: 業務ロジックの実装、SQLiteライブラリの直接操作、UI層への依存

Data層

  • 責務: SQLite接続の共通管理・SQL実行・トランザクション・Migration
  • 許可操作: better-sqlite3へのアクセス・ファイルシステムMigrationファイル・バックアップへのアクセス
  • 禁止操作: 業務ロジックの実装
// 許容: UI → Service → Repository → Data
routeHandler  projectService.createProject(...)  projectRepository.create(...)  db.execute(sql, params)

// 禁止: UI → Data (層飛ばし)
routeHandler  db.execute("INSERT INTO projects ...") // ❌

// 禁止: Repository → SQLite直接 (ラッパー未使用)
projectRepository  new Database(dbPath) // ❌

ランタイム方針

SQLiteを直接扱うため、Next.jsのEdge Runtimeは使用しない。API Route・Server Actions・DBアクセス処理・SSEエンドポイントはすべてNode.js Runtimeで実行する。各Route Handlerの先頭で export const runtime = 'nodejs' を明示する。

Prisma不使用の方針

DBアクセスは独自SQLラッパーlib/db/sqlite.tsとRepositoryクラスで実装する。Prismaは導入しない。

  • 理由1: SQLを直接制御することでクエリ最適化・インデックス設計を明示できる
  • 理由2: better-sqlite3の同期APIと相性が良く、コード生成のオーバーヘッドがない
  • 理由3: MigrationもSQLファイルベースの独自実装でバージョン管理する

データ永続化戦略

保存方式

データ種別 保存先 形式 理由
アプリケーションデータ SQLite./data/app.db リレーショナル トランザクション・外部キー・インデックス・論理削除を一貫管理
アップロードファイル ローカルFS./data/uploads/<projectId>/ バイナリ 外部ストレージ不要・自己完結。DBにメタデータfile_assets)を保存
Migration履歴 SQLiteschema_migrations 行レコード 適用済みファイルを一意管理・再実行回避
バックアップ ローカルFS./backups/ ZIP DBファイル+uploadsディレクトリをZIP化

SQLite接続設定

  • journal_mode = WAL: 読み書きの並行性向上
  • foreign_keys = ON: 外部キー制約・カスケード削除を有効化
  • 接続はシングルトン(getDb()で共有。dbPathは process.env.SQLITE_PATH ?? "./data/app.db"

バックアップ戦略

  • 作成タイミング: 管理者がバックアップ画面から手動実行
  • 作成内容: SQLite DBファイル + uploadsディレクトリをZIP化
  • 保存先: ./backups/backup-<timestamp>.zip
  • 世代管理: 一覧表示・ダウンロード可能(世代数は運用で定義)
  • リストア手順: サーバ停止 → ZIP展開 → ./data/app.db./data/uploads/ を差替 → サーバ再起動

パフォーマンス要件

応答時間

操作 目標時間 測定環境
チャットSSE配信遅延 送信から全クライアント受信まで3秒以内95パーセンタイル 小規模同時接続(数十)
一覧画面表示 1000件データ時1秒以内掲示板・チャット履歴・ファイル一覧・Markdownメモ ページネーション20件/頁
バックアップ作成 DB+uploads合計100MB相当で30秒以内 ローカルFS
Migration実行 1ファイル1トランザクション・失敗時即座ロールバック 初回スキーマ適用

リソース使用量

リソース 上限 理由
メモリ Next.jsサーバプロセス1GB程度 1プロジェクト数十人規模・小規模同時接続前提
CPU 単一サーバで十分 SQLite同期処理・SSE数十接続を想定
ディスク DB+uploads合計数百MB〜数GBを想定 バックアップは別途容量確保

パフォーマンス最適化施策

  • ページネーション: 全一覧APIで ?page=&pageSize= を必須化し必要件数のみ取得
  • インデックス: project_notes(project_id), project_notes(updated_at) 等の高頻度検索カラムにインデックス付与
  • Server Components: 可能な限りServer Componentsでデータ取得しクライアント送信量を削減
  • WALモード: 読み書き並行性向上
  • SSE配信のスコープ限定: プロジェクト単位でクライアント集合を管理し、無関係プロジェクトへの配信コストを排除

セキュリティアーキテクチャ

データ保護

  • パスワード保護: bcryptでハッシュ化保存。平文保存禁止。ソルト付き・適切なコスト係数
  • 暗号化: 通信はHTTPS前提。保存時のDBファイル暗号化は本スコープ外ローカルFSのアクセス権限で保護
  • アクセス制御: サーバプロセスのファイル権限により ./data/, ./backups/ を保護
  • 機密情報管理: 設定は .env で管理(SQLITE_PATH 等)。コード内にハードコード禁止。.env はリポジトリにコミットしない

認証・認可

  • 認証: 独自ログイン方式・セッションベース。未認証リクエストは保護画面/APIにアクセス不可401/リダイレクト)
  • 認可(プロジェクト): Service層で ProjectMemberRepository.isMember(projectId, userId) を必ず実施。非参加者は403
  • 認可(管理者機能): バックアップ・Migration状態確認は role='system_admin' のみ許可
  • ファイルアクセス: ダウンロードAPIでもプロジェクト参加権限をチェック

入力バリデーション

  • バリデーション: 全入力で必須チェック・長さ制限タイトル1-200文字等・形式チェックをService層で実施
  • SQL対策: 全SQLをパラメータバインドで実行。文字列結合によるSQL構築は禁止
  • Markdownサニタイズ: HTML直接入力無効化 + rehype-sanitize でサニタイズ + 危険URLスキームjavascript:等)除外
  • ファイルアップロード: MIMEタイプチェック・ファイル名サニタイズ・保存名の一意化<uuid>.<ext>
  • エラー表示: スタックトレース・内部情報を本番では非表示。ユーザーには抽象メッセージのみ表示

監査

  • 管理者操作・主要な変更操作をアクティビティログに記録(activity_logs テーブル)

スケーラビリティ設計

データ増大への対応

  • 想定データ量: 1プロジェクトあたり数十人・数千〜数万レコードチャット・掲示板・アクティビティログが主要
  • 性能劣化対策:
    • ページネーションによる取得件数制限
    • インデックス最適化(検索頻度高いカラム)
    • 論理削除データの取得除外(deleted_at IS NULL を全取得クエリに付与)
  • アーカイブ戦略: 完了/アーカイブ済みプロジェクトは status='archived' で残置。大量データの物理削除は本スコープ外(運用で判断)

拡張性

  • プラグインシステム: なし(本スコープ外)
  • 設定カスタマイズ: .env による設定管理(SQLITE_PATH・ uploadsパス等
  • API拡張性: Route Handlerベースでリソースごとにエンドポイントを分割。将来の公開REST API化はPost-MVP
  • SSEイベント拡張: SseEvent 型に新種別を追加するだけで新イベント配信が可能

テスト戦略

Unit Test

  • フレームワーク: Vitest
  • 対象: SQLラッパー・Migration・全Repository・全Service・権限チェック・バリデーション・スケジュール重複判定・通知作成ロジック・アクティビティログ作成ロジック・マイルストーン進捗計算
  • カバレッジ目標: Repository/Service層 80%以上
  • 実行コマンド: npm test

統合テスト

  • 方法: Vitestで実際のSQLite一時ファイルを使用
  • 対象: 認証フロー・プロジェクト作成→メンバー追加→権限分離・チャット送信→SSE配信

E2E Test

  • ツール: Playwright
  • シナリオ: 認証・プロジェクト管理・掲示板・チャットSSEリアルタイム・ToDoドラッグ&ドロップ・ファイル共有Lightbox・Markdownメモ・カレンダー・ミーティング予定重複警告・通知・アクティビティログ・バックアップ
  • 実行コマンド: npm run test:e2e

技術的制約

環境要件

  • OS: devcontainer開発/ Linux想定本番。Windows・macOSでもNode.js Runtime動作可能
  • 最小メモリ: 1GB
  • 必要ディスク: DB+uploads+backups数百MB〜数GB
  • 必須外部依存: なし外部DB・外部ストレージ・外部IdPに非依存・自己完結

パフォーマンス制約

  • 1プロジェクトあたり数十人規模を想定数百人規模はスコープ外
  • チャットSSEは小規模同時接続数十接続を前提
  • 一覧取得は必ずページネーション(全件取得禁止)

セキュリティ制約

  • 認証必須(/api/auth/*除く)
  • 全SQLパラメータバインド文字列結合禁止
  • Markdown表示時のHTML無効化・サニタイズ必須
  • パスワード平文保存禁止

ランタイム制約

  • Edge Runtime使用禁止SQLite直接操作のため全てNode.js Runtime
  • Prisma使用禁止

依存管理

ライブラリ 目的 バージョン管理方針
next フレームワーク 固定(破壊的変更リスク大)
react / react-dom UI ^(マイナーアップ許容)
better-sqlite3 SQLiteドライバ ^(ネイティブビルド要注意)
react-markdown / remark-gfm / rehype-sanitize Markdown ^(マイナーアップ許容)
bcrypt パスワードハッシュ ^
tailwindcss スタイリング ^
typescript 型チェック ~パッチのみ自動・devDependencies
vitest Unit Test ^devDependencies
@playwright/test E2E Test ^devDependencies
eslint リンタ ^devDependencies

方針:

  • 安定版は ^ でマイナーアップを許容
  • 破壊的変更リスクのあるものnext等は固定
  • devDependenciesは ~ でパッチのみ自動アップ許容
  • package-lock.jsonで厳密にロックしCIで再現性を担保

チェックリスト

  • 全技術選定に理由が記載されている
  • レイヤードアーキテクチャが明確に定義されている(依存規則含む)
  • パフォーマンス要件が測定可能である
  • セキュリティ考慮事項が文書化されている
  • スケーラビリティが考慮されている
  • バックアップ戦略が定義されている
  • 依存管理方針が明確である
  • テスト戦略が定義されている