@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.
- package/CRM_PLAN.md +343 -0
- package/about.md +122 -0
- package/config/app.config.ts +185 -0
- package/config/billing.config.ts +187 -0
- package/config/dashboard.config.ts +372 -0
- package/config/dev.config.ts +55 -0
- package/config/features.config.ts +336 -0
- package/config/flows.config.ts +511 -0
- package/config/permissions.config.ts +297 -0
- package/config/theme.config.ts +111 -0
- package/entities/activities/activities.config.ts +61 -0
- package/entities/activities/activities.fields.ts +362 -0
- package/entities/activities/activities.service.ts +503 -0
- package/entities/activities/activities.types.ts +117 -0
- package/entities/activities/messages/en.json +123 -0
- package/entities/activities/messages/es.json +123 -0
- package/entities/activities/migrations/020_activities_table.sql +123 -0
- package/entities/activities/migrations/021_activities_metas.sql +114 -0
- package/entities/activities/migrations/022_activities_sample_data.sql +420 -0
- package/entities/campaigns/campaigns.config.ts +61 -0
- package/entities/campaigns/campaigns.fields.ts +413 -0
- package/entities/campaigns/campaigns.service.ts +426 -0
- package/entities/campaigns/campaigns.types.ts +124 -0
- package/entities/campaigns/messages/en.json +145 -0
- package/entities/campaigns/messages/es.json +145 -0
- package/entities/campaigns/migrations/001_campaigns_table.sql +127 -0
- package/entities/campaigns/migrations/002_campaigns_metas.sql +114 -0
- package/entities/campaigns/migrations/003_campaigns_sample_data.sql +364 -0
- package/entities/companies/companies.config.ts +61 -0
- package/entities/companies/companies.fields.ts +429 -0
- package/entities/companies/companies.service.ts +566 -0
- package/entities/companies/companies.types.ts +125 -0
- package/entities/companies/messages/en.json +146 -0
- package/entities/companies/messages/es.json +146 -0
- package/entities/companies/migrations/001_companies_table.sql +150 -0
- package/entities/companies/migrations/002_companies_metas.sql +114 -0
- package/entities/companies/migrations/003_companies_sample_data.sql +246 -0
- package/entities/contacts/contacts.config.ts +61 -0
- package/entities/contacts/contacts.fields.ts +359 -0
- package/entities/contacts/contacts.service.ts +509 -0
- package/entities/contacts/contacts.types.ts +108 -0
- package/entities/contacts/messages/en.json +117 -0
- package/entities/contacts/messages/es.json +117 -0
- package/entities/contacts/migrations/001_contacts_table.sql +134 -0
- package/entities/contacts/migrations/002_contacts_metas.sql +114 -0
- package/entities/contacts/migrations/003_contacts_sample_data.sql +421 -0
- package/entities/leads/leads.config.ts +61 -0
- package/entities/leads/leads.fields.ts +336 -0
- package/entities/leads/leads.service.ts +496 -0
- package/entities/leads/leads.types.ts +114 -0
- package/entities/leads/messages/en.json +132 -0
- package/entities/leads/messages/es.json +132 -0
- package/entities/leads/migrations/001_leads_table.sql +150 -0
- package/entities/leads/migrations/002_leads_metas.sql +120 -0
- package/entities/leads/migrations/003_leads_sample_data.sql +242 -0
- package/entities/notes/messages/en.json +114 -0
- package/entities/notes/messages/es.json +114 -0
- package/entities/notes/migrations/020_notes_table.sql +118 -0
- package/entities/notes/migrations/021_notes_metas.sql +114 -0
- package/entities/notes/migrations/022_notes_sample_data.sql +275 -0
- package/entities/notes/notes.config.ts +61 -0
- package/entities/notes/notes.fields.ts +283 -0
- package/entities/notes/notes.service.ts +320 -0
- package/entities/notes/notes.types.ts +102 -0
- package/entities/opportunities/messages/en.json +107 -0
- package/entities/opportunities/messages/es.json +107 -0
- package/entities/opportunities/migrations/010_opportunities_table.sql +145 -0
- package/entities/opportunities/migrations/011_opportunities_metas.sql +114 -0
- package/entities/opportunities/migrations/012_opportunities_sample_data.sql +438 -0
- package/entities/opportunities/opportunities.config.ts +61 -0
- package/entities/opportunities/opportunities.fields.ts +416 -0
- package/entities/opportunities/opportunities.service.ts +525 -0
- package/entities/opportunities/opportunities.types.ts +135 -0
- package/entities/pipelines/messages/en.json +115 -0
- package/entities/pipelines/messages/es.json +115 -0
- package/entities/pipelines/migrations/001_pipelines_table.sql +106 -0
- package/entities/pipelines/migrations/002_pipelines_metas.sql +114 -0
- package/entities/pipelines/migrations/003_pipelines_sample_data.sql +91 -0
- package/entities/pipelines/pipelines.config.ts +62 -0
- package/entities/pipelines/pipelines.fields.ts +193 -0
- package/entities/pipelines/pipelines.service.ts +383 -0
- package/entities/pipelines/pipelines.types.ts +78 -0
- package/entities/products/messages/en.json +135 -0
- package/entities/products/messages/es.json +135 -0
- package/entities/products/migrations/001_products_table.sql +117 -0
- package/entities/products/migrations/002_products_metas.sql +114 -0
- package/entities/products/migrations/003_products_sample_data.sql +247 -0
- package/entities/products/products.config.ts +62 -0
- package/entities/products/products.fields.ts +361 -0
- package/entities/products/products.service.ts +437 -0
- package/entities/products/products.types.ts +125 -0
- package/lib/crm-constants.ts +77 -0
- package/lib/crm-utils.ts +185 -0
- package/lib/selectors.ts +333 -0
- package/messages/en.json +131 -0
- package/messages/es.json +131 -0
- package/migrations/999_theme_sample_data.sql +473 -0
- package/package.json +18 -0
- package/pendings.md +205 -0
- package/permissions-matrix.md +216 -0
- package/styles/components.css +414 -0
- package/styles/crm-theme.css +358 -0
- package/styles/globals.css +576 -0
- package/styles/variables.css +111 -0
- package/templates/dashboard/(main)/activities/components/ActivityCard.tsx +169 -0
- package/templates/dashboard/(main)/activities/components/ActivityTimeline.tsx +165 -0
- package/templates/dashboard/(main)/activities/page.tsx +297 -0
- package/templates/dashboard/(main)/campaigns/page.tsx +373 -0
- package/templates/dashboard/(main)/companies/page.tsx +296 -0
- package/templates/dashboard/(main)/contacts/page.tsx +347 -0
- package/templates/dashboard/(main)/layout.tsx +98 -0
- package/templates/dashboard/(main)/leads/page.tsx +335 -0
- package/templates/dashboard/(main)/opportunities/[id]/edit/page.tsx +95 -0
- package/templates/dashboard/(main)/opportunities/create/page.tsx +94 -0
- package/templates/dashboard/(main)/opportunities/page.tsx +350 -0
- package/templates/dashboard/(main)/pipelines/[id]/edit/page.tsx +95 -0
- package/templates/dashboard/(main)/pipelines/[id]/page.tsx +143 -0
- package/templates/dashboard/(main)/pipelines/create/page.tsx +94 -0
- package/templates/dashboard/(main)/pipelines/page.tsx +234 -0
- package/templates/dashboard/(main)/products/[id]/edit/page.tsx +97 -0
- package/templates/dashboard/(main)/products/[id]/page.tsx +509 -0
- package/templates/dashboard/(main)/products/create/page.tsx +96 -0
- package/templates/dashboard/(main)/products/page.tsx +308 -0
- package/templates/shared/ActionButtons.tsx +41 -0
- package/templates/shared/CRMDashboard.tsx +519 -0
- package/templates/shared/CRMDataTable.tsx +441 -0
- package/templates/shared/CRMMetricCard.tsx +76 -0
- package/templates/shared/CRMMobileNav.tsx +172 -0
- package/templates/shared/CRMSidebar.tsx +346 -0
- package/templates/shared/CRMTopBar.tsx +265 -0
- package/templates/shared/DealCard.tsx +123 -0
- package/templates/shared/EntityCard.tsx +58 -0
- package/templates/shared/OpportunityForm.tsx +649 -0
- package/templates/shared/PipelineForm.tsx +367 -0
- package/templates/shared/PipelineKanban.tsx +194 -0
- package/templates/shared/QuickFilters.tsx +47 -0
- package/templates/shared/StageColumn.tsx +175 -0
- package/templates/shared/StageSelect.tsx +177 -0
- package/templates/shared/StagesRepeater.tsx +317 -0
- package/templates/shared/index.ts +9 -0
package/messages/es.json
ADDED
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
{
|
|
2
|
+
"crm": {
|
|
3
|
+
"name": "CRM Enterprise",
|
|
4
|
+
"description": "Solución CRM completa para equipos de ventas y marketing",
|
|
5
|
+
"tagline": "Cierra más negocios, haz crecer tu empresa",
|
|
6
|
+
|
|
7
|
+
"navigation": {
|
|
8
|
+
"leads": "Prospectos",
|
|
9
|
+
"contacts": "Contactos",
|
|
10
|
+
"companies": "Empresas",
|
|
11
|
+
"opportunities": "Oportunidades",
|
|
12
|
+
"activities": "Actividades",
|
|
13
|
+
"campaigns": "Campañas",
|
|
14
|
+
"reports": "Reportes",
|
|
15
|
+
"settings": "Configuración"
|
|
16
|
+
},
|
|
17
|
+
|
|
18
|
+
"quickActions": {
|
|
19
|
+
"newLead": "Nuevo Prospecto",
|
|
20
|
+
"newContact": "Nuevo Contacto",
|
|
21
|
+
"newCompany": "Nueva Empresa",
|
|
22
|
+
"newOpportunity": "Nueva Oportunidad",
|
|
23
|
+
"scheduleActivity": "Programar Actividad",
|
|
24
|
+
"createCampaign": "Crear Campaña"
|
|
25
|
+
},
|
|
26
|
+
|
|
27
|
+
"dashboard": {
|
|
28
|
+
"welcome": "¡Bienvenido de nuevo!",
|
|
29
|
+
"welcomeWithName": "¡Bienvenido de nuevo, {name}!",
|
|
30
|
+
"overview": "Resumen de Ventas",
|
|
31
|
+
"pipelineValue": "Valor del Pipeline",
|
|
32
|
+
"openDeals": "Negocios Abiertos",
|
|
33
|
+
"wonThisMonth": "Ganados Este Mes",
|
|
34
|
+
"conversionRate": "Tasa de Conversión",
|
|
35
|
+
"upcomingActivities": "Próximas Actividades",
|
|
36
|
+
"recentLeads": "Prospectos Recientes",
|
|
37
|
+
"topOpportunities": "Mejores Oportunidades"
|
|
38
|
+
},
|
|
39
|
+
|
|
40
|
+
"pipeline": {
|
|
41
|
+
"title": "Pipeline de Ventas",
|
|
42
|
+
"totalValue": "Valor Total",
|
|
43
|
+
"dealCount": "Negocios",
|
|
44
|
+
"stages": {
|
|
45
|
+
"qualification": "Calificación",
|
|
46
|
+
"needsAnalysis": "Análisis de Necesidades",
|
|
47
|
+
"proposal": "Propuesta",
|
|
48
|
+
"negotiation": "Negociación",
|
|
49
|
+
"closedWon": "Ganado",
|
|
50
|
+
"closedLost": "Perdido"
|
|
51
|
+
}
|
|
52
|
+
},
|
|
53
|
+
|
|
54
|
+
"reports": {
|
|
55
|
+
"title": "Reportes",
|
|
56
|
+
"sales": "Reporte de Ventas",
|
|
57
|
+
"marketing": "Reporte de Marketing",
|
|
58
|
+
"pipeline": "Reporte de Pipeline",
|
|
59
|
+
"activity": "Reporte de Actividades",
|
|
60
|
+
"forecast": "Pronóstico de Ventas"
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
"features": {
|
|
64
|
+
"convert": {
|
|
65
|
+
"title": "Convertir Prospecto",
|
|
66
|
+
"description": "Convertir este prospecto en contacto y empresa",
|
|
67
|
+
"createContact": "Crear Contacto",
|
|
68
|
+
"createCompany": "Crear Empresa",
|
|
69
|
+
"success": "Prospecto convertido exitosamente",
|
|
70
|
+
"alreadyConverted": "Este prospecto ya ha sido convertido"
|
|
71
|
+
},
|
|
72
|
+
"bulkImport": {
|
|
73
|
+
"title": "Importar Datos",
|
|
74
|
+
"description": "Importar datos desde archivo CSV o Excel",
|
|
75
|
+
"selectFile": "Seleccionar archivo",
|
|
76
|
+
"mapping": "Mapear columnas",
|
|
77
|
+
"preview": "Vista previa",
|
|
78
|
+
"import": "Importar"
|
|
79
|
+
},
|
|
80
|
+
"bulkExport": {
|
|
81
|
+
"title": "Exportar Datos",
|
|
82
|
+
"description": "Exportar datos a archivo CSV o Excel",
|
|
83
|
+
"allRecords": "Todos los registros",
|
|
84
|
+
"selectedRecords": "Registros seleccionados",
|
|
85
|
+
"filteredRecords": "Registros filtrados"
|
|
86
|
+
}
|
|
87
|
+
},
|
|
88
|
+
|
|
89
|
+
"roles": {
|
|
90
|
+
"owner": "Administrador",
|
|
91
|
+
"admin": "Gerente",
|
|
92
|
+
"member": "Representante",
|
|
93
|
+
"viewer": "Visor",
|
|
94
|
+
"descriptions": {
|
|
95
|
+
"owner": "Acceso completo a todas las funciones y configuraciones del CRM",
|
|
96
|
+
"admin": "Puede gestionar equipo, ver reportes y realizar operaciones masivas",
|
|
97
|
+
"member": "Puede gestionar prospectos, contactos, oportunidades y actividades",
|
|
98
|
+
"viewer": "Acceso de solo lectura a los datos del CRM"
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
|
|
102
|
+
"stats": {
|
|
103
|
+
"totalLeads": "Total de Prospectos",
|
|
104
|
+
"qualifiedLeads": "Prospectos Calificados",
|
|
105
|
+
"totalOpportunities": "Total de Oportunidades",
|
|
106
|
+
"wonOpportunities": "Oportunidades Ganadas",
|
|
107
|
+
"pipelineValue": "Valor del Pipeline",
|
|
108
|
+
"avgDealSize": "Tamaño Promedio",
|
|
109
|
+
"winRate": "Tasa de Éxito",
|
|
110
|
+
"activeCampaigns": "Campañas Activas"
|
|
111
|
+
},
|
|
112
|
+
|
|
113
|
+
"empty": {
|
|
114
|
+
"noLeads": {
|
|
115
|
+
"title": "Aún no hay prospectos",
|
|
116
|
+
"description": "Comienza a capturar prospectos para hacer crecer tu pipeline.",
|
|
117
|
+
"action": "Agregar tu primer prospecto"
|
|
118
|
+
},
|
|
119
|
+
"noOpportunities": {
|
|
120
|
+
"title": "Aún no hay oportunidades",
|
|
121
|
+
"description": "Crea oportunidades a partir de prospectos calificados.",
|
|
122
|
+
"action": "Crear oportunidad"
|
|
123
|
+
},
|
|
124
|
+
"noActivities": {
|
|
125
|
+
"title": "No hay actividades programadas",
|
|
126
|
+
"description": "Programa llamadas, reuniones y tareas.",
|
|
127
|
+
"action": "Programar actividad"
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
}
|
|
@@ -0,0 +1,473 @@
|
|
|
1
|
+
-- ============================================================================
|
|
2
|
+
-- CRM Theme - Sample Data Migration
|
|
3
|
+
-- Scenario: Single-tenant (one company, multiple users with different roles)
|
|
4
|
+
-- Teams Mode: single-tenant
|
|
5
|
+
-- ============================================================================
|
|
6
|
+
|
|
7
|
+
-- ============================================
|
|
8
|
+
-- STEP 0: CLEANUP (preserves superadmin)
|
|
9
|
+
-- ============================================
|
|
10
|
+
DO $$
|
|
11
|
+
DECLARE
|
|
12
|
+
v_superadmin_id TEXT;
|
|
13
|
+
BEGIN
|
|
14
|
+
-- Get superadmin ID to preserve
|
|
15
|
+
SELECT id INTO v_superadmin_id FROM "users" WHERE role = 'superadmin' LIMIT 1;
|
|
16
|
+
|
|
17
|
+
-- Clean theme entities (if tables exist)
|
|
18
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'notes') THEN
|
|
19
|
+
TRUNCATE "notes" CASCADE;
|
|
20
|
+
END IF;
|
|
21
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'activities') THEN
|
|
22
|
+
TRUNCATE "activities" CASCADE;
|
|
23
|
+
END IF;
|
|
24
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'opportunities') THEN
|
|
25
|
+
TRUNCATE "opportunities" CASCADE;
|
|
26
|
+
END IF;
|
|
27
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'campaigns') THEN
|
|
28
|
+
TRUNCATE "campaigns" CASCADE;
|
|
29
|
+
END IF;
|
|
30
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'contacts') THEN
|
|
31
|
+
TRUNCATE "contacts" CASCADE;
|
|
32
|
+
END IF;
|
|
33
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'leads') THEN
|
|
34
|
+
TRUNCATE "leads" CASCADE;
|
|
35
|
+
END IF;
|
|
36
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'companies') THEN
|
|
37
|
+
TRUNCATE "companies" CASCADE;
|
|
38
|
+
END IF;
|
|
39
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'products') THEN
|
|
40
|
+
TRUNCATE "products" CASCADE;
|
|
41
|
+
END IF;
|
|
42
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'pipelines') THEN
|
|
43
|
+
TRUNCATE "pipelines" CASCADE;
|
|
44
|
+
END IF;
|
|
45
|
+
IF EXISTS (SELECT 1 FROM information_schema.tables WHERE table_name = 'invoices') THEN
|
|
46
|
+
TRUNCATE "invoices" CASCADE;
|
|
47
|
+
END IF;
|
|
48
|
+
|
|
49
|
+
-- Note: personal team deletion trigger removed in simplified architecture
|
|
50
|
+
|
|
51
|
+
-- Clean team-related data (except superadmin's)
|
|
52
|
+
IF v_superadmin_id IS NOT NULL THEN
|
|
53
|
+
DELETE FROM "api_audit_log" WHERE "userId" != v_superadmin_id;
|
|
54
|
+
DELETE FROM "api_key" WHERE "userId" != v_superadmin_id;
|
|
55
|
+
DELETE FROM "team_members" WHERE "userId" != v_superadmin_id;
|
|
56
|
+
DELETE FROM "teams" WHERE "ownerId" != v_superadmin_id;
|
|
57
|
+
DELETE FROM "users_metas" WHERE "userId" != v_superadmin_id;
|
|
58
|
+
DELETE FROM "session" WHERE "userId" != v_superadmin_id;
|
|
59
|
+
DELETE FROM "account" WHERE "userId" != v_superadmin_id;
|
|
60
|
+
DELETE FROM "users" WHERE id != v_superadmin_id;
|
|
61
|
+
ELSE
|
|
62
|
+
DELETE FROM "api_audit_log";
|
|
63
|
+
DELETE FROM "api_key";
|
|
64
|
+
DELETE FROM "team_members";
|
|
65
|
+
DELETE FROM "teams";
|
|
66
|
+
DELETE FROM "users_metas";
|
|
67
|
+
DELETE FROM "session";
|
|
68
|
+
DELETE FROM "account";
|
|
69
|
+
DELETE FROM "users";
|
|
70
|
+
END IF;
|
|
71
|
+
|
|
72
|
+
-- Cleanup complete
|
|
73
|
+
|
|
74
|
+
RAISE NOTICE 'CRM theme cleanup complete. Superadmin preserved.';
|
|
75
|
+
END $$;
|
|
76
|
+
|
|
77
|
+
-- ============================================
|
|
78
|
+
-- STEP 1: CREATE USERS
|
|
79
|
+
-- ============================================
|
|
80
|
+
-- Single-tenant: 4 users in one company with different roles
|
|
81
|
+
|
|
82
|
+
INSERT INTO "users" (
|
|
83
|
+
id,
|
|
84
|
+
email,
|
|
85
|
+
name,
|
|
86
|
+
"firstName",
|
|
87
|
+
"lastName",
|
|
88
|
+
role,
|
|
89
|
+
"emailVerified",
|
|
90
|
+
language,
|
|
91
|
+
country,
|
|
92
|
+
timezone,
|
|
93
|
+
"createdAt",
|
|
94
|
+
"updatedAt"
|
|
95
|
+
) VALUES
|
|
96
|
+
-- CEO / Owner
|
|
97
|
+
(
|
|
98
|
+
'usr-crm-ceo',
|
|
99
|
+
'crm_owner_roberto@nextspark.dev',
|
|
100
|
+
'Roberto Martínez',
|
|
101
|
+
'Roberto',
|
|
102
|
+
'Martínez',
|
|
103
|
+
'member',
|
|
104
|
+
true,
|
|
105
|
+
'es',
|
|
106
|
+
'ES',
|
|
107
|
+
'Europe/Madrid',
|
|
108
|
+
NOW(),
|
|
109
|
+
NOW()
|
|
110
|
+
),
|
|
111
|
+
-- Sales Manager / Admin
|
|
112
|
+
(
|
|
113
|
+
'usr-crm-sales-mgr',
|
|
114
|
+
'crm_admin_sofia@nextspark.dev',
|
|
115
|
+
'Sofía Gómez',
|
|
116
|
+
'Sofía',
|
|
117
|
+
'Gómez',
|
|
118
|
+
'member',
|
|
119
|
+
true,
|
|
120
|
+
'es',
|
|
121
|
+
'AR',
|
|
122
|
+
'America/Argentina/Buenos_Aires',
|
|
123
|
+
NOW(),
|
|
124
|
+
NOW()
|
|
125
|
+
),
|
|
126
|
+
-- Sales Rep / Member
|
|
127
|
+
(
|
|
128
|
+
'usr-crm-sales-rep',
|
|
129
|
+
'crm_member_miguel@nextspark.dev',
|
|
130
|
+
'Miguel Castro',
|
|
131
|
+
'Miguel',
|
|
132
|
+
'Castro',
|
|
133
|
+
'member',
|
|
134
|
+
true,
|
|
135
|
+
'es',
|
|
136
|
+
'MX',
|
|
137
|
+
'America/Mexico_City',
|
|
138
|
+
NOW(),
|
|
139
|
+
NOW()
|
|
140
|
+
),
|
|
141
|
+
-- Marketing / Member
|
|
142
|
+
(
|
|
143
|
+
'usr-crm-marketing',
|
|
144
|
+
'crm_member_laura@nextspark.dev',
|
|
145
|
+
'Laura Vega',
|
|
146
|
+
'Laura',
|
|
147
|
+
'Vega',
|
|
148
|
+
'member',
|
|
149
|
+
true,
|
|
150
|
+
'en',
|
|
151
|
+
'US',
|
|
152
|
+
'America/New_York',
|
|
153
|
+
NOW(),
|
|
154
|
+
NOW()
|
|
155
|
+
)
|
|
156
|
+
ON CONFLICT (email) DO NOTHING;
|
|
157
|
+
|
|
158
|
+
-- ============================================
|
|
159
|
+
-- STEP 2: CREATE TEAM
|
|
160
|
+
-- ============================================
|
|
161
|
+
-- Single-tenant: Only ONE work team (the company)
|
|
162
|
+
|
|
163
|
+
INSERT INTO "teams" (
|
|
164
|
+
id,
|
|
165
|
+
name,
|
|
166
|
+
slug,
|
|
167
|
+
description,
|
|
168
|
+
"ownerId",
|
|
169
|
+
"createdAt",
|
|
170
|
+
"updatedAt"
|
|
171
|
+
) VALUES
|
|
172
|
+
(
|
|
173
|
+
'team-crm-company',
|
|
174
|
+
'Ventas Pro S.A.',
|
|
175
|
+
'ventas-pro-sa',
|
|
176
|
+
'Enterprise CRM for Ventas Pro sales team',
|
|
177
|
+
'usr-crm-ceo',
|
|
178
|
+
NOW(),
|
|
179
|
+
NOW()
|
|
180
|
+
)
|
|
181
|
+
ON CONFLICT (id) DO NOTHING;
|
|
182
|
+
|
|
183
|
+
-- ============================================
|
|
184
|
+
-- STEP 3: CREATE TEAM MEMBERSHIPS
|
|
185
|
+
-- ============================================
|
|
186
|
+
|
|
187
|
+
INSERT INTO "team_members" (
|
|
188
|
+
id,
|
|
189
|
+
"teamId",
|
|
190
|
+
"userId",
|
|
191
|
+
role,
|
|
192
|
+
"joinedAt"
|
|
193
|
+
) VALUES
|
|
194
|
+
-- Owner - CEO has full control
|
|
195
|
+
('tm-crm-ceo', 'team-crm-company', 'usr-crm-ceo', 'owner', NOW()),
|
|
196
|
+
-- Admin - Sales Manager can manage team
|
|
197
|
+
('tm-crm-sales-mgr', 'team-crm-company', 'usr-crm-sales-mgr', 'admin', NOW()),
|
|
198
|
+
-- Member - Sales Rep can work with leads/contacts
|
|
199
|
+
('tm-crm-sales-rep', 'team-crm-company', 'usr-crm-sales-rep', 'member', NOW()),
|
|
200
|
+
-- Member - Marketing focuses on campaigns
|
|
201
|
+
('tm-crm-marketing', 'team-crm-company', 'usr-crm-marketing', 'member', NOW())
|
|
202
|
+
ON CONFLICT (id) DO NOTHING;
|
|
203
|
+
|
|
204
|
+
-- ============================================
|
|
205
|
+
-- STEP 4: CREATE ACCOUNTS (Password: Test1234)
|
|
206
|
+
-- ============================================
|
|
207
|
+
|
|
208
|
+
INSERT INTO "account" (
|
|
209
|
+
id,
|
|
210
|
+
"userId",
|
|
211
|
+
"accountId",
|
|
212
|
+
"providerId",
|
|
213
|
+
"accessToken",
|
|
214
|
+
"refreshToken",
|
|
215
|
+
"idToken",
|
|
216
|
+
"accessTokenExpiresAt",
|
|
217
|
+
"refreshTokenExpiresAt",
|
|
218
|
+
"scope",
|
|
219
|
+
"password",
|
|
220
|
+
"createdAt",
|
|
221
|
+
"updatedAt"
|
|
222
|
+
) VALUES
|
|
223
|
+
(
|
|
224
|
+
'acc-crm-ceo',
|
|
225
|
+
'usr-crm-ceo',
|
|
226
|
+
'crm_owner_roberto@nextspark.dev',
|
|
227
|
+
'credential',
|
|
228
|
+
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
229
|
+
'3db9e98e2b4d3caca97fdf2783791cbc:34b293de615caf277a237773208858e960ea8aa10f1f5c5c309b632f192cac34d52ceafbd338385616f4929e4b1b6c055b67429c6722ffdb80b01d9bf4764866',
|
|
230
|
+
NOW(),
|
|
231
|
+
NOW()
|
|
232
|
+
),
|
|
233
|
+
(
|
|
234
|
+
'acc-crm-sales-mgr',
|
|
235
|
+
'usr-crm-sales-mgr',
|
|
236
|
+
'crm_admin_sofia@nextspark.dev',
|
|
237
|
+
'credential',
|
|
238
|
+
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
239
|
+
'3db9e98e2b4d3caca97fdf2783791cbc:34b293de615caf277a237773208858e960ea8aa10f1f5c5c309b632f192cac34d52ceafbd338385616f4929e4b1b6c055b67429c6722ffdb80b01d9bf4764866',
|
|
240
|
+
NOW(),
|
|
241
|
+
NOW()
|
|
242
|
+
),
|
|
243
|
+
(
|
|
244
|
+
'acc-crm-sales-rep',
|
|
245
|
+
'usr-crm-sales-rep',
|
|
246
|
+
'crm_member_miguel@nextspark.dev',
|
|
247
|
+
'credential',
|
|
248
|
+
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
249
|
+
'3db9e98e2b4d3caca97fdf2783791cbc:34b293de615caf277a237773208858e960ea8aa10f1f5c5c309b632f192cac34d52ceafbd338385616f4929e4b1b6c055b67429c6722ffdb80b01d9bf4764866',
|
|
250
|
+
NOW(),
|
|
251
|
+
NOW()
|
|
252
|
+
),
|
|
253
|
+
(
|
|
254
|
+
'acc-crm-marketing',
|
|
255
|
+
'usr-crm-marketing',
|
|
256
|
+
'crm_member_laura@nextspark.dev',
|
|
257
|
+
'credential',
|
|
258
|
+
NULL, NULL, NULL, NULL, NULL, NULL,
|
|
259
|
+
'3db9e98e2b4d3caca97fdf2783791cbc:34b293de615caf277a237773208858e960ea8aa10f1f5c5c309b632f192cac34d52ceafbd338385616f4929e4b1b6c055b67429c6722ffdb80b01d9bf4764866',
|
|
260
|
+
NOW(),
|
|
261
|
+
NOW()
|
|
262
|
+
)
|
|
263
|
+
ON CONFLICT ("providerId", "accountId") DO NOTHING;
|
|
264
|
+
|
|
265
|
+
-- ============================================
|
|
266
|
+
-- STEP 5: CREATE USER METADATA
|
|
267
|
+
-- ============================================
|
|
268
|
+
|
|
269
|
+
INSERT INTO "users_metas" (
|
|
270
|
+
"userId",
|
|
271
|
+
"metaKey",
|
|
272
|
+
"metaValue",
|
|
273
|
+
"dataType",
|
|
274
|
+
"isPublic",
|
|
275
|
+
"isSearchable",
|
|
276
|
+
"createdAt",
|
|
277
|
+
"updatedAt"
|
|
278
|
+
) VALUES
|
|
279
|
+
('usr-crm-ceo', 'activeTeamId', '"team-crm-company"', 'json', false, false, NOW(), NOW()),
|
|
280
|
+
('usr-crm-ceo', 'uiPreferences', '{"theme": "light", "sidebarCollapsed": false}', 'json', false, false, NOW(), NOW()),
|
|
281
|
+
('usr-crm-sales-mgr', 'activeTeamId', '"team-crm-company"', 'json', false, false, NOW(), NOW()),
|
|
282
|
+
('usr-crm-sales-mgr', 'uiPreferences', '{"theme": "light", "sidebarCollapsed": false}', 'json', false, false, NOW(), NOW()),
|
|
283
|
+
('usr-crm-sales-rep', 'activeTeamId', '"team-crm-company"', 'json', false, false, NOW(), NOW()),
|
|
284
|
+
('usr-crm-sales-rep', 'uiPreferences', '{"theme": "dark", "sidebarCollapsed": false}', 'json', false, false, NOW(), NOW()),
|
|
285
|
+
('usr-crm-marketing', 'activeTeamId', '"team-crm-company"', 'json', false, false, NOW(), NOW()),
|
|
286
|
+
('usr-crm-marketing', 'uiPreferences', '{"theme": "light", "sidebarCollapsed": false}', 'json', false, false, NOW(), NOW())
|
|
287
|
+
ON CONFLICT ("userId", "metaKey") DO NOTHING;
|
|
288
|
+
|
|
289
|
+
-- ============================================
|
|
290
|
+
-- STEP 6: CREATE API KEYS
|
|
291
|
+
-- ============================================
|
|
292
|
+
|
|
293
|
+
INSERT INTO "api_key" (
|
|
294
|
+
id,
|
|
295
|
+
"userId",
|
|
296
|
+
name,
|
|
297
|
+
"keyHash",
|
|
298
|
+
"keyPrefix",
|
|
299
|
+
scopes,
|
|
300
|
+
"expiresAt",
|
|
301
|
+
"createdAt",
|
|
302
|
+
"updatedAt",
|
|
303
|
+
status
|
|
304
|
+
) VALUES
|
|
305
|
+
(
|
|
306
|
+
'apikey-crm-ceo',
|
|
307
|
+
'usr-crm-ceo',
|
|
308
|
+
'CEO API Key',
|
|
309
|
+
'd1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2',
|
|
310
|
+
'testkey_crm00001',
|
|
311
|
+
ARRAY['*'],
|
|
312
|
+
NULL,
|
|
313
|
+
NOW(),
|
|
314
|
+
NOW(),
|
|
315
|
+
'active'
|
|
316
|
+
),
|
|
317
|
+
(
|
|
318
|
+
'apikey-crm-sales-mgr',
|
|
319
|
+
'usr-crm-sales-mgr',
|
|
320
|
+
'Sales Manager API Key',
|
|
321
|
+
'e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3',
|
|
322
|
+
'testkey_crm00002',
|
|
323
|
+
ARRAY['leads:read', 'leads:write', 'contacts:read', 'contacts:write', 'opportunities:read', 'opportunities:write'],
|
|
324
|
+
NULL,
|
|
325
|
+
NOW(),
|
|
326
|
+
NOW(),
|
|
327
|
+
'active'
|
|
328
|
+
),
|
|
329
|
+
(
|
|
330
|
+
'apikey-crm-sales-rep',
|
|
331
|
+
'usr-crm-sales-rep',
|
|
332
|
+
'Sales Rep API Key',
|
|
333
|
+
'f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4',
|
|
334
|
+
'testkey_crm00003',
|
|
335
|
+
ARRAY['leads:read', 'leads:write', 'contacts:read', 'opportunities:read'],
|
|
336
|
+
NULL,
|
|
337
|
+
NOW(),
|
|
338
|
+
NOW(),
|
|
339
|
+
'active'
|
|
340
|
+
),
|
|
341
|
+
(
|
|
342
|
+
'apikey-crm-marketing',
|
|
343
|
+
'usr-crm-marketing',
|
|
344
|
+
'Marketing API Key',
|
|
345
|
+
'a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5c6d1e2f3a4b5',
|
|
346
|
+
'testkey_crm00004',
|
|
347
|
+
ARRAY['campaigns:read', 'campaigns:write', 'leads:read'],
|
|
348
|
+
NULL,
|
|
349
|
+
NOW(),
|
|
350
|
+
NOW(),
|
|
351
|
+
'active'
|
|
352
|
+
)
|
|
353
|
+
ON CONFLICT (id) DO NOTHING;
|
|
354
|
+
|
|
355
|
+
-- ============================================
|
|
356
|
+
-- STEP 8: CREATE INVOICES
|
|
357
|
+
-- ============================================
|
|
358
|
+
-- Ventas Pro S.A. subscription: $499/month (Enterprise Plan)
|
|
359
|
+
-- 6 months history: 5 paid + 1 pending (current)
|
|
360
|
+
-- Total: $2,994 ($2,495 paid + $499 pending)
|
|
361
|
+
|
|
362
|
+
INSERT INTO "invoices" (
|
|
363
|
+
id,
|
|
364
|
+
"teamId",
|
|
365
|
+
"invoiceNumber",
|
|
366
|
+
date,
|
|
367
|
+
amount,
|
|
368
|
+
currency,
|
|
369
|
+
status,
|
|
370
|
+
"pdfUrl",
|
|
371
|
+
description
|
|
372
|
+
) VALUES
|
|
373
|
+
-- Ventas Pro S.A. - 6 months of subscription history ($499/month Enterprise Plan)
|
|
374
|
+
('inv-crm-001', 'team-crm-company', 'INV-CRM-001',
|
|
375
|
+
NOW() - INTERVAL '5 months', 499.00, 'USD', 'paid',
|
|
376
|
+
'https://billing.example.com/invoices/inv-crm-001.pdf',
|
|
377
|
+
'Enterprise Plan - Monthly subscription'),
|
|
378
|
+
('inv-crm-002', 'team-crm-company', 'INV-CRM-002',
|
|
379
|
+
NOW() - INTERVAL '4 months', 499.00, 'USD', 'paid',
|
|
380
|
+
'https://billing.example.com/invoices/inv-crm-002.pdf',
|
|
381
|
+
'Enterprise Plan - Monthly subscription'),
|
|
382
|
+
('inv-crm-003', 'team-crm-company', 'INV-CRM-003',
|
|
383
|
+
NOW() - INTERVAL '3 months', 499.00, 'USD', 'paid',
|
|
384
|
+
'https://billing.example.com/invoices/inv-crm-003.pdf',
|
|
385
|
+
'Enterprise Plan - Monthly subscription'),
|
|
386
|
+
('inv-crm-004', 'team-crm-company', 'INV-CRM-004',
|
|
387
|
+
NOW() - INTERVAL '2 months', 499.00, 'USD', 'paid',
|
|
388
|
+
'https://billing.example.com/invoices/inv-crm-004.pdf',
|
|
389
|
+
'Enterprise Plan - Monthly subscription'),
|
|
390
|
+
('inv-crm-005', 'team-crm-company', 'INV-CRM-005',
|
|
391
|
+
NOW() - INTERVAL '1 month', 499.00, 'USD', 'paid',
|
|
392
|
+
'https://billing.example.com/invoices/inv-crm-005.pdf',
|
|
393
|
+
'Enterprise Plan - Monthly subscription'),
|
|
394
|
+
('inv-crm-006', 'team-crm-company', 'INV-CRM-006',
|
|
395
|
+
NOW(), 499.00, 'USD', 'pending',
|
|
396
|
+
NULL, -- No PDF yet for pending invoice
|
|
397
|
+
'Enterprise Plan - Monthly subscription')
|
|
398
|
+
ON CONFLICT (id) DO NOTHING;
|
|
399
|
+
|
|
400
|
+
-- ============================================
|
|
401
|
+
-- STEP 9: SUBSCRIPTIONS (B2B - without userId)
|
|
402
|
+
-- ============================================
|
|
403
|
+
-- Note: CRM theme is single-tenant B2B - NO userId
|
|
404
|
+
-- Subscription belongs to team, not individual user
|
|
405
|
+
-- IMPORTANT: Delete trigger-created free subscription before explicit INSERT
|
|
406
|
+
|
|
407
|
+
DELETE FROM public."subscriptions" WHERE "teamId" = 'team-crm-company';
|
|
408
|
+
|
|
409
|
+
INSERT INTO public."subscriptions" (
|
|
410
|
+
id, "teamId", "planId", status,
|
|
411
|
+
"currentPeriodStart", "currentPeriodEnd", "billingInterval", "paymentProvider",
|
|
412
|
+
"externalSubscriptionId", "externalCustomerId", "createdAt"
|
|
413
|
+
) VALUES
|
|
414
|
+
-- Ventas Pro S.A. → Enterprise Plan $499/mo (active, monthly)
|
|
415
|
+
('sub-crm-company', 'team-crm-company', 'plan_enterprise', 'active',
|
|
416
|
+
NOW() - INTERVAL '15 days', NOW() + INTERVAL '15 days', 'monthly', 'stripe',
|
|
417
|
+
'sub_stripe_ventaspro', 'cus_ventaspro', NOW() - INTERVAL '6 months')
|
|
418
|
+
ON CONFLICT (id) DO NOTHING;
|
|
419
|
+
|
|
420
|
+
-- ============================================
|
|
421
|
+
-- STEP 10: BILLING EVENTS (6 months @ $499 Enterprise)
|
|
422
|
+
-- ============================================
|
|
423
|
+
|
|
424
|
+
INSERT INTO public."billing_events" (id, "subscriptionId", type, status, amount, currency, "createdAt")
|
|
425
|
+
VALUES
|
|
426
|
+
('be-crm-001', 'sub-crm-company', 'payment', 'succeeded', 49900, 'usd', NOW() - INTERVAL '6 months'),
|
|
427
|
+
('be-crm-002', 'sub-crm-company', 'payment', 'succeeded', 49900, 'usd', NOW() - INTERVAL '5 months'),
|
|
428
|
+
('be-crm-003', 'sub-crm-company', 'payment', 'succeeded', 49900, 'usd', NOW() - INTERVAL '4 months'),
|
|
429
|
+
('be-crm-004', 'sub-crm-company', 'payment', 'succeeded', 49900, 'usd', NOW() - INTERVAL '3 months'),
|
|
430
|
+
('be-crm-005', 'sub-crm-company', 'payment', 'succeeded', 49900, 'usd', NOW() - INTERVAL '2 months'),
|
|
431
|
+
('be-crm-006', 'sub-crm-company', 'payment', 'succeeded', 49900, 'usd', NOW() - INTERVAL '1 month')
|
|
432
|
+
ON CONFLICT (id) DO NOTHING;
|
|
433
|
+
|
|
434
|
+
-- ============================================
|
|
435
|
+
-- STEP 11: TEAM METADATA (B2B enterprise attributes)
|
|
436
|
+
-- ============================================
|
|
437
|
+
|
|
438
|
+
UPDATE public."teams" SET metadata = '{"industry": "sales", "employeeCount": 4, "segment": "enterprise", "ssoEnabled": false}'::jsonb WHERE id = 'team-crm-company';
|
|
439
|
+
|
|
440
|
+
-- ============================================
|
|
441
|
+
-- SUCCESS SUMMARY
|
|
442
|
+
-- ============================================
|
|
443
|
+
|
|
444
|
+
DO $$
|
|
445
|
+
BEGIN
|
|
446
|
+
RAISE NOTICE '';
|
|
447
|
+
RAISE NOTICE '═══════════════════════════════════════════════════════════';
|
|
448
|
+
RAISE NOTICE ' CRM Theme Sample Data - Single-tenant B2B';
|
|
449
|
+
RAISE NOTICE '═══════════════════════════════════════════════════════════';
|
|
450
|
+
RAISE NOTICE '';
|
|
451
|
+
RAISE NOTICE ' 👥 TEST USERS (all passwords: Test1234):';
|
|
452
|
+
RAISE NOTICE ' crm_owner_roberto@nextspark.dev → owner (full access)';
|
|
453
|
+
RAISE NOTICE ' crm_admin_sofia@nextspark.dev → admin (sales manager)';
|
|
454
|
+
RAISE NOTICE ' crm_member_miguel@nextspark.dev → member (sales rep)';
|
|
455
|
+
RAISE NOTICE ' crm_member_laura@nextspark.dev → member (marketing)';
|
|
456
|
+
RAISE NOTICE '';
|
|
457
|
+
RAISE NOTICE ' 🏢 TEAM (Single-tenant = 1 company):';
|
|
458
|
+
RAISE NOTICE ' Ventas Pro S.A. - 4 members';
|
|
459
|
+
RAISE NOTICE ' Plan: Enterprise $499/mo (active, monthly)';
|
|
460
|
+
RAISE NOTICE ' Billing: 6 months history ($2,994 total)';
|
|
461
|
+
RAISE NOTICE '';
|
|
462
|
+
RAISE NOTICE ' 📊 SUBSCRIPTION:';
|
|
463
|
+
RAISE NOTICE ' MRR: $499.00 (1 Enterprise monthly)';
|
|
464
|
+
RAISE NOTICE ' Status: Active';
|
|
465
|
+
RAISE NOTICE '';
|
|
466
|
+
RAISE NOTICE ' 📝 TEAMS MODE: single-tenant (B2B)';
|
|
467
|
+
RAISE NOTICE ' - No team switcher (only one team)';
|
|
468
|
+
RAISE NOTICE ' - Cannot create additional teams';
|
|
469
|
+
RAISE NOTICE ' - Subscription belongs to team (no userId)';
|
|
470
|
+
RAISE NOTICE '';
|
|
471
|
+
RAISE NOTICE '═══════════════════════════════════════════════════════════';
|
|
472
|
+
END $$;
|
|
473
|
+
|
package/package.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nextsparkjs/theme-crm",
|
|
3
|
+
"version": "0.1.0-beta.1",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"main": "./config/theme.config.ts",
|
|
7
|
+
"requiredPlugins": [],
|
|
8
|
+
"dependencies": {},
|
|
9
|
+
"peerDependencies": {
|
|
10
|
+
"@nextsparkjs/core": "workspace:*",
|
|
11
|
+
"lucide-react": "^0.539.0",
|
|
12
|
+
"next": "^15.0.0",
|
|
13
|
+
"next-intl": "^4.0.0",
|
|
14
|
+
"react": "^19.0.0",
|
|
15
|
+
"react-dom": "^19.0.0",
|
|
16
|
+
"zod": "^4.0.0"
|
|
17
|
+
}
|
|
18
|
+
}
|