clinica-dental/docs/02-definicion-modulos/modulo-odontograma.md
rckrdmrd a290bd564a feat: Add orchestration configuration and project documentation
- 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>
2026-01-07 05:40:51 -06:00

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