@nextsparkjs/theme-crm 0.1.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (140) hide show
  1. package/CRM_PLAN.md +343 -0
  2. package/about.md +122 -0
  3. package/config/app.config.ts +185 -0
  4. package/config/billing.config.ts +187 -0
  5. package/config/dashboard.config.ts +372 -0
  6. package/config/dev.config.ts +55 -0
  7. package/config/features.config.ts +336 -0
  8. package/config/flows.config.ts +511 -0
  9. package/config/permissions.config.ts +297 -0
  10. package/config/theme.config.ts +111 -0
  11. package/entities/activities/activities.config.ts +61 -0
  12. package/entities/activities/activities.fields.ts +362 -0
  13. package/entities/activities/activities.service.ts +503 -0
  14. package/entities/activities/activities.types.ts +117 -0
  15. package/entities/activities/messages/en.json +123 -0
  16. package/entities/activities/messages/es.json +123 -0
  17. package/entities/activities/migrations/020_activities_table.sql +123 -0
  18. package/entities/activities/migrations/021_activities_metas.sql +114 -0
  19. package/entities/activities/migrations/022_activities_sample_data.sql +420 -0
  20. package/entities/campaigns/campaigns.config.ts +61 -0
  21. package/entities/campaigns/campaigns.fields.ts +413 -0
  22. package/entities/campaigns/campaigns.service.ts +426 -0
  23. package/entities/campaigns/campaigns.types.ts +124 -0
  24. package/entities/campaigns/messages/en.json +145 -0
  25. package/entities/campaigns/messages/es.json +145 -0
  26. package/entities/campaigns/migrations/001_campaigns_table.sql +127 -0
  27. package/entities/campaigns/migrations/002_campaigns_metas.sql +114 -0
  28. package/entities/campaigns/migrations/003_campaigns_sample_data.sql +364 -0
  29. package/entities/companies/companies.config.ts +61 -0
  30. package/entities/companies/companies.fields.ts +429 -0
  31. package/entities/companies/companies.service.ts +566 -0
  32. package/entities/companies/companies.types.ts +125 -0
  33. package/entities/companies/messages/en.json +146 -0
  34. package/entities/companies/messages/es.json +146 -0
  35. package/entities/companies/migrations/001_companies_table.sql +150 -0
  36. package/entities/companies/migrations/002_companies_metas.sql +114 -0
  37. package/entities/companies/migrations/003_companies_sample_data.sql +246 -0
  38. package/entities/contacts/contacts.config.ts +61 -0
  39. package/entities/contacts/contacts.fields.ts +359 -0
  40. package/entities/contacts/contacts.service.ts +509 -0
  41. package/entities/contacts/contacts.types.ts +108 -0
  42. package/entities/contacts/messages/en.json +117 -0
  43. package/entities/contacts/messages/es.json +117 -0
  44. package/entities/contacts/migrations/001_contacts_table.sql +134 -0
  45. package/entities/contacts/migrations/002_contacts_metas.sql +114 -0
  46. package/entities/contacts/migrations/003_contacts_sample_data.sql +421 -0
  47. package/entities/leads/leads.config.ts +61 -0
  48. package/entities/leads/leads.fields.ts +336 -0
  49. package/entities/leads/leads.service.ts +496 -0
  50. package/entities/leads/leads.types.ts +114 -0
  51. package/entities/leads/messages/en.json +132 -0
  52. package/entities/leads/messages/es.json +132 -0
  53. package/entities/leads/migrations/001_leads_table.sql +150 -0
  54. package/entities/leads/migrations/002_leads_metas.sql +120 -0
  55. package/entities/leads/migrations/003_leads_sample_data.sql +242 -0
  56. package/entities/notes/messages/en.json +114 -0
  57. package/entities/notes/messages/es.json +114 -0
  58. package/entities/notes/migrations/020_notes_table.sql +118 -0
  59. package/entities/notes/migrations/021_notes_metas.sql +114 -0
  60. package/entities/notes/migrations/022_notes_sample_data.sql +275 -0
  61. package/entities/notes/notes.config.ts +61 -0
  62. package/entities/notes/notes.fields.ts +283 -0
  63. package/entities/notes/notes.service.ts +320 -0
  64. package/entities/notes/notes.types.ts +102 -0
  65. package/entities/opportunities/messages/en.json +107 -0
  66. package/entities/opportunities/messages/es.json +107 -0
  67. package/entities/opportunities/migrations/010_opportunities_table.sql +145 -0
  68. package/entities/opportunities/migrations/011_opportunities_metas.sql +114 -0
  69. package/entities/opportunities/migrations/012_opportunities_sample_data.sql +438 -0
  70. package/entities/opportunities/opportunities.config.ts +61 -0
  71. package/entities/opportunities/opportunities.fields.ts +416 -0
  72. package/entities/opportunities/opportunities.service.ts +525 -0
  73. package/entities/opportunities/opportunities.types.ts +135 -0
  74. package/entities/pipelines/messages/en.json +115 -0
  75. package/entities/pipelines/messages/es.json +115 -0
  76. package/entities/pipelines/migrations/001_pipelines_table.sql +106 -0
  77. package/entities/pipelines/migrations/002_pipelines_metas.sql +114 -0
  78. package/entities/pipelines/migrations/003_pipelines_sample_data.sql +91 -0
  79. package/entities/pipelines/pipelines.config.ts +62 -0
  80. package/entities/pipelines/pipelines.fields.ts +193 -0
  81. package/entities/pipelines/pipelines.service.ts +383 -0
  82. package/entities/pipelines/pipelines.types.ts +78 -0
  83. package/entities/products/messages/en.json +135 -0
  84. package/entities/products/messages/es.json +135 -0
  85. package/entities/products/migrations/001_products_table.sql +117 -0
  86. package/entities/products/migrations/002_products_metas.sql +114 -0
  87. package/entities/products/migrations/003_products_sample_data.sql +247 -0
  88. package/entities/products/products.config.ts +62 -0
  89. package/entities/products/products.fields.ts +361 -0
  90. package/entities/products/products.service.ts +437 -0
  91. package/entities/products/products.types.ts +125 -0
  92. package/lib/crm-constants.ts +77 -0
  93. package/lib/crm-utils.ts +185 -0
  94. package/lib/selectors.ts +333 -0
  95. package/messages/en.json +131 -0
  96. package/messages/es.json +131 -0
  97. package/migrations/999_theme_sample_data.sql +473 -0
  98. package/package.json +18 -0
  99. package/pendings.md +205 -0
  100. package/permissions-matrix.md +216 -0
  101. package/styles/components.css +414 -0
  102. package/styles/crm-theme.css +358 -0
  103. package/styles/globals.css +576 -0
  104. package/styles/variables.css +111 -0
  105. package/templates/dashboard/(main)/activities/components/ActivityCard.tsx +169 -0
  106. package/templates/dashboard/(main)/activities/components/ActivityTimeline.tsx +165 -0
  107. package/templates/dashboard/(main)/activities/page.tsx +297 -0
  108. package/templates/dashboard/(main)/campaigns/page.tsx +373 -0
  109. package/templates/dashboard/(main)/companies/page.tsx +296 -0
  110. package/templates/dashboard/(main)/contacts/page.tsx +347 -0
  111. package/templates/dashboard/(main)/layout.tsx +98 -0
  112. package/templates/dashboard/(main)/leads/page.tsx +335 -0
  113. package/templates/dashboard/(main)/opportunities/[id]/edit/page.tsx +95 -0
  114. package/templates/dashboard/(main)/opportunities/create/page.tsx +94 -0
  115. package/templates/dashboard/(main)/opportunities/page.tsx +350 -0
  116. package/templates/dashboard/(main)/pipelines/[id]/edit/page.tsx +95 -0
  117. package/templates/dashboard/(main)/pipelines/[id]/page.tsx +143 -0
  118. package/templates/dashboard/(main)/pipelines/create/page.tsx +94 -0
  119. package/templates/dashboard/(main)/pipelines/page.tsx +234 -0
  120. package/templates/dashboard/(main)/products/[id]/edit/page.tsx +97 -0
  121. package/templates/dashboard/(main)/products/[id]/page.tsx +509 -0
  122. package/templates/dashboard/(main)/products/create/page.tsx +96 -0
  123. package/templates/dashboard/(main)/products/page.tsx +308 -0
  124. package/templates/shared/ActionButtons.tsx +41 -0
  125. package/templates/shared/CRMDashboard.tsx +519 -0
  126. package/templates/shared/CRMDataTable.tsx +441 -0
  127. package/templates/shared/CRMMetricCard.tsx +76 -0
  128. package/templates/shared/CRMMobileNav.tsx +172 -0
  129. package/templates/shared/CRMSidebar.tsx +346 -0
  130. package/templates/shared/CRMTopBar.tsx +265 -0
  131. package/templates/shared/DealCard.tsx +123 -0
  132. package/templates/shared/EntityCard.tsx +58 -0
  133. package/templates/shared/OpportunityForm.tsx +649 -0
  134. package/templates/shared/PipelineForm.tsx +367 -0
  135. package/templates/shared/PipelineKanban.tsx +194 -0
  136. package/templates/shared/QuickFilters.tsx +47 -0
  137. package/templates/shared/StageColumn.tsx +175 -0
  138. package/templates/shared/StageSelect.tsx +177 -0
  139. package/templates/shared/StagesRepeater.tsx +317 -0
  140. package/templates/shared/index.ts +9 -0
