Tickets, Doku, Zeiterfassung und Kundengespräche an einem Ort, durchsuchbar per KI. Für Softwarefirmen mit Kundenprojekten. Open Source: auf deinem eigenen Server oder in unserer Cloud in Deutschland.
Mineria Artesanal y Pequeña Escala - Plataforma administrativa
翻译准备中
取自仓库 README
README
正在加载完整 README。 以下为已保存的摘录。
Versión 1.1 — Piloto Iriona 2026
Última actualización: 3 de agosto de 2026
Propietario: MAPE LEGAL
Administrador Único: Willis Yang
Dominio: mape.legal · App privada en Vercel + Supabase
0. BRAND IDENTITY · COLOR MANUAL v1.0
Hard rule: El color manual de abajo es la única fuente de verdad para color y tipografía en MAPE LEGAL. No invented hex outside this manual — si un color que necesitas no está aquí, no existe; abre PR para agregarlo.
Versión 1.1 — Piloto Iriona 2026
Última actualización: 3 de agosto de 2026
Propietario: MAPE LEGAL
Administrador Único: Willis Yang
Dominio: mape.legal · App privada en Vercel + Supabase
0. BRAND IDENTITY · COLOR MANUAL v1.0
Hard rule: El color manual de abajo es la única fuente de verdad para color y tipografía en MAPE LEGAL. No invented hex outside this manual — si un color que necesitas no está aquí, no existe; abre PR para agregarlo.
Future work (frontend, backend, emails, dashboard, landing, broadcast templates, asistente María) debe alinearse a esta identidad. Cualquier hex hardcodeado fuera de app/globals.css es deuda técnica y debe reemplazarse por el token correspondiente.
Principio de marca
"Tinta, piedra, musgo." — autoridad natural, no naturaleza decorativa.
Nota: este proyecto usa Tailwind v4 con @theme inline en globals.css — notailwind.config.js. Si introduces Tailwind config-based en otro repo (mobile, packaging), usa los mismos hex aliasados como ink, moss, state.{ok,warn,block,info}.
Fuentes: las utilidades de Tailwind que deban usar una fuente de marca tienen que estar mapeadas en @theme inline — hoy --font-sans: var(--font-body). Sin ese mapeo la clase font-sans sustituye Inter por la fuente del sistema operativo. Ver DESIGN.md §10.
0.6 Documentos relacionados
DESIGN.md — guía completa de componentes UI, escala tipográfica, reglas de uso.
docs/auditoria-marca-2026-08.md — auditoría de cumplimiento del manual contra el código real (2026-08-05). Estado por área, deuda pendiente y falsos positivos ya descartados.
1. VISIÓN Y PROPÓSITO
MAPE.LEGAL es la plataforma digital que actúa como motor de evidencia legal de origen mineral para minería artesanal y de pequeña escala en Honduras.
Su propósito es generar, almacenar y certificar evidencia legalmente defendible de que el oro proviene de operaciones formalizadas conforme a la Ley de Minería, Reglamento MAPE (Acuerdo 042-2013), ILO 169, SLAS-2 y estándares internacionales (CRAFT / Fairmined / RJC).
2. CONTEXTO DE NEGOCIO
MAPE LEGAL = marca institucional del proyecto
Fundador: Willis Yang (Administrador Único)
Socio 50%: Ricardo Alfredo Montes Nájera
Modelo de negocio:
MAPE.LEGAL opera bajo dos líneas: (1) servicios de formalización minera (expediente, licenciamiento ambiental y trazabilidad documental), con precios publicados en el sitio; y (2) comercialización formal de oro con origen certificado, bajo un precio de referencia diario publicado y una Política de Precios versionada, conforme a los Arts. 37 y 38 de la Ley General de Minería. Los términos económicos específicos con contrapartes se rigen por sus contratos y no forman parte de este documento.
Piloto 2026: Asociación de Mineros de Iriona, Colón (~60 mineros)
Catálogo de servicios:
Servicio
Precio
Pagos
Formalización Minera MAPE
L 1.600.000
3 hitos: 20% / 30% / 50%
Titulación de Propiedad
L 60.000 base + L 25.000/manzana adicional
Único
Contrato de Sociedad Minera
L 55.000 (co-pago 50/50)
Único
3. ARQUITECTURA TÉCNICA
Componente
Decisión
Hosting
Vercel
Base de datos
Supabase (PostgreSQL + Auth + Storage)
Framework
Next.js 16.2.4 (App Router, Turbopack)
Frontend
React 19 + Tailwind v4 (@theme inline)
Autenticación
httpOnly cookies (auth-token, auth-role, user-email) — 4 roles
Guard de rutas
proxy.ts (Next.js 16 — ES el middleware del framework; valida sesión real vía lib/sessionValidator.ts)
Email
SendGrid REST API
WhatsApp
Meta Cloud API v21.0 (webhook) + Twilio (María bot)
IA
Anthropic Claude Haiku (claude-haiku-4-5-20251001) — asistente María
4. ESQUEMA DE BASE DE DATOS (40 migraciones)
Migración
Contenido
001
Workflow por fases, pagos, auditoría
002
Grafo de transiciones explícito, historial de fases
003
Renombrado al español (fases, pagos, registro_auditoria…)
Historial: últimos 20 mensajes de conversaciones_whatsapp por número
Contexto dinámico: inyecta datos del cliente conocido; suprime re-saludos en conversaciones en curso
Auto-registro: extrae nombre y municipio de la conversación y registra en clientes
Dedup: filtra mensajes assistant consecutivos antes de enviar a Claude
Trigger de transacción: "✅ Listo" + "Confirmas" → inserta en transacciones_pendientes
Modo admin: willis yang + passphrase (MARIA_ADMIN_PASSPHRASE en env; requiere además rol='admin' en usuarios_broadcast) → reporte ejecutivo de 3 mensajes
Contact forwarding: respuestas con promesa de callback → alerta WhatsApp a Willis (+504 3210 0683)
7. MOTOR DE WORKFLOW
GET /api/expedientes/:id/next-actions
→ getNextActions(expedienteId)
→ getAvailableTransitions(fase_actual_id) ← grafo transiciones_fase
→ getBlockingReasons(expedienteId, faseId) ← chequea documentos + pagos
→ { can_advance, is_final, blocking[], available_transitions[] }
POST /api/expedientes/:id/transition
→ advancePhase(expedienteId, userId, transitionId)
→ valida condiciones
→ cierra expediente_fases (salida_en)
→ actualiza expedientes.fase_actual_id
→ abre nuevo expediente_fases (entrada_en)
→ inserta registro_auditoria
→ revierte si falla el insert
8. ESTADO ACTUAL (11 mayo 2026)
Completado
Dominio y hosting (Vercel + Supabase)
Schema completo — 23 migraciones (008 base + 010–023 incrementales)
Motor de workflow con chequeo real de documentos e is_final
Sistema RBAC: 4 roles, cookies httpOnly, guard proxy.ts
Webhook Meta Business Portal → /api/webhook/whatsapp
Webhook Twilio → /api/whatsapp
Runbook — Añadir conocimiento al RAG de María
Vercel no corre scripts de seed. Cada documento nuevo en data/maria-knowledge/** requiere dos pasos manuales antes de que María lo pueda citar. La omisión del paso 1 fue causa raíz del incidente 2026-05-15 (María deflectaba "¿Qué dice el Artículo 28-A?" a [email protected] porque los 165 chunks de Ley 104-93 / Decreto 181-2007 / SLAS-2 nunca se insertaron en producción).
Flujo canónico para añadir nuevo conocimiento:
Transcribir la fuente (PDF, gaceta, manual) a markdown verbatim en data/maria-knowledge/<categoria>/NN-titulo.md.
Escribir / extender el seed script en scripts/seed-maria-<categoria>.mjs siguiendo el patrón de seed-maria-honduras-ambiental.mjs (chunker estructura-aware, idempotente por source LIKE '<categoria>/%', soporta --dry-run --json).
Verificar localmente con node scripts/seed-maria-<categoria>.mjs --dry-run --json → revisar data/maria-knowledge/<categoria>.chunks.json y el conteo total de chunks.
Cargar a producción — elegir UNO:
(a) Con env vars locales (NEXT_PUBLIC_SUPABASE_URL + SUPABASE_SERVICE_ROLE_KEY):
node scripts/seed-maria-<categoria>.mjs
(b) Sin env vars locales — generar SQL pegable en Supabase Studio:
node scripts/seed-maria-<categoria>.mjs --dry-run --json
node scripts/chunks-json-to-sql.mjs data/maria-knowledge/<categoria>.chunks.json \
> data/maria-knowledge/seed-<categoria>.sql
# Pegar el .sql en Supabase Studio → SQL Editor → Run
Generar embeddings — log in como admin a /admin/maria/rag-health → botón "Completar (todas las pendientes)". Alternativamente node scripts/embed-maria-knowledge.mjs si hay env vars locales.
Verificar end-to-end:
/admin/maria/rag-health debe mostrar Sin embedding: 0 y banner verde RAG operativo.
Smoke test FTS desde SQL Editor: select * from public.search_maria_knowledge_fts('<keyword del nuevo doc>', 5); — debe retornar filas.
Pregunta de prueba por WhatsApp → María debe citar el documento.
Diagnóstico cuando "el RAG no funciona":
Primer chequeo: abrir /admin/maria/rag-health (admin only). El JSON / UI dice exactamente qué falta — env vars, RPCs, embeddings count, dim mismatch, OpenAI key, etc.
Segundo chequeo: SQL select source, count(*), count(*) filter (where embedding is not null) from public.maria_knowledge group by source; — confirma que (a) los chunks están seedeados y (b) tienen embedding.
Logs de Vercel filtrados por [rag] muestran si María elige path=semantic, path=fts, o path=none en cada turno.
Próximas fases en cola
Phase 2B — Transactions + Certificate issuance: transacciones_oro CRUD,
flujo de emisión que crea filas en certificados_origen con
hash_verificacion (SHA-256), generación de PDF imprimible. Después de 2B,
certificados reales fluyen a /verificar/[numero].
Phase 2C — Expediente full tracking: UI de fases INHGEOMIN, hitos,
tareas, upload de documentos atado a fases; cierra gap de contratos UI.
Phase 0 — Estabilización (recomendado entre 2B y 2C, dado que 2B es el
primer paso legalmente consecuente): middleware.ts, race conditions del
workflow, fix de import errors en webhook María, lint warning carryover en
app/dashboard/minas/page.tsx.
Phase 2D — Refactor visual: dashboard inline styles → tokens del
Color Manual v1.0.
Desbloqueo del cache de precios_diarios: policy service_all_precios_diarios idempotente + RPC upsert_precios_diarios SECURITY DEFINER
026
Mercado de Proyectos: projects, project_documents, document_chunks (vector 1536), document_tables, investor_project_access, document_access_log + RPCs de búsqueda híbrida + bucket project-documents
027
equipos_mercado (catálogo de maquinaria de lavado de oro): CHECK de 10 categorías, FTS español, soft-delete activo, RLS pública/admin/service_role + RPCs SECURITY DEFINER search_equipos_mercado, get_equipo_by_slug, equipos_categoria_stats. 12 productos seed.
028
precios_combustibles (diésel y combustibles regulados SEN) — valor almacenado + vigente_desde, RLS pública/staff/service_role
029
Bucket público equipos-imagenes (carga de láminas del admin de equipos)
030
precios_referencia + RPC reemplazar_precio_referencia — Precio de Referencia diario indeleble
031
ensayes — registro indeleble de determinaciones de ley (liquidación / contraste / verificación externa)
032
RLS en tablas de María: conversaciones_whatsapp + transacciones_pendientes (service role only)
033
RPC avanzar_expediente_fase — transición de expediente con SELECT ... FOR UPDATE (sin carreras)
034
Llaves de referencia institucional en minas (expediente INHGEOMIN, permiso municipal — campos internos)
035
verificaciones_fuente — registro append-only de verificación documental por entidad
036
certificados_origen.hash_sha256 + vista pública con huella y certificado_id
037
conversaciones_whatsapp.tipo_interlocutor — marca persistente de interlocutor institucional (gate de María)
038
Reparación Plan 2 (1/3): renames y backfills del esquema a-mano de producción al contrato del código (clientes/expedientes/documentos; indice_legalidad→legacy)
039
Reparación Plan 2 (2/3): motor de workflow (fases 0-4, transiciones, historial, auditoría, pagos) + tablas hijas del dashboard, sin seeds demo
040
Reparación Plan 2 (3/3): estructura del piloto (minas, contratos, indice_legalidad nuevo, transacciones_oro) con RLS, sin datos demo
Catálogo dinámico de roles con permisos JSON
contenido_cms
Contenido editable de la landing page
configuracion_sistema
Configuración global del sistema
notificaciones
Log de notificaciones enviadas
contactos
Formulario de contacto de la landing
registro_auditoria
Audit trail append-only
Pública — conteos por categoría (cache 300s)
/api/admin/equipos
GET / POST
Lista + creación de equipos (GET admin/abogado/tecnico, POST admin/abogado)
GET, PATCH /api/admin/indice-legalidad/[mina_id] (upsert por componente)
/dashboard/minas: modal "+ Nueva mina", row → detail link
/dashboard/minas/[id]: tabs General · Legalidad · Contratos · Transacciones
Edit modal para campos de mina; retiro vía estado='clausurada'
Cierra el gap de auditoría: minas UI 0/10 → ~7/10
Phase 2E — Registro INHGEOMIN público + María RAG (2026-05-11)
587 concesiones transcritas de 3 PDFs INHGEOMIN (125 explotación otorgada
170 exploración otorgada + 292 en solicitud)
Migración 023 con tabla concesiones_mineras_registro, vista pública,
RPCs search_concesion_minera y concesiones_minera_stats
(SECURITY DEFINER al estilo migración 019)
Admin UI /admin/concesiones con KPIs, filtros, paginación
Página pública /registro con búsqueda en vivo (debounce 250ms)
Endpoint público /api/concesiones/buscar con cache edge 60s + SWR 5min
María integration: buildConcesionContext() keyword-triggered,
inyecta hasta 5 filas en el system prompt con guardrail explícito de no
afirmar aprobación cuando la categoría es solicitud_pendiente