# README

<div align="center"><img src="https://3403371154-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Fk1LL2DR82bornzI2xcsu%2Fuploads%2Fgit-blob-beea143db46267b6eeee0586b3b2a8259df4c922%2Fcierro-logo.svg?alt=media" alt="Cierro Logo" width="200"></div>

<h2 align="center">Cierro - Propuestas Comerciales Inteligentes</h2>

<p align="center"><strong>SaaS para crear propuestas comerciales profesionales con asistencia de IA</strong></p>

<p align="center"><a href="#características">Características</a> • <a href="#stack-tecnológico">Stack</a> • <a href="#arquitectura">Arquitectura</a> • <a href="#base-de-datos">Base de Datos</a> • <a href="#edge-functions">Edge Functions</a> • <a href="#instalación">Instalación</a></p>

<div align="center"><img src="https://img.shields.io/badge/React-18.3-61DAFB?logo=react" alt="React"> <img src="https://img.shields.io/badge/TypeScript-5.0-3178C6?logo=typescript" alt="TypeScript"> <img src="https://img.shields.io/badge/Vite-5.0-646CFF?logo=vite" alt="Vite"> <img src="https://img.shields.io/badge/Tailwind-3.4-06B6D4?logo=tailwindcss" alt="Tailwind"> <img src="https://img.shields.io/badge/Supabase-Backend-3FCF8E?logo=supabase" alt="Supabase"></div>

***

### 📋 Tabla de Contenidos

