Logo Apisdom
InicioAPIsProyectosServiciosBlog
Volver a Proyectos

ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet

Plataforma SaaS de generación de contenido con IA. Claude Sonnet 4.5 + Haiku 4.5, streaming SSE en vivo, editor TipTap, 15 tipos de contenido, adaptación a 7 redes sociales y checkout Stripe.

Imagen principal de ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Categoría: Inteligencia Artificial / SaaS
Publicado: 15 de abril de 2026
Actualizado: 15 de abril de 2026
Orden: #0
Ver Proyecto

Galería del Proyecto

Imagen 1 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 2 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 3 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 4 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 5 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 6 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 7 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 8 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 9 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 10 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet
Imagen 11 del proyecto ApisDom Studio: Plataforma SaaS con Next.js 16, FastAPI y Claude Sonnet

Tecnologías Utilizadas

Next.js 16
React 19
TypeScript
FastAPI
Python
Claude API
Stripe
Firebase

Sobre el Proyecto

Cargando contenido...

Información Técnica

Slug del proyecto:

apisdom-studio-saas-generacion-contenido-ia

ID del proyecto:

rNvCnikb3w4OZZb8gA4r

Estado:Publicado
Posición en lista:Orden #0

Documentación Específica del Proyecto

Flujos de trabajo y pipelines
Cargando contenido...
Interfaz de usuario y panel de control
Cargando contenido...
Infraestructura y microservicio backend
Cargando contenido...
Calidad, métricas y modelo de negocio
Cargando contenido...

Compartir este Conocimiento

Si este proyecto aporta valor o podría inspirar a otros, considera difundirlo en tu red profesional.

Logo Apisdom

Potenciando el futuro con APIs de Inteligencia Artificial y desarrollo de software a medida.

  • Términos de Servicio
  • Política de Privacidad
  • Política de Cookies
  • Política de Pagos
  • Aviso Legal
  • APIs y Precios
  • Documentación
  • Blog
  • Proyectos
  • Servicios
  • FAQ
  • Contacto: admin@apisdom.com
Contribuir
Logo Apisdom

Potenciando el futuro con APIs de Inteligencia Artificial y desarrollo de software a medida.

Redes
Políticas
  • Términos de Servicio
  • Política de Privacidad
  • Política de Cookies
  • Política de Pagos
  • Aviso Legal
Enlaces Rápidos
  • APIs y Precios
  • Documentación
  • Blog
  • Proyectos
  • Servicios
  • FAQ
Contacto
  • Email: admin@apisdom.com
  • Juan Luis
Contribuir

Contribuye al desarrollo

© 2026 Apisdom. Todos los derechos reservados.