package/CRM_PLAN.md ADDED
@@ -0,0 +1,343 @@
1
+ # Plan de Implementación del Sistema CRM
2
+
3
+ ## Estado: EN DESARROLLO
4
+ ## Fecha: 2025-09-27
5
+
6
+ ## Entidades del CRM (9 entidades fundamentales)
7
+
8
+ ### 1. LEADS
9
+ **Descripción**: Prospectos potenciales que aún no son clientes
10
+ **Tabla**: `leads`
11
+ **Campos**:
12
+ - `id` (TEXT/UUID) - Primary key
13
+ - `userId` (TEXT) - User who owns this lead
14
+ - `companyName` (TEXT) - Company name
15
+ - `contactName` (TEXT) - Contact person name
16
+ - `email` (TEXT) - Email address
17
+ - `phone` (TEXT) - Phone number
18
+ - `website` (TEXT) - Company website
19
+ - `source` (TEXT) - Lead source (web, referral, cold_call, trade_show, social_media)
20
+ - `status` (TEXT) - Lead status (new, contacted, qualified, proposal, negotiation, converted, lost)
21
+ - `score` (INTEGER) - Lead score (0-100)
22
+ - `industry` (TEXT) - Industry sector
23
+ - `companySize` (TEXT) - Company size (1-10, 11-50, 51-200, 201-500, 500+)
24
+ - `budget` (DECIMAL) - Estimated budget
25
+ - `assignedTo` (TEXT) - User ID of assigned sales rep
26
+ - `convertedDate` (TIMESTAMPTZ) - Date when lead was converted
27
+ - `convertedToContactId` (TEXT) - Reference to contact if converted
28
+ - `convertedToCompanyId` (TEXT) - Reference to company if converted
29
+ - `notes` (TEXT) - Internal notes
30
+ - `createdAt` (TIMESTAMPTZ)
31
+ - `updatedAt` (TIMESTAMPTZ)
32
+
33
+ ### 2. CONTACTS
34
+ **Descripción**: Personas de contacto en las empresas
35
+ **Tabla**: `contacts`
36
+ **Campos**:
37
+ - `id` (TEXT/UUID) - Primary key
38
+ - `userId` (TEXT) - User who owns this contact
39
+ - `companyId` (TEXT) - Reference to companies table (nullable for standalone contacts)
40
+ - `firstName` (TEXT) - First name
41
+ - `lastName` (TEXT) - Last name
42
+ - `email` (TEXT) - Email address
43
+ - `phone` (TEXT) - Phone number
44
+ - `mobile` (TEXT) - Mobile phone
45
+ - `position` (TEXT) - Job position/title
46
+ - `department` (TEXT) - Department
47
+ - `isPrimary` (BOOLEAN) - Is primary contact for company
48
+ - `birthDate` (DATE) - Birth date
49
+ - `linkedin` (TEXT) - LinkedIn profile URL
50
+ - `twitter` (TEXT) - Twitter handle
51
+ - `preferredChannel` (TEXT) - Preferred contact channel (email, phone, whatsapp, linkedin)
52
+ - `timezone` (TEXT) - Contact's timezone
53
+ - `lastContactedAt` (TIMESTAMPTZ) - Last contact date
54
+ - `createdAt` (TIMESTAMPTZ)
55
+ - `updatedAt` (TIMESTAMPTZ)
56
+
57
+ ### 3. COMPANIES
58
+ **Descripción**: Empresas clientes o prospectos
59
+ **Tabla**: `companies`
60
+ **Campos**:
61
+ - `id` (TEXT/UUID) - Primary key
62
+ - `userId` (TEXT) - User who owns this company
63
+ - `name` (TEXT) - Company name
64
+ - `legalName` (TEXT) - Legal company name
65
+ - `taxId` (TEXT) - Tax identification number
66
+ - `website` (TEXT) - Company website
67
+ - `email` (TEXT) - General company email
68
+ - `phone` (TEXT) - Main phone number
69
+ - `industry` (TEXT) - Industry sector
70
+ - `type` (TEXT) - Company type (prospect, customer, partner, competitor)
71
+ - `size` (TEXT) - Company size (1-10, 11-50, 51-200, 201-500, 500+)
72
+ - `annualRevenue` (DECIMAL) - Annual revenue
73
+ - `address` (TEXT) - Street address
74
+ - `city` (TEXT) - City
75
+ - `state` (TEXT) - State/Province
76
+ - `country` (TEXT) - Country
77
+ - `postalCode` (TEXT) - Postal/ZIP code
78
+ - `logo` (TEXT) - Logo URL
79
+ - `linkedin` (TEXT) - LinkedIn company page
80
+ - `facebook` (TEXT) - Facebook page
81
+ - `twitter` (TEXT) - Twitter handle
82
+ - `rating` (TEXT) - Company rating (hot, warm, cold)
83
+ - `assignedTo` (TEXT) - User ID of account manager
84
+ - `createdAt` (TIMESTAMPTZ)
85
+ - `updatedAt` (TIMESTAMPTZ)
86
+
87
+ ### 4. OPPORTUNITIES
88
+ **Descripción**: Oportunidades de venta
89
+ **Tabla**: `opportunities`
90
+ **Campos**:
91
+ - `id` (TEXT/UUID) - Primary key
92
+ - `userId` (TEXT) - User who owns this opportunity
93
+ - `name` (TEXT) - Opportunity name
94
+ - `companyId` (TEXT) - Reference to companies table
95
+ - `contactId` (TEXT) - Primary contact for this opportunity
96
+ - `pipelineId` (TEXT) - Reference to pipelines table
97
+ - `stageId` (TEXT) - Current stage in pipeline
98
+ - `amount` (DECIMAL) - Deal amount
99
+ - `currency` (TEXT) - Currency code (USD, EUR, MXN)
100
+ - `probability` (INTEGER) - Win probability (0-100)
101
+ - `expectedRevenue` (DECIMAL) - amount * (probability/100)
102
+ - `closeDate` (DATE) - Expected close date
103
+ - `type` (TEXT) - Opportunity type (new_business, existing_business, renewal)
104
+ - `source` (TEXT) - Lead source
105
+ - `competitor` (TEXT) - Main competitor
106
+ - `status` (TEXT) - Status (open, won, lost)
107
+ - `lostReason` (TEXT) - Reason if lost
108
+ - `wonDate` (DATE) - Date when won
109
+ - `lostDate` (DATE) - Date when lost
110
+ - `assignedTo` (TEXT) - User ID of sales rep
111
+ - `createdAt` (TIMESTAMPTZ)
112
+ - `updatedAt` (TIMESTAMPTZ)
113
+
114
+ ### 5. ACTIVITIES
115
+ **Descripción**: Actividades y tareas relacionadas con CRM
116
+ **Tabla**: `activities`
117
+ **Campos**:
118
+ - `id` (TEXT/UUID) - Primary key
119
+ - `userId` (TEXT) - User who owns this activity
120
+ - `type` (TEXT) - Activity type (call, email, meeting, task, note)
121
+ - `subject` (TEXT) - Activity subject/title
122
+ - `description` (TEXT) - Detailed description
123
+ - `status` (TEXT) - Status (scheduled, completed, cancelled)
124
+ - `priority` (TEXT) - Priority (low, medium, high, urgent)
125
+ - `dueDate` (TIMESTAMPTZ) - Due date/time
126
+ - `completedAt` (TIMESTAMPTZ) - Completion date/time
127
+ - `duration` (INTEGER) - Duration in minutes
128
+ - `outcome` (TEXT) - Activity outcome/result
129
+ - `location` (TEXT) - Location (for meetings)
130
+ - `entityType` (TEXT) - Related entity type (lead, contact, company, opportunity)
131
+ - `entityId` (TEXT) - Related entity ID
132
+ - `contactId` (TEXT) - Related contact (optional)
133
+ - `companyId` (TEXT) - Related company (optional)
134
+ - `opportunityId` (TEXT) - Related opportunity (optional)
135
+ - `assignedTo` (TEXT) - User ID assigned to
136
+ - `createdAt` (TIMESTAMPTZ)
137
+ - `updatedAt` (TIMESTAMPTZ)
138
+
139
+ ### 6. CAMPAIGNS
140
+ **Descripción**: Campañas de marketing
141
+ **Tabla**: `campaigns`
142
+ **Campos**:
143
+ - `id` (TEXT/UUID) - Primary key
144
+ - `userId` (TEXT) - User who owns this campaign
145
+ - `name` (TEXT) - Campaign name
146
+ - `type` (TEXT) - Campaign type (email, social, event, webinar, advertising, content)
147
+ - `status` (TEXT) - Status (planned, active, paused, completed, cancelled)
148
+ - `objective` (TEXT) - Campaign objective
149
+ - `description` (TEXT) - Detailed description
150
+ - `startDate` (DATE) - Start date
151
+ - `endDate` (DATE) - End date
152
+ - `budget` (DECIMAL) - Campaign budget
153
+ - `actualCost` (DECIMAL) - Actual cost spent
154
+ - `targetAudience` (TEXT) - Target audience description
155
+ - `targetLeads` (INTEGER) - Target number of leads
156
+ - `actualLeads` (INTEGER) - Actual leads generated
157
+ - `targetRevenue` (DECIMAL) - Target revenue
158
+ - `actualRevenue` (DECIMAL) - Actual revenue generated
159
+ - `roi` (DECIMAL) - Return on investment percentage
160
+ - `channel` (TEXT) - Main channel (email, social_media, web, print, tv, radio)
161
+ - `assignedTo` (TEXT) - User ID of campaign manager
162
+ - `createdAt` (TIMESTAMPTZ)
163
+ - `updatedAt` (TIMESTAMPTZ)
164
+
165
+ ### 7. NOTES
166
+ **Descripción**: Notas y comentarios
167
+ **Tabla**: `notes`
168
+ **Campos**:
169
+ - `id` (TEXT/UUID) - Primary key
170
+ - `userId` (TEXT) - User who created this note
171
+ - `title` (TEXT) - Note title
172
+ - `content` (TEXT) - Note content
173
+ - `type` (TEXT) - Note type (general, call, meeting, email, followup)
174
+ - `isPinned` (BOOLEAN) - Is pinned/important
175
+ - `isPrivate` (BOOLEAN) - Is private to creator
176
+ - `entityType` (TEXT) - Related entity type (lead, contact, company, opportunity, campaign)
177
+ - `entityId` (TEXT) - Related entity ID
178
+ - `contactId` (TEXT) - Related contact (optional)
179
+ - `companyId` (TEXT) - Related company (optional)
180
+ - `opportunityId` (TEXT) - Related opportunity (optional)
181
+ - `attachments` (JSONB) - Array of attachment URLs
182
+ - `createdAt` (TIMESTAMPTZ)
183
+ - `updatedAt` (TIMESTAMPTZ)
184
+
185
+ ### 8. PRODUCTS
186
+ **Descripción**: Productos o servicios que se venden
187
+ **Tabla**: `products`
188
+ **Campos**:
189
+ - `id` (TEXT/UUID) - Primary key
190
+ - `userId` (TEXT) - User who owns this product
191
+ - `code` (TEXT) - Product code/SKU
192
+ - `name` (TEXT) - Product name
193
+ - `category` (TEXT) - Product category
194
+ - `type` (TEXT) - Type (product, service, subscription)
195
+ - `description` (TEXT) - Product description
196
+ - `features` (JSONB) - Array of product features
197
+ - `price` (DECIMAL) - Standard price
198
+ - `cost` (DECIMAL) - Product cost
199
+ - `currency` (TEXT) - Currency code
200
+ - `unit` (TEXT) - Unit of measure (piece, hour, month, year)
201
+ - `isActive` (BOOLEAN) - Is currently active
202
+ - `image` (TEXT) - Product image URL
203
+ - `brochureUrl` (TEXT) - Product brochure URL
204
+ - `minimumQuantity` (INTEGER) - Minimum order quantity
205
+ - `commissionRate` (DECIMAL) - Sales commission percentage
206
+ - `createdAt` (TIMESTAMPTZ)
207
+ - `updatedAt` (TIMESTAMPTZ)
208
+
209
+ ### 9. PIPELINES
210
+ **Descripción**: Pipelines de ventas con sus etapas
211
+ **Tabla**: `pipelines`
212
+ **Campos**:
213
+ - `id` (TEXT/UUID) - Primary key
214
+ - `userId` (TEXT) - User who owns this pipeline
215
+ - `name` (TEXT) - Pipeline name
216
+ - `description` (TEXT) - Pipeline description
217
+ - `type` (TEXT) - Pipeline type (sales, support, project)
218
+ - `isDefault` (BOOLEAN) - Is default pipeline
219
+ - `isActive` (BOOLEAN) - Is currently active
220
+ - `stages` (JSONB) - Array of stages with order, name, probability
221
+ ```json
222
+ [
223
+ {"order": 1, "name": "Qualification", "probability": 10, "color": "#3B82F6"},
224
+ {"order": 2, "name": "Needs Analysis", "probability": 25, "color": "#10B981"},
225
+ {"order": 3, "name": "Proposal", "probability": 50, "color": "#F59E0B"},
226
+ {"order": 4, "name": "Negotiation", "probability": 75, "color": "#8B5CF6"},
227
+ {"order": 5, "name": "Closed Won", "probability": 100, "color": "#059669"},
228
+ {"order": 6, "name": "Closed Lost", "probability": 0, "color": "#EF4444"}
229
+ ]
230
+ ```
231
+ - `dealRottenDays` (INTEGER) - Days until deal is considered rotten
232
+ - `createdAt` (TIMESTAMPTZ)
233
+ - `updatedAt` (TIMESTAMPTZ)
234
+
235
+ ## Relaciones entre Entidades
236
+
237
+ ### Conversión Lead → Contact/Company
238
+ - `leads.convertedToContactId` → `contacts.id`
239
+ - `leads.convertedToCompanyId` → `companies.id`
240
+
241
+ ### Relaciones de Contacts
242
+ - `contacts.companyId` → `companies.id`
243
+
244
+ ### Relaciones de Opportunities
245
+ - `opportunities.companyId` → `companies.id`
246
+ - `opportunities.contactId` → `contacts.id`
247
+ - `opportunities.pipelineId` → `pipelines.id`
248
+
249
+ ### Relaciones de Activities
250
+ - Polimórfica vía `entityType` y `entityId`
251
+ - Referencias opcionales directas:
252
+ - `activities.contactId` → `contacts.id`
253
+ - `activities.companyId` → `companies.id`
254
+ - `activities.opportunityId` → `opportunities.id`
255
+
256
+ ### Relaciones de Notes
257
+ - Polimórfica vía `entityType` y `entityId`
258
+ - Referencias opcionales directas:
259
+ - `notes.contactId` → `contacts.id`
260
+ - `notes.companyId` → `companies.id`
261
+ - `notes.opportunityId` → `opportunities.id`
262
+
263
+ ### Relaciones de Campaign
264
+ - Las campañas pueden generar leads
265
+ - Tracking vía activities y notes
266
+
267
+ ## Consideraciones de Implementación
268
+
269
+ ### Seguridad y Permisos
270
+ - Todas las tablas tienen `userId` para aislamiento multi-tenant
271
+ - RLS (Row Level Security) habilitado en todas las tablas
272
+ - Políticas por rol: admin, sales, marketing, viewer
273
+
274
+ ### Metadatos
275
+ - Todas las entidades soportan tabla `{entity}_metas`
276
+ - Estructura estándar: `entityId`, `metaKey`, `metaValue`
277
+
278
+ ### Índices Recomendados
279
+ - Por `userId` en todas las tablas
280
+ - Por campos de búsqueda frecuente (email, phone, name)
281
+ - Por foreign keys para JOINs eficientes
282
+ - Por fechas para ordenamiento temporal
283
+
284
+ ### Validaciones
285
+ - Emails únicos por usuario en leads y contacts
286
+ - Phone con formato internacional
287
+ - Enums para campos de estado y tipo
288
+ - Probabilidades entre 0-100
289
+ - Montos y costos >= 0
290
+
291
+ ## Timeline de Implementación
292
+
293
+ ### Fase 1: Estructura Base (Actual)
294
+ 1. ✅ Leads (parcialmente creado)
295
+ 2. ⏳ Contacts
296
+ 3. ⏳ Companies
297
+ 4. ⏳ Pipelines
298
+
299
+ ### Fase 2: Funcionalidad Core
300
+ 5. ⏳ Opportunities
301
+ 6. ⏳ Activities
302
+ 7. ⏳ Notes
303
+
304
+ ### Fase 3: Extensiones
305
+ 8. ⏳ Products
306
+ 9. ⏳ Campaigns
307
+
308
+ ### Fase 4: Sample Data
309
+ - Crear datos relacionados coherentes
310
+ - 10 leads, 5 convertidos a contacts/companies
311
+ - 20 contacts distribuidos en 8 companies
312
+ - 15 opportunities en diferentes stages
313
+ - 50+ activities variadas
314
+ - 5 campaigns con resultados
315
+ - 30+ notes
316
+ - 10 products
317
+ - 2 pipelines (Sales, Support)
318
+
319
+ ## Notas de Desarrollo
320
+
321
+ ### Convenciones
322
+ - Tablas en plural: `leads`, `contacts`, `companies`
323
+ - Foreign keys genéricas: `entityId` en metas
324
+ - Timestamps: `createdAt`, `updatedAt`
325
+ - IDs como TEXT (UUID convertido)
326
+ - camelCase para campos (compatibilidad con JS/TS)
327
+
328
+ ### Performance
329
+ - JSONB para datos estructurados variables (stages, features, attachments)
330
+ - Índices GIN para búsquedas en JSONB
331
+ - Vistas materializadas para dashboards
332
+ - Particionamiento por fecha para activities (futuro)
333
+
334
+ ### Integración
335
+ - API REST v1 automática para todas las entidades
336
+ - GraphQL opcional via Hasura
337
+ - Webhooks para eventos importantes
338
+ - Bulk operations para imports/exports
339
+
340
+ ## Estado Actual: EN DESARROLLO
341
+
342
+ Creado: 2025-09-27
343
+ Actualizado: 2025-09-27
package/about.md ADDED
@@ -0,0 +1,122 @@
1
+ # CRM Theme
2
+
3
+ ## Objetivo
4
+
5
+ Demostrar el modo `single-tenant` donde una empresa tiene un único equipo de trabajo con múltiples usuarios y roles diferenciados para ventas, marketing y gestión.
6
+
7
+ ## Producto
8
+
9
+ **SalesForce Pro** - CRM empresarial completo para gestión de ventas, clientes y oportunidades de negocio.
10
+
11
+ ## Empresa
12
+
13
+ **Ventas Pro S.A.** - Empresa B2B de servicios tecnológicos que necesita gestionar su pipeline de ventas y relaciones con clientes de forma estructurada.
14
+
15
+ ## Teams Mode
16
+
17
+ ```
18
+ single-tenant
19
+ ```
20
+
21
+ - Work team único al registrarse (no personal)
22
+ - Sin team switcher (solo 1 equipo)
23
+ - Invitaciones habilitadas
24
+ - Sin creación de equipos adicionales
25
+
26
+ ## Entidades
27
+
28
+ | Entidad | Descripción |
29
+ |---------|-------------|
30
+ | leads | Prospectos y oportunidades iniciales |
31
+ | contacts | Contactos de clientes y empresas |
32
+ | companies | Empresas clientes |
33
+ | opportunities | Oportunidades de venta en pipeline |
34
+ | activities | Llamadas, reuniones, tareas relacionadas |
35
+ | notes | Notas y comentarios sobre entidades |
36
+ | campaigns | Campañas de marketing |
37
+ | pipelines | Configuración de etapas de venta |
38
+ | products | Catálogo de productos/servicios |
39
+
40
+ ## Features
41
+
42
+ | Feature | Descripción | Roles |
43
+ |---------|-------------|-------|
44
+ | reports.sales | Ver reportes de ventas | owner, admin |
45
+ | reports.pipeline | Ver reportes de pipeline | owner, admin |
46
+ | reports.marketing | Ver reportes de marketing | owner, admin |
47
+ | leads.convert | Convertir lead a contacto | owner, admin |
48
+ | bulk.import | Importación masiva de datos | owner |
49
+ | bulk.export | Exportación masiva de datos | owner |
50
+ | settings.pipelines | Configurar etapas de pipeline | owner |
51
+ | settings.products | Gestionar catálogo de productos | owner |
52
+ | dashboard.forecasting | Ver pronósticos de ventas | owner, admin |
53
+
54
+ ## Permisos Resumidos
55
+
56
+ | Entidad | owner | admin | member |
57
+ |---------|:-----:|:-----:|:------:|
58
+ | leads | CRUD | CRUD | CRU |
59
+ | contacts | CRUD | CRUD | CRU |
60
+ | companies | CRUD | CRUD | R |
61
+ | opportunities | CRUD | CRUD | R |
62
+ | activities | CRUD | CRUD | CRUD |
63
+ | notes | CRUD | CRUD | CRUD |
64
+ | campaigns | CRUD | CRUD | R |
65
+ | pipelines | CRUD | R | R |
66
+ | products | CRUD | R | R |
67
+
68
+ ## Usuarios de Prueba
69
+
70
+ | Email | Password | Rol | Descripción |
71
+ |-------|----------|-----|-------------|
72
+ | crm_owner_roberto@nextspark.dev | Test1234 | owner | CEO - Control total |
73
+ | crm_admin_sofia@nextspark.dev | Test1234 | admin | Sales Manager |
74
+ | crm_member_miguel@nextspark.dev | Test1234 | member | Sales Rep |
75
+ | crm_member_laura@nextspark.dev | Test1234 | member | Marketing |
76
+
77
+ ## Billing
78
+
79
+ ### Modelo de Pricing: Enterprise Tiers
80
+
81
+ > **Los planes y facturas siempre están asociados al team global único. Los tiers se basan en capacidad de usuarios.**
82
+
83
+ ### Planes Disponibles
84
+
85
+ | Plan | Mensual | Usuarios Incluidos |
86
+ |------|---------|-------------------|
87
+ | Starter | $299/mes | Hasta 10 |
88
+ | Business | $599/mes | Hasta 50 |
89
+ | Enterprise | $1,499+/mes | Ilimitados |
90
+
91
+ ### Características por Plan
92
+
93
+ | Feature | Starter | Business | Enterprise |
94
+ |---------|:-------:|:--------:|:----------:|
95
+ | Leads/Contacts | Ilimitados | Ilimitados | Ilimitados |
96
+ | Pipelines | 2 | 5 | Ilimitados |
97
+ | Productos | 10 | 50 | Ilimitados |
98
+ | Reports | Básicos | Avanzados | Custom |
99
+ | API access | ❌ | ✅ | ✅ |
100
+ | Bulk import/export | ❌ | ✅ | ✅ |
101
+ | SSO/SAML | ❌ | ❌ | ✅ |
102
+ | SLA garantizado | ❌ | ❌ | ✅ |
103
+ | Soporte dedicado | ❌ | ❌ | ✅ |
104
+
105
+ ### Facturación
106
+
107
+ - **Unidad de cobro:** Por team global (tiers por capacidad de usuarios)
108
+ - **Ciclos:** Mensual (contratos anuales con descuento disponibles bajo negociación)
109
+
110
+ ### Sample Invoices
111
+
112
+ | Team | Plan | Invoices | Status | Total |
113
+ |------|------|----------|--------|-------|
114
+ | Ventas Pro S.A. | Starter | 6 | 5 paid + 1 pending | $1,794 |
115
+
116
+ ## Casos de Uso
117
+
118
+ 1. CEO revisa pronósticos y configura pipelines
119
+ 2. Sales Manager convierte leads y genera reportes
120
+ 3. Sales Rep registra actividades y actualiza oportunidades
121
+ 4. Marketing gestiona campañas y analiza resultados
122
+
@@ -0,0 +1,185 @@
1
+ /**
2
+ * CRM Theme - Application Configuration
3
+ *
4
+ * Single-tenant mode: One organization with multiple teams/departments.
5
+ * Perfect for enterprise sales and marketing operations.
6
+ */
7
+
8
+ export const APP_CONFIG_OVERRIDES = {
9
+ // =============================================================================
10
+ // APPLICATION METADATA
11
+ // =============================================================================
12
+ app: {
13
+ name: 'CRM Enterprise',
14
+ version: '2.0.0',
15
+ },
16
+
17
+ // =============================================================================
18
+ // TEAMS CONFIGURATION - SINGLE-TENANT MODE
19
+ // =============================================================================
20
+ /**
21
+ * Single-tenant mode:
22
+ * - One work team created at signup (no personal team)
23
+ * - Owner can invite members with different roles
24
+ * - No team switching (only one organization)
25
+ * - Multi-department structure via roles
26
+ */
27
+ teams: {
28
+ mode: 'single-tenant' as const,
29
+ options: {
30
+ maxMembersPerTeam: 50,
31
+ allowLeaveTeam: false, // Controlled by admin
32
+ },
33
+ },
34
+
35
+ // =============================================================================
36
+ // INTERNATIONALIZATION
37
+ // =============================================================================
38
+ i18n: {
39
+ supportedLocales: ['en', 'es'],
40
+ defaultLocale: 'en' as const,
41
+ namespaces: [
42
+ 'common',
43
+ 'dashboard',
44
+ 'settings',
45
+ 'auth',
46
+ 'validation',
47
+ // CRM entities
48
+ 'leads',
49
+ 'contacts',
50
+ 'companies',
51
+ 'opportunities',
52
+ 'activities',
53
+ 'campaigns',
54
+ 'notes',
55
+ 'products',
56
+ 'pipelines',
57
+ // Theme specific
58
+ 'crm',
59
+ ],
60
+ },
61
+
62
+ // =============================================================================
63
+ // API CONFIGURATION
64
+ // =============================================================================
65
+ api: {
66
+ cors: {
67
+ allowedOrigins: {
68
+ development: [
69
+ 'http://localhost:3000',
70
+ 'http://localhost:5173',
71
+ ],
72
+ production: [],
73
+ },
74
+ },
75
+ },
76
+
77
+ // =============================================================================
78
+ // DOCUMENTATION
79
+ // =============================================================================
80
+ docs: {
81
+ enabled: true,
82
+ public: false,
83
+ searchEnabled: true,
84
+ breadcrumbs: true,
85
+ theme: {
86
+ enabled: true,
87
+ open: true,
88
+ label: "CRM Theme",
89
+ },
90
+ plugins: {
91
+ enabled: false,
92
+ open: false,
93
+ label: "Plugins",
94
+ },
95
+ core: {
96
+ enabled: true,
97
+ open: false,
98
+ label: "Core",
99
+ },
100
+ showPluginsDocsInProd: false,
101
+ },
102
+
103
+ // =============================================================================
104
+ // SCHEDULED ACTIONS (CRM needs more history and higher throughput)
105
+ // =============================================================================
106
+ scheduledActions: {
107
+ enabled: true,
108
+ retentionDays: 14, // CRM needs more history for auditing
109
+ batchSize: 20, // CRM has more scheduled actions
110
+ defaultTimeout: 45000, // Longer timeout for CRM integrations
111
+ },
112
+
113
+ // =============================================================================
114
+ // MOBILE NAVIGATION
115
+ // =============================================================================
116
+ mobileNav: {
117
+ items: [
118
+ {
119
+ id: 'home',
120
+ labelKey: 'common.mobileNav.home',
121
+ href: '/dashboard',
122
+ icon: 'Home',
123
+ enabled: true,
124
+ },
125
+ {
126
+ id: 'leads',
127
+ labelKey: 'crm.navigation.leads',
128
+ href: '/dashboard/leads',
129
+ icon: 'UserSearch',
130
+ enabled: true,
131
+ },
132
+ {
133
+ id: 'create',
134
+ labelKey: 'common.mobileNav.create',
135
+ icon: 'Plus',
136
+ isCentral: true,
137
+ action: 'quickCreate',
138
+ enabled: true,
139
+ },
140
+ {
141
+ id: 'opportunities',
142
+ labelKey: 'crm.navigation.opportunities',
143
+ href: '/dashboard/opportunities',
144
+ icon: 'TrendingUp',
145
+ enabled: true,
146
+ },
147
+ {
148
+ id: 'settings',
149
+ labelKey: 'common.mobileNav.settings',
150
+ href: '/dashboard/settings',
151
+ icon: 'Settings',
152
+ enabled: true,
153
+ },
154
+ ],
155
+ moreSheetItems: [
156
+ {
157
+ id: 'contacts',
158
+ labelKey: 'crm.navigation.contacts',
159
+ href: '/dashboard/contacts',
160
+ icon: 'Users',
161
+ enabled: true,
162
+ },
163
+ {
164
+ id: 'companies',
165
+ labelKey: 'crm.navigation.companies',
166
+ href: '/dashboard/companies',
167
+ icon: 'Building2',
168
+ enabled: true,
169
+ },
170
+ {
171
+ id: 'activities',
172
+ labelKey: 'crm.navigation.activities',
173
+ href: '/dashboard/activities',
174
+ icon: 'Calendar',
175
+ enabled: true,
176
+ },
177
+ ],
178
+ },
179
+
180
+ // =============================================================================
181
+ // DEV KEYRING - MOVED TO dev.config.ts
182
+ // =============================================================================
183
+ // DevKeyring configuration has been moved to config/dev.config.ts
184
+ // This separates development-only settings from production configuration.
185
+ }