Proyecto

General

Perfil

NC – Tareas #178 » bd-personas.sql

Borrador de sql para personas - Diego Ovando, 2026-01-30 17:10

 
1
-- =================================================================================
2
-- 1. ESQUEMA GLOBAL (Catálogos y Maestros Estáticos)
3
-- =================================================================================
4
create schema if not exists global;
5

    
6
-- 1.1 Países
7
create table global.paises (
8
    pais_id int generated always as identity,
9
    nombre varchar(100) not null,
10
    siglas char(3) not null, -- PRY, ARG
11
    codigo_telefonico varchar(5),
12
    gentilicio varchar(100),
13
    
14
    -- Auditoría
15
    creado_en timestamptz default now() not null,
16
    creado_por bigint,
17
    actualizado_en timestamptz,
18
    actualizado_por bigint,
19
    
20
    -- Borrado Lógico
21
    eliminado_en timestamptz default null,
22
    eliminado_por bigint,
23

    
24
    constraint pk_paises primary key (pais_id),
25
    constraint uq_paises_siglas unique (siglas)
26
);
27

    
28
-- 1.2 Tipos de Documento (Refactorizado a ID Numérico)
29
create table global.tipos_documentos (
30
    tipo_documento_id int generated always as identity, -- Ahora es INT
31
    codigo varchar(10) not null, -- 'CI', 'RUC', 'PAS'
32
    descripcion varchar(50) not null,
33
    mascara_validacion varchar(100), -- Regex para frontend
34
    es_fiscal boolean default false, -- True si sirve para tributación
35
    
36
    -- Auditoría
37
    creado_en timestamptz default now() not null,
38
    creado_por bigint,
39
    actualizado_en timestamptz,
40
    actualizado_por bigint,
41

    
42
    -- Borrado Lógico
43
    eliminado_en timestamptz default null,
44
    eliminado_por bigint,
45

    
46
    constraint pk_tipos_documento primary key (tipo_documento_id),
47
    constraint uq_tipos_doc_codigo unique (codigo)
48
);
49

    
50
-- 1.3 Ciudades
51
create table global.ciudades (
52
    ciudad_id int generated always as identity,
53
    pais_id int not null,
54
    nombre varchar(100) not null,
55
    codigo_postal varchar(20),
56
    
57
    -- Auditoría
58
    creado_en timestamptz default now() not null,
59
    creado_por bigint,
60
    actualizado_en timestamptz,
61
    actualizado_por bigint,
62

    
63
    constraint pk_ciudades primary key (ciudad_id),
64
    constraint fk_ciudades_pais foreign key (pais_id) references global.paises(pais_id),
65
    constraint uq_ciudades_nombre_pais unique (pais_id, nombre)
66
);
67

    
68
-- 1.4 Estados Civiles
69
create table global.estados_civiles (
70
    estado_civil_id int generated always as identity,
71
    descripcion varchar(50) not null,
72
    
73
    -- Auditoría
74
    creado_en timestamptz default now() not null,
75
    creado_por bigint,
76
    actualizado_en timestamptz,
77
    actualizado_por bigint,
78

    
79
    constraint pk_estados_civiles primary key (estado_civil_id),
80
    constraint uq_estados_civiles_desc unique (descripcion)
81
);
82

    
83
-- 1.5 Sexos (Refactorizado a ID Numérico)
84
create table global.sexos (
85
    sexo_id int generated always as identity, -- Ahora es INT
86
    sigla char(1) not null, -- 'M', 'F'
87
    descripcion varchar(20) not null,
88
    
89
    -- Auditoría
90
    creado_en timestamptz default now() not null,
91
    creado_por bigint,
92
    actualizado_en timestamptz,
93
    actualizado_por bigint,
94

    
95
    constraint pk_sexos primary key (sexo_id),
96
    constraint uq_sexos_sigla unique (sigla)
97
);
98

    
99
-- 1.6 Tipos de Sociedad (Jurídica)
100
create table global.tipos_sociedad (
101
    tipo_sociedad_id int generated always as identity,
102
    siglas varchar(10), -- 'SA', 'SRL'
103
    descripcion varchar(100) not null,
104
    
105
    -- Auditoría
106
    creado_en timestamptz default now() not null,
107
    creado_por bigint,
108
    actualizado_en timestamptz,
109
    actualizado_por bigint,
110

    
111
    constraint pk_tipos_sociedad primary key (tipo_sociedad_id)
112
);
113

    
114
-- 1.7 Régimen Patrimonial (Gananciales, Separación)
115
create table global.regimenes_matrimoniales (
116
    regimen_id int generated always as identity,
117
    descripcion varchar(100) not null,
118
    
119
    constraint pk_regimenes primary key (regimen_id)
120
);
121

    
122
-- 1.8 Nivel Educativo
123
create table global.niveles_educativos (
124
    nivel_educativo_id int generated always as identity,
125
    descripcion varchar(100) not null, -- 'Primaria', 'Universitario'
126
    
127
    constraint pk_niveles_educativos primary key (nivel_educativo_id)
128
);
129

    
130
-- 1.9 Actividades Económicas (Para Socio y Empleador)
131
create table global.actividades_economicas (
132
    actividad_id int generated always as identity,
133
    descripcion varchar(150) not null, -- 'Ganadería', 'Salud', 'Software'
134
    sector varchar(50), -- 'PRIMARIO', 'SERVICIOS'
135
    
136
    constraint pk_actividades_economicas primary key (actividad_id)
137
);
138

    
139
-- 1.10 Tipos de Relación Laboral
140
create table global.tipos_relacion_laboral (
141
    tipo_relacion_id int generated always as identity,
142
    descripcion varchar(100) not null, -- 'Nombrado', 'Jornalero', 'Independiente'
143
    
144
    constraint pk_tipos_relacion_laboral primary key (tipo_relacion_id)
145
);
146

    
147
-- 1.11 Situación Vivienda
148
create table global.tipos_vivienda (
149
    tipo_vivienda_id int generated always as identity,
150
    descripcion varchar(100) not null, -- 'Propia', 'Alquilada'
151
    
152
    constraint pk_tipos_vivienda primary key (tipo_vivienda_id)
153
);
154

    
155
-- 1.12 Tenencia de Tierra
156
create table global.tipos_tenencia_tierra (
157
    tenencia_id int generated always as identity,
158
    descripcion varchar(100) not null, -- 'Propietario con título', 'Ocupante'
159
    
160
    constraint pk_tipos_tenencia primary key (tenencia_id)
161
);
162

    
163
-- 3.3 Régimen Tributario (IVA General, IRE, etc.)
164
create table global.regimenes_tributarios (
165
    regimen_id int generated always as identity,
166
    descripcion varchar(100) not null, -- 'IVA General', 'IRE SIMPLE'
167
    siglas varchar(20),
168
    
169
    constraint pk_regimenes_tributarios primary key (regimen_id)
170
);
171

    
172
-- 3.3 Rangos de Ingresos Anuales (Para perfilamiento)
173
create table global.rangos_ingresos (
174
    rango_ingreso_id int generated always as identity,
175
    descripcion varchar(100) not null, -- '0 - 500 Millones', '+ 3.000 Millones'
176
    valor_minimo numeric(19, 2), -- Para lógica de negocio (scoring)
177
    valor_maximo numeric(19, 2),
178
    moneda varchar(3) default 'PYG',
179
    
180
    constraint pk_rangos_ingresos primary key (rango_ingreso_id)
181
);
182

    
183
-- 3.3 Rangos de Cantidad de Empleados
184
create table global.rangos_empleados (
185
    rango_empleado_id int generated always as identity,
186
    descripcion varchar(50) not null, -- '1-5', '6-20', '+50'
187
    min_empleados int,
188
    max_empleados int,
189
    
190
    constraint pk_rangos_empleados primary key (rango_empleado_id)
191
);
192

    
193
-- =================================================================================
194
-- 2. ESQUEMA CORE (Identidad y Datos Maestros)
195
-- =================================================================================
196
create schema if not exists core;
197

    
198
-- 2.1 TABLA MAESTRA: PERSONAS
199
create table core.personas (
200
    persona_id bigint generated always as identity,
201
    tipo_persona char(1) not null, 
202
    
203
    -- Propósito del Registro (Punto 1)
204
    motivo_registro varchar(50) not null, -- 'CANDIDATO_SOCIO', 'CODEUDOR', 'REPRESENTANTE'
205
    
206
    pais_emision_id int not null,
207
    tipo_documento_id int not null,
208
    numero_documento varchar(30) not null,
209
    nombre_completo_normalizado varchar(255) not null,
210
    
211
    estado varchar(20) default 'ACTIVO',
212
    version int default 1, -- Optimistic Locking (Punto 4)
213

    
214
    -- Auditoría Híbrida
215
    creado_en timestamptz default now() not null,
216
    creado_por bigint, 
217
    actualizado_en timestamptz,
218
    actualizado_por bigint,
219
    
220
    -- Borrado Lógico
221
    eliminado_en timestamptz default null,
222
    eliminado_por bigint,
223

    
224
    constraint pk_personas primary key (persona_id),
225
    constraint fk_personas_pais foreign key (pais_emision_id) references global.paises(pais_id),
226
    constraint fk_personas_tipo_doc foreign key (tipo_documento_id) references global.tipos_documento(tipo_documento_id),
227
    constraint uq_personas_identidad unique (pais_emision_id, tipo_documento_id, numero_documento),
228
    constraint ck_personas_tipo check (tipo_persona in ('F', 'J'))
229
);
230

    
231
create index idx_personas_activos on core.personas(persona_id) where eliminado_en is null;
232
create index idx_personas_fecha_registro on core.personas(creado_en desc);
233

    
234
-- 2.2 ESPECIFICACIÓN: PERSONAS FÍSICAS
235
create table core.personas_fisicas (
236
    persona_id bigint not null,
237
    
238
    nombres varchar(100) not null,
239
    apellidos varchar(100) not null,
240
    fecha_nacimiento date not null,
241
    sexo_id int not null,
242
    ciudad_nacimiento_id int,
243
    
244
    -- 3.5 Perfil Personal y Familiar
245
    estado_civil_id int,
246
    regimen_matrimonial_id int, -- Visible solo si es Casado (Validar en App)
247
    cantidad_dependientes int default 0,
248
    tiene_hijos_escolar boolean default false,
249
    
250
    -- 3.6 Perfil Socioeconómico (Resumen)
251
    nivel_educativo_id int,
252
    profesion_oficio varchar(150), -- Texto libre para especificidad
253
    
254
    -- 3.7 Perfil de Riesgo y Cumplimiento
255
    situacion_vivienda_id int,
256
    tenencia_tierra_id int,
257
    posee_seguro_medico boolean default false,
258
    
259
    -- Auditoría
260
    creado_en timestamptz default now() not null,
261
    creado_por bigint,
262
    actualizado_en timestamptz,
263
    actualizado_por bigint,
264

    
265
    constraint pk_personas_fisicas primary key (persona_id),
266
    
267
    constraint fk_fisicas_persona foreign key (persona_id) references core.personas(persona_id) on delete cascade,
268
    constraint fk_fisicas_sexo foreign key (sexo_id) references global.sexos(sexo_id),
269
    constraint fk_fisicas_est_civil foreign key (estado_civil_id) references global.estados_civiles(estado_civil_id),
270
    constraint fk_fisicas_regimen foreign key (regimen_matrimonial_id) references global.regimenes_matrimoniales(regimen_id),
271
    constraint fk_fisicas_educacion foreign key (nivel_educativo_id) references global.niveles_educativos(nivel_educativo_id),
272
    constraint fk_fisicas_vivienda foreign key (situacion_vivienda_id) references global.tipos_vivienda(tipo_vivienda_id),
273
    constraint fk_fisicas_tierra foreign key (tenencia_tierra_id) references global.tipos_tenencia_tierra(tenencia_id)
274
);
275

    
276
-- 2.3 ESPECIFICACIÓN: PERSONAS JURÍDICAS
277
create table core.personas_juridicas (
278
    persona_id bigint not null,
279
    
280
    -- 3.1 Identificación
281
    razon_social varchar(200) not null,
282
    nombre_fantasia varchar(200), -- Nombre Comercial
283
    
284
    tipo_sociedad_id int not null,
285
    fecha_constitucion date, -- Legal
286
    
287
    -- 3.3 Perfil de Negocio y Operativo
288
    fecha_inicio_operaciones date, -- Para calcular "Antigüedad del Negocio"
289
    
290
    actividad_economica_id int, -- CIUU (Ya creado en paso anterior)
291
    regimen_tributario_id int,  -- Nuevo
292
    rango_ingreso_anual_id int, -- Nuevo
293
    rango_cantidad_empleados_id int, -- Nuevo
294
    
295
    sitio_web varchar(150),
296
    
297
    -- Auditoría
298
    creado_en timestamptz default now() not null,
299
    creado_por bigint, 
300
    actualizado_en timestamptz,
301
    actualizado_por bigint,
302

    
303
    -- CONSTRAINTS
304
    constraint pk_personas_juridicas primary key (persona_id),
305
    
306
    constraint fk_juridicas_persona foreign key (persona_id) references core.personas(persona_id) on delete cascade,
307
    constraint fk_juridicas_tipo_soc foreign key (tipo_sociedad_id) references global.tipos_sociedad(tipo_sociedad_id),
308
    
309
    -- Foreign Keys a los nuevos catálogos
310
    constraint fk_juridicas_actividad foreign key (actividad_economica_id) references global.actividades_economicas(actividad_id),
311
    constraint fk_juridicas_regimen foreign key (regimen_tributario_id) references global.regimenes_tributarios(regimen_id),
312
    constraint fk_juridicas_rango_ing foreign key (rango_ingreso_anual_id) references global.rangos_ingresos(rango_ingreso_id),
313
    constraint fk_juridicas_rango_emp foreign key (rango_cantidad_empleados_id) references global.rangos_empleados(rango_empleado_id)
314
);
315

    
316
-- 2.4 DIRECCIONES (Agregada y Completa) 
317
create table core.direcciones (
318
    direccion_id bigint generated always as identity,
319
    persona_id bigint not null,
320
    
321
    ciudad_id int not null,
322
    barrio varchar(100),
323
    calle_principal varchar(150) not null,
324
    numeracion varchar(20),
325
    referencia_ubicacion text,
326
    
327
    -- Geolocalización para mapas
328
    latitud decimal(10, 8),
329
    longitud decimal(11, 8),
330
    
331
    es_principal boolean default false,
332
    tipo_direccion varchar(20) default 'PARTICULAR', -- 'LABORAL', 'LEGAL'
333
    
334
    -- Auditoría
335
    creado_en timestamptz default now() not null,
336
    creado_por bigint,
337
    actualizado_en timestamptz,
338
    actualizado_por bigint,
339

    
340
    constraint pk_direcciones primary key (direccion_id),
341
    constraint fk_direcciones_persona foreign key (persona_id) references core.personas(persona_id),
342
    constraint fk_direcciones_ciudad foreign key (ciudad_id) references global.ciudades(ciudad_id)
343
);
344

    
345
-- =================================================================================
346
-- 3. ESQUEMA RELACIONES (Vínculos N:M)
347
-- =================================================================================
348
create schema if not exists relaciones;
349

    
350
-- 3.1 Catálogo de Tipos de Vínculo
351
create table relaciones.tipos_vinculo (
352
    tipo_vinculo_id int generated always as identity,
353
    descripcion varchar(50) not null,
354
    es_reciproco boolean default false,
355
    
356
    -- Auditoría
357
    creado_en timestamptz default now() not null,
358
    creado_por bigint,
359
    actualizado_en timestamptz,
360
    actualizado_por bigint,
361

    
362
    constraint pk_tipos_vinculo primary key (tipo_vinculo_id)
363
);
364

    
365
-- 3.2 Tabla de Vínculos
366
create table relaciones.vinculos_personas (
367
    vinculo_id bigint generated always as identity,
368
    
369
    persona_origen_id bigint not null,
370
    persona_destino_id bigint not null,
371
    tipo_vinculo_id int not null,
372
    
373
    es_garante boolean default false,
374
    fecha_inicio date default current_date,
375
    activo boolean default true,
376
    
377
    -- Auditoría Completa
378
    creado_en timestamptz default now() not null,
379
    creado_por bigint,
380
    actualizado_en timestamptz,
381
    actualizado_por bigint,
382

    
383
    constraint pk_vinculos_personas primary key (vinculo_id),
384
    
385
    constraint fk_vinculos_origen foreign key (persona_origen_id) references core.personas(persona_id),
386
    constraint fk_vinculos_destino foreign key (persona_destino_id) references core.personas(persona_id),
387
    constraint fk_vinculos_tipo foreign key (tipo_vinculo_id) references relaciones.tipos_vinculo(tipo_vinculo_id),
388
    
389
    constraint ck_vinculos_bucle check (persona_origen_id <> persona_destino_id)
390
);
391

    
392
-- =================================================================================
393
-- 4. ESQUEMA RIESGO
394
-- =================================================================================
395
create schema if not exists riesgo;
396

    
397
-- 4.1 Calificaciones
398
create table riesgo.calificaciones (
399
    calificacion_id bigint generated always as identity,
400
    persona_id bigint not null,
401
    
402
    fuente_informacion varchar(50) not null, 
403
    fecha_consulta timestamptz default now() not null,
404
    estado_resultado varchar(50) not null, 
405
    score_numerico int,
406
    respuesta_json_raw jsonb, 
407
    
408
    -- Auditoría
409
    creado_en timestamptz default now() not null,
410
    creado_por bigint,
411
    actualizado_en timestamptz,
412
    actualizado_por bigint,
413

    
414
    constraint pk_calificaciones primary key (calificacion_id),
415
    constraint fk_calificaciones_persona foreign key (persona_id) references core.personas(persona_id)
416
);
417

    
418
-- 4.2 Registros PEP
419
create table riesgo.registros_pep (
420
    pep_id bigint generated always as identity,
421
    persona_id bigint not null,
422
    
423
    es_pep_actual boolean default true,
424
    cargo varchar(150),
425
    institucion varchar(150),
426
    fecha_inicio date,
427
    fecha_fin date,
428
    
429
    -- Auditoría
430
    creado_en timestamptz default now() not null,
431
    creado_por bigint,
432
    actualizado_en timestamptz,
433
    actualizado_por bigint,
434

    
435
    constraint pk_registros_pep primary key (pep_id),
436
    constraint fk_pep_persona foreign key (persona_id) references core.personas(persona_id)
437
);
438

    
439
-- =================================================================================
440
-- 5. ESQUEMA SOCIOECONÓMICO
441
-- =================================================================================
442
create schema if not exists socioeconomico;
443

    
444
create table socioeconomico.perfiles_laborales (
445
    laboral_id bigint generated always as identity,
446
    persona_id bigint not null,
447
    
448
    lugar_trabajo varchar(150),
449
    cargo varchar(100),
450
    fecha_ingreso date, 
451
    ingreso_mensual_declarado numeric(19, 4), 
452
    moneda varchar(3) default 'PYG',
453
    es_trabajo_principal boolean default true,
454
    
455
    -- Auditoría
456
    creado_en timestamptz default now() not null,
457
    creado_por bigint,
458
    actualizado_en timestamptz,
459
    actualizado_por bigint,
460

    
461
    constraint pk_perfiles_laborales primary key (laboral_id),
462
    constraint fk_laboral_persona foreign key (persona_id) references core.personas(persona_id)
463
);
464

    
465
-- =================================================================================
466
-- 6. ESQUEMA AUDITORÍA (Centralizada)
467
-- =================================================================================
468
create schema if not exists auditoria;
469

    
470
create table auditoria.logs_eventos (
471
    log_id bigint generated always as identity,
472
    
473
    fecha_evento timestamptz default now() not null,
474
    usuario_id bigint, 
475
    ip_origen varchar(45),
476
    
477
    operacion varchar(10) not null, 
478
    esquema_afectado varchar(63) not null,
479
    tabla_afectada varchar(63) not null,
480
    pk_registro_afectado text not null,
481
    
482
    datos_anteriores jsonb, 
483
    datos_nuevos jsonb,     
484

    
485
    constraint pk_logs_eventos primary key (log_id),
486
    constraint ck_logs_operacion check (operacion in ('INSERT', 'UPDATE', 'DELETE'))
487
) partition by range (fecha_evento);
488

    
489
-- Particiones
490
create table auditoria.logs_eventos_y2025 partition of auditoria.logs_eventos
491
    for values from ('2025-01-01') to ('2026-01-01');
