CreaRack-SL

Base de datos workspace · arquitectura técnica

Base de datos workspace · arquitectura técnica

Referencia técnica del esquema D1 del workspace. Para una explicación accesible ve a [[workspace-tech—bd—coloquial]].


1. Stack de persistencia

ComponenteVersiónRol
Cloudflare D1latestBD principal · SQLite replicado en edge
Cloudflare R2latestObject storage (blobs · imágenes/PDFs adjuntos a tasks)
Cloudflare VectorizelatestVector store para embeddings (Bibliotecario search semántico)
Wrangler4.85+CLI de migrations + deploy + import/export
CF Pages Functions—Runtime que ejecuta los handlers que consultan D1

Bindings (wrangler.toml)

[[d1_databases]]
binding = "DB"
database_name = "crearacksl-workspace-db"
database_id = "<uuid>"

[[r2_buckets]]
binding = "R2"
bucket_name = "crearacksl-workspace-blobs"

[[vectorize]]
binding = "VECTORIZE"
index_name = "bib-chunks-embeddings"

Limitaciones D1 documentadas (footguns)

LímiteImpactoWorkaround
100 bind params max por queryWHERE id IN (?,?,...) con más rompeChunk a 90 vía db.batch()
Worker subrequestsLoop con SELECT + INSERT por iteración excede límitedb.batch() + INSERT ON CONFLICT + pre-fetch IN chunks
CHECK constraints laxosAlgunos INSERT path no validan CHECKValidar también en aplicación
datetime() + bind concat`datetime(‘now’,’-’

2. Migrations · estado actual

30 migrations aplicadas (migrations/ en el repo workspace):

#NombreDominioNotas
0001create_newsdashboardAnuncios
0002create_taskstasksTablero principal
0003create_notesdashboardPost-its colores
0004create_alertsdashboardBanner home
0005create_auth_codesauthMagic link nonces
0006create_activity_logtoolsBitácora MCP
0007create_reportsdashboardInformes IA
0008create_bibliotecasupercontext8 tablas bib_* base
0009create_bib_chunkssupercontextChunks para semantic search
0010biblioteca_graphifysupercontextbib_communities + confidence en edges
0011create_task_attachmentstasksAdjuntos R2
0012tasks_transition_timestampstasksTimestamps de transición
0013tasks_resolutiontasksResolución/cierre
0014create_bib_wikisupercontext4 tablas wiki Supercontexto
0015bib_wiki_log_allow_deletesupercontextFix CHECK constraint
0016create_ai_eval_runstoolsHistorial /tools/ai-eval
0017create_quick_linksherramientas-personalesHub URLs
0018seed_quick_linksherramientas-personalesSeed inicial
0019quicklinks_tailnet_updateherramientas-personalesUpdate URLs tailnet
0020create_directionsherramientas-personalesAgenda contactos
0021seed_directionsherramientas-personalesSeed
0022create_notebookherramientas-personalesBloc markdown
0023tasks_linked_notestasksVínculo task ↔ note
0024kind_lifecycle_driftsupercontextSchema wiki extension
0025quick_links_uniqueherramientas-personalesUNIQUE constraint (fix footgun #d1_migrations_untracked)
0026create_zoho_oauthoauthSingleton tokens Edu
0027zoho_per_user_and_task_linksoauth + tasksMulti-user + vínculos Calendar/Mail
0028task_calendar_link_typetasksTipo de link
0029create_task_commentstasksComentarios lineales (s69)
0030create_chatchatChat grupal equipo (s69)

Aplicar migrations

# Local dev
pnpm wrangler d1 execute crearacksl-workspace-db --local --file=./migrations/0030_create_chat.sql

# Producción
pnpm wrangler d1 migrations apply crearacksl-workspace-db --remote

Footgun s64: migrations aplicadas con execute --file directo NO quedan en d1_migrations table. Un migrations apply posterior las re-aplica silenciosamente. Causó duplicado de 27 quick_links. Solución: usar siempre migrations apply para migrations versionadas + UNIQUE constraints donde haga falta.

Desde el 11-09-2026 (s323) nadie aplica migraciones a mano: las aplica el deploy de OPS (cf-pages-deploy.sh) antes de publicar, con candado contra el registro desincronizado (reincidencia del 11-09: 0045-0053 sin registrar, migrations apply reventó en la 0045). Flujo: PR con el .sql en migrations/ + su línea en scripts/seed-d1-migrations.sql → merge → el tick del deploy la aplica. Detalle: [[ia-tech—automatismos—metodo—cf-pages-deploy]].


3. Mapa ER por dominios

3.1 Dashboard del home

erDiagram
    news {
        int id PK
        string title
        string content
        string author
        string category
        int pinned
        string created_at
        string updated_at
    }
    notes {
        int id PK
        string title
        string content
        string color "blue|green|yellow|pink|orange"
        string author
        string created_at
        string updated_at
    }
    alerts {
        int id PK
        string message
        string type "info|warning|critical"
        int active
        string author
        string created_at
    }
    reports {
        int id PK
        string type
        string title
        string data "JSON"
        string ai_analysis
        string period
        string created_at
    }

Tablas independientes, sin FKs. CRUD simple desde React + Workers.

3.2 Tasks ecosystem

erDiagram
    tasks ||--o{ task_attachments : "tiene"
    tasks ||--o{ task_comments : "tiene"
    tasks ||--o{ task_calendar_events : "vinculado a"
    tasks ||--o{ task_emails : "vinculado a"
    tasks {
        int id PK
        string title
        string description
        string assignee "Edu|Dani|Txell|Equipo"
        string status "pending|in_progress|completed|deleted"
        string priority "low|normal|high|urgent"
        string due_date
        string created_by
        string created_at
        string updated_at
    }
    task_attachments {
        int id PK
        int task_id FK
        string r2_key UK "tasks/{id}/{uuid}.{ext}"
        string filename
        string content_type
        int size_bytes
        string uploaded_by
        string uploaded_at
    }
    task_comments {
        int id PK
        int task_id FK
        string author
        string body
        string target_user_ids "JSON array"
        string created_at
    }
    task_calendar_events {
        int task_id PK
        string zoho_event_uid PK
        string calendar_uid
        string title
        string start_at
        string end_at
        string url
        string created_by
        string created_at
    }
    task_emails {
        int task_id PK
        string zoho_message_id PK
        string thread_id
        string subject
        string from_address
        string email_date
        string url
        string linked_by
        string linked_at
    }

Único bloque con FKs reales (ON DELETE CASCADE). Borrar una task limpia attachments, comments, calendar links y email links en cascada. Los blobs R2 los elimina el endpoint DELETE manualmente.

3.3 Herramientas personales (scope user)

erDiagram
    notebook_notes {
        int id PK
        string owner_id "email CF Access"
        string title
        string content "JSON TipTap"
        int word_count
        int pinned
        string archived_at
        string created_at
        string updated_at
    }
    directions {
        int id PK
        string type "person|company"
        string name
        string nif
        string company
        string role
        string email
        string phone
        string linkedin
        string street
        string zip
        string city
        string province
        string country
        string tags "CSV"
        string notes
        string archived_at
        string owner_id
        string created_at
        string updated_at
    }
    quick_links {
        int id PK
        string label
        string url
        string description
        string category "infrastructure|code|ai|monitoring|product|selfhosted|admin|general"
        string icon_url
        int position
        int is_shared "1=team|0=private"
        string owner_id
        string archived_at
        string created_at
        string updated_at
    }

Patrón común: owner_id (email CF Access) + archived_at para soft-delete.

3.4 OAuth Zoho · evolución per-user

erDiagram
    zoho_oauth_tokens {
        string team_member PK "CHECK Edu|Dani|Txell"
        string zoho_email
        string refresh_token
        string access_token
        string access_token_expires_at
        string dc "default eu"
        string granted_by_cf_email
        string granted_at
        string updated_at
    }
    zoho_oauth_state {
        string state PK
        string created_by
        string created_at
    }

Evolución:

  • s67 (0026): singleton (CHECK id = 1) con un solo refresh token del “equipo”
  • s68 pivot (0027): migrado a per-user, team_member como PK, preservando token de Edu

3.5 Supercontexto · grafo + wiki

Es el dominio más rico del workspace. Conceptualmente:

erDiagram
    bib_nodes ||--o{ bib_edges : "source"
    bib_nodes ||--o{ bib_edges : "target"
    bib_nodes ||--o| bib_docs : "metadata doc"
    bib_nodes ||--o| bib_endpoints : "metadata endpoint"
    bib_nodes ||--o{ bib_chunks : "chunks para search"
    bib_nodes ||--o{ bib_change_log : "auditoría"
    bib_nodes }o--o| bib_communities : "cluster"
    bib_index_runs ||--o{ bib_change_log : "registra"
    bib_wiki_pages ||--o{ bib_wiki_log : "operaciones"
    bib_wiki_pages ||--o{ bib_wiki_utility : "eventos uso"
    bib_wiki_pages }o--o| bib_communities : "cluster"
    bib_wiki_pages }o--o{ bib_wiki_contradictions : "página A"
    bib_wiki_pages }o--o{ bib_wiki_contradictions : "página B"

Tablas (~13):

TablaPropósitoSchema clave
bib_nodesNodos del grafo (endpoint, model, service, signal, schema, doc, view, template, js_module, function, class, method, module)qualified_name UNIQUE, node_type, app, file_path, content_hash, community_id
bib_edgesRelaciones tipadassource_id FK, target_id FK, edge_type, weight, confidence (EXTRACTED/INFERRED), confidence_score
bib_docsMetadata extendida para nodes doctitle, category, doc_type, sections JSON, mentions_apps JSON, word_count
bib_endpointsMetadata extendida para nodes endpointmethod, path UK con method, operation_id, tags JSON, request_schema, response_schema, parameters JSON, deprecated
bib_agentsJerarquía agentes (bibliotecario, escribas, libreros, devs, agente-usuario)agent_id UK, role, model, tier, parent_agent_id, permissions JSON, scope JSON
bib_index_runsAuditoría de indexacionesrun_type, status, source, nodes_created, nodes_updated, edges_created, errors JSON, duration_ms
bib_change_logCambios detectados entre indexacionesnode_id FK, change_type, field_changed, old_value, new_value, run_id FK
bib_federationMulti-biblioteca (futuro)library_id UK, base_url, last_sync_at, sync_status
bib_chunksChunks de contenido para semantic searchnode_id FK, chunk_index, content, word_count, content_hash, embedding_b64, vectorize_id
bib_communitiesClusters detectados (Louvain)community_index UK, label, member_count, cohesion, bridge_nodes JSON, top_nodes JSON
bib_wiki_pagesPáginas wiki Supercontexto (esta misma página)slug UK, `type CHECK(entity_page
bib_wiki_logAppend-only bitácora de operaciones wiki`operation CHECK(ingest
bib_wiki_contradictionsConflictos detectados por Lintpage_a_slug, page_b_slug, claim_a, claim_b, subject, `status CHECK(open
bib_wiki_utilityEventos de uso per-pagepage_slug, `event CHECK(query_hit

3.6 Chat del equipo + activity_log + ai_eval_runs

erDiagram
    chat_messages {
        int id PK
        string author "Edu|Dani|Txell"
        string body
        string created_at
    }
    chat_typing {
        string author PK
        string last_typed_at "TTL 5s"
    }
    activity_log {
        int id PK
        string timestamp
        string actor
        string action
        string entity_type
        string entity_id
        string entity_title
        string details "JSON"
        string source "default mcp"
        int duration_ms
    }
    ai_eval_runs {
        int id PK
        string created_at
        string user_email
        string candidates "JSON array"
        string cases "JSON array"
        string results "JSON matrix"
        int total_cells
        int duration_ms
        string status "completed|partial|failed"
        string notes
    }
    auth_codes {
        string nonce PK
        string used_at
        string created_at
    }

4. Persistencia híbrida wiki

Cada página wiki vive en dos sitios a la vez:

src/content/wiki/<slug>.md   (commit GitHub, source of truth para Astro build)
        ↕
bib_wiki_pages D1            (metadata, lint, search, utility tracking)

Flujo de creación

VíaAtomicidad
wiki_create_page MCPAtómico (commit GitHub + INSERT D1 en la misma transacción)
Commit manual (.md)NO atómico — reconcile job en bib_ingest.py propaga metadata a D1 post-merge

Footguns wiki documentados

FootgunImpactoSesión
wiki_update_page con patch:{content,...} corrompe el .md (escribe el JSON literal)s66 corrupción ADR + catálogoUsar patch como STRING para body
wiki_create_page no valida schema Astro (objetos en sources requeridos)s56 — 11 CI rojos consecutivos por CF Pages InvalidContentEntryDataErrorCopiar patrón de page hermana antes
wiki_update_page silent failure en related[]s32 — returns updated=true sin aplicarUsar otro hub padre
D1↔repo driftCommits docs: sin pasar por MCP no actualizaban D1Sesión 18 fix: branch reconcile en bib_ingest.py

5. Search semántico · pipeline

.md / código  →  bib_index_*  →  bib_nodes + bib_chunks
                                       ↓
                                  Embedding (Gemma 4 vía Google AI Studio o Workers AI)
                                       ↓
                                  Vectorize (CF) → vectorize_id en bib_chunks
                                       ↓
                                  bib_search_semantic tool → top-k chunks por cosine sim

Fallback embebido en D1: embedding_b64 (base64 del vector) usado si Vectorize está caído.


6. Backups y DR

MecanismoFrecuenciaStorage
Snapshots automáticos CFContinuosCloudflare (sin acceso directo)
Wrangler export periódicoDiario (cron STAGE)/opt/dr-backups/d1-YYYY-MM-DD.sql en STAGE + mirror nginx:8090
GitHub repoEn cada commitWiki .md + migrations versionadas (source of truth)

Restaurar desde cero

# 1. Clonar repo workspace
git clone https://github.com/CreaRackSL/CreaRackSL-workspace.git

# 2. Crear D1 nueva
wrangler d1 create crearacksl-workspace-db

# 3. Importar último dump
wrangler d1 execute crearacksl-workspace-db --remote --file=/opt/dr-backups/d1-LATEST.sql

# 4. Deploy
pnpm build && wrangler pages deploy

7. Operaciones comunes

Query directa contra D1 remoto

# Single query
pnpm wrangler d1 execute crearacksl-workspace-db --remote --command="SELECT COUNT(*) FROM bib_nodes"

# Desde fichero
pnpm wrangler d1 execute crearacksl-workspace-db --remote --file=./query.sql

# Export tabla
pnpm wrangler d1 export crearacksl-workspace-db --table tasks --output tasks.sql

Listar tablas

SELECT name FROM sqlite_master WHERE type='table' ORDER BY name;

Tamaño aproximado por tabla

SELECT name, SUM(pgsize) AS bytes
FROM dbstat
GROUP BY name
ORDER BY bytes DESC;

Migrations aplicadas vs en repo

SELECT * FROM d1_migrations ORDER BY id;
-- comparar con ls migrations/

8. Acceso operativo

CómoComando
Dashboard D1https://dash.cloudflare.com → Workers & Pages → D1 → crearacksl-workspace-db
Query rápida (workspace UI)https://workspace.crearack.com/biblioteca (vista del grafo)
MCP tools (Claude Code)mcp__crearack-workspace__bib_*, wiki_*, list_tasks, create_note, etc.
Logs Workers (debugging)pnpm wrangler tail
Wrangler localpnpm wrangler d1 execute crearacksl-workspace-db --local ...

Véase también

  • [[workspace-tech—bd—coloquial]] — Versión accesible para entrada al proyecto
  • [[crearack-tech—bd—tecnico]] — BD del SaaS CreaRack-Pro (PostgreSQL)
  • [[crearack-tech—general—feature-catalog]] — Sección Biblioteca/Supercontexto desde el lado producto