Files
Autoparts-DB/pos/migrations/v3.0_public_api.sql
Nexus Dev 9ff3dc4c8b FASE 4-5-6: Infraestructura, CRM, Service Orders, Notificaciones, Ahorro, Logistica, API Publica
FASE 4:
- Redis cache de stock con fallback graceful
- Multi-moneda (MXN/USD) con contabilidad en MXN
- Proveedores y ordenes de compra completo
- Meilisearch 1.5M+ partes indexadas
- Metabase KPIs con dashboard auto-generado

FASE 5:
- CRM mejorado: activities, tags, loyalty program, analytics
- Imagenes de partes: upload, resize, thumbnails WebP
- Ordenes de servicio Kanban: received->diagnosis->repair->ready->delivered
- Garantias/RMA, alertas de reorden, multi-sucursal
- Stubs BNPL (APLAZO) y ERP Sync (Aspel/Contpaqi)

FASE 6:
- Notificaciones automaticas: push/WhatsApp/email/in-app
- Reportes de ahorro vs retail_price
- Logistica + tracking: DHL, FedEx, Estafeta, 99min, Uber
- API Publica: API keys, rate limiting, catalog search

Migraciones: v1.9-v3.0
Tests: 93/93 pasando
Backup: nexus_backup_20260427_045859.tar.gz
2026-04-27 05:23:30 +00:00

48 lines
2.0 KiB
SQL

-- v3.0 Public API: API keys and rate limiting
CREATE TABLE IF NOT EXISTS api_keys (
id SERIAL PRIMARY KEY,
tenant_id INTEGER NOT NULL,
name VARCHAR(200) NOT NULL, -- e.g. "Integration Acme Corp"
key_hash VARCHAR(64) NOT NULL, -- SHA-256 hash of the API key
key_prefix VARCHAR(8) NOT NULL, -- first 8 chars for display
scopes JSONB DEFAULT '["read"]'::jsonb, -- ["read", "write", "admin"]
rate_limit_rpm INTEGER DEFAULT 60, -- requests per minute
rate_limit_rpd INTEGER DEFAULT 10000, -- requests per day
is_active BOOLEAN DEFAULT TRUE,
last_used_at TIMESTAMPTZ,
expires_at TIMESTAMPTZ,
created_by INTEGER REFERENCES employees(id),
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE UNIQUE INDEX IF NOT EXISTS idx_api_keys_hash ON api_keys(key_hash);
CREATE INDEX IF NOT EXISTS idx_api_keys_tenant ON api_keys(tenant_id, is_active);
-- API request log for analytics and abuse detection
CREATE TABLE IF NOT EXISTS api_request_logs (
id BIGSERIAL PRIMARY KEY,
api_key_id INTEGER REFERENCES api_keys(id),
tenant_id INTEGER,
method VARCHAR(10) NOT NULL,
path TEXT NOT NULL,
status_code INTEGER,
response_time_ms INTEGER,
ip_address INET,
user_agent TEXT,
created_at TIMESTAMPTZ DEFAULT NOW()
);
CREATE INDEX IF NOT EXISTS idx_api_logs_key ON api_request_logs(api_key_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_api_logs_tenant ON api_request_logs(tenant_id, created_at DESC);
CREATE INDEX IF NOT EXISTS idx_api_logs_path ON api_request_logs(path, created_at DESC);
-- Rate limit counters (in-memory/redis preferred, but table as fallback)
CREATE TABLE IF NOT EXISTS api_rate_limit_counters (
id SERIAL PRIMARY KEY,
api_key_id INTEGER NOT NULL REFERENCES api_keys(id) ON DELETE CASCADE,
window_start TIMESTAMPTZ NOT NULL,
window_type VARCHAR(10) NOT NULL, -- 'minute', 'day'
request_count INTEGER DEFAULT 0,
UNIQUE(api_key_id, window_start, window_type)
);
CREATE INDEX IF NOT EXISTS idx_rate_limit_window ON api_rate_limit_counters(api_key_id, window_type, window_start);