DOC-002: Modelo de dominio SaaS
Estado
Accepted — 2026-09-08 (producto: B2C Subscriber, no Tenant B2B).
Visión: DOC-001
Opciones / IV: DOC-003
Glosario corto (agentes/código): .cursor/rules/seed-domain.mdc
Aislamiento: ADR-018
Identidad: ADR-023
Este documento es la fuente de verdad del negocio SaaS. El motor de señales (CLI) sigue DOC-003. Si un agente no sabe “de qué trata el producto”, empieza aquí.
No es consejo financiero.
1. Qué es IVPrior (una frase)
IVPrior ayuda a traders retail de opciones a decidir qué mirar hoy: dirección probable, si la prima está cara o barata (régimen de IV (Implied Volatility / volatilidad implícita)), y qué tipo de jugada encaja.
No es broker, no ejecuta órdenes, no es asesor regulado, no garantiza retornos.
2. Modelo comercial (cerrado)
B2C de suscripción. El comprador es una persona de internet que paga un Plan para usar el scanner y el resto de funcionalidades.
| Es | No es |
|---|---|
| Subscriber (cuenta de un trader) | Tenant / Organization B2B (restaurante, agencia, “empresa con staff”) |
| Un humano compra un plan | Un negocio invita empleados a un panel operativo |
| Diferenciación = calidad de oportunidad + honestidad de datos | Marketplace, delivery, cobranzas, locations |
Staff IVPrior opera /platform | El suscriptor “es un tenant” en copy de producto |
Cashlane / FoodHub aportaron la fábrica (auth, billing, /platform, help). No aportan el modelo de negocio. Copiar “Tenants” como entidad de producto está prohibido a partir de este DOC.
3. Actores
| Actor (código) | Quién | Superficie |
|---|---|---|
| PowerUser | Amigo / usuario diario del CLI | apps/cli (V0) |
| Subscriber | Trader retail que se registra y (cuando haya billing) paga un plan | App web del producto (hoy scaffold; dominio IVPrior en slices) |
| PlatformUser | Staff interno de IVPrior (ops, support, admin) | /platform |
| Builder | Quien mantiene producto y semilla | Repo |
| Compliance | Asesor legal externo | Fuera de la app |
No hay en V1: empleados del suscriptor, OWNER/FINANCE_ADMIN de una org, couriers, locations, “finance manager”.
4. Bounded contexts
┌─────────────────────┐ ┌──────────────────────────┐
│ Engine │ │ Subscriber account │
│ Python `apps/cli` │ │ Nest/Next (SaaS) │
│ Signal │ │ Subscriber │
│ Opportunity │◄───►│ Watchlist (cuenta) │
│ IvRegime │ │ Subscription + Plan │
│ DataSource │ │ PaperDiary (futuro web) │
└─────────────────────┘ └──────────────────────────┘
▲
│ entitlements
┌────────┴────────┐
│ Billing │
│ Plan catalog │
│ Stripe │
└────────┬────────┘
│
┌────────┴────────┐
│ Platform ops │
│ PlatformUser │
│ Branding/social│
│ Plans admin │
│ IAM staff │
└─────────────────┘
| Contexto | Pregunta | Dueño de datos |
|---|---|---|
| Engine | ¿Qué oportunidad sale hoy y con qué calidad de IV? | CLI / futuro worker Python |
| Subscriber account | ¿Quién es el usuario, qué plan tiene, qué watchlist? | API Nest, aislado por subscriberId |
| Billing | ¿Qué planes se venden y está al día el pago? | Stripe + catálogo en /platform/plans |
| Platform ops | ¿Cómo opera el equipo IVPrior la marca y el catálogo? | PlatformUser, sin datos de scanner del subscriber salvo impersonation auditada (slice futuro) |
Comunicación Engine ↔ SaaS: contrato explícito (CLI hoy; API/worker después). No mezclar tablas food ni “tenant restaurant” en el motor.
5. Entidades de producto (SaaS)
Nombres en código = inglés. Docs en español pueden usar el alias.
| Entidad | Definición | V1 |
|---|---|---|
| Subscriber | Cuenta de un trader. Un signup = un Subscriber. Es el límite de aislamiento (ADR-018). | Sí |
| Subscription | Relación Subscriber ↔ Plan (estado Stripe / entitlements). | Sí (fábrica billing) |
| Plan | Oferta comercial (precio, intervalo, límites). Catálogo en platform. | Sí |
| Watchlist | Tickers que el Subscriber sigue. Solo puede elegir símbolos del catálogo de platform. | SaaS |
| PlatformTicker | Catálogo global de símbolos que staff publica para watchlists / Analyze. | SaaS |
| Opportunity | Salida priorizada (ticker + señal + IV/HV + score). Pertenece a una corrida / al Subscriber. | CLI hoy; SaaS después |
| PlatformUser | Staff IVPrior. No es Subscriber. | Sí |
| PlatformRole / PlatformPermission | IAM de staff. Branding, planes, usuarios internos. | Sí |
Prohibido como entidad de producto
| Término fábrica / food | Por qué no |
|---|---|
| Tenant (copy UI) | Vocabulario B2B; el comprador es Subscriber |
| Organization (negocio) | No hay empresa-cliente con sucursales ni staff |
| Location, Menu, Order, Courier, Marketplace | Dominio food |
| Customer = deudor / Invoice / Promise | Dominio Cashlane (cobranzas) |
| Order / Trade como Signal | Una señal no es una orden de broker |
“Customer” en copy de marketing = el Subscriber. En código, preferir Subscriber para no chocar con el Customer deudor de Cashlane.
6. Superficies
| Superficie | URL / path | Quién |
|---|---|---|
| CLI | make cli | PowerUser |
| App Subscriber | login / app del producto (scaffold hoy en rutas tenant de fábrica) | Subscriber |
| Platform admin | /platform | PlatformUser |
| Help / Docs | :3002 / :3003 | público + staff |
| Marketing / pricing | sitio público | visitante → signup |
/platform conserva módulos de fábrica que sí son genéricos: branding, redes sociales, planes, permisos/roles/usuarios de staff, audit, sesiones, jobs.
El ítem de nav Tenants es leftover de FoodHub: en producto es el listado de Subscribers. Rename de UI/schema = slice posterior (no este DOC). Hasta ese slice, los agentes MUST hablar de Subscribers en docs y no inventar features de “tenant restaurant”.
7. Aislamiento de datos
Ver ADR-018 (enmienda 2026-09-08).
- Toda fila de negocio del Subscriber lleva el id de cuenta (
subscriberIden vocabulario; en Prisma de fábrica puede seguir llamándoseorganizationIdhasta el remap). - Un Subscriber no ve watchlists, corridas ni billing de otro.
- PlatformUser no usa un id mágico para “ver todos”; listados de platform son queries de ops con audit.
- V1: un usuario humano = un Subscriber. Seats / equipo del trader = fuera de V1.
8. leftover de fábrica (código vs vocabulario)
Tras SLICE-003-06 (Prisma DDL), el schema físico usa subscribers / subscriber_id. Quedan nombres de módulo/ruta legacy en código de aplicación:
| Vocabulario producto (obligatorio en docs/UI nueva) | Código / schema actual (no inventar paralelo) |
|---|---|
| Subscriber | Prisma Subscriber · tablas subscribers |
subscriberId | Columna subscriber_id · JWT subscriber_id |
| App del Subscriber | /s/{slug}/… (ruta legacy de tenant; ver nota abajo) · código: TenantShell |
| Listado de cuentas en platform | /platform/subscribers (API) · nav legacy |
Reglas para agentes:
- No crear un segundo modelo “Organization B2B” encima de Subscriber.
- No borrar branding / social / platform IAM porque “no son de opciones”: son ops de la marca.
- No implementar locations, orders, menu, couriers.
- Copy nueva: Subscriber / plan / scanner — nunca “tenant”, “orders”, “locations”.
- Renombres de módulos Nest (
tenant-*→subscriber-*) y UI = slices posteriores del epic FEAT-004; Prisma DDL ya aplicado (ADR-018). - Rutas con slug (
/s/demo/login,/s/{slug}/scanner): leftover de FoodHub multi-tenant. En B2C V1 un humano = un Subscriber; el email identifica la cuenta, no el slug en la URL. Target de producto:/login+/app/*(sin slug visible). Migración = slice/ADR aparte; no crear copy que pida al usuario “elegir su workspace”.
9. Relación con el CLI
V0 no autentica Subscribers. El PowerUser corre el motor localmente.
Cuando el SaaS exponga el scanner: el Engine produce Opportunities; la cuenta Subscriber guarda watchlist, historial y entitlements del Plan. El CLI puede seguir siendo la misma lógica empaquetada.
10. Compliance (recordatorio)
- Disclaimer: herramienta de investigación, no advice.
- Gate legal externo antes de cobrar en EE.UU. (DOC-001 §9).
- Exactitud de IV/datos > growth copy.
11. Aprobación
| Rol | Decisión | Fecha |
|---|---|---|
| Producto (Marcel) | B2C Subscriber; no Tenant B2B; DOC-002 Accepted | 2026-09-08 |
Follow-up de ingeniería (fuera de este DOC): seed catálogo IAM platform (para que reaparezcan branding/roles en el nav); rename Tenants → Subscribers; Spec Kit del módulo Subscriber cuando se toque schema.