RoomCraft — v1.0.0 — 2026-03-19
RoomCraft のシステムアーキテクチャドキュメントです。
graph TB
subgraph Client["クライアント (ブラウザ)"]
UI["Next.js App Router\n(React 19)"]
3D["3Dレンダラー\n(Three.js / R3F)"]
Store["状態管理\n(Zustand)"]
end
subgraph Server["Next.js Server (App Router)"]
Pages["Server Components\nPage Rendering"]
API["API Routes\n(/api/*)"]
end
subgraph Data["データ層"]
Prisma["Prisma ORM"]
PG["PostgreSQL"]
end
subgraph External["外部サービス"]
Stripe["Stripe\n(決済)"]
S3["AWS S3\n(3Dモデル・画像)"]
end
subgraph Infra["AWS インフラ"]
ECR["Amazon ECR\n(コンテナレジストリ)"]
ECS["Amazon ECS\n(コンテナ実行)"]
CB["AWS CodeBuild\n(CI/CD)"]
CP["AWS CodePipeline\n(パイプライン)"]
end
UI --> Pages
UI --> API
3D --> S3
Store --> UI
Pages --> Prisma
API --> Prisma
API --> Stripe
Prisma --> PG
CB --> ECR
ECR --> ECS
CP --> CB
CP --> ECS
next/image による画像最適化、next/font によるフォント最適化が標準提供@react-three/drei が提供するヘルパー(OrbitControls, Environment, useGLTF等)でThree.jsの複雑なボイラープレートを削減floorPlan, furniture, wallSettings 等)でルームの自由形式データを格納@prisma/adapter-pg でEdge Runtime対応も可能sequenceDiagram
actor Consumer as 消費者
participant Catalog as カタログページ
participant Simulator as 3Dシミュレーター
participant Cart as カート
participant Order as 注文API
participant DB as PostgreSQL
Consumer->>Catalog: 商品を検索・閲覧
Catalog->>DB: GET /api/products
Consumer->>Simulator: ルームを作成 / 既存ルームを開く
Simulator->>DB: GET /api/rooms/:id
loop 家具を試し置き
Consumer->>Simulator: 商品をドラッグ配置
Simulator->>Simulator: Three.jsシーン更新 (Zustand)
Consumer->>Simulator: 保存
Simulator->>DB: PATCH /api/rooms/:id (furniture JSON更新)
end
Consumer->>Cart: 気に入った商品をカートに追加
Cart->>DB: POST /api/cart
Consumer->>Order: 注文確定
Order->>DB: POST /api/orders (OrderItem作成)
Order-->>Consumer: 注文完了
sequenceDiagram
actor Consumer as 消費者
participant AI as AIコーディネートAPI
participant DB as PostgreSQL
Consumer->>AI: POST /api/ai-coordinate\n(budget, style, roomWidth, roomDepth)
AI->>DB: 予算内・スタイル条件で商品を検索
DB-->>AI: 最大100件の商品リスト
AI->>AI: 3パターンのコーディネートを生成\n(予算の85%/90%/95%で組み合わせ)
AI-->>Consumer: 3パターンのコーディネート提案
Consumer->>Consumer: 提案をルームに反映 / カートに追加
sequenceDiagram
actor Maker as メーカー担当者
participant Dashboard as メーカーダッシュボード
participant ProductAPI as 商品API
participant OrderAPI as 注文API
participant Analytics as 分析API
participant DB as PostgreSQL
Maker->>Dashboard: ログイン
Maker->>ProductAPI: 商品を登録\n(POST /api/maker/products)
ProductAPI->>DB: Product + Variant + ThreeDModel 作成
Note over Maker,DB: 消費者が商品を購入
Maker->>OrderAPI: 注文を確認\n(GET /api/maker/orders)
OrderAPI->>DB: makerId で絞り込んだ注文一覧
Maker->>Analytics: 売上分析を確認\n(GET /api/maker/analytics?period=month)
Analytics->>DB: 期間内の配達済み注文から売上集計
Analytics-->>Maker: 商品別売上・総売上・コンバージョン率
erDiagram
User {
string id PK
string email
string name
UserRole role
}
Maker {
string id PK
string name
string slug
MakerPlan plan
MakerStatus status
decimal commissionRate
}
Product {
string id PK
string makerId FK
string categoryId FK
string name
decimal price
ProductStatus status
int stockCount
}
ProductVariant {
string id PK
string productId FK
VariantType type
string name
string value
decimal priceOverride
}
ThreeDModel {
string id PK
string productId FK
string fileUrl
string format
ModelStatus status
}
Category {
string id PK
string name
string slug
string parentId FK
}
Room {
string id PK
string userId FK
string name
json floorPlan
json furniture
json wallSettings
json floorSettings
json lightSettings
}
CartItem {
string id PK
string userId FK
string productId FK
string variantId FK
int quantity
}
Order {
string id PK
string userId FK
string makerId FK
OrderStatus status
decimal totalAmount
json shippingAddress
}
OrderItem {
string id PK
string orderId FK
string productId FK
string variantId FK
int quantity
decimal price
}
CommunityPost {
string id PK
string userId FK
string roomId FK
string title
int likes
PostStatus status
}
Favorite {
string id PK
string userId FK
string productId FK
}
MakerStaff {
string id PK
string makerId FK
string userId FK
StaffRole role
}
User ||--o{ Room : "作成"
User ||--o{ CartItem : "持つ"
User ||--o{ Order : "発注"
User ||--o{ CommunityPost : "投稿"
User ||--o{ Favorite : "お気に入り"
User ||--o{ MakerStaff : "スタッフ"
Maker ||--o{ Product : "出品"
Maker ||--o{ Order : "受注"
Maker ||--o{ MakerStaff : "所属"
Product ||--o{ ProductVariant : "バリアント"
Product ||--o{ ThreeDModel : "3Dモデル"
Product ||--o{ CartItem : "カート"
Product ||--o{ OrderItem : "注文明細"
Product ||--o{ Favorite : "お気に入り"
Category ||--o{ Product : "分類"
Category ||--o{ Category : "階層"
Room ||--o{ CommunityPost : "紐付き投稿"
Order ||--o{ OrderItem : "明細"
src/
├── app/ # プレゼンテーション層 (Next.js Pages + API Routes)
│ ├── (auth)/ # 認証ページ
│ ├── api/ # API エンドポイント
│ └── [各ページ]/ # UI ページ
├── components/ # 再利用可能UIコンポーネント
│ ├── three/ # 3D専用コンポーネント
│ └── ui/ # 汎用UIコンポーネント
├── lib/ # ユーティリティ・クライアント初期化
│ └── prisma.ts # Prisma シングルトンクライアント
├── stores/ # クライアント状態管理 (Zustand)
└── types/ # 共有TypeScript型定義
各 route.ts は以下のみを担当します:
ビジネスロジックが複雑になる場合は src/lib/ 以下にサービス関数として切り出します。
GitHub
↓ push
AWS CodePipeline
↓ ソース取得
AWS CodeBuild (buildspec.yml)
↓ Dockerイメージビルド・ECRプッシュ
Amazon ECR
↓ イメージデプロイ
Amazon ECS (Fargate)
↓ コンテナ起動
Application Load Balancer
↓ トラフィック
エンドユーザー
Dockerfile は3ステージ構成でイメージサイズを最小化します:
| ステージ | 目的 |
|---|---|
deps | node_modules のインストールのみ |
builder | prisma generate + next build |
runner | .next/standalone のみを含む軽量本番イメージ |
Next.js の output: 'standalone' モードにより、node_modules 全体をコピーせずに実行可能なサーバーを生成します。