492

    
493
create table auditoria.logs_eventos_y2026 partition of auditoria.logs_eventos
494
    for values from ('2026-01-01') to ('2027-01-01');
495

    
496
-----------------------------------------------------
497

    
498
-- Nueva versión más normalizada
499

    
500
------------------------------------------------------
501

    
502

    
503
-- =================================================================================
504
-- 1. ESQUEMA GLOBAL (Catálogos y Estados Centralizados)
505
-- =================================================================================
506
create schema if not exists global;
507

    
508
-- 1.1 TABLA MAESTRA DE ESTADOS (Centralizada)
509
create table global.estados_sistema (
510
    estado_id int generated by default as identity,
511
    
512
    dominio varchar(50) not null, -- 'PERSONA', 'PRESTAMO', 'USUARIO', 'CUENTA'
513
    codigo varchar(50) not null,  -- 'ACTIVO', 'PENDIENTE', 'BLOQUEADO', 'MORA_30'
514
    descripcion varchar(100) not null,
515
    
516
    es_estado_final boolean default false, -- Útil para saber si permite transiciones
517
    color_hex varchar(7), -- Para el Frontend (ej: '#FF0000')
518
    
519
    creado_en timestamptz default now() not null,
520
    
521
    constraint pk_estados_sistema primary key (estado_id),
522
    -- Asegura que no dupliquemos el código dentro del mismo dominio
523
    constraint uq_estados_dominio_codigo unique (dominio, codigo)
524
);
525

    
526
-- Datos Semilla (Ejemplos conceptuales)
527
-- INSERT INTO global.estados_sistema (dominio, codigo, descripcion) VALUES 
528
-- ('PERSONA', 'ACTIVO', 'Socio habilitado para operar'),
529
-- ('PERSONA', 'BLOQUEADO', 'Bloqueo por cumplimiento o mora'),
530
-- ('PERSONA', 'FALLECIDO', 'Cese de operaciones por deceso');
531

    
532
-- 1.2 Países (Identity by Default para migración)
533
create table global.paises (
534
    pais_id int generated by default as identity,
535
    nombre varchar(100) not null,
536
    codigo_iso_alpha3 char(3) not null,
537
    
538
    constraint pk_paises primary key (pais_id),
539
    constraint uq_paises_iso unique (codigo_iso_alpha3)
540
);
541

    
542
-- (Se mantienen tipos_documento, ciudades, etc. con 'BY DEFAULT')
543
-- ... Resumido para brevedad, asume que todos usan "generated by default" ...
544

    
545
create table global.tipos_documento (
546
    tipo_documento_id int generated by default as identity,
547
    codigo varchar(10) not null, 
548
    descripcion varchar(50) not null,
549
    mascara_validacion varchar(100),
550
    es_fiscal boolean default false,
551
    
552
    constraint pk_tipos_documento primary key (tipo_documento_id),
553
    constraint uq_tipos_doc_codigo unique (codigo)
554
);
555

    
556
create table global.actividades_economicas (
557
    actividad_id int generated by default as identity,
558
    descripcion varchar(150) not null,
559
    sector varchar(50),
560
    constraint pk_actividades_economicas primary key (actividad_id)
561
);
562

    
563
create table global.regimenes_tributarios (
564
    regimen_id int generated by default as identity,
565
    descripcion varchar(100) not null,
566
    constraint pk_regimenes_tributarios primary key (regimen_id)
567
);
568

    
569
-- =================================================================================
570
-- 2. ESQUEMA CORE (Aplicando Estados Centralizados y Migración)
571
-- =================================================================================
572
create schema if not exists core;
573

    
574
create table core.personas (
575
    persona_id bigint generated by default as identity, -- CAMBIO CLAVE PARA MIGRACIÓN
576
    
577
    tipo_persona char(1) not null, 
578
    motivo_registro varchar(50) not null,
579
    
580
    pais_emision_id int not null,
581
    tipo_documento_id int not null,
582
    numero_documento varchar(30) not null,
583
    nombre_completo_normalizado varchar(255) not null,
584
    
585
    fecha_nacimiento_constitucion date not null, 
586
    
587
    actividad_economica_id int, 
588
    regimen_tributario_id int,  
589
    
590
    email_principal varchar(150),
591
    telefono_principal varchar(50),
592
    sitio_web varchar(150),
593
    
594
    -- ESTADO CENTRALIZADO
595
    -- Ahora apuntamos a la tabla maestra.
596
    estado_id int not null, 
597
    
598
    version int default 1, 
599

    
600
    creado_en timestamptz default now() not null,
601
    creado_por bigint, 
602
    actualizado_en timestamptz,
603
    actualizado_por bigint,
604
    eliminado_en timestamptz,
605
    eliminado_por bigint,
606

    
607
    constraint pk_personas primary key (persona_id),
608
    
609
    constraint fk_personas_pais foreign key (pais_emision_id) references global.paises(pais_id),
610
    constraint fk_personas_tipo_doc foreign key (tipo_documento_id) references global.tipos_documento(tipo_documento_id),
611
    constraint fk_personas_actividad foreign key (actividad_economica_id) references global.actividades_economicas(actividad_id),
612
    constraint fk_personas_regimen foreign key (regimen_tributario_id) references global.regimenes_tributarios(regimen_id),
613
    
614
    -- FK AL ESTADO
615
    constraint fk_personas_estado foreign key (estado_id) references global.estados_sistema(estado_id),
616

    
617
    constraint uq_personas_identidad unique (pais_emision_id, tipo_documento_id, numero_documento),
618
    constraint ck_personas_tipo check (tipo_persona in ('F', 'J'))
619
);
620

    
621
create index idx_personas_activos on core.personas(persona_id) where eliminado_en is null;
622

    
623
-- Las tablas hijas (fisicas/juridicas) heredan la identidad "By Default"
624
create table core.personas_fisicas (
625
    persona_id bigint not null,
626
    -- ... campos ...
627
    constraint pk_personas_fisicas primary key (persona_id),
628
    constraint fk_fisicas_persona foreign key (persona_id) references core.personas(persona_id) on delete cascade
629
);
630

    
631
create table core.personas_juridicas (
632
    persona_id bigint not null,
633
    -- ... campos ...
634
    constraint pk_personas_juridicas primary key (persona_id),
635
    constraint fk_juridicas_persona foreign key (persona_id) references core.personas(persona_id) on delete cascade
636
);
637

    
638

    
639

    
640
create schema if not exists core;
641

    
642
create table core.personas (
643
    persona_id bigint generated by default as identity, 
644
    
645
    -- ==========================================
646
    -- NUEVA COLUMNA: TRAZABILIDAD LEGADA
647
    -- ==========================================
648
    id_legado varchar(50), -- El ID original del sistema viejo (ej: '5040' o 'CLI-99')
649
    
650
    -- Discriminador
651
    tipo_persona char(1) not null, 
652
    motivo_registro varchar(50) not null,
653
    
654
    -- Identidad
655
    pais_emision_id int not null,
656
    tipo_documento_id int not null,
657
    numero_documento varchar(30) not null,
658
    nombre_completo_normalizado varchar(255) not null,
659
    
660
    -- Datos Promovidos
661
    fecha_nacimiento_constitucion date not null, 
662
    actividad_economica_id int, 
663
    regimen_tributario_id int,  
664
    
665
    email_principal varchar(150),
666
    telefono_principal varchar(50),
667
    sitio_web varchar(150),
668
    
669
    -- Estado Centralizado
670
    estado_id int not null, 
671
    version int default 1, 
672

    
673
    -- Auditoría
674
    creado_en timestamptz default now() not null,
675
    creado_por bigint, 
676
    actualizado_en timestamptz,
677
    actualizado_por bigint,
678
    eliminado_en timestamptz,
679
    eliminado_por bigint,
680

    
681
    constraint pk_personas primary key (persona_id),
682
    
683
    -- Constraints FK (Resumidos)
684
    constraint fk_personas_pais foreign key (pais_emision_id) references global.paises(pais_id),
685
    constraint fk_personas_tipo_doc foreign key (tipo_documento_id) references global.tipos_documento(tipo_documento_id),
686
    constraint fk_personas_actividad foreign key (actividad_economica_id) references global.actividades_economicas(actividad_id),
687
    constraint fk_personas_regimen foreign key (regimen_tributario_id) references global.regimenes_tributarios(regimen_id),
688
    constraint fk_personas_estado foreign key (estado_id) references global.estados_sistema(estado_id),
689

    
690
    constraint uq_personas_identidad unique (pais_emision_id, tipo_documento_id, numero_documento),
691
    constraint ck_personas_tipo check (tipo_persona in ('F', 'J'))
692
);
693

    
694
-- ÍNDICE ÚNICO PARA ID LEGADO
695
-- Vital para asegurar que no migres el mismo cliente viejo dos veces.
696
create unique index uq_personas_id_legado on core.personas(id_legado) where id_legado is not null;
697

    
698
-- Índices de performance
699
create index idx_personas_activos on core.personas(persona_id) where eliminado_en is null;
(1-1/3)