* [Descripción](#descripción)
* [Características](#características)
* [Stack Tecnológico](#stack-tecnológico)
* [Arquitectura del Proyecto](#arquitectura-del-proyecto)
* [Base de Datos](#base-de-datos)
* [Edge Functions](#edge-functions)
* [Sistema de Emails](#sistema-de-emails)
* [Autenticación y Roles](#autenticación-y-roles)
* [Páginas y Rutas](#páginas-y-rutas)
* [Instalación](#instalación)
* [Variables de Entorno](#variables-de-entorno)
* [Guías de Migración](#guías-de-migración)
* [Despliegue](#despliegue)
* [Contribución](#contribución)
* [Licencia](#licencia)

***

### Descripción

**Cierro** es una plataforma SaaS diseñada para agencias y equipos de ventas que necesitan crear propuestas comerciales profesionales de manera rápida y eficiente. Utiliza inteligencia artificial para generar contenido, ofrece colaboración en tiempo real y proporciona herramientas completas para la gestión del pipeline de ventas.

#### ¿Para quién es Cierro?

* 🏢 **Agencias de Marketing y Publicidad** - Propuestas creativas con branding personalizado
* 💼 **Equipos de Ventas B2B** - Cotizaciones profesionales con seguimiento
* 🔧 **Consultoras y Servicios Profesionales** - Documentos estructurados con etapas y entregables
* 🚀 **Startups y Freelancers** - Propuestas rápidas con asistencia de IA

***

### Características

#### 📝 Editor de Propuestas Avanzado

* Editor WYSIWYG basado en TipTap
* Generación de contenido con IA (Gemini/OpenAI)
* Bloques personalizables: texto, imágenes, tablas de precios, etapas
* Exportación a PDF con diseño profesional
* Plantillas predefinidas y personalizables

#### 👥 Colaboración en Tiempo Real

* Edición simultánea con Liveblocks + Yjs
* Cursores y presencia de colaboradores
* Historial de versiones con comparación
* Chat integrado por propuesta

#### 📊 Gestión de Ventas

* Pipeline de propuestas (borrador, enviado, aprobado, rechazado)
* Dashboard con métricas y KPIs
* Metas de ventas por ejecutivo
* Comisiones configurables
* Reportes exportables

#### 🎨 Personalización de Marca

* Colores y tipografías personalizables
* Logo de empresa
* Encabezados configurables
* Biblioteca de imágenes

#### 🔗 Integraciones

* **HubSpot**: Sincronización de contactos y deals
* **Pipedream**: Conexión con +1000 apps
* **Reveniu**: Procesamiento de pagos (Chile)

#### 📧 Notificaciones

* Emails transaccionales con Resend
* Recordatorios de vencimiento
* Alertas de aprobación

***

### Stack Tecnológico

#### Frontend

| Tecnología        | Uso                         |
| ----------------- | --------------------------- |
| **React 18**      | Framework UI                |
| **TypeScript**    | Tipado estático             |
| **Vite**          | Build tool                  |
| **Tailwind CSS**  | Estilos                     |
| **shadcn/ui**     | Componentes UI              |
| **TipTap**        | Editor de texto             |
| **Liveblocks**    | Colaboración en tiempo real |
| **Yjs**           | CRDT para sync              |
| **React Query**   | Estado del servidor         |
| **React Router**  | Navegación                  |
| **Recharts**      | Gráficos                    |
| **Framer Motion** | Animaciones                 |

#### Backend

| Tecnología        | Uso                                            |
| ----------------- | ---------------------------------------------- |
| **Supabase**      | BaaS (Database, Auth, Storage, Edge Functions) |
| **PostgreSQL**    | Base de datos                                  |
| **Clerk**         | Autenticación                                  |
| **Resend**        | Emails transaccionales                         |
| **Google Gemini** | IA para contenido                              |
| **OpenAI GPT**    | IA alternativa                                 |
| **Reveniu**       | Pagos                                          |

#### Herramientas de Desarrollo

| Tecnología  | Uso                      |
| ----------- | ------------------------ |
| **ESLint**  | Linting                  |
| **Lovable** | Plataforma de desarrollo |
| **Git**     | Control de versiones     |

***

### Arquitectura del Proyecto

```
cierro/
├── src/
│   ├── assets/                    # Imágenes y recursos estáticos
│   │   ├── cierro-logo.svg
│   │   ├── features/              # Imágenes de características
│   │   └── nlace-logo.svg
│   │
│   ├── components/
│   │   ├── budget/                # Componentes de presupuestos
│   │   │   ├── editor/            # Editor de documentos
│   │   │   │   ├── blocks/        # Bloques del editor
│   │   │   │   ├── templates/     # Plantillas
│   │   │   │   ├── tiptap/        # Extensiones TipTap
│   │   │   │   │   ├── dialogs/   # Diálogos del editor
│   │   │   │   │   ├── extensions/# Extensiones personalizadas
│   │   │   │   │   └── toolbar/   # Componentes de toolbar
│   │   │   │   └── utils/         # Utilidades del editor
│   │   │   └── ...                # Otros componentes de budget
│   │   │
│   │   ├── dashboard/             # Componentes del dashboard
│   │   ├── landing/               # Componentes de landing page
│   │   ├── layout/                # Layout de la aplicación
│   │   ├── reports/               # Componentes de reportes
│   │   │   └── export/            # Exportación de reportes
│   │   ├── settings/              # Componentes de configuración
│   │   ├── subscription/          # Componentes de suscripción
│   │   ├── team/                  # Componentes de equipo
│   │   └── ui/                    # Componentes UI (shadcn)
│   │
│   ├── contexts/
│   │   └── AuthContext.tsx        # Contexto de autenticación
│   │
│   ├── hooks/
│   │   ├── use-mobile.tsx         # Detección de móvil
│   │   ├── use-toast.ts           # Notificaciones toast
│   │   ├── useAnalytics.ts        # Analytics
│   │   ├── useBrandColors.ts      # Colores de marca
│   │   ├── useBrandFonts.ts       # Fuentes de marca
│   │   ├── useDebounce.ts         # Debounce
│   │   ├── useImageLibrary.ts     # Biblioteca de imágenes
│   │   ├── useImageUpload.ts      # Subida de imágenes
│   │   ├── usePageTracking.ts     # Tracking de páginas
│   │   ├── usePermissions.ts      # Permisos de usuario
│   │   ├── useScrollAnimation.ts  # Animaciones de scroll
│   │   ├── useSubscription.ts     # Suscripción
│   │   └── useSupabaseAuth.ts     # Auth con Supabase
│   │
│   ├── integrations/
│   │   └── supabase/
│   │       ├── client.ts          # Cliente Supabase
│   │       └── types.ts           # Tipos generados
│   │
│   ├── lib/
│   │   ├── analytics.ts           # Configuración analytics
│   │   ├── budgetTransformers.ts  # Transformadores de budget
│   │   ├── budgetUtils.tsx        # Utilidades de budget
│   │   ├── currency.ts            # Formateo de moneda
│   │   ├── currencyConversion.ts  # Conversión de moneda
│   │   ├── exportUtils.ts         # Exportación de datos
│   │   ├── googleFonts.ts         # Google Fonts
│   │   ├── liveblocks.ts          # Configuración Liveblocks
│   │   ├── translations.ts        # Traducciones
│   │   └── utils.ts               # Utilidades generales
│   │
│   ├── pages/
│   │   ├── About.tsx              # Página sobre nosotros
│   │   ├── AcceptInvite.tsx       # Aceptar invitación
│   │   ├── Admin.tsx              # Panel de administración
│   │   ├── Auth.tsx               # Autenticación
│   │   ├── BudgetDetail.tsx       # Detalle de presupuesto
│   │   ├── BudgetNew.tsx          # Nuevo presupuesto
│   │   ├── Budgets.tsx            # Lista de presupuestos
│   │   ├── Catalog.tsx            # Catálogo de productos
│   │   ├── CheckoutFailure.tsx    # Pago fallido
│   │   ├── CheckoutSuccess.tsx    # Pago exitoso
│   │   ├── Contact.tsx            # Contacto
│   │   ├── Dashboard.tsx          # Dashboard principal
│   │   ├── Features.tsx           # Características
│   │   ├── Integrations.tsx       # Integraciones
│   │   ├── Landing.tsx            # Landing page
│   │   ├── NotFound.tsx           # 404
│   │   ├── Onboarding.tsx         # Onboarding
│   │   ├── Pricing.tsx            # Precios
│   │   ├── Privacy.tsx            # Privacidad
│   │   ├── Reports.tsx            # Reportes
│   │   ├── Settings.tsx           # Configuración
│   │   ├── Team.tsx               # Equipo
│   │   └── Terms.tsx              # Términos
│   │
│   ├── types/
│   │   ├── budget.ts              # Tipos de budget
│   │   └── index.ts               # Tipos generales
│   │
│   ├── App.tsx                    # Componente principal
│   ├── index.css                  # Estilos globales
│   └── main.tsx                   # Entry point
│
├── supabase/
│   ├── config.toml                # Configuración Supabase
│   ├── functions/                 # Edge Functions
│   │   ├── accept-invitation/
│   │   ├── admin-panel/
│   │   ├── cancel-subscription/
│   │   ├── chat-gemini/
│   │   ├── check-trial-expiration/
│   │   ├── crm-via-pipedream/
│   │   ├── exchange-rates/
│   │   ├── hubspot-api/
│   │   ├── import-budget/
│   │   ├── invite-team-member/
│   │   ├── liveblocks-auth/
│   │   ├── manage-team/
│   │   ├── parse-document/
│   │   ├── pipedream-action/
│   │   ├── pipedream-auth/
│   │   ├── reactivate-subscription/
│   │   ├── reveniu-webhook/
│   │   ├── send-contact-form/
│   │   └── send-notification-email/
│   │       └── _templates/        # Plantillas de email
│   └── migrations/                # Migraciones SQL
│
├── docs/
│   └── migration/                 # Guías de migración
│       ├── 01-schema-migration.sql
│       ├── 02-data-export-queries.sql
│       ├── 03-migration-guide.md
│       ├── 04-edge-functions-config.toml
│       ├── 05-self-hosting-guide.md
│       └── scripts/               # Scripts de migración
│
├── public/
│   ├── favicon.ico
│   ├── robots.txt
│   └── sitemap.xml
│
├── index.html
├── package.json
├── tailwind.config.ts
├── tsconfig.json
└── vite.config.ts
```

***

### Base de Datos

Cierro utiliza PostgreSQL a través de Supabase. A continuación se describe el esquema de base de datos.

#### Diagrama de Relaciones

```
┌─────────────────┐     ┌─────────────────┐     ┌─────────────────┐
│   companies     │────<│    profiles     │────<│   user_roles    │
└─────────────────┘     └─────────────────┘     └─────────────────┘
        │                       │
        │                       │
        ▼                       ▼
┌─────────────────┐     ┌─────────────────┐
│    budgets      │────<│ budget_versions │
└─────────────────┘     └─────────────────┘
        │
        ├──────────────────────┐
        ▼                      ▼
┌─────────────────┐     ┌─────────────────┐
│budget_conversat.│     │    products     │
└─────────────────┘     └─────────────────┘
```

#### Tablas Principales

**Companies (Empresas)**

Almacena la información de cada empresa/organización.

| Campo                  | Tipo      | Descripción               |
| ---------------------- | --------- | ------------------------- |
| `id`                   | UUID      | Identificador único       |
| `name`                 | TEXT      | Nombre de la empresa      |
| `logo_url`             | TEXT      | URL del logo              |
| `primary_color`        | TEXT      | Color primario de marca   |
| `secondary_color`      | TEXT      | Color secundario          |
| `font_title`           | TEXT      | Fuente para títulos       |
| `font_body`            | TEXT      | Fuente para cuerpo        |
| `default_currency`     | TEXT      | Moneda por defecto (USD)  |
| `default_language`     | TEXT      | Idioma por defecto (es)   |
| `subscription_status`  | TEXT      | Estado de suscripción     |
| `subscription_plan_id` | UUID      | Plan de suscripción       |
| `trial_ends_at`        | TIMESTAMP | Fin del período de prueba |

**Profiles (Usuarios)**

Perfiles de usuario vinculados a Clerk.

| Campo            | Tipo    | Descripción            |
| ---------------- | ------- | ---------------------- |
| `id`             | UUID    | Identificador único    |
| `clerk_user_id`  | TEXT    | ID de Clerk            |
| `email`          | TEXT    | Email del usuario      |
| `full_name`      | TEXT    | Nombre completo        |
| `avatar_url`     | TEXT    | URL del avatar         |
| `company_id`     | UUID    | Empresa asociada       |
| `is_super_admin` | BOOLEAN | Es super administrador |

**User Roles (Roles)**

Roles de usuarios por empresa.

| Campo        | Tipo | Descripción                                 |
| ------------ | ---- | ------------------------------------------- |
| `id`         | UUID | Identificador único                         |
| `profile_id` | UUID | Usuario                                     |
| `company_id` | UUID | Empresa                                     |
| `role`       | ENUM | Rol: `admin`, `manager`, `member`, `viewer` |

**Budgets (Presupuestos)**

Propuestas comerciales.

| Campo            | Tipo    | Descripción                                     |
| ---------------- | ------- | ----------------------------------------------- |
| `id`             | UUID    | Identificador único                             |
| `company_id`     | UUID    | Empresa                                         |
| `created_by`     | UUID    | Creador                                         |
| `title`          | TEXT    | Título                                          |
| `client_name`    | TEXT    | Nombre del cliente                              |
| `client_company` | TEXT    | Empresa del cliente                             |
| `client_email`   | TEXT    | Email del cliente                               |
| `status`         | TEXT    | Estado: `draft`, `sent`, `approved`, `rejected` |
| `total_amount`   | NUMERIC | Monto total                                     |
| `currency`       | TEXT    | Moneda                                          |
| `validity_days`  | INTEGER | Días de validez                                 |
| `raw_html`       | TEXT    | Contenido HTML                                  |
| `stages`         | JSONB   | Etapas del proyecto                             |
| `costs`          | JSONB   | Costos detallados                               |
| `sections`       | JSONB   | Secciones del documento                         |

**Products (Productos)**

Catálogo de productos/servicios.

| Campo                | Tipo    | Descripción                   |
| -------------------- | ------- | ----------------------------- |
| `id`                 | UUID    | Identificador único           |
| `company_id`         | UUID    | Empresa                       |
| `name`               | TEXT    | Nombre                        |
| `description`        | TEXT    | Descripción                   |
| `default_unit_price` | NUMERIC | Precio unitario               |
| `cost_type`          | TEXT    | Tipo: `one-time`, `recurring` |
| `category`           | TEXT    | Categoría                     |
| `item_type`          | TEXT    | Tipo: `product`, `service`    |

**Sales Goals (Metas de Ventas)**

Objetivos de ventas por período.

| Campo            | Tipo    | Descripción         |
| ---------------- | ------- | ------------------- |
| `id`             | UUID    | Identificador único |
| `company_id`     | UUID    | Empresa             |
| `profile_id`     | UUID    | Ejecutivo           |
| `one_time_goal`  | NUMERIC | Meta one-time       |
| `recurring_goal` | NUMERIC | Meta recurrente     |
| `period_start`   | DATE    | Inicio del período  |
| `period_end`     | DATE    | Fin del período     |

**Commission Rules (Reglas de Comisión)**

Configuración de comisiones.

| Campo                   | Tipo    | Descripción            |
| ----------------------- | ------- | ---------------------- |
| `id`                    | UUID    | Identificador único    |
| `company_id`            | UUID    | Empresa                |
| `profile_id`            | UUID    | Ejecutivo              |
| `rule_type`             | TEXT    | Tipo de regla          |
| `commission_percentage` | NUMERIC | Porcentaje de comisión |
| `bonus_percentage`      | NUMERIC | Porcentaje de bonus    |

**Subscription Plans (Planes)**

Planes de suscripción disponibles.

| Campo           | Tipo    | Descripción         |
| --------------- | ------- | ------------------- |
| `id`            | UUID    | Identificador único |
| `name`          | TEXT    | Nombre interno      |
| `display_name`  | TEXT    | Nombre visible      |
| `price_monthly` | NUMERIC | Precio mensual      |
| `limits`        | JSONB   | Límites del plan    |
| `features`      | JSONB   | Características     |

#### Políticas RLS

Todas las tablas tienen Row Level Security (RLS) habilitado. Las políticas principales:

* **Companies**: Lectura pública, escritura restringida
* **Profiles**: Usuarios pueden ver/editar su propio perfil
* **Budgets**: Acceso basado en rol y empresa
* **Products**: Acceso por empresa

***

### Edge Functions

Cierro utiliza Supabase Edge Functions para lógica de backend. Todas las funciones están en TypeScript y se ejecutan en Deno.

#### Lista de Funciones

| Función                   | Endpoint | Descripción                                           |
| ------------------------- | -------- | ----------------------------------------------------- |
| `accept-invitation`       | POST     | Acepta invitación de equipo, crea perfil y rol        |
| `admin-panel`             | POST     | Panel de administración para super admins             |
| `cancel-subscription`     | POST     | Cancela suscripción activa                            |
| `chat-gemini`             | POST     | Chat con IA para generación de contenido              |
| `check-trial-expiration`  | GET      | Cron job para verificar trials y enviar recordatorios |
| `crm-via-pipedream`       | POST     | Ejecuta acciones CRM via Pipedream                    |
| `exchange-rates`          | GET      | Obtiene tasas de cambio actualizadas                  |
| `hubspot-api`             | POST     | Proxy para API de HubSpot                             |
| `import-budget`           | POST     | Importa presupuesto desde archivo                     |
| `invite-team-member`      | POST     | Envía invitación por email                            |
| `liveblocks-auth`         | POST     | Autenticación para Liveblocks                         |
| `manage-team`             | POST     | Gestión de miembros del equipo                        |
| `parse-document`          | POST     | Parsea documentos (PDF, DOCX)                         |
| `pipedream-action`        | POST     | Ejecuta acciones de Pipedream                         |
| `pipedream-auth`          | POST     | Autenticación OAuth para Pipedream                    |
| `reactivate-subscription` | POST     | Reactiva suscripción cancelada                        |
| `reveniu-webhook`         | POST     | Webhook de pagos Reveniu                              |
| `send-contact-form`       | POST     | Envía formulario de contacto                          |
| `send-notification-email` | POST     | Envía emails transaccionales                          |

#### Documentación Detallada

Ver [docs/api-reference.md](https://docs.cierro.app/docs/api-reference) para documentación completa de cada función.

***

### Sistema de Emails

Cierro utiliza [Resend](https://resend.com) para envío de emails transaccionales con templates React.

#### Templates Disponibles

| Template                   | Trigger             | Descripción                      |
| -------------------------- | ------------------- | -------------------------------- |
| `welcome_trial`            | Registro            | Bienvenida al período de prueba  |
| `trial_expiring`           | Cron (7, 3, 1 días) | Recordatorio de trial por vencer |
| `trial_expired`            | Cron                | Notificación de trial expirado   |
| `budget_expiring`          | Cron (7, 3, 1 días) | Presupuesto por vencer           |
| `budget_approved`          | Aprobación          | Presupuesto aprobado por cliente |
| `team_invitation`          | Invitación          | Invitación a unirse al equipo    |
| `team_welcome`             | Aceptación          | Bienvenida al nuevo miembro      |
| `subscription_activated`   | Pago                | Suscripción activada             |
| `subscription_cancelled`   | Cancelación         | Suscripción cancelada            |
| `subscription_reactivated` | Reactivación        | Suscripción reactivada           |
| `payment_failed`           | Fallo de pago       | Error en el pago                 |

#### Ubicación de Templates

```
supabase/functions/send-notification-email/_templates/
├── base-layout.tsx           # Layout base
├── welcome-trial.tsx         # Bienvenida trial
├── trial-expiring.tsx        # Trial por vencer
├── budget-approved.tsx       # Presupuesto aprobado
├── budget-expiring.tsx       # Presupuesto por vencer
├── team-invitation.tsx       # Invitación de equipo
├── team-welcome.tsx          # Bienvenida equipo
├── subscription-activated.tsx
├── subscription-cancelled.tsx
├── subscription-reactivated.tsx
└── payment-failed.tsx
```

***

### Autenticación y Roles

#### Flujo de Autenticación

1. Usuario inicia sesión con **Clerk**
2. Clerk emite JWT con `clerk_user_id`
3. Supabase valida JWT y extrae `clerk_user_id`
4. RLS policies verifican permisos usando funciones helper

#### Funciones Helper de Auth

```sql
-- Obtener company_id del usuario actual
get_company_id_from_clerk(_clerk_user_id TEXT) → UUID

-- Obtener profile_id del usuario actual
get_profile_id_from_clerk(_clerk_user_id TEXT) → UUID

-- Verificar si tiene rol específico
has_role_in_company(_clerk_user_id, _company_id, _role) → BOOLEAN

-- Verificar si tiene rol mínimo
has_min_role_in_company(_clerk_user_id, _company_id, _min_role) → BOOLEAN

-- Verificar si es super admin
is_super_admin(_clerk_user_id) → BOOLEAN

-- Verificar si puede ver presupuesto
can_view_budget(_clerk_user_id, _budget_id) → BOOLEAN

-- Verificar si puede editar presupuesto
can_edit_budget(_clerk_user_id, _budget_id) → BOOLEAN
```

#### Roles y Permisos

| Rol       | Descripción   | Permisos                                            |
| --------- | ------------- | --------------------------------------------------- |
| `admin`   | Administrador | Todo: configuración, equipo, reportes, presupuestos |
| `manager` | Gerente       | Ver todos los presupuestos, reportes, metas         |
| `member`  | Miembro       | CRUD sus propios presupuestos                       |
| `viewer`  | Visualizador  | Solo lectura de sus presupuestos                    |

#### Matriz de Permisos

| Acción                       | Admin | Manager | Member | Viewer |
| ---------------------------- | ----- | ------- | ------ | ------ |
| Ver dashboard                | ✅     | ✅       | ✅      | ✅      |
| Crear presupuestos           | ✅     | ✅       | ✅      | ❌      |
| Ver todos los presupuestos   | ✅     | ✅       | ❌      | ❌      |
| Editar presupuestos propios  | ✅     | ✅       | ✅      | ❌      |
| Editar presupuestos de otros | ✅     | ✅       | ❌      | ❌      |
| Configuración de empresa     | ✅     | ❌       | ❌      | ❌      |
| Gestión de equipo            | ✅     | ✅       | ❌      | ❌      |
| Ver reportes                 | ✅     | ✅       | ✅      | ✅      |
| Configurar comisiones        | ✅     | ✅       | ❌      | ❌      |

***

### Páginas y Rutas

#### Páginas Públicas

| Ruta             | Componente   | Descripción                  |
| ---------------- | ------------ | ---------------------------- |
| `/`              | Landing      | Página principal             |
| `/features`      | Features     | Características del producto |
| `/pricing`       | Pricing      | Planes y precios             |
| `/about`         | About        | Sobre nosotros               |
| `/contact`       | Contact      | Formulario de contacto       |
| `/terms`         | Terms        | Términos y condiciones       |
| `/privacy`       | Privacy      | Política de privacidad       |
| `/auth`          | Auth         | Login/Registro               |
| `/accept-invite` | AcceptInvite | Aceptar invitación           |

#### Páginas Privadas (Requieren Auth)

| Ruta            | Componente   | Descripción           |
| --------------- | ------------ | --------------------- |
| `/dashboard`    | Dashboard    | Panel principal       |
| `/budgets`      | Budgets      | Lista de presupuestos |
| `/budgets/new`  | BudgetNew    | Crear presupuesto     |
| `/budgets/:id`  | BudgetDetail | Editar presupuesto    |
| `/catalog`      | Catalog      | Catálogo de productos |
| `/reports`      | Reports      | Reportes y analytics  |
| `/team`         | Team         | Gestión de equipo     |
| `/settings`     | Settings     | Configuración         |
| `/onboarding`   | Onboarding   | Configuración inicial |
| `/integrations` | Integrations | Integraciones         |

#### Páginas de Checkout

| Ruta                | Componente      | Descripción  |
| ------------------- | --------------- | ------------ |
| `/checkout/success` | CheckoutSuccess | Pago exitoso |
| `/checkout/failure` | CheckoutFailure | Pago fallido |

#### Páginas de Admin

| Ruta     | Componente | Descripción          |
| -------- | ---------- | -------------------- |
| `/admin` | Admin      | Panel de super admin |

***

### Instalación

#### Requisitos Previos

* Node.js 18+
* npm o yarn
* Cuenta de Supabase (o usar Lovable Cloud)
* Cuenta de Clerk

#### Instalación Local

```bash
# 1. Clonar repositorio
git clone https://github.com/tu-usuario/cierro.git
cd cierro

# 2. Instalar dependencias
npm install

# 3. Configurar variables de entorno
cp .env.example .env
# Editar .env con tus valores

# 4. Iniciar desarrollo
npm run dev
```

#### Scripts Disponibles

```bash
npm run dev          # Inicia servidor de desarrollo
npm run build        # Build de producción
npm run preview      # Preview del build
npm run lint         # Ejecutar ESLint
```

***

### Variables de Entorno

#### Variables de Cliente (.env)

```env
# Supabase
VITE_SUPABASE_URL=https://xxxxx.supabase.co
VITE_SUPABASE_PUBLISHABLE_KEY=eyJhbGci...

# Clerk
VITE_CLERK_PUBLISHABLE_KEY=pk_test_...
```

#### Secrets de Edge Functions (Supabase)

| Secret                      | Descripción               | Requerido  |
| --------------------------- | ------------------------- | ---------- |
| `CLERK_SECRET_KEY`          | API key de Clerk          | ✅          |
| `CLERK_PUBLISHABLE_KEY`     | Key pública de Clerk      | ✅          |
| `SUPABASE_URL`              | URL del proyecto Supabase | ✅          |
| `SUPABASE_ANON_KEY`         | Anon key de Supabase      | ✅          |
| `SUPABASE_SERVICE_ROLE_KEY` | Service role key          | ✅          |
| `RESEND_API_KEY`            | API key de Resend         | ✅          |
| `GEMINI_API_KEY`            | API key de Google Gemini  | ✅          |
| `OPENAI_API_KEY`            | API key de OpenAI         | Opcional   |
| `LIVEBLOCKS_SECRET_KEY`     | Secret de Liveblocks      | ✅          |
| `REVENIU_SECRET_KEY`        | Secret de Reveniu         | Para pagos |
| `HUBSPOT_ACCESS_TOKEN`      | Token de HubSpot          | Opcional   |
| `PIPEDREAM_CLIENT_ID`       | Client ID de Pipedream    | Opcional   |
| `PIPEDREAM_CLIENT_SECRET`   | Client Secret             | Opcional   |
| `PIPEDREAM_PROJECT_ID`      | Project ID                | Opcional   |

***

### Guías de Migración

Para self-hosting o migración a otra infraestructura, consulta:

* [01-schema-migration.sql](https://github.com/NLACE-COM/cierroapp/blob/main/docs/migration/01-schema-migration.sql) - Schema SQL completo
* [02-data-export-queries.sql](https://github.com/NLACE-COM/cierroapp/blob/main/docs/migration/02-data-export-queries.sql) - Queries de exportación
* [03-migration-guide.md](https://docs.cierro.app/docs/migration/03-migration-guide) - Guía paso a paso
* [04-edge-functions-config.toml](https://github.com/NLACE-COM/cierroapp/blob/main/docs/migration/04-edge-functions-config.toml) - Config de Edge Functions
* [05-self-hosting-guide.md](https://docs.cierro.app/docs/migration/05-self-hosting-guide) - Guía de self-hosting

***

### Despliegue

#### Despliegue con Lovable

1. Ir a [Lovable](https://lovable.dev)
2. Abrir el proyecto
3. Click en **Share → Publish**

#### Self-Hosting

**Vercel**

```bash
# Instalar Vercel CLI
npm i -g vercel

# Desplegar
vercel
```

**Netlify**

```bash
# Instalar Netlify CLI
npm i -g netlify-cli

# Desplegar
netlify deploy --prod
```

**Docker**

```dockerfile
FROM node:18-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
```

***

### Contribución

#### Guía de Contribución

1. Fork el repositorio
2. Crear rama: `git checkout -b feature/nueva-caracteristica`
3. Commit: `git commit -m 'Agregar nueva característica'`
4. Push: `git push origin feature/nueva-caracteristica`
5. Crear Pull Request

#### Estándares de Código

* Usar TypeScript estricto
* Seguir convenciones de ESLint
* Componentes en PascalCase
* Hooks con prefijo `use`
* Archivos de componente en PascalCase.tsx

#### Estructura de Commits

```
feat: nueva característica
fix: corrección de bug
docs: documentación
style: formateo
refactor: refactorización
test: tests
chore: mantenimiento
```

***

### Licencia

Este proyecto es propietario. Todos los derechos reservados.

© 2024 Cierro - Desarrollado por [NLACE](https://nlace.com)

***

### Contacto

* **Email**: <soporte@cierro.app>
* **Website**: [cierro.app](https://cierro.app)
* **Desarrollado por**: [NLACE](https://nlace.com)

***

<p align="center"><sub>Built with ❤️ using Lovable</sub></p>
