guinness-backend ディレクトリアーキテクチャ
guinness-backend モノレポは Bun を使用する Turborepo ワークスペースです。4 つのアプリ(ユーザー API、管理者 API、MCP v2 サーバー、PostgreSQL マイグレーション)と 4 つの共有パッケージを含みます。インフラストラクチャのトポロジーについては 管理者インフラストラクチャ および ユーザーインフラストラクチャ を参照してください。
リポジトリ構成
guinness-backend/
apps/
app/ # @guinness-backend/app — ユーザー向け REST API(Hono + Bun)
admin/ # @guinness-backend/admin — 管理者向け REST API(Hono + Bun)
mcp-v2/ # @guinness-backend/mcp-v2 — Model Context Protocol サーバー
migration-pg/ # @guinness-backend/migration-pg — PostgreSQL スキーママイグレーション(Drizzle Kit)
packages/
models/ # @guinness-backend/models — PostgreSQL Drizzle ORM スキーマ
utils/ # @guinness-backend/utils — 共有ユーティリティ(認証、エラー、ページネーション等)
guinness-backend-sdk/ # 共有バックエンド・テストヘルパー
typescript-config/ # @guinness-backend/typescript-config — 共有 tsconfig
docs/ # MkDocs ドキュメントサイト
bin/ # 運用スクリプト(RDS/DocDB 向け SSM セッション)
api-collections/ # API コレクションファイル(Postman/Bruno)
アプリ構造パターン
各 API アプリ(app、admin、mcp-v2)は 4 層アーキテクチャに従います:routes → services → repositories → models。
apps/app/src/
server.ts # Bun サーバーエントリポイント
app.ts # Hono アプリ設定
config/
env.ts # 環境変数バリデーション(Zod)
database.ts # データベース接続設定
cognito.ts # AWS Cognito クライアント設定
middlewares/
protected-route.ts # JWT 認証ミドルウェア
error-handler.ts # グローバルエラーハンドリング
rate-limit.ts # レート制限
winston-logger.ts # リクエストログ
routes/v1/ # HTTP ハンドラー(ドメイン別ファイル)
services/ # ビジネスロジック(ドメイン別ファイル)
repositories/ # データアクセス — Drizzle クエリ(ドメイン別ファイル)
schemas/
components/ # OpenAPI コンポーネントスキーマ(Zod)
routes/ # ルート別リクエスト/レスポンススキーマ(Zod)
types/
endpoint/ # エンドポイント別型定義
lib/
database.ts # DB 接続プールシングルトン
server.ts # サーバーセットアップヘルパー
utils/
pagination.ts # ページネーションヘルパー
security.ts # セキュリティユーティリティ
admin アプリはこのパターンを拡張し、追加の認可ミドルウェア(require-admin-access、require-organization-access、require-project-access、require-user-access、resolve-actor-admin、access-level-rank)を備えています。
リクエストフロー
リクエストは以下の順序でレイヤーを通過します。
Client Request
↓
Middlewares(認証・ログ・エラーハンドリング)
↓
Routes(リクエストバリデーション・レスポンスフォーマット)
↓
Services(ビジネスロジック)
↓
Repositories(データアクセス)
↓
Database / External Services(AWS Cognito, S3, SQS)
ミドルウェアパイプライン
| ミドルウェア | ファイル | 役割 |
|---|---|---|
requestId() |
hono/request-id |
トレース用の一意なリクエスト ID を付与 |
winstonLogger() |
middlewares/winston-logger.ts |
リクエスト / レスポンスの構造化ログ(所要時間含む) |
cors() |
hono/cors |
クロスオリジンリソース共有 |
compress() |
hono/compress |
Gzip レスポンス圧縮 |
rateLimit() |
middlewares/rate-limit.ts |
リクエストレート制限 |
protectedRoute |
middlewares/protected-route.ts |
JWT 検証・Cognito sub 抽出 |
errorHandler |
middlewares/error-handler.ts |
集中エラーハンドリング・統一フォーマット返却 |
各レイヤーの実装パターン
Routes レイヤー
HTTP ハンドリング・バリデーション・レスポンス整形を担う。ビジネスロジックは持たず Service に委譲する。
route.openapi(getUser, async (c) => {
const { user_id } = c.req.valid('param');
const { sub: requesterUsername } = c.get('auth');
try {
const user = await userService.findOneById(user_id, requesterUsername);
return c.json(formatOutput(user));
} catch (error) {
logger.error('Failed to fetch user', { error, user_id });
throw error;
}
});
Services レイヤー
ビジネスルールの実装・複数リポジトリの調整・外部サービス(Cognito, S3, SQS)との連携を担う。
export async function findOneById(
userId: string,
requesterUsername: string
): Promise<User> {
const user = await userRepository.findById(userId);
if (!user) throw new NotFoundError(`User ${userId} not found`);
if (!hasPermission(requesterUsername, user)) throw new ForbiddenError('Insufficient permissions');
return user;
}
Repositories レイヤー
Drizzle ORM を使ったデータベース操作のみを担う。ビジネスロジックは持たない。
export async function findById(userId: string): Promise<User | null> {
const result = await db
.select()
.from(users)
.where(and(eq(users.id, userId), isNull(users.deletedAt)))
.limit(1);
return result[0] ?? null;
}
エラーハンドリング
標準エラーレスポンス
すべてのエラーは以下の JSON 形式で返却される。
HTTP ステータスコード
| ステータス | 用途 |
|---|---|
400 Bad Request |
無効な入力データ |
401 Unauthorized |
認証がないか無効 |
403 Forbidden |
権限不足 |
404 Not Found |
リソースが見つからない |
409 Conflict |
リソースの競合(重複など) |
500 Internal Server Error |
予期しないサーバーエラー |
共有パッケージ責務
| パッケージ | 主要ファイル | 責務 |
|---|---|---|
packages/models |
postgresql/*.ts |
全テーブルの Drizzle ORM スキーマ定義、テーブル別ファイル + リレーション |
packages/models |
postgresql/shared/audit-fields.ts |
共有監査カラム(created_at, updated_at) |
packages/models |
postgresql/shared/constants.ts |
共有 DB 定数 |
packages/utils |
src/cognito-jwt.ts |
Cognito トークンの JWT 検証 |
packages/utils |
src/error.ts |
カスタムエラークラス(Validation, Unauthorized, Forbidden, NotFound, Conflict, InternalServer) |
packages/utils |
src/pagination.ts |
ページネーションヘルパー |
packages/utils |
src/logger.ts |
Winston ロガー設定 |
packages/utils |
src/encryption.ts |
暗号化/復号ユーティリティ |
packages/utils |
src/response.ts |
API レスポンスフォーマット |
packages/utils |
src/retry.ts |
指数バックオフ付きリトライロジック |
packages/utils |
src/request-validation.ts |
リクエストバリデーションヘルパー |
packages/utils |
src/figma.ts |
Figma API ヘルパー |
packages/guinness-backend-sdk |
src/test-utils/postgres-container.ts |
Testcontainers PostgreSQL 設定 |
packages/guinness-backend-sdk |
src/test-utils/vitest-global-setup.ts |
テスト DB 向け Vitest グローバルセットアップ |
packages/typescript-config |
base.json, app.json |
共有 tsconfig プリセット |
共有依存パッケージ
| パッケージ | 用途 |
|---|---|
hono |
Web フレームワーク(v4.12)— ルーティング、ミドルウェア、OpenAPI |
drizzle-orm |
データベース ORM — PostgreSQL 向けクエリビルダー |
drizzle-kit |
スキーママイグレーションツール |
zod (v4) |
スキーマバリデーション — リクエスト/レスポンス、環境変数 |
@aws-sdk/client-* |
AWS SDK — S3, SQS, Cognito, DocumentDB |
winston |
構造化ログ |
testcontainers |
インテグレーションテスト用 PostgreSQL testcontainers |
vitest |
テストランナー |
biome |
リント + フォーマット |
turbo |
モノレポビルドオーケストレーション |
lefthook |
Git フック管理 |