Base de Datos
La API usa Cloudflare D1 (SQLite distribuido) con Drizzle ORM.
Diagrama Entidad-Relación
erDiagram
API_KEYS ||--o{ OAUTH_TOKENS : "client_name"
API_KEYS {
text id PK
text client_name UK
text key UK
text description
int active
int created_at
int last_used_at
}
OAUTH_TOKENS {
text id PK
text client_name UK
text access_token
text refresh_token
text token_type
text scope
text public_key
int mp_user_id
int live_mode
text expires_at
int created_at
int updated_at
}
OAUTH_STATES {
text id PK
text client_name
text target_url
text code_verifier
text used_at
int created_at
}
STORES ||--|{ POS : "store_id"
STORES {
text id PK
text client_name
text mp_store_id
text external_id
text name
text street_name
text city_name
text state_name
real latitude
real longitude
int created_at
}
POS {
text id PK
text client_name
text store_id FK
text mp_pos_id
text mp_qr_id
text external_id
text external_store_id
text name
int created_at
}
ORDERS {
text id PK
text client_name
text mp_order_id UK
text external_reference
text idempotency_key
text caja_id
text sucursal_id
text terminal_id
text amount
text description
text status
text mp_status
text mp_status_detail
int created_at
int updated_at
int processed_at
}
WEBHOOK_LOGS {
text id PK
text action
text order_id
text external_reference
text status
text raw_payload
int created_at
}
ACTIVITY_LOGS {
text id PK
text client_name
text ip_address
text action
text resource_type
text resource_id
text status
text error_message
text metadata
int duration_ms
int created_at
}
Tablas
api_keys
Credenciales de acceso por cliente. El admin crea/revoca keys.
| Columna | Tipo | Descripción |
|---|---|---|
id |
TEXT PK | UUID |
client_name |
TEXT UNIQUE | Nombre del cliente |
key |
TEXT UNIQUE | API key (mk_ + 64 hex chars) |
description |
TEXT | Descripción opcional |
active |
INT | 1 = activa, 0 = revocada |
created_at |
INT | Unix timestamp |
last_used_at |
INT | Última vez usada |
oauth_tokens
Tokens OAuth de MercadoPago por cliente.
| Columna | Tipo | Descripción |
|---|---|---|
client_name |
TEXT UNIQUE | Nombre del cliente |
access_token |
TEXT | Token de acceso a MP |
refresh_token |
TEXT | Token de renovación |
mp_user_id |
INT | User ID en MercadoPago |
live_mode |
INT | 1 = producción, 0 = sandbox |
expires_at |
TEXT | Fecha de expiración |
oauth_states
States temporales para el flujo OAuth PKCE. Se limpian diariamente.
stores
Sucursales mapeadas entre el ERP y MercadoPago.
| Columna | Tipo | Descripción |
|---|---|---|
external_id |
TEXT | ID del ERP (ej: SUC001) |
mp_store_id |
TEXT | ID en MercadoPago |
name |
TEXT | Nombre de la sucursal |
location |
— | Dirección, coordenadas |
pos
Cajas POS asociadas a sucursales.
| Columna | Tipo | Descripción |
|---|---|---|
external_id |
TEXT | ID del ERP (ej: SUC001-POS001) |
mp_pos_id |
TEXT | ID en MercadoPago |
store_id |
TEXT FK | Referencia a stores |
external_store_id |
TEXT | External ID de la sucursal padre |
orders
Órdenes de pago con estado sincronizado desde MercadoPago.
| Columna | Tipo | Descripción |
|---|---|---|
idempotency_key |
TEXT | UUID generado por el sistema (único por cliente) |
mp_order_id |
TEXT UNIQUE | ID de la orden en MP |
external_reference |
TEXT | Referencia del ERP (puede repetirse) |
caja_id |
TEXT | ID de la caja del ERP |
amount |
TEXT | Monto normalizado (con punto) |
status |
TEXT | Estado interno: created, completed, canceled, updated |
mp_status |
TEXT | Estado real de MP |
activity_logs
Log de auditoría de operaciones de escritura (POST, PUT, DELETE).
| Columna | Tipo | Descripción |
|---|---|---|
action |
TEXT | Ej: order.created, store.deleted |
resource_type |
TEXT | Ej: order, store, api_key |
resource_id |
TEXT | ID del recurso afectado |
status |
TEXT | success o failed |
metadata |
TEXT (JSON) | Datos adicionales de la operación |
duration_ms |
INT | Duración de la operación |
Índices
-- API Keys
CREATE UNIQUE INDEX idx_api_keys_key ON api_keys(key);
CREATE UNIQUE INDEX idx_api_keys_client ON api_keys(client_name);
-- Orders
CREATE UNIQUE INDEX idx_orders_mp_id ON orders(mp_order_id);
CREATE UNIQUE INDEX idx_orders_idempotency ON orders(client_name, idempotency_key);
CREATE INDEX idx_orders_client ON orders(client_name);
CREATE INDEX idx_orders_external_ref ON orders(client_name, external_reference);
-- Stores / POS
CREATE UNIQUE INDEX idx_stores_external ON stores(client_name, external_id);
CREATE UNIQUE INDEX idx_pos_external ON pos(client_name, external_id);
-- Activity Logs
CREATE INDEX idx_activity_client_created ON activity_logs(client_name, created_at);
CREATE INDEX idx_activity_resource ON activity_logs(resource_type, resource_id);
CREATE INDEX idx_activity_action ON activity_logs(action);
Migraciones
Las migraciones están en migrations/ y se ejecutan con:
| Archivo | Descripción |
|---|---|
0001_oauth_states.sql |
Estados OAuth PKCE |
0002_oauth_tokens.sql |
Tokens OAuth |
0003_stores_and_pos.sql |
Sucursales y POS |
0004_orders.sql |
Órdenes de pago |
0005_api_keys.sql |
API keys |
0006_activity_logs.sql |
Logs de auditoría |