- Add CONTEXT-MAP.yml and PROJECT-STATUS.md - Add _MAP.md for documentation index - Update orchestration structure 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
561 lines
12 KiB
Markdown
561 lines
12 KiB
Markdown
# Modulo Odontograma
|
|
|
|
**Proyecto:** clinica-dental
|
|
**Modulo:** ODT-001
|
|
**Prioridad:** P1 - Core
|
|
**Estado:** Especificacion
|
|
**Fecha:** 2026-01-07
|
|
|
|
---
|
|
|
|
## 1. DESCRIPCION GENERAL
|
|
|
|
El odontograma es el registro grafico del estado dental del paciente. Representa visualmente cada pieza dental con su condicion actual, tratamientos realizados e historial de cambios.
|
|
|
|
### Proposito
|
|
- Visualizar estado completo de la dentadura
|
|
- Registrar condicion de cada pieza dental
|
|
- Documentar caras afectadas
|
|
- Mantener historial de cambios
|
|
- Facilitar diagnostico y plan de tratamiento
|
|
|
|
### Alcance
|
|
- Adultos (32 piezas permanentes)
|
|
- Ninos (20 piezas deciduas)
|
|
- Estados por pieza
|
|
- Historial temporal
|
|
- Anotaciones por pieza
|
|
|
|
---
|
|
|
|
## 2. ENTIDADES
|
|
|
|
### 2.1 odontograma
|
|
|
|
```yaml
|
|
tabla: dental.odontogramas
|
|
descripcion: "Registro principal del estado dental"
|
|
|
|
campos:
|
|
- nombre: id
|
|
tipo: UUID
|
|
pk: true
|
|
descripcion: "Identificador unico"
|
|
|
|
- nombre: paciente_id
|
|
tipo: UUID
|
|
fk: clinicas.pacientes(id)
|
|
not_null: true
|
|
descripcion: "Paciente al que pertenece"
|
|
|
|
- nombre: tipo
|
|
tipo: ENUM
|
|
valores: ['adulto', 'deciduo', 'mixto']
|
|
default: 'adulto'
|
|
descripcion: "Tipo de denticion"
|
|
|
|
- nombre: fecha_registro
|
|
tipo: TIMESTAMP
|
|
default: NOW()
|
|
descripcion: "Fecha de creacion"
|
|
|
|
- nombre: fecha_actualizacion
|
|
tipo: TIMESTAMP
|
|
descripcion: "Ultima modificacion"
|
|
|
|
- nombre: odontologo_id
|
|
tipo: UUID
|
|
fk: core.usuarios(id)
|
|
descripcion: "Odontologo que registro"
|
|
|
|
- nombre: notas_generales
|
|
tipo: TEXT
|
|
descripcion: "Observaciones generales"
|
|
|
|
- nombre: activo
|
|
tipo: BOOLEAN
|
|
default: true
|
|
descripcion: "Odontograma vigente"
|
|
|
|
indices:
|
|
- nombre: idx_odontograma_paciente
|
|
campos: [paciente_id]
|
|
- nombre: idx_odontograma_fecha
|
|
campos: [fecha_registro DESC]
|
|
|
|
rls:
|
|
- policy: "tenant_isolation"
|
|
using: "tenant_id = current_tenant_id()"
|
|
```
|
|
|
|
### 2.2 pieza_dental
|
|
|
|
```yaml
|
|
tabla: dental.piezas_dentales
|
|
descripcion: "Estado individual de cada pieza"
|
|
|
|
campos:
|
|
- nombre: id
|
|
tipo: UUID
|
|
pk: true
|
|
|
|
- nombre: odontograma_id
|
|
tipo: UUID
|
|
fk: dental.odontogramas(id)
|
|
not_null: true
|
|
on_delete: CASCADE
|
|
|
|
- nombre: numero_pieza
|
|
tipo: INTEGER
|
|
not_null: true
|
|
check: "(numero_pieza BETWEEN 11 AND 48) OR (numero_pieza BETWEEN 51 AND 85)"
|
|
descripcion: "Numero FDI de la pieza"
|
|
|
|
- nombre: estado
|
|
tipo: ENUM
|
|
valores: ['sano', 'caries', 'obturacion_resina', 'obturacion_amalgama',
|
|
'endodoncia', 'corona', 'puente_pilar', 'puente_ponico',
|
|
'implante', 'ausente', 'extraccion_indicada', 'supernumerario',
|
|
'retenido', 'fracturado']
|
|
default: 'sano'
|
|
descripcion: "Estado actual de la pieza"
|
|
|
|
- nombre: caras_afectadas
|
|
tipo: TEXT[]
|
|
descripcion: "Array de caras: M, D, O, V, L, I, P"
|
|
|
|
- nombre: movilidad
|
|
tipo: INTEGER
|
|
check: "movilidad BETWEEN 0 AND 3"
|
|
descripcion: "Grado de movilidad (0=normal, 3=severa)"
|
|
|
|
- nombre: sensibilidad
|
|
tipo: BOOLEAN
|
|
default: false
|
|
descripcion: "Sensibilidad al frio/calor"
|
|
|
|
- nombre: notas
|
|
tipo: TEXT
|
|
descripcion: "Observaciones especificas"
|
|
|
|
- nombre: fecha_actualizacion
|
|
tipo: TIMESTAMP
|
|
default: NOW()
|
|
|
|
indices:
|
|
- nombre: idx_pieza_odontograma
|
|
campos: [odontograma_id]
|
|
- nombre: idx_pieza_numero
|
|
campos: [odontograma_id, numero_pieza]
|
|
unique: true
|
|
|
|
constraints:
|
|
- nombre: uk_pieza_odontograma
|
|
tipo: UNIQUE
|
|
campos: [odontograma_id, numero_pieza]
|
|
```
|
|
|
|
### 2.3 historial_pieza
|
|
|
|
```yaml
|
|
tabla: dental.historial_piezas
|
|
descripcion: "Cambios historicos en cada pieza"
|
|
|
|
campos:
|
|
- nombre: id
|
|
tipo: UUID
|
|
pk: true
|
|
|
|
- nombre: pieza_id
|
|
tipo: UUID
|
|
fk: dental.piezas_dentales(id)
|
|
not_null: true
|
|
on_delete: CASCADE
|
|
|
|
- nombre: estado_anterior
|
|
tipo: VARCHAR(50)
|
|
|
|
- nombre: estado_nuevo
|
|
tipo: VARCHAR(50)
|
|
not_null: true
|
|
|
|
- nombre: caras_anterior
|
|
tipo: TEXT[]
|
|
|
|
- nombre: caras_nuevo
|
|
tipo: TEXT[]
|
|
|
|
- nombre: tratamiento_id
|
|
tipo: UUID
|
|
fk: dental.tratamientos(id)
|
|
descripcion: "Tratamiento que causo el cambio"
|
|
|
|
- nombre: fecha_cambio
|
|
tipo: TIMESTAMP
|
|
default: NOW()
|
|
|
|
- nombre: odontologo_id
|
|
tipo: UUID
|
|
fk: core.usuarios(id)
|
|
|
|
- nombre: motivo
|
|
tipo: TEXT
|
|
descripcion: "Razon del cambio"
|
|
|
|
indices:
|
|
- nombre: idx_historial_pieza
|
|
campos: [pieza_id]
|
|
- nombre: idx_historial_fecha
|
|
campos: [fecha_cambio DESC]
|
|
```
|
|
|
|
---
|
|
|
|
## 3. NOMENCLATURA FDI
|
|
|
|
### Sistema de Numeracion
|
|
|
|
```
|
|
SUPERIOR
|
|
┌───────────┬───────────┐
|
|
│ Derecho │ Izquierdo │
|
|
│ 18-11 │ 21-28 │
|
|
├───────────┼───────────┤
|
|
│ 48-41 │ 31-38 │
|
|
│ Derecho │ Izquierdo │
|
|
└───────────┴───────────┘
|
|
INFERIOR
|
|
```
|
|
|
|
### Dientes Permanentes (32 piezas)
|
|
|
|
| Cuadrante | Posicion | Piezas | Descripcion |
|
|
|-----------|----------|--------|-------------|
|
|
| 1 | Superior Derecho | 11-18 | Incisivo central a 3er molar |
|
|
| 2 | Superior Izquierdo | 21-28 | Incisivo central a 3er molar |
|
|
| 3 | Inferior Izquierdo | 31-38 | Incisivo central a 3er molar |
|
|
| 4 | Inferior Derecho | 41-48 | Incisivo central a 3er molar |
|
|
|
|
### Dientes Deciduos (20 piezas)
|
|
|
|
| Cuadrante | Posicion | Piezas | Descripcion |
|
|
|-----------|----------|--------|-------------|
|
|
| 5 | Superior Derecho | 51-55 | Incisivo a 2do molar |
|
|
| 6 | Superior Izquierdo | 61-65 | Incisivo a 2do molar |
|
|
| 7 | Inferior Izquierdo | 71-75 | Incisivo a 2do molar |
|
|
| 8 | Inferior Derecho | 81-85 | Incisivo a 2do molar |
|
|
|
|
### Caras Dentales
|
|
|
|
| Sigla | Nombre | Aplicable a |
|
|
|-------|--------|-------------|
|
|
| M | Mesial | Todas |
|
|
| D | Distal | Todas |
|
|
| O | Oclusal | Premolares, Molares |
|
|
| I | Incisal | Incisivos, Caninos |
|
|
| V | Vestibular | Todas |
|
|
| B | Bucal | Sinonimo de V |
|
|
| L | Lingual | Inferiores |
|
|
| P | Palatino | Superiores |
|
|
|
|
---
|
|
|
|
## 4. ESTADOS DE PIEZAS
|
|
|
|
### Catalogo de Estados
|
|
|
|
```yaml
|
|
estados:
|
|
- codigo: SANO
|
|
nombre: "Sano"
|
|
color: "#4CAF50"
|
|
descripcion: "Pieza sin patologia"
|
|
|
|
- codigo: CARIES
|
|
nombre: "Caries"
|
|
color: "#F44336"
|
|
descripcion: "Lesion cariosa activa"
|
|
|
|
- codigo: OBT_RES
|
|
nombre: "Obturacion Resina"
|
|
color: "#2196F3"
|
|
descripcion: "Restauracion con resina"
|
|
|
|
- codigo: OBT_AMG
|
|
nombre: "Obturacion Amalgama"
|
|
color: "#9E9E9E"
|
|
descripcion: "Restauracion con amalgama"
|
|
|
|
- codigo: ENDO
|
|
nombre: "Endodoncia"
|
|
color: "#9C27B0"
|
|
descripcion: "Tratamiento de conductos"
|
|
|
|
- codigo: CORONA
|
|
nombre: "Corona"
|
|
color: "#FFC107"
|
|
descripcion: "Corona protesica"
|
|
|
|
- codigo: PUENTE_P
|
|
nombre: "Puente Pilar"
|
|
color: "#FF9800"
|
|
descripcion: "Pieza pilar de puente"
|
|
|
|
- codigo: PUENTE_O
|
|
nombre: "Puente Ponico"
|
|
color: "#FF5722"
|
|
descripcion: "Pieza artificial de puente"
|
|
|
|
- codigo: IMPLANTE
|
|
nombre: "Implante"
|
|
color: "#00BCD4"
|
|
descripcion: "Implante dental"
|
|
|
|
- codigo: AUSENTE
|
|
nombre: "Ausente"
|
|
color: "#BDBDBD"
|
|
descripcion: "Pieza extraida"
|
|
|
|
- codigo: EXT_IND
|
|
nombre: "Extraccion Indicada"
|
|
color: "#E91E63"
|
|
descripcion: "Requiere extraccion"
|
|
|
|
- codigo: FRACTURADO
|
|
nombre: "Fracturado"
|
|
color: "#795548"
|
|
descripcion: "Pieza fracturada"
|
|
```
|
|
|
|
---
|
|
|
|
## 5. API ENDPOINTS
|
|
|
|
### Odontograma
|
|
|
|
```yaml
|
|
endpoints:
|
|
- method: GET
|
|
path: /api/v1/pacientes/{pacienteId}/odontograma
|
|
descripcion: "Obtener odontograma actual"
|
|
response: Odontograma con todas las piezas
|
|
|
|
- method: POST
|
|
path: /api/v1/pacientes/{pacienteId}/odontograma
|
|
descripcion: "Crear nuevo odontograma"
|
|
body:
|
|
tipo: string (adulto|deciduo|mixto)
|
|
notas_generales: string (opcional)
|
|
response: Odontograma creado
|
|
|
|
- method: PUT
|
|
path: /api/v1/odontogramas/{odontogramaId}
|
|
descripcion: "Actualizar odontograma"
|
|
body:
|
|
notas_generales: string
|
|
response: Odontograma actualizado
|
|
```
|
|
|
|
### Piezas Dentales
|
|
|
|
```yaml
|
|
endpoints:
|
|
- method: GET
|
|
path: /api/v1/odontogramas/{odontogramaId}/piezas
|
|
descripcion: "Obtener todas las piezas"
|
|
response: Array de piezas
|
|
|
|
- method: GET
|
|
path: /api/v1/odontogramas/{odontogramaId}/piezas/{numeroPieza}
|
|
descripcion: "Obtener pieza especifica"
|
|
response: Pieza con historial
|
|
|
|
- method: PUT
|
|
path: /api/v1/odontogramas/{odontogramaId}/piezas/{numeroPieza}
|
|
descripcion: "Actualizar estado de pieza"
|
|
body:
|
|
estado: string
|
|
caras_afectadas: string[]
|
|
movilidad: number (0-3)
|
|
sensibilidad: boolean
|
|
notas: string
|
|
motivo: string
|
|
response: Pieza actualizada + entrada en historial
|
|
|
|
- method: GET
|
|
path: /api/v1/piezas/{piezaId}/historial
|
|
descripcion: "Historial de cambios de pieza"
|
|
query:
|
|
desde: date
|
|
hasta: date
|
|
response: Array de cambios
|
|
```
|
|
|
|
---
|
|
|
|
## 6. FLUJOS DE USUARIO
|
|
|
|
### 6.1 Crear Odontograma Inicial
|
|
|
|
```
|
|
1. Paciente nuevo o sin odontograma
|
|
2. Odontologo abre pantalla de odontograma
|
|
3. Sistema detecta que no existe → muestra dialogo
|
|
4. Selecciona tipo: Adulto / Deciduo / Mixto
|
|
5. Sistema crea odontograma con 32/20 piezas en estado SANO
|
|
6. Odontologo realiza exploracion
|
|
7. Marca cada pieza segun estado actual
|
|
8. Guarda odontograma
|
|
```
|
|
|
|
### 6.2 Actualizar Estado de Pieza
|
|
|
|
```
|
|
1. Odontologo abre odontograma existente
|
|
2. Click en pieza a modificar
|
|
3. Panel lateral muestra estado actual + historial
|
|
4. Selecciona nuevo estado del dropdown
|
|
5. Marca caras afectadas (checkboxes)
|
|
6. Agrega notas (opcional)
|
|
7. Indica motivo del cambio
|
|
8. Guarda cambios
|
|
9. Sistema registra en historial
|
|
```
|
|
|
|
### 6.3 Comparar Odontogramas
|
|
|
|
```
|
|
1. Odontologo solicita comparacion
|
|
2. Selecciona dos fechas
|
|
3. Sistema muestra lado a lado
|
|
4. Resalta piezas con cambios
|
|
5. Permite ver detalle de cada cambio
|
|
```
|
|
|
|
---
|
|
|
|
## 7. COMPONENTES UI
|
|
|
|
### 7.1 OdontogramaView
|
|
|
|
```typescript
|
|
interface OdontogramaViewProps {
|
|
pacienteId: string;
|
|
readOnly?: boolean;
|
|
onPiezaClick?: (pieza: PiezaDental) => void;
|
|
}
|
|
|
|
// Estados visuales
|
|
const COLORES_ESTADO: Record<EstadoPieza, string> = {
|
|
sano: '#4CAF50',
|
|
caries: '#F44336',
|
|
obturacion_resina: '#2196F3',
|
|
// ...
|
|
};
|
|
```
|
|
|
|
### 7.2 PiezaDentalComponent
|
|
|
|
```typescript
|
|
interface PiezaDentalProps {
|
|
numero: number;
|
|
estado: EstadoPieza;
|
|
carasAfectadas: string[];
|
|
selected: boolean;
|
|
onClick: () => void;
|
|
}
|
|
|
|
// Renderiza SVG de pieza con colores por estado
|
|
// Marca visual de caras afectadas
|
|
```
|
|
|
|
### 7.3 HistorialPiezaPanel
|
|
|
|
```typescript
|
|
interface HistorialPiezaPanelProps {
|
|
piezaId: string;
|
|
onClose: () => void;
|
|
}
|
|
|
|
// Muestra timeline de cambios
|
|
// Permite filtrar por fecha
|
|
// Link a tratamientos relacionados
|
|
```
|
|
|
|
---
|
|
|
|
## 8. VALIDACIONES
|
|
|
|
### Reglas de Negocio
|
|
|
|
```yaml
|
|
validaciones:
|
|
- regla: "Pieza ausente no puede tener caras afectadas"
|
|
condicion: estado == 'ausente' AND caras_afectadas.length > 0
|
|
error: "Una pieza ausente no puede tener caras afectadas"
|
|
|
|
- regla: "Corona cubre todas las caras"
|
|
condicion: estado == 'corona' AND caras_afectadas != ['M','D','O','V','L']
|
|
accion: "Auto-completar todas las caras"
|
|
|
|
- regla: "Numero de pieza valido"
|
|
condicion: NOT (numero IN rango_valido)
|
|
error: "Numero de pieza dental invalido"
|
|
|
|
- regla: "Implante requiere pieza ausente previa"
|
|
condicion: estado == 'implante' AND estado_anterior != 'ausente'
|
|
warning: "Normalmente se coloca implante en espacio de pieza ausente"
|
|
```
|
|
|
|
---
|
|
|
|
## 9. CASOS DE USO
|
|
|
|
### CU-ODT-001: Exploración Inicial
|
|
|
|
**Actor:** Odontólogo
|
|
**Precondición:** Paciente registrado sin odontograma
|
|
**Flujo:**
|
|
1. Abrir expediente del paciente
|
|
2. Ir a sección Odontograma
|
|
3. Crear nuevo odontograma (tipo adulto)
|
|
4. Realizar exploración pieza por pieza
|
|
5. Marcar estados encontrados
|
|
6. Guardar odontograma
|
|
|
|
**Postcondición:** Odontograma creado con estado inicial
|
|
|
|
### CU-ODT-002: Registrar Tratamiento
|
|
|
|
**Actor:** Odontólogo
|
|
**Precondición:** Odontograma existente, tratamiento a realizar
|
|
**Flujo:**
|
|
1. Abrir odontograma del paciente
|
|
2. Seleccionar pieza tratada
|
|
3. Cambiar estado (ej: caries → obturación_resina)
|
|
4. Marcar caras tratadas
|
|
5. Vincular con tratamiento
|
|
6. Guardar cambios
|
|
|
|
**Postcondición:** Estado actualizado, historial registrado
|
|
|
|
---
|
|
|
|
## 10. DEPENDENCIAS
|
|
|
|
### Depende de
|
|
- `clinicas.pacientes` - Paciente al que pertenece
|
|
- `core.usuarios` - Odontólogo que registra
|
|
- `dental.tratamientos` - Vinculación de cambios
|
|
|
|
### Dependientes
|
|
- `dental.tratamientos` - Referencia piezas afectadas
|
|
- `dental.presupuestos` - Calcula costos por pieza
|
|
- `reportes` - Estadísticas de salud dental
|
|
|
|
---
|
|
|
|
**Documento creado:** 2026-01-07
|
|
**Autor:** Agente Orquestador Workspace
|
|
**Version:** 1.0.0
|