6.8 KiB
6.8 KiB
RF-CATALOG-002: Paises y Estados (Catalogo Global)
Identificacion
| Campo | Valor |
|---|---|
| ID | RF-CATALOG-002 |
| Modulo | MGN-005 Catalogs |
| Titulo | Paises y Estados (Catalogo Global) |
| Prioridad | Alta |
| Estado | Draft |
| Fecha | 2025-12-05 |
Descripcion
El sistema debe proporcionar un catalogo global de paises y sus subdivisiones (estados, provincias, departamentos) basado en estandares ISO. Este catalogo es compartido por todos los tenants y NO tiene tenant_id.
Referencia Odoo:
res.country(odoo/addons/base/models/res_country.py)res.country.state(mismo archivo)res.country.group(agrupaciones regionales)
Requisitos Funcionales
RF-CATALOG-002.1: Catalogo de Paises
El sistema debe incluir todos los paises segun ISO 3166-1:
| Campo | Tipo | Descripcion | Ejemplo |
|---|---|---|---|
| id | UUID | Identificador unico | auto |
| name | string | Nombre del pais (traducible) | "Mexico" |
| code | char(2) | Codigo ISO 3166-1 alpha-2 | "MX" |
| code3 | char(3) | Codigo ISO 3166-1 alpha-3 | "MEX" |
| numeric_code | int | Codigo ISO 3166-1 numerico | 484 |
| phone_code | int | Codigo telefonico internacional | 52 |
| currency_id | FK | Moneda oficial | UUID-MXN |
| flag_url | string | URL a imagen de bandera | computed |
| is_active | boolean | Disponible para seleccion | true |
Datos:
- 249 paises segun ISO 3166-1
- Precargados en migracion inicial
RF-CATALOG-002.2: Formato de Direccion por Pais
Cada pais define su formato de direccion:
address_format: "%(street)s\n%(street2)s\n%(city)s %(state_code)s %(zip)s\n%(country_name)s"
| Campo | Tipo | Descripcion |
|---|---|---|
| address_format | text | Template de direccion |
| name_position | enum | before/after address |
| state_required | boolean | Estado obligatorio |
| zip_required | boolean | CP obligatorio |
| vat_label | string | Etiqueta para VAT (RFC, NIT, RUT) |
Ejemplos de formato:
Mexico:
"%(street)s\n%(street2)s\n%(zip)s %(city)s, %(state_code)s\n%(country_name)s"
USA:
"%(street)s\n%(street2)s\n%(city)s, %(state_code)s %(zip)s\n%(country_name)s"
Spain:
"%(street)s\n%(street2)s\n%(zip)s %(city)s (%(state_name)s)\n%(country_name)s"
RF-CATALOG-002.3: Estados/Provincias
Subdivisiones de paises segun ISO 3166-2:
| Campo | Tipo | Descripcion | Ejemplo |
|---|---|---|---|
| id | UUID | Identificador unico | auto |
| country_id | FK | Pais padre | UUID-MX |
| name | string | Nombre del estado | "Jalisco" |
| code | string | Codigo ISO 3166-2 | "MX-JAL" |
| is_active | boolean | Disponible para seleccion | true |
Datos:
- ~4,000 subdivisiones globales
- Precargados para paises principales (MX, US, ES, CO, AR, etc.)
RF-CATALOG-002.4: Grupos de Paises
Agrupaciones regionales para configuraciones:
| Campo | Tipo | Descripcion |
|---|---|---|
| id | UUID | Identificador unico |
| name | string | Nombre del grupo |
| country_ids | M:N | Paises incluidos |
Grupos predefinidos:
- EU (Union Europea)
- LATAM (Latinoamerica)
- NAFTA (Norteamerica)
- MERCOSUR
- CARICOM
Operaciones (Solo Lectura para Tenants)
Listar Paises
GET /api/v1/catalogs/countries?active=true&search=mex
Response:
{
"data": [
{
"id": "uuid",
"name": "Mexico",
"code": "MX",
"phoneCode": 52,
"flagUrl": "/flags/mx.png",
"currencyId": "uuid-mxn"
}
]
}
Obtener Estados de un Pais
GET /api/v1/catalogs/countries/:code/states
Response:
{
"data": [
{ "id": "uuid", "name": "Aguascalientes", "code": "MX-AGU" },
{ "id": "uuid", "name": "Jalisco", "code": "MX-JAL" },
...
]
}
Busqueda de Paises
GET /api/v1/catalogs/countries/search?q=me
// Busca en: name, code, code3
Response:
[
{ "id": "uuid", "name": "Mexico", "code": "MX" },
{ "id": "uuid", "name": "Montenegro", "code": "ME" }
]
Restricciones
Catalogo Global - Solo Lectura
| Operacion | Permitido | Rol Requerido |
|---|---|---|
| Leer | Si | Cualquier usuario autenticado |
| Crear | No | - (Solo migracion) |
| Actualizar | No | - (Solo platform_admin) |
| Eliminar | No | - (Solo platform_admin) |
Justificacion: Los datos de paises son estandares internacionales que no deben ser modificados por tenants individuales.
Sin RLS
Las tablas de paises y estados NO tienen tenant_id ni RLS:
-- No tiene tenant_id
CREATE TABLE core_catalogs.countries (
id UUID PRIMARY KEY,
name VARCHAR(100) NOT NULL,
code CHAR(2) NOT NULL UNIQUE,
...
);
-- Sin RLS
-- ALTER TABLE ... ENABLE ROW LEVEL SECURITY; (NO APLICAR)
Seed de Datos
Fuentes de Datos
| Datos | Fuente | Cantidad |
|---|---|---|
| Paises | ISO 3166-1 | 249 |
| Estados MX | INEGI | 32 |
| Estados US | USPS | 50 + DC + territories |
| Estados ES | INE | 52 provincias |
| Otros | ISO 3166-2 | Variable |
Script de Carga
-- Paises principales (ejemplo)
INSERT INTO core_catalogs.countries (name, code, code3, numeric_code, phone_code, vat_label) VALUES
('Mexico', 'MX', 'MEX', 484, 52, 'RFC'),
('United States', 'US', 'USA', 840, 1, 'Tax ID'),
('Spain', 'ES', 'ESP', 724, 34, 'NIF'),
('Colombia', 'CO', 'COL', 170, 57, 'NIT'),
('Argentina', 'AR', 'ARG', 32, 54, 'CUIT');
-- Estados Mexico (ejemplo)
INSERT INTO core_catalogs.states (country_id, name, code) VALUES
((SELECT id FROM countries WHERE code = 'MX'), 'Aguascalientes', 'MX-AGU'),
((SELECT id FROM countries WHERE code = 'MX'), 'Baja California', 'MX-BCN'),
...
Casos de Prueba
| ID | Escenario | Resultado Esperado |
|---|---|---|
| TC-001 | Listar paises activos | 200+ paises |
| TC-002 | Obtener estados de Mexico | 32 estados |
| TC-003 | Buscar por codigo "MX" | Mexico encontrado |
| TC-004 | Buscar por nombre parcial | Resultados filtrados |
| TC-005 | Intentar crear pais (tenant) | 403 Forbidden |
| TC-006 | Pais inactivo no aparece en lista | Excluido |
Criterios de Aceptacion
- 249 paises cargados segun ISO 3166-1
- Estados cargados para paises principales
- Busqueda por nombre y codigo
- Formato de direccion por pais
- Solo lectura para tenants
- Banderas disponibles
Notas Tecnicas
Indices
-- Busqueda rapida
CREATE INDEX idx_countries_code ON core_catalogs.countries(code);
CREATE INDEX idx_countries_name ON core_catalogs.countries(name);
CREATE INDEX idx_states_country ON core_catalogs.states(country_id);
CREATE INDEX idx_states_code ON core_catalogs.states(code);
Cache
Los catalogos globales deben cachearse agresivamente:
- TTL: 24 horas
- Invalidacion: Manual por platform_admin
Historial
| Version | Fecha | Autor | Cambios |
|---|---|---|---|
| 1.0 | 2025-12-05 | System | Creacion inicial |