Sumario diario BORME
Índice de todos los actos publicados del día, con identificadores BORME-A-YYYY-NNN-NN y metadata estructural.
Cómo procesamos los datos
OpenMercantil convierte el Boletín Oficial del Registro Mercantil —publicado en PDF y XML por la Agencia Estatal BOE— en un dataset estructurado, versionado y consultable. Todo el pipeline es automático, reproducible y auditable: cualquier acto publicado puede trazarse hasta el PDF oficial del día en que se publicó. Ejecutamos el pipeline completo cada día hábil tras la publicación matinal del BORME.
Etapa 01 · Ingesta diaria
Cada mañana, tras la publicación oficial (~08:00 CET), el pipeline se conecta a la API de datos abiertos del BOE y descarga tres artefactos clave:
Índice de todos los actos publicados del día, con identificadores BORME-A-YYYY-NNN-NN y metadata estructural.
Documentos completos de las Secciones I (actos inscribibles) y II (anuncios legales), uno por acto.
Provincia, sección, fecha oficial publicación. Conservados con SHA-256 para garantizar integridad e permitir reprocesamiento.
Etapa 02 · Parsing dual
Cada documento del día pasa por dos parsers complementarios. Cuando el mismo acto aparece en ambas secciones, el validador cruzado concilia campos eligiendo el de mayor fiabilidad (XML > PDF).
Motor PDF (Sección I). Extrae texto plano con pdfplumber
y aplica una batería de reglas regex + heurísticas tipadas para identificar:
CIF (con validación de letra de control oficial AEAT), razón social, tipo de acto
(constituciones, nombramientos, ceses, ampliaciones, fusiones, concursales,
disoluciones, escisiones) y personas involucradas con su cargo normalizado.
Motor XML (Sección II). Procesa los anuncios legales estructurados directamente desde el XML oficial, donde los campos ya están etiquetados con schemas del BOE. Mucho más fiable que el PDF cuando está disponible.
Validador cruzado. Cuando un acto aparece en ambas fuentes, se comparan los campos extraídos. Discrepancias se loguean para auditoría manual semanal. Precisión actual medida en muestra estadística: >98% CIF, >96% razón social, >92% tipo de acto.
Etapa 03 · Normalización + enriquecimiento
Tras el parsing, cada campo pasa por una pipeline de normalización determinista que garantiza consistencia + permite cruces multi-fuente.
Etapa 04 · Generación de artefactos
En lugar de una base relacional clásica, producimos un dataset estático versionado que se sirve directamente desde disco/CDN. Filosofía data-as-code: cada release versionado, diffable, replicable.
in.json, te.json... agrupan empresas por prefijo de 2 chars para búsqueda <100ms
{slug-cif}.json con KPIs, timeline cronológico, cargos vigentes/históricos
Etapa 05 · Publicación y cache
El frontend lee directamente los JSON estáticos y pre-renderiza HTML cacheado en varios niveles. Sin base de datos relacional en producción → alta disponibilidad, coste marginal próximo a cero, latencia mínima.
Latencia objetivo: <100 ms para búsqueda, <200 ms para ficha de empresa, <300 ms para grafos persona. Medidas reales mejores en la mayoría de los casos por cache hit ratio CF + LiteSpeed > 90%.
Stack productivo: PHP 8.3 + SQLite (lectura-only para datos derivados pesados como facts BORME) + JSON estáticos para hot path + Cloudflare CDN + LiteSpeed cache + OPcache. Cero MySQL/Postgres.
Deploy atómico: nuevas versiones del dataset se suben con nombre temporal, se renombran atómicamente en producción tras smoke tests pasados → cero downtime, rollback en segundos si algo falla post-flight.
Garantía de origen
Cada acto listado en OpenMercantil conserva el identificador oficial
BORME-A-YYYY-NNN-NN que enlaza al PDF original publicado por la
Agencia Estatal BOE. Si detectas un error de extracción, puedes compararlo siempre
con la fuente autoritativa.
Canal de rectificación: usa el canal oficial de rectificación · respondemos en <48h hábiles. Para ejercer derechos RGPD (rectificación, oposición, supresión) sobre datos personales, aquí.
Ver también: indicadores de calidad ↗ · trazabilidad por fuente ↗ · condiciones reutilización ↗.
Reconciliación entre fuentes
Cuando una empresa aparece en varias fuentes (por ejemplo BORME + CNMV + OEPM), OpenMercantil intenta reconciliar todas las menciones en una sola ficha. Esto se hace mediante tres estrategias en orden de fiabilidad.
Reconocemos abiertamente las siguientes limitaciones técnicas:
Si detecta que una mención está mal asociada a su empresa (o a otra empresa), puede notificarlo en el canal de rectificación. Plazo de respuesta: 48-72 horas hábiles. Indique en el correo el slug afectado y la mención concreta.
Señal documental orientativa
OpenMercantil publica un Indicador documental (anteriormente denominado "Trust Score") en algunas fichas de empresa. Es una estimación algorítmica orientativa basada exclusivamente en señales documentales públicas:
⚠️ Importante: El Indicador documental NO es una calificación crediticia oficial, ni una recomendación financiera, ni sustituye un informe profesional de solvencia. Es una herramienta orientativa basada únicamente en señales documentales públicas. Para decisiones financieras o de crédito, consultar profesionales acreditados.
Cuando una empresa coincide con una entrada en listas internacionales (OpenSanctions, ICIJ Offshore Leaks, etc.), OpenMercantil lo refleja pero con disclaimers explícitos en la ficha:
Algoritmo completo y ponderaciones del Indicador documental disponibles en /trust-score.
Transparencia técnica
OpenMercantil reconoce abiertamente las siguientes deudas técnicas y trabaja activamente en resolverlas. Este apartado se actualiza trimestralmente.
(entity, predicate, value, source, source_date, observed_at, confidence, parser_version) para auditoría completa de cada dato.Si tiene preguntas técnicas, sugerencias o detecta una limitación no documentada, contacto en [email protected]. Las propuestas de mejora se valoran semanalmente.
Modelo unificado de trazabilidad
Estructura adoptada en OpenMercantil para que cada afirmación tenga fuente, fecha, nivel de confianza y trazabilidad completa.
Inicialmente, OpenMercantil indexaba los datos en tablas-por-fuente (sanctions_aepd_companies, cnmc_sanctions, sanciones_aepd, etc.). Esto funcionaba pero limitaba la auditoría: no había un identificador único por afirmación ni un historial de versiones.
Migramos progresivamente a un modelo unificado donde cada afirmación se representa como una tupla auditable.
claims_evidence (
id PK
entity_type 'company' | 'person' | 'org'
entity_slug FK a /empresa/{slug} o /persona/{slug}
entity_name denormalized para display
claim_id UUID único
predicate e.g. 'sanctioned_by_aepd', 'awarded_contract'
value string normalizado
value_extra JSON adicional opcional
source_name 'AEPD', 'BORME', 'CNMV', ...
source_url URL oficial
source_publication_date YYYY-MM-DD
observed_at cuándo lo observó OpenMercantil
confidence 'high' | 'medium' | 'low' | 'experimental'
raw_text_hash sha256 del texto fuente
parser_version ej. 'aepd-v2.1'
normalized_value post-normalización OpenMercantil
interpretation 'official' | 'derived' | 'inferred'
status 'active' | 'superseded' | 'corrected' | 'disputed'
)
Tabla claims_evidence creada en BD standalone artifacts/claims_evidence.sqlite
con seeding inicial de 3 ejemplos AEPD para validar el esquema. Helpers PHP disponibles:
openmercantil_get_company_claims($slug, $predicate, $limit)openmercantil_get_claims_stats()Roadmap de migración (incremental, sin breaking):
Durante el período migratorio, los datos legacy seguirán visibles desde sus tablas originales. El frontend mostrará indicadores cuando un dato proceda del modelo nuevo vs legacy.
Sprint Integración 2026 Q2
Las siguientes fuentes se incorporan progresivamente durante 2026 (mayo-junio). Cada una sigue el modelo de trazabilidad: tabla SQLite dedicada, migration aditiva (sin breaking), match key explícito (CIF/NIF), cobertura progresiva con disclaimer cuando no hay datos para una empresa concreta.
companies.cifaepd.es/documento/PS-XXXXX-YYYY.pdf)claims_evidence.sqlitePatrón común: todas las nuevas integraciones siguen el modelo additive (CREATE TABLE IF NOT EXISTS · ALTER TABLE · INSERT OR IGNORE) garantizando cero breaking changes en producción. Las fichas sin coincidencia documental muestran un bloque elegante "Datos aún no disponibles en fuentes procesadas" en lugar de filas vacías, reflejando limitación documental y no ficha incompleta.