This commit is contained in:
2026-06-10 02:04:37 -06:00
parent 1ba3d8dea4
commit 31cdce03a0
131 changed files with 15922 additions and 106 deletions
+470
View File
@@ -0,0 +1,470 @@
# Cotizador E3 — API Documentation for AI Skills
## Overview
REST API for Consultoría E3's digital marketing quotation system. Allows AI agents to manage clients, browse service catalogs, create quotations, calculate financing, generate PDF/Excel documents, and manage the full sales pipeline.
**Base URL:** `http://localhost:8000`
**Auth:** API Key via `X-API-Key` header or `Authorization: Bearer <key>`
**Content-Type:** `application/json`
**OpenAPI Spec:** `GET /openapi.json` (no auth required)
---
## Domain Context
Consultoría E3 is a digital marketing agency in Querétaro, México. Services are organized in 4 project phases:
- **Fase 0 — Auditoría / Acompañamiento:** Initial assessments and ongoing consulting
- **Fase 1 — Setup e Infraestructura:** One-time setup (websites, branding, CRM config)
- **Fase 2 — Publicidad y Manejo:** Ongoing advertising and social media management
- **Fase 3 — Contenido y SEO:** Content creation and search engine optimization
Two payment types:
- **unico:** One-time payment
- **mensual:** Monthly recurring payment
Currency: MXN (Mexican Pesos) or USD. IVA (tax) rate: 16%.
---
## Authentication
### API Key (for agents)
```
X-API-Key: your-api-key-here
```
or
```
Authorization: Bearer your-api-key-here
```
### JWT (for human login)
```
POST /auth/login
Body: { "email": "[email protected]", "password": "secret" }
Response: { "user": { "id", "name", "email", "role" } }
Sets cookie: cotizador-session (httpOnly, 7 days)
```
---
## Endpoints Reference
### Health & Info
#### GET /health
Health check endpoint. No auth required.
- **Response:** `{ "status": "ok", "timestamp": "2026-05-03T..." }`
#### GET /api-info
API capabilities and version info.
- **Response:** `{ "name": "Cotizador E3 API", "version": "1.0.0", "capabilities": [...] }`
---
### Clients (Clientes)
#### GET /clientes
List clients with optional search and pagination.
- **Query params:** `?q=texto&page=1&limit=50`
- **Response:** `{ "data": [Cliente], "meta": { "total", "page", "limit", "pages" } }`
#### POST /clientes
Create a new client.
- **Body:**
```json
{
"nombre": "Juan Pérez",
"empresa": "ACME Corp",
"email": "[email protected]",
"telefono": "4421234567"
}
```
- **Response (201):** Full Cliente object with `id`
#### GET /clientes/{id}
Get client details including recent quotations.
- **Response:** Cliente object + `cotizaciones` array
#### PUT /clientes/{id}
Update client information.
- **Body:** Same as POST (all fields optional for update)
#### DELETE /clientes/{id}
Delete client. Returns 409 if client has quotations.
- **Response (200):** `{ "ok": true }`
- **Error (409):** `{ "error": "Cliente tiene N cotizaciones asociadas" }`
---
### Service Catalog (Catálogo)
#### GET /catalogo
List all active services with optional filters.
- **Query params:** `?fase=0&tipoPago=mensual&categoriaId=xxx&q=seo`
- **Response:** Array of ServicioCatalogo objects
Each service:
```json
{
"id": "cuid",
"nombre": "Posicionamiento SEO",
"descripcion": "...",
"fase": 3,
"tipoPago": "mensual",
"precioBase": 2900,
"tiempoEntrega": "7 - 14 dias",
"entregablesDefault": ["Keyword research", "On-page optimization"],
"categoriaId": "cuid",
"variante": null,
"activo": true,
"orden": 0
}
```
#### POST /catalogo
Create a new service.
- **Body:**
```json
{
"nombre": "Nuevo Servicio",
"descripcion": "Descripción del servicio",
"fase": 1,
"tipoPago": "unico",
"precioBase": 5000,
"tiempoEntrega": "7 - 14 dias",
"entregablesDefault": ["Entregable 1", "Entregable 2"],
"categoriaId": "cuid",
"variante": null,
"orden": 0
}
```
#### GET /catalogo/{id}
Get service details with category info.
#### PUT /catalogo/{id}
Update service. Same body as POST.
#### DELETE /catalogo/{id}
Soft-delete if used in quotations, hard-delete otherwise.
- **Response:** `{ "ok": true, "archived": true|false }`
---
### Categories (Categorías)
Available: SEO (#10b981), Marketing (#6366f1), Paid Media (#f59e0b), Desarrollo Web (#3b82f6), Automatizaciones (#8b5cf6), CRM (#ec4899), Desarrollo Personalizado (#14b8a6)
#### GET /categorias
List all categories ordered by `orden`.
#### POST /categorias
- **Body:** `{ "nombre": "Nueva Cat", "descripcion": "...", "color": "#6b7280", "orden": 0 }`
#### GET /categorias/{id}
Get category with its services.
#### PUT /categorias/{id}
- **Body:** `{ "nombre", "descripcion", "color", "orden", "activo" }`
#### DELETE /categorias/{id}
Returns 409 if category has associated services.
---
### Quotations (Cotizaciones)
#### GET /cotizaciones
List quotations with filters.
- **Query params:** `?estado=borrador&asesorId=xxx&clienteId=xxx&q=texto&desde=2026-01-01&hasta=2026-12-31&page=1&limit=50`
- **Response:** Array with full relations (cliente, asesor, servicios+catalogo, planBucefalo)
#### POST /cotizaciones
Create a complete quotation. Auto-creates client if not found.
- **Body:**
```json
{
"numero": "UJ2605AG001",
"fecha": "2026-05-03",
"vigencia": "2026-05-24",
"moneda": "MXN",
"tipoCambio": "NA",
"proyecto": "MKT Digital",
"esquemaPago": "Pago Unico/Mensual",
"incluirBonos": false,
"incluirFinanciamiento": false,
"observaciones": "",
"asesorId": "cuid",
"cliente": {
"nombre": "Juan Pérez",
"empresa": "ACME Corp",
"email": "[email protected]",
"telefono": "4421234567"
},
"servicios": [
{
"catalogoId": "cuid",
"nombre": "SEO On-Page",
"fase": 3,
"tipoPago": "mensual",
"precio": 2900,
"tiempoEntrega": "7 - 14 dias",
"entregables": ["Keyword research", "On-page SEO"]
}
],
"planBucefalo": {
"nivel": "basico",
"precio": 1000
}
}
```
#### GET /cotizaciones/{id}
Get quotation with all relations.
#### PUT /cotizaciones/{id}
Update quotation. Replaces all services in a transaction.
- **Body:** Same as POST without `numero` and `asesorId`. Optional `estado`.
#### DELETE /cotizaciones/{id}
Hard-delete with cascade.
#### PATCH /cotizaciones/{id}/precio
Update price of a single service.
- **Body:** `{ "servicioId": "cuid", "precio": 7500 }`
#### PATCH /cotizaciones/{id}/estado
Change quotation status.
- **Body:** `{ "estado": "enviada" }``borrador`, `enviada`, `aprobada`, `rechazada`
#### POST /cotizaciones/{id}/duplicate
Duplicate quotation as new copy in `borrador` state.
---
### Packages (Paquetes)
#### GET /paquetes
List active packages with nested phases and services.
#### POST /paquetes
- **Body:**
```json
{
"nombre": "Paquete Básico",
"descripcion": "...",
"fases": [
{ "nombre": "Auditoría", "orden": 0 },
{ "nombre": "Setup", "orden": 1 }
]
}
```
#### GET /paquetes/{id}
Get package with full nested structure.
#### PUT /paquetes/{id}
- **Body:** `{ "nombre", "descripcion", "activo" }`
#### DELETE /paquetes/{id}
Hard-delete with cascade.
#### POST /paquetes/{id}/manage
Multi-action endpoint:
- `{ "action": "addFase", "nombre": "Fase 3", "orden": 2 }`
- `{ "action": "updateFase", "faseId": "cuid", "nombre": "New Name", "orden": 1 }`
- `{ "action": "deleteFase", "faseId": "cuid" }`
- `{ "action": "addServicio", "servicioCatalogoId": "cuid", "fasePaqueteId": "cuid" }`
- `{ "action": "removeServicio", "servicioCatalogoId": "cuid", "fasePaqueteId": "cuid" }`
---
### Configuration (Configuración)
Allowed keys: `color_primario`, `color_secundario`, `logo_base64`, `razon_social`, `rfc`, `domicilio_fiscal`, `cuenta_nacional`, `clabe_interbancaria`, `cuenta_internacional`, `cuenta_internacional_swift`, `hora_centinela`, `anualidad_hosting`, `iva`, `terminos_condiciones`, `no_incluye`, `notas_adicionales`
#### GET /configuracion
- **Response:** `{ "color_primario": "#2563eb", "razon_social": "...", ... }`
#### PUT /configuracion
Bulk upsert. Only whitelisted keys processed.
- **Body:** `{ "color_primario": "#ff0000", "razon_social": "Nuevo Nombre" }`
---
### Bonuses (Bonos)
Available: Centinela Web, Workshop Buyer Persona, Workshop Propuesta de Valor, Membresía Premium, Mes Gratis CRM, Script de Ventas
#### GET /bonos
---
### Financing (Financiamiento)
| Months | Rate | Commission | Min Amount |
|--------|------|------------|------------|
| 3 | 7.7% | 2.5% | $300 |
| 6 | 10.7% | 2.5% | $600 |
| 9 | 13.7% | 2.5% | $900 |
| 12 | 16.7% | 2.5% | $1,200 |
#### GET /financiamiento/planes
#### POST /financiamiento/calcular
- **Body:** `{ "monto": 50000, "meses": 6 }`
- **Response:** `{ "pagoMensual", "ivaMensual", "totalMensual", "comisionTotal", "granTotal" }`
#### GET /financiamiento/simulacion/{cotizacion_id}
Auto-calculate financing for existing quotation.
---
### Export
#### POST /export/pdf — PDF from draft data
#### GET /export/pdf/{id} — PDF from saved quotation
#### POST /export/excel — Excel from draft data
#### GET /export/excel/{id} — Excel from saved quotation
#### GET /export/catalogo — CSV of active services
#### GET /export/catalogo/plantilla — CSV import template
---
### Import
#### POST /import/catalogo
Bulk import services from CSV. `multipart/form-data` with `file` field.
- **Response:** `{ "creados": 5, "omitidos": 2, "errores": [...] }`
---
## Business Rules
### Quotation Number
Format: `UJ{YY}{MM}{AsesorInitials}{sequence}` — e.g., `UJ2605AG001`
### Quotation Validity
15 business days from issue (excludes Sat/Sun).
### CRM Bucefalo Plans
basico=$1,000/mes, estandar=$3,500/mes, premium=$4,500/mes, empresarial=$7,500/mes
### Client Deduplication
Matched by `(nombre, empresa)` pair.
### Service Soft-Delete
If referenced by quotations → `activo=false`. Otherwise hard-delete.
### Financing Formula
```
comisionTotal = monto × comision%
montoConComision = monto + comisionTotal
pagoMensual = montoConComision × (1 + tasa) / meses
ivaMensual = pagoMensual × 0.16
totalMensual = pagoMensual + ivaMensual
granTotal = totalMensual × meses
```
---
## Common Responses
### Success (paginated)
```json
{
"data": [...],
"meta": { "total": 45, "page": 1, "limit": 50, "pages": 1 }
}
```
### Error
```json
{ "error": "Message", "detail": "Details", "code": "ERROR_CODE" }
```
### HTTP Codes
200=OK, 201=Created, 204=No Content, 400=Bad Request, 401=Unauthorized, 404=Not Found, 409=Conflict, 500=Server Error
---
## Agent Workflows
### Create quotation
```
1. GET /catalogo?fase=0 → audit services
2. GET /catalogo?fase=1 → setup services
3. GET /catalogo?fase=2&tipoPago=mensual → ongoing services
4. POST /financiamiento/calcular → simulate payments
5. POST /cotizaciones → create quotation
6. GET /export/pdf/{id} → generate PDF
```
### Review pipeline
```
1. GET /cotizaciones?estado=borrador → pending
2. GET /cotizaciones?estado=enviada → awaiting
3. GET /cotizaciones?estado=aprobada → won
```
### Negotiate price
```
1. GET /cotizaciones/{id} → current state
2. PATCH /cotizaciones/{id}/precio → adjust price
3. GET /export/pdf/{id} → regenerate PDF
```
---
## MCP Integration
MCP server at `/mcp` for OpenClaw, Claude, ChatGPT.
### Tools
| Tool | Description |
|------|-------------|
| `buscar_servicios` | Search catalog by phase, payment type, category, text |
| `crear_cotizacion` | Create complete quotation in one call |
| `obtener_cotizacion` | Get quotation details |
| `listar_cotizaciones` | List with filters |
| `cambiar_estado_cotizacion` | Change status |
| `actualizar_precio_servicio` | Adjust service price |
| `duplicar_cotizacion` | Clone as draft |
| `calcular_financiamiento` | Calculate payments |
| `generar_pdf_cotizacion` | Generate PDF |
| `obtener_configuracion` | Company config |
| `listar_bonos` | Available bonuses |
| `listar_planes_bucefalo` | CRM plans |
### Resources
| Resource | Description |
|----------|-------------|
| `cotizador://servicios` | Full catalog |
| `cotizador://categorias` | Categories |
| `cotizador://configuracion` | Company config |
---
## Environment
```
DB_HOST=localhost
DB_PORT=5432
DB_USER=postgres
DB_PASSWORD=postgres
DB_NAME=cotizador_e3
API_KEY=your-secret-api-key
JWT_SECRET=your-jwt-secret
```
## Run
```bash
pip install -r requirements.txt
uvicorn main:app --reload --host 0.0.0.0 --port 8000
# Swagger: http://localhost:8000/docs
# ReDoc: http://localhost:8000/redoc
# OpenAPI: http://localhost:8000/openapi.json
```