Fullstack App Creator - De cero a producción
Arquitectura Automática
App completa en 5 minutos:
├── Backend: FastAPI/Express + PostgreSQL
├── Frontend: React/Next.js + Tailwind
├── Auth: JWT + OAuth (Google, GitHub)
├── API: REST + WebSocket
├── Deploy: Docker + Railway/Vercel
└── Monitoreo: Logs + Health checks
Stack Recomendado por Caso de Uso
| Caso de Uso |
Backend |
Frontend |
DB |
Deploy |
| SaaS B2B |
FastAPI |
Next.js |
PostgreSQL |
Railway |
| E-commerce |
Express |
React + Stripe |
PostgreSQL |
Vercel |
| Dashboard |
FastAPI |
React + Recharts |
PostgreSQL |
Fly.io |
| Social App |
Express |
Next.js + Socket.io |
MongoDB |
Render |
| API Only |
FastAPI |
- |
PostgreSQL |
Railway |
| Landing Page |
- |
Next.js |
- |
Vercel |
Backend: FastAPI (Producción)
# app/main.py
from fastapi import FastAPI, HTTPException, Depends
from fastapi.middleware.cors import CORSMiddleware
from sqlalchemy.ext.asyncio import AsyncSession
from pydantic import BaseModel
import uvicorn
app = FastAPI(title="MyApp", version="1.0.0")
# CORS
app.add_middleware(
CORSMiddleware,
allow_origins=["http://localhost:3000"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Database
from app.database import get_db, Base, engine
@app.on_event("startup")
async def startup():
async with engine.begin() as conn:
await conn.run_sync(Base.metadata.create_all)
# Models
class UserCreate(BaseModel):
email: str
name: str
password: str
class UserResponse(BaseModel):
id: int
email: str
name: str
# Routes
@app.post("/api/users", response_model=UserResponse)
async def create_user(user: UserCreate, db: AsyncSession = Depends(get_db)):
from app.models import User
db_user = User(**user.dict())
db.add(db_user)
await db.commit()
await db.refresh(db_user)
return db_user
@app.get("/api/users/{user_id}", response_model=UserResponse)
async def get_user(user_id: int, db: AsyncSession = Depends(get_db)):
from app.models import User
user = await db.get(User, user_id)
if not user:
raise HTTPException(status_code=404, detail="User not found")
return user
@app.get("/health")
async def health():
return {"status": "ok"}
if __name__ == "__main__":
uvicorn.run("main:app", host="0.0.0.0", port=8000, reload=True)
Database: PostgreSQL + SQLAlchemy
# app/database.py
from sqlalchemy.ext.asyncio import create_async_engine, AsyncSession, async_sessionmaker
from sqlalchemy.orm import DeclarativeBase
DATABASE_URL = "postgresql+asyncpg://user:pass@localhost:5432/mydb"
engine = create_async_engine(DATABASE_URL, echo=True)
async_session = async_sessionmaker(engine, class_=AsyncSession, expire_on_commit=False)
class Base(DeclarativeBase):
pass
async def get_db():
async with async_session() as session:
yield session
# app/models.py
from sqlalchemy import Column, Integer, String, DateTime
from sqlalchemy.sql import func
from app.database import Base
class User(Base):
__tablename__ = "users"
id = Column(Integer, primary_key=True, index=True)
email = Column(String, unique=True, index=True, nullable=False)
name = Column(String, nullable=False)
hashed_password = Column(String, nullable=False)
created_at = Column(DateTime(timezone=True), server_default=func.now())
updated_at = Column(DateTime(timezone=True),
Frontend: React + Tailwind
// src/App.tsx
import { useState, useEffect } from 'react';
function App() {
const [users, setUsers] = useState([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch('/api/users')
.then(res => res.json())
.then(data => setUsers(data))
.finally(() => setLoading(false));
}, []);
return (
<div className="min-h-screen bg-gray-50">
<nav className="bg-white shadow">
<div className="max-w-7xl mx-auto px-4 py-4">
<h1 className="text-xl font-bold">MyApp</h1>
</div>
</nav>
<main className="max-w-7xl mx-auto px-4 py-8">
{loading ? (
<div className="text-center">Loading...</div>
) : (
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{users.map(user => (
<div key={user.id} className="bg-white rounded-lg shadow p-6">
<h3 className="font-semibold">{user.name}</h3>
<p className="text-gray-600">{user.email}</p>
</div>
))}
</div>
)}
</main>
</div>
);
}
export default App;
Auth: JWT + OAuth
# app/auth.py
from datetime import datetime, timedelta
from jose import JWTError, jwt
from passlib.context import CryptContext
from fastapi import Depends, HTTPException
from fastapi.security import OAuth2PasswordBearer
SECRET_KEY = "your-secret-key"
ALGORITHM = "HS256"
ACCESS_TOKEN_EXPIRE_MINUTES = 30
pwd_context = CryptContext(schemes=["bcrypt"], deprecated="auto")
oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
def verify_password(plain_password, hashed_password):
return pwd_context.verify(plain_password, hashed_password)
def get_password_hash(password):
return pwd_context.hash(password)
def create_access_token(data: dict, expires_delta: timedelta = None):
to_encode = data.copy()
expire = datetime.utcnow() + (expires_delta or timedelta(minutes=15))
to_encode.update({"exp": expire})
return jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
async def get_current_user(token: str = Depends(oauth2_scheme)):
credentials_exception = HTTPException(
status_code=401,
detail="Could not validate credentials",
headers={"WWW-Authenticate": "Bearer"},
)
try:
payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
user_id: str = payload.get("sub")
if user_id is None:
raise credentials_exception
except JWTError:
raise credentials_exception
return user_id
Docker
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
EXPOSE 8000
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000"]
# docker-compose.yml
version: '3.8'
services:
db:
image: postgres:15
environment:
POSTGRES_USER: user
POSTGRES_PASSWORD: pass
POSTGRES_DB: mydb
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
app:
build: .
ports:
- "8000:8000"
environment:
DATABASE_URL: postgresql+asyncpg://user:pass@db:5432/mydb
depends_on:
- db
volumes:
postgres_data:
Deploy: Railway
# Instalar Railway CLI
npm install -g @railway/cli
# Login
railway login
# Crear proyecto
railway init
# Agregar PostgreSQL
railway add --database postgresql
# Deploy
railway up