Skip to main content

アーキテクチャ

Jeliqで生成されるアプリケーションのアーキテクチャと設計思想を解説します。

全体構成

┌─────────────────────────────────────────────────────┐
│                    Frontend                          │
│               (Next.js / React)                      │
├─────────────────────────────────────────────────────┤
│                   Supabase Client                    │
├─────────────────────────────────────────────────────┤
│                    Supabase                          │
│  ┌──────────────┬──────────────┬──────────────────┐ │
│  │   Database   │     Auth     │     Storage      │ │
│  │ (PostgreSQL) │              │                  │ │
│  └──────────────┴──────────────┴──────────────────┘ │
└─────────────────────────────────────────────────────┘

ディレクトリ構造

your-app/
├── src/
│   ├── app/                    # Next.js App Router
│   │   ├── (auth)/             # 認証関連ページ
│   │   │   ├── login/
│   │   │   └── register/
│   │   ├── (dashboard)/        # 認証後のページ
│   │   │   ├── layout.tsx      # ダッシュボードレイアウト
│   │   │   ├── page.tsx        # トップページ
│   │   │   └── [resource]/     # 各リソースのCRUDページ
│   │   ├── api/                # APIルート(必要に応じて)
│   │   ├── layout.tsx          # ルートレイアウト
│   │   └── page.tsx            # ランディングページ
│   ├── components/             # Reactコンポーネント
│   │   ├── ui/                 # 基本UIコンポーネント
│   │   ├── forms/              # フォームコンポーネント
│   │   ├── tables/             # テーブルコンポーネント
│   │   └── layouts/            # レイアウトコンポーネント
│   ├── lib/                    # ユーティリティ関数
│   │   ├── supabase/           # Supabaseクライアント
│   │   ├── utils/              # 汎用ユーティリティ
│   │   └── hooks/              # カスタムフック
│   └── types/                  # TypeScript型定義
│       ├── database.types.ts   # DBスキーマ型
│       └── index.ts            # その他の型
├── supabase/
│   ├── migrations/             # DBマイグレーション
│   └── config.toml             # Supabase設定
├── public/                     # 静的ファイル
├── package.json
├── tsconfig.json
├── tailwind.config.js
└── next.config.js

フロントエンド

Next.js App Router

Next.js 14のApp Routerを使用しています。 特徴:
  • Server Components / Client Componentsの使い分け
  • ファイルベースルーティング
  • レイアウトの共有
ルーティング例:
パスファイル説明
/app/page.tsxトップページ
/loginapp/(auth)/login/page.tsxログインページ
/dashboardapp/(dashboard)/page.tsxダッシュボード
/customersapp/(dashboard)/customers/page.tsx顧客一覧
/customers/[id]app/(dashboard)/customers/[id]/page.tsx顧客詳細

コンポーネント設計

コンポーネントは以下の原則で設計されています。
各コンポーネントは単一の責任を持ちます。大きなコンポーネントは小さなコンポーネントに分割されています。
深いネストでのProps受け渡しを避けるため、React ContextやカスタムHooksを使用しています。
components/ui/配下のコンポーネントは、アプリ全体で再利用できる汎用コンポーネントです。

状態管理

  • サーバー状態: Supabase Clientで直接取得
  • クライアント状態: React useState / useContext
  • フォーム状態: React Hook Form

バックエンド

Supabase

バックエンドにはSupabaseを使用しています。

Database

PostgreSQLベースのリレーショナルデータベース

Auth

認証・認可システム(メール/パスワード、OAuth)

Storage

ファイルストレージ(画像、ドキュメント等)

Realtime

リアルタイムサブスクリプション(将来対応予定)

データアクセス

Supabase JavaScript Clientを使用してデータベースにアクセスします。 例:データ取得
// lib/supabase/client.ts
import { createClient } from '@supabase/supabase-js'
import { Database } from '@/types/database.types'

export const supabase = createClient<Database>(
  process.env.NEXT_PUBLIC_SUPABASE_URL!,
  process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)

// 使用例
const { data, error } = await supabase
  .from('customers')
  .select('*')
  .eq('status', 'active')
  .order('created_at', { ascending: false })

Row Level Security (RLS)

データベースにはRow Level Security (RLS)が設定されており、ユーザーは自分のデータのみにアクセスできます。
-- 例:顧客テーブルのRLSポリシー
CREATE POLICY "Users can view own customers" ON customers
  FOR SELECT
  USING (auth.uid() = user_id);

認証・認可

認証フロー

┌───────────┐     ┌───────────┐     ┌───────────┐
│   User    │────▶│  Next.js  │────▶│  Supabase │
│           │◀────│           │◀────│   Auth    │
└───────────┘     └───────────┘     └───────────┘
     │                                    │
     │        JWT Token                   │
     │◀──────────────────────────────────┘

認証方式

  • メール/パスワード認証: デフォルトで実装
  • OAuth: Google, GitHub等(設定により追加可能)

認可

  • RLS(Row Level Security): データベースレベルでのアクセス制御
  • ミドルウェア: ページレベルでの認証チェック

型安全性

TypeScript

全てのコードはTypeScriptで記述されており、型安全性が確保されています。

データベース型

Supabaseのスキーマから自動生成される型定義を使用します。
// types/database.types.ts(自動生成)
export interface Database {
  public: {
    Tables: {
      customers: {
        Row: {
          id: string
          name: string
          email: string
          created_at: string
        }
        Insert: { ... }
        Update: { ... }
      }
    }
  }
}

スタイリング

Tailwind CSS

UIスタイリングにはTailwind CSSを使用しています。 特徴:
  • ユーティリティファーストのアプローチ
  • レスポンシブデザインのサポート
  • ダークモード対応(設定により)

カスタムテーマ

tailwind.config.jsでカラースキームやフォントをカスタマイズできます。

拡張ポイント

app/api/ディレクトリにAPIルートを追加し、外部サービスとの連携を実装できます。
Supabase Authの設定を変更するか、別の認証プロバイダー(Auth0、Firebase Authなど)に置き換えられます。
より複雑な状態管理が必要な場合、Zustand、Jotai、Redux Toolkitなどを追加できます。
Jest、Testing Library、Playwrightなどを追加してテストを実装できます。