2026ko abuztuaren 18a - Euskolabs
SaaS eskalagarria eraikitzeak ez luke hilabeterik beharko. euskolabs-en SaaS MVPak 14 egun baino gutxiagoan ugaritzen dira, pila optimizatua erabiliz: Laguntza datu-baserako eta autherako, FastAPI motorrarentzat, Stripe ordainketa eta Docker hedatzeko. Gida teknikoa da hori egiteko.
Elementu anitzeko gakoa datu-basearen diseinuan dago. Erabili egiten dugu Errenkada-mailaren segurtasuna (RLS) postgreSQL-tik, Supabasetik, maizter bakoitzaren datuak isolatzeko, kontsulta bakoitzean eskuzko iragazkirik behar izan gabe.
-- Tabla de tenants (organizaciones/clientes)
CREATE TABLE tenants (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
name TEXT NOT NULL,
plan TEXT DEFAULT 'free',
stripe_customer_id TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Tabla de usuarios vinculada a tenants
CREATE TABLE users (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
email TEXT UNIQUE NOT NULL,
role TEXT DEFAULT 'member',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Tabla de datos del SaaS (ejemplo: proyectos)
CREATE TABLE projects (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
tenant_id UUID REFERENCES tenants(id) ON DELETE CASCADE,
name TEXT NOT NULL,
status TEXT DEFAULT 'active',
created_at TIMESTAMPTZ DEFAULT NOW()
);
-- Row Level Security: cada usuario solo ve datos de su tenant
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
CREATE POLICY "tenant_isolation" ON projects
FOR ALL USING (tenant_id = (
SELECT tenant_id FROM users
WHERE id = auth.uid()
));
RLS gaituta, Supabase automatikoki iragazten duzun edozein kontsulta, autentifikatutako erabiltzailearen maizterrak. Teniente batek ezin ditu datuak beste batetik atzitu, ezta hutsegitez ere.
FastAPI-k automatikoki sortzen du OpenAPI dokumentazioa, baliozko motak pidantikoekin eta jatorrizko async onartzen ditu. Motorraren egitura:
app/
├── main.py # Entry point + routers
├── deps.py # Dependencias (auth, db)
├── models.py # Modelos Pydantic
├── routers/
│ ├── tenants.py # CRUD tenants
│ ├── projects.py # CRUD proyectos
│ ├── auth.py # Login/registro via Supabase
│ └── billing.py # Webhooks Stripe
└── supabase.py # Cliente Supabase
from fastapi import Depends, HTTPException
from supabase import create_client
async def get_current_user(token: str = Depends(oauth2_scheme)):
supabase = create_client(SUPABASE_URL, SUPABASE_KEY)
user = supabase.auth.get_user(token)
if not user:
raise HTTPException(401, "No autorizado")
return user
Erabiliko dugun aurrealdean Next.js sSRrekin SEOrako eta kode automatikoa zatitzeko. Stripe-rekin integratzea:
@app.post("/webhooks/stripe")
async def stripe_webhook(request: Request):
event = stripe.Webhook.construct_event(
payload, sig, ENDPOINT_SECRET
)
if event["type"] == "invoice.paid":
tenant_id = event["data"]["object"]["metadata"]["tenant_id"]
activate_tenant(tenant_id)
elif event["type"] == "invoice.payment_failed":
tenant_id = event["data"]["object"]["metadata"]["tenant_id"]
suspend_tenant(tenant_id)
FROM python:3.12-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
services:
api:
build: .
ports: ["8000:8000"]
env_file: .env
restart: always
caddy:
image: caddy:2
ports: ["443:443", "80:80"]
volumes: ["./Caddyfile:/etc/caddy/Caddyfile"]
Caddyk SSL automatikoki kudeatzen du 'Let's Encrypt-ekin. SaaS-a HTTPSrekin bizi da.
Pila honekin SaaS multitenant funtzionala eskaintzen dugu 14 egunetan:
SaaSa jaurti nahi duzu? Eskatu diagnostikoa euskolabs. com.