Bỏ qua

Kiến trúc tổng quan Light Stack

High-level Architecture

                            ┌─────────────────┐
                            │     Client      │
                            │  (Browser/App)  │
                            └────────┬────────┘
┌────────────────────────────────────────────────────────────────┐
│                     CLOUDFLARE EDGE NETWORK                     │
│                                                                 │
│  ┌──────────────────────────────────────────────────────────┐  │
│  │                    Next.js on Workers                     │  │
│  │  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐       │  │
│  │  │    SSR      │  │ API Routes  │  │   Static    │       │  │
│  │  │   Pages     │  │  /api/*     │  │   Assets    │       │  │
│  │  └─────────────┘  └─────────────┘  └─────────────┘       │  │
│  └──────────────────────────────────────────────────────────┘  │
│                                                                 │
│  ┌─────────────┐  ┌─────────────┐  ┌─────────────┐             │
│  │    Queue    │  │    Cron     │  │     KV      │             │
│  │  (Messages) │  │  (Triggers) │  │   (Cache)   │             │
│  └─────────────┘  └─────────────┘  └─────────────┘             │
│                                                                 │
└────────────────────────────────────────────────────────────────┘
┌────────────────────────────────────────────────────────────────┐
│                          SUPABASE                               │
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │  PostgreSQL  │  │     Auth     │  │   Storage    │          │
│  │   Database   │  │   (JWT)      │  │   (Files)    │          │
│  │   + REST     │  │              │  │              │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│                                                                 │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │   Realtime   │  │    Queue     │  │     Cron     │          │
│  │  (WebSocket) │  │   (pgmq)     │  │  (pg_cron)   │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│                                                                 │
└────────────────────────────────────────────────────────────────┘

Request Flow

1. Static Page Request

Browser ──▶ Cloudflare CDN ──▶ Cached HTML
                 └── Cache HIT: Return immediately
                     Cache MISS: Generate from Worker

2. SSR Page Request

Browser ──▶ Worker ──▶ Supabase DB ──▶ Render HTML ──▶ Response
                 └── Fetch data ──▶ Build page ──▶ Cache

3. API Request

Browser ──▶ Worker (/api/*) ──▶ Supabase ──▶ JSON Response
                 ├── Direct to Supabase REST API
                 └── Or custom logic in Worker

4. Background Job

Trigger ──▶ Queue ──▶ Worker Consumer ──▶ Process ──▶ Done
   ├── User action (enqueue)
   └── Cron trigger (scheduled)

Component Responsibilities

Next.js (Frontend + API Gateway)

Responsibility How
UI Rendering React components, SSR/SSG
Routing App Router
API Gateway Route Handlers
Auth middleware Next.js Middleware

Cloudflare (Edge Infrastructure)

Responsibility How
Hosting Workers (compute)
CDN Automatic edge caching
Background jobs Queue + Cron Triggers
Fast storage KV (key-value)

Supabase (Backend Services)

Responsibility How
Database PostgreSQL + REST API
Authentication Auth service + JWT
File storage Storage buckets
Realtime WebSocket subscriptions
Background pgmq + pg_cron

Data Flow Patterns

Pattern 1: Direct Client → Supabase

// Client-side: Bypass Worker, direct to Supabase
const { data } = await supabase
  .from('posts')
  .select('*')
  .eq('published', true);

Khi nào dùng: Simple reads, realtime subscriptions

Pattern 2: Client → Worker → Supabase

// API Route in Worker
export async function GET(request: Request) {
  // Custom business logic
  const data = await fetchFromSupabase();
  const processed = transform(data);
  return Response.json(processed);
}

Khi nào dùng: Complex logic, data transformation, auth checks

Pattern 3: Background Processing

// Producer: Enqueue job
await queue.send({ type: 'email', to: 'user@example.com' });

// Consumer: Process job
export default {
  async queue(batch: MessageBatch) {
    for (const msg of batch.messages) {
      await sendEmail(msg.body);
      msg.ack();
    }
  }
};

Khi nào dùng: Async tasks, notifications, heavy processing


Security Architecture

Authentication Flow

┌────────┐    ┌────────┐    ┌──────────┐    ┌──────────┐
│ Client │───▶│ Worker │───▶│ Supabase │───▶│ Database │
└────────┘    └────────┘    │   Auth   │    └──────────┘
     │             │        └──────────┘
     │             │              │
     │             │              ▼
     │             │        ┌──────────┐
     │             └───────▶│   JWT    │
     │                      │ Validate │
     │                      └──────────┘
     │                            │
     └────────────────────────────┘
              Access Token

Authorization (Row Level Security)

-- Supabase RLS Policy
CREATE POLICY "Users can only see own data"
ON tasks FOR SELECT
USING (auth.uid() = user_id);

-- Automatic filtering based on JWT
SELECT * FROM tasks;
-- Returns only current user's tasks

Deployment Architecture

Environments

┌─────────────────────────────────────────────────────────┐
│                    GitHub Repository                     │
└────────────────────────┬────────────────────────────────┘
           ┌─────────────┼─────────────┐
           │             │             │
           ▼             ▼             ▼
    ┌──────────┐  ┌──────────┐  ┌──────────┐
    │   Dev    │  │ Staging  │  │Production│
    │  Branch  │  │  Branch  │  │  Branch  │
    └────┬─────┘  └────┬─────┘  └────┬─────┘
         │             │             │
         ▼             ▼             ▼
    ┌──────────┐  ┌──────────┐  ┌──────────┐
    │Cloudflare│  │Cloudflare│  │Cloudflare│
    │  Preview │  │ Staging  │  │Production│
    └────┬─────┘  └────┬─────┘  └────┬─────┘
         │             │             │
         ▼             ▼             ▼
    ┌──────────┐  ┌──────────┐  ┌──────────┐
    │ Supabase │  │ Supabase │  │ Supabase │
    │   Dev    │  │ Staging  │  │Production│
    └──────────┘  └──────────┘  └──────────┘

Cost Breakdown by Component

Component Free Tier Paid Tier
Cloudflare Workers 100K req/day $5/10M req
Cloudflare KV 100K reads/day $0.50/1M
Cloudflare Queue 1M ops/month $0.40/1M
Supabase Database 500MB $25/8GB
Supabase Auth 50K MAU Included
Supabase Storage 1GB $0.02/GB

Typical PoC: $0-25/tháng


Tổng kết

Architecture Principles

  1. Edge-first - Compute gần user nhất
  2. Serverless - Không quản lý servers
  3. API-driven - Supabase REST API
  4. Event-driven - Queue cho async tasks

Key Takeaways

  • Client có thể gọi trực tiếp Supabase (với RLS)
  • Worker xử lý business logic phức tạp
  • Queue cho background processing
  • Cron cho scheduled tasks

Q&A

  1. Bạn thấy pattern nào phù hợp với dự án của bạn?
  2. Có câu hỏi gì về data flow?
  3. Security concerns nào bạn đang nghĩ đến?