- Tabla crm.cases (expediente) con folio EXP2026-08-001 (next_folio entidad EXP,
sin dirección). Nace al crear la Oportunidad y se hereda vía case_id a
solicitud → cotización → operación → factura. advance_stage solo avanza.
- case_id (FK a crm.cases) en crm.opportunities/service_requests/quotes,
ops.shipments y fin.invoices; propagación en sus create_*. Migración
d4e5f6a7b8c9 reversible.
- Endpoints GET /v1/crm/cases, /cases/{id}, /cases/by-ref/{ref} con timeline
(historia completa para UI y otros sistemas).
- Frontend: casesAPI, ruta /dashboard/crm/expedientes (lista + timeline vertical),
chip "📁 Expediente" en solicitud/cotización, "Expedientes" en el sidebar.
- Consecutivo de folios sin tope (soporta >10,000,000/mes).
- 4 pruebas de expediente (minteo, propagación, timeline, no-retroceso). Suite en verde (113).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
126 lines
2.9 KiB
TypeScript
126 lines
2.9 KiB
TypeScript
import {
|
|
LayoutDashboard,
|
|
Settings2,
|
|
Users,
|
|
Shield,
|
|
Briefcase,
|
|
Ship,
|
|
Receipt,
|
|
Building,
|
|
} from '@lucide/svelte';
|
|
|
|
export type SystemContext = 'fixed_asset' | 'inventory';
|
|
|
|
export interface NavItem {
|
|
title: string;
|
|
url: string;
|
|
permission?: string;
|
|
systemContext?: SystemContext;
|
|
}
|
|
|
|
export interface NavMainItem {
|
|
title: string;
|
|
url: string;
|
|
icon: any;
|
|
isActive?: boolean;
|
|
permission?: string;
|
|
items?: NavItem[];
|
|
}
|
|
|
|
/**
|
|
* Navegación principal del dashboard.
|
|
* Agrega aquí los módulos de tu proyecto.
|
|
*/
|
|
export function getNavMain(): NavMainItem[] {
|
|
return [
|
|
{
|
|
title: 'Dashboard',
|
|
url: '/dashboard',
|
|
icon: LayoutDashboard,
|
|
},
|
|
{
|
|
title: 'CRM',
|
|
url: '/dashboard/crm',
|
|
icon: Briefcase,
|
|
// Orden por flujo comercial: captación → embudo → solicitud → cotización → apoyo
|
|
items: [
|
|
{ title: 'Panel', url: '/dashboard/crm' },
|
|
{ title: 'Expedientes', url: '/dashboard/crm/expedientes' },
|
|
{ title: 'Clientes / Prospectos', url: '/dashboard/crm/cuentas' },
|
|
{ title: 'Contactos', url: '/dashboard/crm/contactos' },
|
|
{ title: 'Prospectos (embudo)', url: '/dashboard/crm/prospectos' },
|
|
{ title: 'Oportunidades', url: '/dashboard/crm/oportunidades' },
|
|
{ title: 'Solicitudes', url: '/dashboard/crm/solicitudes' },
|
|
{ title: 'Cotizaciones', url: '/dashboard/crm/cotizaciones' },
|
|
{ title: 'Tarifarios', url: '/dashboard/crm/tarifarios' },
|
|
{ title: 'Cotizador', url: '/dashboard/crm/cotizador' },
|
|
{ title: 'Proveedores', url: '/dashboard/crm/proveedores' },
|
|
{ title: 'Actividades', url: '/dashboard/crm/actividades' },
|
|
{ title: 'Catálogos', url: '/dashboard/crm/catalogos' },
|
|
],
|
|
},
|
|
{
|
|
title: 'Operaciones',
|
|
url: '/dashboard/ops/embarques',
|
|
icon: Ship,
|
|
items: [
|
|
{ title: 'Embarques', url: '/dashboard/ops/embarques' },
|
|
],
|
|
},
|
|
{
|
|
title: 'Facturación',
|
|
url: '/dashboard/fin/facturas',
|
|
icon: Receipt,
|
|
items: [
|
|
{ title: 'Facturas y cobranza', url: '/dashboard/fin/facturas' },
|
|
],
|
|
},
|
|
{
|
|
title: 'Compañías',
|
|
url: '/dashboard/companias',
|
|
icon: Building,
|
|
},
|
|
{
|
|
title: 'Usuarios',
|
|
url: '/dashboard/users',
|
|
icon: Users,
|
|
},
|
|
{
|
|
title: 'Roles y permisos',
|
|
url: '/dashboard/roles',
|
|
icon: Shield,
|
|
},
|
|
{
|
|
title: 'Configuración',
|
|
url: '/dashboard/settings/general',
|
|
icon: Settings2,
|
|
items: [
|
|
{ title: 'General', url: '/dashboard/settings/general' },
|
|
{ title: 'Formato de cotización', url: '/dashboard/settings/cotizacion' },
|
|
],
|
|
},
|
|
];
|
|
}
|
|
|
|
/**
|
|
* Datos completos del sidebar (navegación + usuario fallback + proyectos).
|
|
* El usuario real se inyecta desde page.data en app-sidebar.svelte.
|
|
*/
|
|
export function getSidebarData() {
|
|
return {
|
|
navMain: getNavMain(),
|
|
projects: [] as { name: string; url: string; icon: any }[],
|
|
user: {
|
|
name: '',
|
|
email: '',
|
|
username: '',
|
|
firstName: null,
|
|
lastName: null,
|
|
displayName: '',
|
|
avatarUrl: null,
|
|
workspaceAvatarUrl: null,
|
|
legacyAvatarUrl: null,
|
|
},
|
|
};
|
|
}
|