Desarrollado con Next.js

    ¿Que es APISDOM Studio?

    APISDOM Studio es una plataforma SaaS de generacion de contenido con IA que convierte un brief simple (tema, tono, audiencia, longitud) en un articulo profesional listo para publicar: HTML/Markdown estructurado, metadata SEO, resumen, tabla de contenidos, Q&A, bloques de codigo y fuentes web citadas. Cada generacion cruza la red en tiempo real por Server-Sent Events para que el usuario vea el texto aparecer palabra a palabra en el editor.

    El sistema se divide en dos servicios independientes con fronteras explicitas:

    ServicioResponsabilidadHosting
    Frontend Next.js (studio.apisdom.com)UI, autenticacion, panel admin, editor TipTap, checkout Stripe, gestion de usuarios/creditos/perfiles/marcas, proxy firmado al backendFirebase App Hosting (Cloud Run us-central1, 1 CPU, 512 MiB, escala 0-10)
    Backend FastAPI (studio-api-...europe-west1.run.app)Motor de generacion, llamadas a Claude, busqueda web, streaming SSE, perfiles de generacion, historial, adaptacion a redes socialesCloud Run europe-west1, escala a cero

    El motor usa dos modelos de Claude segun el tier del usuario: claude-haiku-4-5 para tier free y adaptacion a redes, claude-sonnet-4-5 para tier premium. El modelo puede sobrescribirse en vivo desde el panel de administracion sin redesplegar (override con TTL de 60s en AdminConfig, y una clave emergency_model_override que fuerza el modelo para todos los usuarios).


    Que puede generar

    15 tipos de contenido con 4 longitudes, 10 tonos, 4 niveles de audiencia y 2 idiomas (ES / EN), configurables por llamada o fijados en un perfil reutilizable.

    CategoriaTipos soportados
    Articulosarticle · blog_post · tutorial · how_to · case_study · comparison · listicle · opinion
    Marketinglanding_page · product_description · press_release · newsletter
    Otrossocial_post · documentation · faq

    Longitudes reales (definidas en schemas.py y mapeadas a max_tokens en engine.py):

    LengthPalabras objetivomax_tokens
    short300-5002.000
    medium800-1.2004.000
    long1.800-2.5008.000
    extra_long3.000-5.00016.000

    Cada generacion devuelve un JSON estructurado con los mismos campos siempre: content_body, meta_seo (title, description, slug, Open Graph, keywords), summary, table_of_contents, sections, qa_items, code_blocks, sources, input_tokens, output_tokens, web_searches y model. Los campos opcionales (Q&A, codigo, TOC, resumen, fuentes) se activan por parametro en el request y se validan antes de llegar a Claude.


    Arquitectura hexagonal (Ports & Adapters) de verdad

    El frontend esta organizado en capas con una regla dura verificada en CI: core/ no puede importar de adapters/, lib/, ni paquetes externos. La estructura real de src/ es:

    src/
    ├── core/
    │   ├── entities/     (14 entidades: User, Generation, ApiKey, Partner, Brand, ...)
    │   ├── ports/        (13 interfaces: AuthPort, ContentPort, PaymentPort, ...)
    │   └── use-cases/    (18 funciones puras: CalculateCreditCost, ValidateGenerationInput, ...)
    ├── adapters/
    │   ├── api/          (StudioApiAdapter — cliente del backend FastAPI)
    │   ├── auth/         (AuthAdapter — Firebase Auth)
    │   ├── database/     (firebase/, memory/)
    │   └── payment/      (StripePaymentAdapter)
    ├── presentation/
    │   ├── components/   (169 componentes .tsx organizados por feature)
    │   ├── hooks/        (35 hooks)
    │   └── stores/       (Zustand)
    ├── app/              (Next.js App Router — 28 paginas bajo [locale])
    ├── config/           (pricing, credit-costs, env, firebase, i18n)
    └── lib/
    

    Cifras reales: 458 archivos .ts/.tsx, 169 componentes React, 53 route handlers Next.js (/api/**/route.ts), 28 paginas bajo [locale], i18n completo en es / en.


    Stack tecnico real

    Frontend (frontend/package.json)

    PiezaVersion
    Next.js16.1.5 (App Router, Server Components, SSR)
    React19.0.4
    TypeScript5.9.3
    Tailwind CSS4.1.18 + @tailwindcss/typography
    TipTap3.20.0 (StarterKit + image, link, table, text-align, code-block-lowlight, placeholder)
    Framer Motion12.29.2
    Firebase client SDK12.8.0
    Firebase Admin SDK13.6.0
    Stripe@stripe/stripe-js 8.6.4 + stripe 20.2.0 server SDK
    Zustand5.0.10 (state management)
    Zod4.3.6 (validacion runtime)
    isomorphic-dompurify2.35.0 (sanitizacion HTML)
    marked17.0.3 (Markdown → HTML en descargas)
    jsPDF4.0.0 (descargas PDF)
    nodemailer + Zoho SMTPNewsletter y emails transaccionales
    Phosphor Icons2.1.7 (unica libreria de iconos)
    Vitest4.0.18 + Playwright 1.58.0

    Backend (backend/requirements.txt)

    PiezaVersion minima
    Python3.12+
    FastAPI0.109+
    Uvicorn0.27+
    Anthropic SDK0.44+ (claude-sonnet-4-5-20250929 · claude-haiku-4-5-20251001)
    SQLAlchemy async2.0.25+
    aiosqlite0.19+ (desarrollo) · PostgreSQL asyncpg en produccion via DATABASE_URL
    Pydantic2.6+ + pydantic-settings
    sse-starlette2.0+ (Server-Sent Events)
    httpx0.26+
    mypy --strict1.8+
    ruff0.2+ (E,W,F,B,C90,I,N,UP,S)

    Hosting y dominio

    • Frontend: Firebase App Hosting — proyecto apisdom-studio, bucket apisdom-studio.firebasestorage.app, dominio https://studio.apisdom.com.
    • Backend: Google Cloud Run region europe-west1, despliegue automatico por Cloud Build desde push a main (imagen en Artifact Registry europe-west1-docker.pkg.dev).
    • Pagos: Stripe live (pk_live_...).
    • Email transaccional: Zoho SMTP via nodemailer.

    Pipeline de generacion de contenido

    Una llamada a POST /v1/generate lanza un flujo secuencial de 8 pasos que parte del brief del usuario y termina con un JSON completo persistido en historial. El frontend actua como proxy firmado hacia el backend FastAPI para que la clave del backend no toque nunca el navegador.

    PasoProcesoTecnologia
    1. Autenticacion y creditos/api/internal/generate/route.ts verifica Firebase Auth, calcula coste con CalculateCreditCost (tipo + longitud), bloquea si no hay creditos y descuenta atomicamenteFirebase Admin SDK + Firestore
    2. Validacion de requestvalidate_generate_request + validate_topic_length rechazan combinaciones invalidas (include_code sin code_language, max_qa_items fuera de rango, topic vacio...) antes de llamar al modeloPydantic v2 + validadores custom
    3. Seleccion de modelo_get_model_name_async lee DB overrides con prioridad: emergency_model_override → model_<tier> → env var por defecto. TTL de cache 60s en AdminConfigRepositorySQLAlchemy async + cache
    4. Construccion del promptbuild_system_prompt inyecta skill segun content_type, reglas de longitud, tono, audiencia, idioma, website del usuario, instrucciones custom y flags de Q&A / codigo / TOC / fuentesPlantillas en prompts/seo-content-generator/
    5. Web search condicionalshould_enable_search + determine_search_config deciden si activar la tool nativa web_search_20250305 de Anthropic con tool_choice=any y max_sources configurablesAnthropic web_search tool
    6. Llamada a Claude con fallbackPrimer intento al modelo del tier. Si devuelve RateLimitError o APIStatusError 429/503, reintento automatico con el modelo alternativo sin perder el requestAnthropic SDK
    7. Procesado de respuestaExtraccion de tool_use_blocks, parseo del JSON estructurado, extraccion de citations nativas (web_search_result_location) con URL, titulo y texto citadoParsers propios
    8. Persistencia + respuestaGuardado en historial (Generation SQLAlchemy) con input_tokens, output_tokens, web_searches, model y status. Respuesta final como JSON o stream SSE segun stream=true/falseSQLAlchemy + sse-starlette

    Streaming SSE en tiempo real

    Cuando el request trae stream: true, el backend devuelve StreamingResponse con text/event-stream y el frontend consume con EventSource. Cada evento lleva tipo y payload:

    EventoContenido
    metaModelo elegido, max_tokens, si hay web search activa
    deltaFragmento de texto generado (palabra / frase) — se pinta en vivo en el editor TipTap
    tool_useClaude lanzo una busqueda web (web_search tool call)
    citationURL + titulo + texto citado — aparece en el panel de fuentes mientras se genera
    doneJSON final completo con todos los campos estructurados
    errorError capturado por wrap_sse_stream — se convierte en stream_error sin cortar la conexion bruscamente

    El handler esta en streaming.py y el usuario ve el contenido aparecer progresivamente sin esperar a que Claude termine.


    Pipeline de adaptacion a redes sociales (POST /v1/adapt)

    Una vez generado un contenido, el usuario puede adaptarlo a 7 plataformas sociales sin coste extra para adaptaciones de 1 a 3 plataformas (1 credito) o 4 a 7 plataformas (2 creditos), definido en credit-costs.ts.

    PasoProceso
    1. Lectura del contenido origenSe pasan content_body y metadata del contenido generado previamente
    2. Limites nativos por plataformaGET /v1/platforms devuelve el limite real de caracteres de Facebook, Instagram, X, LinkedIn, TikTok, YouTube, Pinterest
    3. Llamada a Claude HaikuSe usa claude-haiku-4-5 (anthropic_model_adapt) para reducir coste — la adaptacion no necesita razonamiento largo
    4. Formato nativoHashtags, menciones, emojis, CTAs y saltos de linea segun las convenciones de cada plataforma
    5. Respuesta multi-plataformaJSON con una entrada por plataforma solicitada, cada una con text, character_count, hashtags y avisos de limite

    Las adaptaciones no consumen web_search y no generan nuevas citations — trabajan sobre el contenido ya existente.


    Perfiles de generacion reutilizables

    Los usuarios (y el panel admin) pueden guardar profiles con configuracion preferida de tono, longitud, audiencia, idioma, style_guide, brand_voice y preferencias SEO. Cada request puede referenciar un perfil por profile_id y el backend los mergea con los parametros del request antes de construir el prompt. Endpoints en routes_profiles.py y UI en app/[locale]/profiles/.


    Cada generacion queda registrada en el historial del usuario con todos los parametros, tokens consumidos, fuentes citadas y el JSON completo del resultado. El historial se expone en app/[locale]/history/ con filtros, re-descarga y re-uso como plantilla.

    Editor TipTap y panel de administracion

    APISDOM Studio tiene dos piezas de UI centrales: el editor WYSIWYG con TipTap donde el usuario ve y retoca el contenido generado por Claude, y un panel de administracion completo donde se gestionan usuarios, creditos, modelos, blog, partners y metricas globales.

    Editor WYSIWYG — TipTap 3.20

    El editor usa TipTap 3.20 con un conjunto completo de extensiones oficiales instaladas en produccion: StarterKit, Image, Link, Placeholder, Table + TableCell / TableHeader / TableRow, TextAlign y CodeBlockLowlight con resaltado de sintaxis via lowlight 3.3. Implementacion en editor/:

    • EditorContentArea.tsx — Area de edicion principal con useEditor, recibe el stream SSE del backend y va insertando nodos en vivo mientras Claude genera
    • EditorToolbar.tsx — Barra de formato: bold / italic / strike / headings / listas / quote / codigo / link / imagen / tabla / alineacion / undo-redo
    • EditorSidebar.tsx — Panel lateral con metadata SEO, TOC navegable, lista de fuentes citadas, Q&A y bloques de codigo detectados
    • FreeEditorSidebar.tsx — Variante para el modo editor libre sin generacion previa
    • HtmlSourceModal.tsx — Modal para editar el HTML crudo (sanitizado con isomorphic-dompurify antes de aplicarse)
    • EditorActions.tsx — Exportar a PDF (jsPDF), Markdown (marked), HTML plano, copiar al portapapeles, guardar como borrador

    El contenido generado llega del backend en formato html / markdown / plain_text segun output_format del request, se parsea al schema de TipTap y el usuario puede seguir editando libremente. Todo lo que sale del editor pasa por isomorphic-dompurify antes de persistirse para evitar XSS.


    Panel de administracion

    Ruta /[locale]/admin protegida por rol de admin verificado en Firebase custom claims. La UI esta organizada en tabs en admin/:

    TabComponenteQue permite
    Estadisticas globalesGlobalStatsTab.tsxUsuarios totales, generaciones hoy/semana/mes, tokens gastados, creditos vendidos, modelo mas usado
    Usuarios de la appAppUsersTab.tsx + UserDetailModal.tsx + AddCreditsModal.tsxBuscar usuarios, ver detalle, anadir/quitar creditos manualmente, bloquear/desbloquear, ver historial de generaciones del usuario
    Usuarios APIApiUsersTab.tsxGestion de usuarios que consumen la API publica /v1/** via API key
    Logs de APIApiLogsTab.tsxRegistro de llamadas a la API con usuario, endpoint, status, tokens, latencia
    Config del backendBackendConfigTab.tsxOverride en vivo (sin redesplegar) de modelo por tier, emergency_model_override, max_tokens_<length>, cache TTL 60s
    BlogBlogTab.tsx + BlogEditorModal.tsx + BlogEditorGuideModal.tsxCRUD del blog publico en /blog con el mismo editor TipTap
    Partnerspartners/PartnersTab.tsx + 9 componentesWhite-label completo: crear partners, planes, usuarios por partner, analytics, settings

    El modelo activo y los max_tokens por longitud se pueden cambiar en caliente desde BackendConfigTab sin tocar env vars ni redesplegar — el backend lee el override con TTL de 60 segundos en AdminConfigRepository.


    Partners / white-label

    El sistema soporta partners con endpoints publicos bajo /api/v1/[partner]/** (generate, adapt, user/status) para integraciones de terceros con su propia base de usuarios, planes y analytics. Gestionados en el panel admin via 9 componentes dedicados: PartnerDashboard, PartnerDetail, PartnerPlans, PartnerUsers, PartnerSettings, PartnerGuideModal, CreatePartnerModal, PlanEditorModal, PartnersTab.

    Cada partner tiene sus propios planes (creditos + precio), sus propios usuarios aislados y endpoints dedicados con autenticacion por API key. La separacion esta en la entidad Partner en core/entities/Partner.ts y PartnerPort en core/ports/PartnerPort.ts.


    API publica para desarrolladores

    Aparte de la app web, el backend expone una API REST publica documentada con OpenAPI 3 (/docs Swagger, /redoc ReDoc con logo custom inyectado en el schema). Los endpoints publicos son:

    MetodoEndpointAuthDescripcion
    POST/v1/generateBearerGenerar contenido (standard o SSE)
    POST/v1/adaptBearerAdaptar a redes sociales
    GET/v1/platforms—Listar plataformas y limites
    GET / POST / PUT / DELETE/v1/profiles/**BearerCRUD de perfiles

    La pagina publica para desarrolladores esta en /[locale]/developers, la gestion de API keys del usuario en /[locale]/api-keys y la entidad + use-case de validacion en ApiKey.ts + ValidateApiKeyInput.ts.

    Microservicio FastAPI (backend/)

    El motor de generacion vive en un microservicio independiente escrito en Python 3.12 + FastAPI, desplegado en Google Cloud Run europe-west1 con escalado a cero. Esta aislado del frontend por dos razones: 1) la ANTHROPIC_API_KEY solo existe en el entorno del backend y jamas se expone al navegador, 2) el microservicio puede redesplegarse sin tocar el frontend (y al reves) porque Cloud Build tiene un filtro included files: backend/** en el trigger.

    Estructura real

    22 archivos Python · 6.214 lineas organizados por responsabilidad:

    backend/
    ├── app/
    │   ├── main.py                    (283 lineas — FastAPI app, CORS, lifespan, health, OpenAPI custom)
    │   ├── config.py                  (Settings con pydantic-settings + lru_cache)
    │   ├── api/
    │   │   ├── routes_generate.py     (849 lineas — POST /v1/generate standard + SSE)
    │   │   ├── routes_adapt.py        (516 lineas — POST /v1/adapt multi-plataforma)
    │   │   ├── routes_profiles.py     (204 lineas — CRUD /v1/profiles)
    │   │   └── routes_admin.py        (339 lineas — /admin/** oculto del OpenAPI publico)
    │   ├── auth/
    │   │   └── middleware.py          (2 niveles: ADMIN Bearer + STUDIO X-Studio-Key)
    │   ├── core/
    │   │   ├── engine.py              (1.426 lineas — nucleo de generacion, fallback y citations)
    │   │   ├── streaming.py           (225 lineas — wrapper SSE con eventos tipados)
    │   │   ├── search_strategy.py     (281 lineas — decision de activar web_search)
    │   │   ├── prompts.py             (100 lineas — builder del system prompt)
    │   │   └── validators.py          (105 lineas — validacion topic y parametros)
    │   ├── db/
    │   │   ├── connection.py          (SQLAlchemy async engine + init_db/close_db en lifespan)
    │   │   └── repository.py          (578 lineas — AdminConfigRepository, ProfileRepository, HistoryRepository)
    │   └── models/
    │       ├── database.py            (4 tablas: admin_config, profiles, generations, adaptations)
    │       └── schemas.py             (812 lineas — Pydantic v2: requests, responses, enums)
    ├── prompts/
    │   ├── seo-content-generator/SKILL.md    (skill base de generacion)
    │   └── adapt/SKILL.md                    (skill de adaptacion a redes)
    ├── Dockerfile             (multi-stage: builder con gcc + runtime slim, usuario no-root, HEALTHCHECK)
    ├── cloudbuild.yaml        (build → push → deploy → cleanup revisiones/imagenes antiguas)
    └── requirements.txt
    

    Autenticacion en dos niveles

    El middleware en app/auth/middleware.py distingue dos identidades que llaman al microservicio:

    NivelHeaderSecretoUso
    ADMINAuthorization: Bearer <ADMIN_API_KEY>studio-admin-key (Secret Manager)Acceso total, sin rate limit, endpoints /admin/** ocultos del OpenAPI publico
    STUDIOX-Studio-Key: <STUDIO_SECRET>studio-secret (Secret Manager)Llamadas del frontend Next.js como proxy firmado. Rate limits aplican

    El frontend nunca expone estos secretos: los route handlers /api/internal/** de Next.js los leen de Firebase App Hosting Secret Manager y los adjuntan en servidor antes de llamar a STUDIO_API_URL. El navegador solo ve la llamada al propio dominio.

    Headers adicionales para propagar contexto sin duplicar sesiones:

    • X-User-Id — propaga el UID de Firebase Auth al historial
    • X-User-Tier — free / premium, determina modelo Claude usado
    • X-Request-Id — trace id para correlacionar logs frontend ↔ backend

    Modelo de datos (SQLAlchemy 2.0 async)

    4 tablas, todas declarativas con Mapped[...] y tipado estricto. Definidas en app/models/database.py:

    TablaPropositoCampos clave
    admin_configKey-value editable en caliente desde el panel admin sin redesplegarkey, value, updated_at. Cache TTL 60s en AdminConfigRepository. Claves reales: emergency_model_override, model_free, model_premium, max_tokens_<length>
    profilesPerfiles reutilizables con tono, audiencia, idioma, style_guide, brand_voice, forbidden_words, mandatory_elements, disclaimer, seo_preferences, content_rules (JSON)Se mergean con los parametros del request antes de llamar a Claude
    generationsHistorial completo de cada generacion con input/output, tokens, web searches, modelo y statusConsultable desde /api/internal/history del frontend y desde el panel admin
    adaptationsRegistro de cada adaptacion multi-plataforma con contenido origen y variantes generadasSe enlaza con la generacion original por generation_id

    El engine async soporta tanto SQLite (sqlite+aiosqlite:///./apisdom_studio.db en desarrollo) como PostgreSQL (postgresql+asyncpg://... en produccion) via la variable DATABASE_URL. Las tablas se crean en el lifespan de FastAPI con init_db() y la conexion se cierra limpiamente con close_db() al recibir SIGTERM de Cloud Run.


    Docker multi-stage optimizado para Cloud Run

    El Dockerfile usa build stage con gcc para compilar dependencias nativas + runtime stage python:3.12-slim con solo el virtualenv copiado. Usuario no-root appuser, PYTHONDONTWRITEBYTECODE=1, PYTHONUNBUFFERED=1, y un HEALTHCHECK que hace urlopen contra /health cada 30s. Arranque con uvicorn --workers 1 --timeout-keep-alive 30 (1 worker porque Cloud Run ya pone 1 contenedor por instancia con concurrency 80).

    Configuracion real en Cloud Run (cloudbuild.yaml):

    ParametroValor
    Regioneurope-west1
    CPU1 + --cpu-boost (arranque rapido en cold start)
    Memoria512 MiB
    Instancias min/max0 / 5
    Concurrencia por instancia80
    Timeout de request300s (generaciones largas con stream SSE)
    Puerto8000
    CORSSolo https://studio.apisdom.com (no comodin)
    Log levelwarning
    Secretos inyectadosANTHROPIC_API_KEY, ADMIN_API_KEY, STUDIO_SECRET desde Secret Manager

    Pipeline de despliegue automatico (trigger en push a main con filtro backend/**):

    1. Build de la imagen Docker
    2. Push a Artifact Registry europe-west1-docker.pkg.dev/$PROJECT_ID/studio/api
    3. Deploy a Cloud Run con la nueva revision
    4. Limpieza: borra todas las revisiones excepto las 2 mas recientes
    5. Limpieza: borra imagenes del registry excepto las 3 mas recientes

    La limpieza automatica mantiene el coste de almacenamiento a cero sin intervencion manual — importante para un proyecto con despliegues frecuentes.


    OpenAPI publico con branding custom

    FastAPI genera automaticamente /docs (Swagger UI) y /redoc (ReDoc). En main.py se parchea el schema OpenAPI para inyectar:

    • info.x-logo — logo horizontal de APISDOM en ReDoc con enlace a https://studio.apisdom.com
    • Descripcion markdown extensa con tablas de tipos de contenido, idiomas, plataformas sociales y codigos de error
    • Tags organizados (generate, adapt, profiles) con descripciones detalladas
    • Rutas /admin/** ocultas del schema publico con include_in_schema=False
    • /health (shallow) y /health/deep (verifica DB + formato de ANTHROPIC_API_KEY) fuera del schema publico

    El favicon.ico se sirve desde backend/favicon/ como FileResponse estatico para que las pestanas del navegador muestren la marca correctamente en /docs y /redoc.


    Calidad de codigo enforced

    Sin excepciones en el backend:

    mypy src/ --ignore-missing-imports --strict
    ruff check src/ --select=E,W,F,B,C90,I,N,UP,S --ignore=E501
    pytest
    
    • mypy --strict — todas las funciones publicas con anotaciones completas, Any solo donde el SDK de Anthropic no expone tipos concretos
    • ruff con reglas de seguridad (S), bugbear (B), complejidad McCabe (C90), naming (N), pyupgrade (UP) e imports ordenados (I)
    • pytest + pytest-asyncio para cobertura de los flujos de generacion, adaptacion y perfiles

    Verificadores automaticos de calidad

    Cada cambio en el codigo del frontend pasa por una cadena de verificadores antes de poder commitear. El comando npm run verify:all los encadena en secuencia y un precommit de husky los dispara automaticamente. Definido en package.json:

    "verify": "tsx scripts/verify-code-quality.ts",
    "verify:types": "tsx scripts/verify-type-consistency.ts",
    "verify:colors": "tsx scripts/find-hardcoded-colors.ts",
    "verify:duplicates": "npx jscpd src --reporters console --min-lines 5 --min-tokens 50",
    "verify:all": "npm run verify && npm run verify:types && npm run verify:colors && npm run type-check && npm run verify:duplicates",
    "precommit": "npm run verify:all"
    

    Que cubre cada verificador:

    ScriptRegla principal
    verify-code-quality.tsMaximo 40 lineas por funcion en .ts y 70 lineas por funcion en .tsx. Prohibe TODO, FIXME, HACK, WIP, TEMP. Exenciones explicitas para paginas legales, Footer y MobileMenu
    verify-type-consistency.tsTipos alineados entre core/entities y los schemas del backend
    find-hardcoded-colors.tsCero colores hardcodeados fuera del tema centralizado en config/
    tsc --noEmitTypeScript strict sobre los 458 archivos del proyecto
    jscpdCero duplicacion de codigo con umbral de 5 lineas / 50 tokens

    Auditorias adicionales en scripts/audit/:

    • verify-error-handling.ts — Detecta catch {} vacios, ?? '' en adapters, promesas sin await y accesos a arrays sin chequeo de longitud
    • verify-runtime-safety.ts — Detecta JSON.parse sin try/catch, fetch sin check de response.ok, localStorage sin fallback SSR

    En el backend la cadena equivalente es:

    mypy src/ --ignore-missing-imports --strict
    ruff check src/ --select=E,W,F,B,C90,I,N,UP,S --ignore=E501
    

    Con mypy --strict obligatorio: todas las funciones publicas llevan anotaciones de tipo completas y Any solo aparece donde el SDK de Anthropic no expone tipos concretos.


    Cifras reales del proyecto

    Todas las metricas estan contadas sobre el codigo real del repositorio, no estimadas.

    MetricaValor
    Archivos TypeScript/TSX del frontend (src/)458
    Componentes React (presentation/components/**/*.tsx)169
    Hooks React (presentation/hooks/)35
    Route handlers Next.js (app/api/**/route.ts)53
    Paginas bajo [locale]28
    Entidades de dominio (core/entities/)14
    Ports (interfaces) (core/ports/)13
    Use-cases puros (core/use-cases/)18
    Idiomas soportados2 (es, en)
    Tipos de contenido generables15
    Tonos disponibles10
    Niveles de audiencia4
    Longitudes de contenido4 (short / medium / long / extra_long)
    Formatos de salida3 (html / markdown / plain_text)
    Plataformas sociales soportadas7 (Facebook, Instagram, X, LinkedIn, TikTok, YouTube, Pinterest)
    Modelos Claude en produccion2 (claude-sonnet-4-5-20250929 + claude-haiku-4-5-20251001)
    Endpoints API publicos/v1/generate · /v1/adapt · /v1/platforms · /v1/profiles/**
    Region backendCloud Run europe-west1
    Region frontendFirebase App Hosting us-central1

    Sistema de creditos real

    Definido en pricing.ts — precios en centimos de euro:

    PackCreditosPrecio€/creditoAhorro
    Studio Starter109,00 €0,90 €—
    Studio Pro5039,00 €0,78 €13 %
    Studio Business200129,00 €0,645 €28 %
    Studio Enterprise1.000499,00 €0,499 €45 %
    • 3 creditos gratis al registrarse (FREE_CREDITS_ON_SIGNUP = 3)
    • Adaptaciones multi-plataforma: 1 credito para 1-3 redes, 2 creditos para 4-7 redes
    • Coste variable por tipo + longitud: un social_post cuesta 1 credito, un article_long cuesta 5, un tutorial cuesta 4 — tabla completa en credit-costs.ts
    • Checkout con Stripe live (pk_live_...), webhook en /api/webhook/route.ts que procesa checkout.session.completed y abona los creditos atomicamente
    • Portal de facturacion Stripe en /api/billing/portal/route.ts para gestionar metodo de pago y facturas

    Seguridad y cumplimiento

    • Autenticacion: Firebase Auth en el cliente, Firebase Admin SDK en los route handlers server-side. El frontend jamas expone la clave del backend — actua como proxy firmado hacia STUDIO_API_URL
    • Secrets: gestionados por Firebase App Hosting Secret Manager, declarados como secret: ... en apphosting.yaml (STRIPE_SECRET_KEY, STRIPE_WEBHOOK_SECRET, FIREBASE_ADMIN_PRIVATE_KEY, ZOHO_EMAIL_PASSWORD, IP_SALT, BACKEND_ADMIN_KEY...)
    • Sanitizacion de HTML: isomorphic-dompurify en todo input/output del editor
    • GDPR: export de datos en /api/user/export/route.ts y /api/user/export-pdf/route.ts, borrado de cuenta en /api/user/delete/route.ts con verificacion de borrados previos, certificado GDPR propio en gdpr-certificate.ts
    • Newsletter con unsubscribe firmado: token HMAC con UNSUBSCRIBE_SECRET y salt de IP (IP_SALT) para evitar enumeracion
    • Rate limiting + fingerprint: @fingerprintjs/fingerprintjs en el trial gratuito para limitar abuso sin registro
    • Tests E2E: Playwright 1.58 con flujos criticos (login, generacion, checkout, editor, admin)