mirror of
https://github.com/supabase/supabase.git
synced 2026-10-12 12:55:06 +03:00
Architecture page
This commit is contained in:
1 parent
c1e0ca4f27
commit
697d457f1d
2 files changed
+274
-44
No files matched your search
@@ -1,4 +1,8 @@
|
||||
'use client'
|
||||
|
||||
import { Check } from 'lucide-react'
|
||||
import { useEffect, useRef, useState } from 'react'
|
||||
import { useLocalStorage } from './use-local-storage'
|
||||
|
||||
interface ChapterCompletionProps {
|
||||
chapterNumber: number
|
||||
@@ -6,28 +10,135 @@ interface ChapterCompletionProps {
|
||||
}
|
||||
|
||||
export function ChapterCompletion({ chapterNumber, completionMessage }: ChapterCompletionProps) {
|
||||
const [completedChapters, setCompletedChapters] = useLocalStorage<number[]>(
|
||||
'completed-chapters',
|
||||
[]
|
||||
)
|
||||
const [isCompleted, setIsCompleted] = useState(false)
|
||||
const [isVisible, setIsVisible] = useState(false)
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const timerRef = useRef<NodeJS.Timeout | null>(null)
|
||||
|
||||
// Check if chapter is already completed on mount
|
||||
useEffect(() => {
|
||||
if (completedChapters.includes(chapterNumber)) {
|
||||
setIsCompleted(true)
|
||||
}
|
||||
}, [chapterNumber, completedChapters])
|
||||
|
||||
useEffect(() => {
|
||||
const container = containerRef.current
|
||||
if (!container) return
|
||||
|
||||
const observer = new IntersectionObserver(
|
||||
(entries) => {
|
||||
entries.forEach((entry) => {
|
||||
if (entry.isIntersecting) {
|
||||
setIsVisible(true)
|
||||
} else {
|
||||
setIsVisible(false)
|
||||
// Reset timer if user scrolls away
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
timerRef.current = null
|
||||
}
|
||||
}
|
||||
})
|
||||
},
|
||||
{
|
||||
threshold: 0.5, // Trigger when 50% of the component is visible
|
||||
rootMargin: '0px',
|
||||
}
|
||||
)
|
||||
|
||||
observer.observe(container)
|
||||
|
||||
return () => {
|
||||
observer.disconnect()
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
}
|
||||
}, [])
|
||||
|
||||
useEffect(() => {
|
||||
if (isVisible && !isCompleted) {
|
||||
// Start timer when component becomes visible
|
||||
timerRef.current = setTimeout(() => {
|
||||
setIsCompleted(true)
|
||||
// Save to local storage
|
||||
if (!completedChapters.includes(chapterNumber)) {
|
||||
setCompletedChapters([...completedChapters, chapterNumber])
|
||||
}
|
||||
}, 5000) // 5 seconds
|
||||
} else if (!isVisible && timerRef.current) {
|
||||
// Clear timer if user scrolls away before completion
|
||||
clearTimeout(timerRef.current)
|
||||
timerRef.current = null
|
||||
}
|
||||
|
||||
return () => {
|
||||
if (timerRef.current) {
|
||||
clearTimeout(timerRef.current)
|
||||
}
|
||||
}
|
||||
}, [isVisible, isCompleted, chapterNumber, completedChapters, setCompletedChapters])
|
||||
|
||||
return (
|
||||
<div className="mb-16 mt-8">
|
||||
<div className="flex items-center gap-12">
|
||||
<div ref={containerRef} className="mb-16 mt-8">
|
||||
<div className="flex items-center gap-12">
|
||||
{/* Large circle with chapter number */}
|
||||
<div className="relative mb-6">
|
||||
<div className="w-24 h-24 rounded-full bg-green-50 flex items-center justify-center">
|
||||
<span className="text-4xl font-bold text-brand-500">{chapterNumber}</span>
|
||||
<div
|
||||
className={`w-24 h-24 rounded-full flex items-center justify-center transition-all duration-500 ${
|
||||
isCompleted ? 'bg-green-50' : 'bg-muted'
|
||||
}`}
|
||||
>
|
||||
<span
|
||||
className={`text-4xl font-bold transition-all duration-500 ${
|
||||
isCompleted ? 'text-brand-500' : 'text-foreground-muted'
|
||||
}`}
|
||||
>
|
||||
{chapterNumber}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
{/* Small checkmark circle overlapping bottom-right */}
|
||||
<div className="absolute -bottom-1 -right-1 w-8 h-8 bg-brand-500 rounded-full flex items-center justify-center shadow-md">
|
||||
<Check className="h-6 w-6 text-white" strokeWidth={3} />
|
||||
<div
|
||||
className={`absolute -bottom-1 -right-1 w-8 h-8 rounded-full flex items-center justify-center shadow-md transition-all duration-500 ${
|
||||
isCompleted ? 'bg-brand-500 scale-100 opacity-100' : 'bg-muted scale-75 opacity-0'
|
||||
}`}
|
||||
>
|
||||
<Check
|
||||
className={`h-6 w-6 text-white transition-all duration-300 ${
|
||||
isCompleted ? 'scale-100 opacity-100' : 'scale-0 opacity-0'
|
||||
}`}
|
||||
strokeWidth={3}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
{/* Completion text */}
|
||||
<h3 className="text-2xl font-bold text-foreground mb-2">
|
||||
<h3
|
||||
className={`text-2xl font-bold mb-2 transition-all duration-500 ${
|
||||
isCompleted
|
||||
? 'text-foreground opacity-100 translate-y-0'
|
||||
: 'text-foreground-muted opacity-60 translate-y-2'
|
||||
}`}
|
||||
>
|
||||
You've completed Chapter {chapterNumber}
|
||||
</h3>
|
||||
|
||||
{completionMessage && (
|
||||
<p className="text-base text-foreground-light max-w-2xl">{completionMessage}</p>
|
||||
<p
|
||||
className={`text-base max-w-2xl transition-all duration-500 delay-100 ${
|
||||
isCompleted
|
||||
? 'text-foreground-light opacity-100 translate-y-0'
|
||||
: 'text-foreground-light opacity-0 translate-y-2'
|
||||
}`}
|
||||
>
|
||||
{completionMessage}
|
||||
</p>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -4,57 +4,176 @@ description: Learn how Supabase's core products work together.
|
||||
chapterNumber: 1
|
||||
---
|
||||
|
||||
In this short course, you'll explore how Supabase brings together **Database**, **Auth**, **Storage**, **Edge Functions**, and **Realtime** into a unified developer platform.
|
||||
---
|
||||
|
||||
By the end, you'll understand how each piece of Supabase fits together, how to persist and protect your data, and how to start confidently building your own applications.
|
||||
|
||||
## What you'll learn
|
||||
|
||||
- **Architecture**: how Supabase's core products work together.
|
||||
- **Data fundamentals**: create tables, insert and retrieve data, and explore our generated APIs.
|
||||
- **Authentication**: create and sign in users, and make secure requests.
|
||||
- **Security**: enable Row Level Security (RLS) and write policies to protect your data.
|
||||
- **Storage**: upload and serve files using buckets.
|
||||
- **Edge Functions**: run custom backend logic close to your users, using Deno and Supabase's serverless runtime.
|
||||
- **Vector search**: store and query embeddings for AI-powered search and recommendations.
|
||||
title: Architecture
|
||||
description: A high-level view of how Supabase fits together: Postgres at the center,
|
||||
with services for auth, APIs, storage, realtime, edge functions, and vector search.
|
||||
|
||||
---
|
||||
|
||||
## Prerequisites
|
||||
This page explains how Supabase is structured and how its main services work
|
||||
together. Supabase is built on top of a powerful open source database called
|
||||
Postgres, but it includes much more than a database. Around Postgres,
|
||||
Supabase adds services for authentication, serverless functions, file storage, realtime updates, AI-powered search, and easy APIs to access it — all designed to work easily together.
|
||||
|
||||
- A [Supabase account](https://supabase.com/) (free)
|
||||
- Basic familiarity with a terminal to run queries.
|
||||
The goal is to give you a complete backend that feels consistent and connected,
|
||||
so you can focus on building your app instead of wiring together separate tools.
|
||||
|
||||
---
|
||||
|
||||
## Course outline
|
||||
## The mental model
|
||||
|
||||
The course is split into 7 chapters, each approximately 10 minutes long.
|
||||
At the center of Supabase is Postgres. Every other part connects to it.
|
||||
|
||||
1. **What is Supabase?**
|
||||
Get an overview of Supabase's architecture and core products. Create your first project and make a simple API call.
|
||||
2. **Your First Table**
|
||||
Create a Postgres table in Supabase, insert data, and query it through the REST API.
|
||||
3. **Authentication Basics**
|
||||
Add users, sign them in, and understand how Supabase secures your APIs with JWTs.
|
||||
4. **Secure Your Data with Row-Level Security**
|
||||
Enable Row-Level Security and write policies to ensure users only access their own data.
|
||||
5. **Storage**
|
||||
Store files in Supabase Storage and upload and serve files from your buckets.
|
||||
6. **Edge Functions**
|
||||
Deploy simple functions to run backend logic close to your users using Deno.
|
||||
7. **Vector Search**
|
||||
Store and query embeddings for AI-powered search and recommendations using Supabase Vector.
|
||||
```text
|
||||
Clients (web, mobile, scripts)
|
||||
|
|
||||
v
|
||||
API layer (REST via PostgREST, GraphQL)
|
||||
|
|
||||
v
|
||||
Postgres <---- Realtime (listens for changes)
|
||||
| ^
|
||||
| |
|
||||
v |
|
||||
Storage | Auth (manages users)
|
||||
| | Edge Functions (runs code)
|
||||
v | Vector Search (pgvector)
|
||||
Files + URLs Studio, CLI, Policies (RLS)
|
||||
```
|
||||
|
||||
You interact with Supabase mainly through the API layer or the client libraries.
|
||||
The API talks to Postgres, and Postgres enforces security rules that you define.
|
||||
All the other services stay in sync because they share the same database.
|
||||
|
||||
---
|
||||
|
||||
## Before you begin
|
||||
## The main components
|
||||
|
||||
Create a new project at [supabase.com](https://supabase.com), open the **Supabase Dashboard**, and grab your **API URL** and **anon key** from the [Connect dialog](https://supabase.com/dashboard/project/_/settings/api?showConnect=true&connectTab=frameworks).
|
||||
You'll use them throughout the course to send real requests to your database and APIs.
|
||||
### Database (Postgres)
|
||||
|
||||
Your data lives in Postgres tables. You can design tables, columns, and
|
||||
relationships using SQL or the visual editor in Supabase Studio. Supabase
|
||||
manages backups, scaling, and migrations for you.
|
||||
|
||||
**Why this matters:** Postgres is a full relational database with features like
|
||||
foreign keys, indexes, and extensions. Supabase gives you these tools without
|
||||
the usual setup.
|
||||
|
||||
---
|
||||
|
||||
## Duration
|
||||
### API layer (REST and GraphQL)
|
||||
|
||||
Approx. **1 hour** — a fast, hands-on introduction to the Supabase platform.
|
||||
Supabase automatically exposes your tables as APIs using PostgREST (for REST)
|
||||
and PostGraphile (for GraphQL). You can read, insert, update, and delete rows
|
||||
with simple HTTP requests. You can also expose your own SQL functions as custom
|
||||
endpoints.
|
||||
|
||||
**Why this matters:** You can connect any frontend or script directly to your
|
||||
database without building a separate API server.
|
||||
|
||||
---
|
||||
|
||||
### Auth (users and tokens)
|
||||
|
||||
Auth manages users and issues tokens that identify them. When someone signs in,
|
||||
their token is sent with every request, and Postgres uses that identity to apply
|
||||
the right access rules.
|
||||
|
||||
**Why this matters:** Authentication is built into your database layer, so you
|
||||
don't need an external service to handle sign-ups or sessions.
|
||||
|
||||
---
|
||||
|
||||
### Row Level Security (RLS) and policies
|
||||
|
||||
RLS lets you write SQL rules that decide who can read or modify each row in your
|
||||
tables. These policies apply everywhere — through REST, GraphQL, or Realtime.
|
||||
|
||||
**Why this matters:** Security lives directly in the database. You define it
|
||||
once, and it's enforced across every API call.
|
||||
|
||||
---
|
||||
|
||||
### Storage (files and buckets)
|
||||
|
||||
Storage provides an S3-style interface for storing files such as images, videos,
|
||||
and documents. File metadata lives in Postgres, so you can apply the same access
|
||||
policies you use for your data.
|
||||
|
||||
**Why this matters:** File access and data access follow the same security rules,
|
||||
which keeps your system consistent and simple.
|
||||
|
||||
---
|
||||
|
||||
### Realtime
|
||||
|
||||
Realtime listens to changes in Postgres and sends them to connected clients over
|
||||
WebSocket. You can subscribe to table events and see updates as they happen.
|
||||
|
||||
**Why this matters:** You can build collaborative or live-updating interfaces
|
||||
without managing your own socket server.
|
||||
|
||||
---
|
||||
|
||||
### Edge Functions
|
||||
|
||||
Edge Functions let you run server-side JavaScript or TypeScript using Deno.
|
||||
They're good for webhooks, background tasks, and any logic that shouldn't run
|
||||
on the client.
|
||||
|
||||
**Why this matters:** You can write custom backend logic without maintaining a
|
||||
full server or worrying about scaling.
|
||||
|
||||
---
|
||||
|
||||
### Vector Search
|
||||
|
||||
The pgvector extension adds support for storing and searching **embeddings** —
|
||||
numerical representations of text, images, or other data. This allows you to
|
||||
search by meaning, not just by keywords.
|
||||
|
||||
**Why this matters:** You can add AI-style semantic search or recommendations
|
||||
directly to your database.
|
||||
|
||||
---
|
||||
|
||||
### Studio and CLI
|
||||
|
||||
Supabase Studio is the web dashboard for managing your project: running SQL,
|
||||
browsing data, editing policies, and managing users. The CLI is for local
|
||||
development and migrations, so your schema can live alongside your code.
|
||||
|
||||
**Why this matters:** You can move smoothly between GUI and code, keeping your
|
||||
database versioned and reproducible.
|
||||
|
||||
---
|
||||
|
||||
## How everything connects
|
||||
|
||||
When your app makes a request, it goes through a simple path:
|
||||
|
||||
1. The client calls a Supabase API endpoint, sending a project key and (usually)
|
||||
a user token.
|
||||
2. The API turns that request into a SQL query.
|
||||
3. Postgres runs the query and applies any RLS policies.
|
||||
4. The API returns the results as JSON.
|
||||
5. If there are changes, Realtime broadcasts them to any connected clients that
|
||||
are allowed to see them.
|
||||
|
||||
Edge Functions can follow the same pattern — they can call the APIs or connect
|
||||
directly to Postgres when they need more control.
|
||||
|
||||
---
|
||||
|
||||
## Why this architecture helps
|
||||
|
||||
- **Everything shares one source of truth:** Postgres is at the center.
|
||||
- **Security is consistent:** RLS policies apply across every service.
|
||||
- **No separate backend required:** APIs are generated automatically from you database.
|
||||
- **You can grow gradually:** Start with just a table, add realtime, storage, or functions later.
|
||||
- **It's just Postgres:** You can use standard SQL, extensions, and tools.
|
||||
|
||||
Supabase gives you the power of Postgres with the convenience of a fully
|
||||
integrated backend platform.
|
||||
Reference in new issue
Block a user