Técnico

Arquitectura Técnica

Stack y decisiones de diseño.

Fuego Social — Architecture Decision Record

> Antes de tocar cualquier feature, leer también SECURITY.md y BRAND.md.

> Esos dos documentos son ley. Si una decision tecnica los rompe, se rediseña.

What we're building

Two-sided marketplace for asados. Hosts publish seats, venues, events. Guests book and pay. Commission model (12%).

Stack

Capas de la app (cada request las atraviesa en orden)

`

Cliente

→ Cloudflare (TLS, WAF, edge rate limit) [pendiente conectar]

→ Cloudflared tunnel

→ Hub serve.js (4500, docs) | API api.js (4501)

| 1. CORS allowlist

| 2. Security headers

| 3. Global rate limit (per IP)

| 4. Authentication (JWT)

| 5. Per-route rate limit

| 6. Body size cap + JSON parse

| 7. Zod validation

| 8. Authorization (ownership)

| 9. Parameterised SQL

| 10. Audit log

| → DB (PostgreSQL)

`

Cada capa esta en fuegosocial-hub/lib/:

The rule that protects everything (branding)

No component may contain:

The rule that protects everything (security)

Ningun endpoint puede:

Detalle completo: ver SECURITY.md.

Branding change cost

Change brand name: 1 line in brand.config.ts

Change palette: 1 section in brand.config.ts

Change tagline: 1 line in brand.config.ts

Time to rebrand completely: < 5 minutes + 1 build

Language

Listing types

Booking flow (Airbnb-derived)

Review system (bidirectional — like Airbnb)

Guest reviews host: food, fire technique, hospitality, cleanliness, value

Host reviews guest: punctuality, respect, social vibe, would_invite_again

Neither party sees the other's review until both have submitted (or 14 days pass)

Database tables

Core: users, listings, listing_dates, bookings, reviews, messages, sessions, saved_listings, platform_metrics

Security additions (migrations/001_security.sql): audit_log, rate_limits, api_keys, webhook_events, login_attempts. Plus columns on users (password_hash, google_sub, locked_until, mfa_*) and sessions (refresh_token_hash, revoked_at, rotated_to).

Pages

/ landing, /explorar browse, /asado/[slug] detail, /ser-anfitrion host onboarding,

/publicar create listing, /login, /registro, /cuenta dashboard, /reserva/[id] booking detail,

/perfil/[id], /mensajes, /valorar/[bookingId], /admin, /como-funciona, /404. Cada una replicada en /en/*.

Responsive strategy

Mobile-first. Three genuine layouts — not squeezed desktop.

Mobile < 768: single col, bottom nav, booking = modal

Tablet 768-1024: 2-col grid, sidebar booking

Desktop > 1024: 4-col grid, sticky 1/3 sidebar

Escala (roadmap explicito)

EtapaUsuariosDBCachingCosto

|---|---|---|---|---|

Hoy0 → 10kPostgreSQL en VM€0 extra
Tracción10k → 200kSupabase / Railway managedRedis (Upstash)€25-100/mes
Escala Airbnb200k → 1M+RDS Aurora + read replicasRedis cluster + CDN imagenes€2k-10k/mes

Migracion entre etapas: la pool en lib/db.js solo cambia su connection string. Toda la lógica del codigo se mantiene.

Pendientes alineados con la doctrina

Producto

SEO & LLM Visibility — Doctrina

> El modelo de Airbnb: no blog. El contenido lo genera la plataforma.

SEO programático (prioridad alta)

Cada combinación de ciudad + tipo + amenidad es una URL indexable generada automáticamente.

Ejemplos:

Regla: nunca blog externo. Las guías viven dentro de /guias/* como páginas Astro estáticas, indexables, con schema.org.

Schema.org (structured data)

Todo listing debe tener markup de:

Esto activa rich snippets en Google y es la señal más fuerte para LLMs que leen la web.

Sitemap & hreflang

Visibilidad en LLMs (ChatGPT, Perplexity, Claude)

Los LLMs no se optimizan como Google — se trabaja con PR digital:

Regla: cada feature nueva debe preguntarse — ¿genera una URL indexable? ¿tiene schema.org? ¿crea contenido que otros van a citar?

Seguridad (ver SECURITY.md backlog)

Infra


Admin Dashboard — Doctrina y Arquitectura

Acceso

API Admin (/api/admin/*)

Todos los endpoints:

EndpointMetodoDescripcion

|---|---|---|

/api/admin/statsGETResumen: usuarios, listings, reservas, GMV, comision
/api/admin/usersGETLista paginada con busqueda (q=)
/api/admin/users/:idPATCHToggle is_active / is_admin
/api/admin/listingsGETTodos los listings (todos los estados) con filtros
/api/admin/listings/:idPATCHCambiar status (published/paused/archived)
/api/admin/bookingsGETTodas las reservas con filtro por status
/api/admin/auditGETAudit log con filtro por accion

Reglas de seguridad para toda feature admin nueva