ee-database Sync Client - Entity Enricher-documentatie

ee-database sync client

De open-source apply-client voor schemadatabases. Draai hem op elke machine die je eigen PostgreSQL kan bereiken, koppel één keer en hij houdt die database in sync met je enrichments — door te initialiseren vanaf een snapshot en daarna een live delta-feed toe te passen via één uitgaande WebSocket. Je connection string verlaat die machine nooit.

Entity Enricherserver · outboxee-databasejouw machineJe databasePostgres · MySQL · SQLitebatch · lease 120sapply — één transactiecommitack volgende venster direct verstuurd

Elke statement is revisie-bewaakt, dus een opnieuw geleverde batch convergeert naar dezelfde rijen. Een SQL-fout rolt de batch terug en stopt — een giftige delta wordt nooit stilzwijgend overgeslagen.

De client haalt status op, geen operaties: elke delta bevat de volledige huidige rij(en) voor een gewijzigde entiteit als een idempotente INSERT … ON CONFLICT … DO UPDATE, zodat het doel convergeert, zelfs als een batch is gemist.

Waarom de sync-client?

Database syncs kunnen op verschillende manieren worden gebruikt — n8n, Make.com, MCP, ruwe webhooks of de REST delta feed. De sync client is de volledig geautomatiseerde route: het minste om te bouwen en het minste om te lekken.

Geen workflow om te bouwen

Geen n8n-scenario, geen cron, geen lijmcode. Koppel één keer en het bootstrapt vanaf de snapshot, en past daarna elke delta toe zodra die binnenkomt.

Je DSN verlaat nooit je machine

De connectiestring wordt meegegeven op de commandoregel of lokaal opgeslagen met mode-600 — deze wordt nooit naar Entity Enricher gestuurd. De client verbindt alleen naar buiten.

Replay-veilig door ontwerp

Elke delta is een idempotente, revisie-bewaakte upsert. Als de client halverwege een batch crasht, wordt de batch opnieuw geleverd nadat de lease verloopt, en opnieuw toepassen convergeert naar dezelfde rijen.

Quarantaine bij fouten, nooit stilzwijgend

Een SQL-fout draait de batch terug en meldt de mislukte delta. De server plaatst de hele batch van die verrijking in quarantaine en stuurt de wachtrij zonder die batch opnieuw door, zodat de client verbonden blijft en blijft toepassen — één slechte rij kan niet alles wat erachter staat blokkeren, en het werk in quarantaine blijft in de lijst staan totdat je het afhandelt.

Snel aan de slag

Registreer eerst een database op een schema, koppel daarna een client en draai hem op een machine die je database kan bereiken.

  1. 1

    Registreer een database

    Registreer op de pagina Database Sync een database op het schema dat je wilt spiegelen en controleer de database keys. Zie Database Sync voor het volledige model. Deze stap legt het doeldialect vast dat de client zal toepassen.

  2. 2

    Installeer de client

    Plak dit in een terminal. Het script verifieert een cosign-handtekening voordat het installeert.

    curl -fsSL https://entityenricher.ai/install-eedatabase.sh | sh

    Windows: iwr -useb https://entityenricher.ai/install-eedatabase.ps1 | iex. Of download een ondertekende binary via Releases, of bouw vanaf de broncode (Go ≥ 1.23): go build -o ee-database .

    Broncode en ondertekende releases vind je op TOT-Concept/ee-database (MIT).

  3. 3

    Koppelen via je browser

    Voer ee-database pair uit. Er opent een browsertabblad op /database/connect met een korte code — bevestig deze en kies welke database deze client moet synchroniseren.

    ee-database pair --server https://entityenricher.ai
    
    Open this URL in your browser to confirm pairing:
       https://entityenricher.ai/database/connect?code=7QX-KP2
    
      Code: 7QX-KP2
    
    Waiting for confirmation...

    Liever een token? Maak er een aan op de Database Sync-pagina (Syncclient → Een client koppelen) en geef het direct mee: ee-database pair --server … <refresh-token>.

    De enige keuze in de flow: welke geregistreerde database deze machine synchroniseert. Koppelen vervangt de vorige credential van die database, waardoor een oude client stopt.
  4. 4

    Draai hem op een machine die je database kan bereiken

    Bij de eerste run haalt de client de .sql-snapshot op en past die toe, en maakt daarna verbinding om delta's te streamen. --save-dsn slaat de connection string lokaal op, zodat latere runs geen argumenten nodig hebben.

    Elke run controleert ook zelf de provisioning-rechten van de login (database aanmaken, DDL, DML) en meldt het resultaat op de Sync client-kaart, zodat een ontbrekende toekenning zichtbaar is voordat delta's niet toegepast kunnen worden. Als er nog geen gekoppeld schema is gepubliceerd, blijft de client verbonden en wacht — de eerste publicatie start de feed vanzelf, geen herstart nodig.

    ee-database run --dsn "postgres://user:pass@localhost:5432/mydb" --save-dsn

    „Naast” betekent netwerk-nabij, niet op de databaseserver: elke machine of container die de DSN kan bereiken werkt — inclusief cloud-beheerde PostgreSQL (Azure, OVHcloud, AWS RDS…), die meestal TLS afdwingt: …/mydb?sslmode=require.

    Wat de draaiende client terugmeldt: of hij verbonden is, en wat de zelfcontrole van zijn provisioningrechten heeft opgeleverd.

Beheerde sync-hosts

Meerdere databases op één machine? Een synchost tilt de koppelingsceremonie een niveau hoger: koppel de machine één keer, en elke Database Sync die je eraan toewijst wordt automatisch geclaimd, ingericht en gesynchroniseerd gehouden — voor het registreren van een nieuwe sync is nooit meer een terminalsessie nodig. Vereist client 1.5.0 of hoger, die één keer per server koppelt in plaats van één keer per machine — zo kan één host meerdere Entity Enricher-instanties naast elkaar bedienen.

  1. 1

    Een host registreren

    Klik op de pagina Database Sync op de werkbalkknop Sync hosts en voeg een host toe die naar de machine is vernoemd. Er verschijnt precies één keer een eenmalige koppelingstoken, verwerkt in een host pair-commando dat je kunt kopiëren en plakken, met begeleide installatiestappen.

  2. 2

    Koppel de machine één keer

    Voer het commando uit op de machine die je databaseserver kan bereiken. De --dsn is een basisverbindingsstring die de server benoemt, zonder databasenaam — elke toegewezen sync leidt daaruit zijn eigen database af. Zoals elke DSN wordt hij lokaal opgeslagen met mode-600 en nooit naar Entity Enricher verstuurd.

    ee-database host pair --server https://entityenricher.ai \
      --dsn "postgres://user:pass@host:5432/" <token>

    Bij het koppelen worden de provisioning-rechten van de login zelf gecontroleerd (database aanmaken, DDL, DML) en het faalt direct bij een ontbrekende toekenning. Liever een login met minimale rechten? Voeg --admin-dsn toe en provisioning maakt in plaats daarvan elke ontbrekende rol en database aan via de admin-verbinding — de admin-DSN wordt alleen gebruikt tijdens provisioning, nooit opgeslagen.

    Een host wordt één keer per machine gekoppeld; elke registratie die je er later aan toewijst, wordt aangemaakt en gesynchroniseerd zonder die machine opnieuw aan te raken.
  3. 3

    Voer het uit en wijs daarna syncs toe vanuit de UI

    ee-database host run

    De host houdt één control-plane-WebSocket open en reageert op toewijzingen die in de UI worden gemaakt: kies de host bij het registreren van een database, of later op het tabblad Overzicht van de database. Elke toegewezen sync wordt geclaimd, zijn database wordt aangemaakt als die ontbreekt (snake_case op basis van de naam van de sync; overschrijf per sync via database_names in de config.json van de host), en vervolgens gesynchroniseerd door de gewone lus hieronder.

    Een database die al gekoppeld is met een andere client wordt gemeld en overgeslagen — nooit overgenomen. Het intrekken van de host in de UI verbreekt de machine direct, inclusief elke per-database-credential die deze claimde; toewijzingen en al gesynchroniseerde data blijven behouden, zodat een opnieuw gekoppelde host verdergaat waar de oude stopte.

Hoe levering werkt: lease & ack

Delta's verlaten Entity Enricher via een strikte FIFO-outbox per database. De server leaset het zichtbare venster voor 120 seconden en pusht het als één batch; de client past de hele batch toe in één transactie en antwoordt met ack , waardoor de cursor vooruitgaat en direct het volgende venster wordt getriggerd. Een client die halverwege een batch crasht, wordt gedekt door het verlopen van de lease en een re-push aan de serverkant — er gaat niets verloren en niets wordt dubbel gecommit.

Snapshot = delta vanaf nul

Bootstrap en steady-state delen één codepad. Sla de bootstrap over met --skip-bootstrap als je database al is geseed.

Revisie-bewaakt

Elke statement bevat een _sync_revision zodat een oudere rij nooit een nieuwere overschrijft, zelfs niet buiten volgorde.

Quarantaine bij fouten

Een SQL-fout draait de batch terug en meldt de mislukte delta met het volledige statement dat de fout veroorzaakte. De server plaatst de batch van die verrijking in quarantaine en stuurt de wachtrij zonder die batch opnieuw door — de client blijft de rest toepassen. Alleen een fout die geen delta noemt, eindigt met een niet-nul exitcode.

Wat elk venster schrijft

Elk toegepast venster rapporteert per tabel de vorm die het heeft geschreven — zo hoef je voor het inschatten van een nachtelijke herverrijking nooit in logs te graven naar delta's die al bevestigd en opgeruimd zijn.

applying 12 delta(s) (10831 .. 10842) in one transaction
applied 12 delta(s) in 84ms — 38 statement(s): mushroom 4 upserts,
  mushroom_common_names 12 upserts + 4 prunes, mushroom_human_uses 14 upserts + 4 prunes
acked up to delta 10842

Eén upsert is één rij, dus de aantallen zijn rijaantallen; een prune is de enkele revisie-bewaakte DELETE die de child- of junction-rijen wist die een nieuwe payload niet langer claimt. Children worden ter plekke bijgewerkt — nooit gewist en opnieuw ingevoegd. Voeg --verbose toe voor één regel per delta, met het entiteitstype, de doorlooptijd en de eigen vorm.

Databases & dialecten

Het doeldialect ligt vast door de registratie van de schema-database in Entity Enricher — de client voert simpelweg de SQL uit die de server genereert. PostgreSQL is het startdialect; renderers voor MySQL / MariaDB, SQL Server en Oracle staan gepland (de MySQL-driver wordt al meegeleverd). Het toepassen van meerdere statements wordt per driver afgehandeld (pgx simple protocol, MySQL multiStatements).

Vereiste databaserechten (PostgreSQL)

Als de doeldatabase al bestaat, heeft de login alleen CONNECT op de database en USAGE + CREATE op het doelschema nodig. (Sinds PostgreSQL 15 verleent public niet langer standaard CREATE aan iedereen.)

Al het overige volgt uit eigenaarschap: de client maakt de replicatabellen zelf aan en is er dus eigenaar van, en eigenaarschap impliceert de lees- en schrijfrechten die de datadelta's nodig hebben. Eigenaarschap is niet optioneel — de feed levert ook migratiestatements (ALTER TABLE …, CREATE INDEX …) die PostgreSQL beperkt tot de eigenaar van de tabel, en geen enkele combinatie van grants is daarvoor een vervanging.

Als de replicatabellen al bestaan onder een andere eigenaar, slaagt de rechtencontrole vooraf van de run nog steeds — de login kan nieuwe tabellen aanmaken — maar de eerste migratiedelta mislukt. Draag ze over met ALTER TABLE … OWNER TO <login> (of maak de login lid van de eigenaarsrol) in plaats van rechten toe te voegen.

Wanneer een delta in quarantaine gaat

Een statement dat je database weigert — meestal door een al bestaand duplicaat onder een nieuwe unieke index — legt de feed niet stil. De batch wordt teruggedraaid, de client meldt de mislukte delta samen met het volledige statement dat de fout veroorzaakte (nooit afgekapt), en de server plaatst de batch van die verrijking in quarantaine en stuurt de wachtrij zonder die batch opnieuw door. Je client blijft alles wat erna komt toepassen.

Werk in quarantaine blijft vermeld op het tabblad Quarantaine van de pagina Database Sync totdat je het afhandelt: verhelp de oorzaak in je database en injecteer opnieuw — waarbij de entiteit opnieuw wordt geprojecteerd vanuit haar huidige staat in plaats van de verouderde statement af te spelen — of laat het vallen als de rij er niet meer toe doet.

Een mislukte bootstrap is anders: de snapshot is één transactie, dus er wordt niets gedeeltelijk toegepast, en de client slaat hem op in de profielmap van de koppeling als snapshot-failed.sql (modus 0600, bij elke poging vervangen, bij de volgende geslaagde poging verwijderd) zodat je hem kunt inspecteren of opnieuw afspelen met psql -f.

Beveiliging

Alleen uitgaand

De client start de WebSocket over :443/wss. Je databasehost accepteert nooit inkomende verbindingen — geen poorten om te openen, geen ingress om te configureren.

Eén inloggegeven, één database, één client

Een credential is gekoppeld aan één database sync. Opnieuw koppelen roteert deze en verwijdert direct de vorige actieve verbinding.

Kortlevende toegangstokens

Het refresh-token met een geldigheid van 365 dagen (opgeslagen met mode-600) wordt ingewisseld voor toegangstokens van 15 minuten die de WebSocket authenticeren. Intrekken in de UI verbreekt binnen ~1 seconde de verbinding met een actieve client.

De host-pairingsleutel is een opaak geheim

Een beheerde host koppelt met een korte eeh_…-sleutel in plaats van een JWT: de server bewaart alleen de hash ervan, hij verloopt nooit, en pas als je de host in de UI intrekt, eindigt hij.

Eén proces per koppeling

Een lock per profiel voorkomt dat twee processen dezelfde koppeling tegelijk uitvoeren — anders zouden ze elkaars WebSocket-sessie in een lus verdringen.

Beperkt in rechten, maar eigenaar van de eigen tabellen

Draai de client onder een speciale rol die beperkt is tot het gesynchroniseerde schema, zodat een gelekt token nergens anders bij kan — maar laat die rol de replicatabellen aanmaken zodat hij er eigenaar van is. De migratiestatements vereisen eigenaarschap, geen grants.

CLI-referentie

OpdrachtWat het doet
ee-database pair --server URLDevice-code-koppeling bevestigd via de browser. Kies welke database je wilt synchroniseren.
ee-database pair --server URL <token>Koppel met een token dat is uitgegeven op de pagina Database Sync (geschikt voor headless gebruik).
ee-database run --dsn DSN [--save-dsn] [--skip-bootstrap]Bootstrap vanaf de snapshot (tenzij overgeslagen), maak vervolgens verbinding en pas de delta's toe.
ee-database run … --create-missingMaak de doeldatabase eerst aan als die nog niet bestaat, met de eigen inloggegevens van de DSN (postgres heeft CREATEDB nodig, mysql het CREATE-recht).
ee-database run … --create-missing --admin-dsn DSNBootstrap alles wat de doel-DSN benoemt via een admin-verbinding: de ontbrekende rol/gebruiker (met het wachtwoord van de DSN) en de database die eigendom is van die rol. De doel-DSN heeft dan geen aanmaakrechten nodig; de admin-DSN wordt nooit opgeslagen.
ee-database run --allSynchroniseer elke gekoppelde database gelijktijdig vanuit één proces (elk heeft een opgeslagen DSN nodig).
ee-database run … --verboseLog de schrijfvorm en doorlooptijd van elke delta, niet alleen de samenvatting per venster. Wordt ook geaccepteerd door host run.
ee-database host pair --server URL --dsn BASE_DSN [--admin-dsn DSN] <token>Koppel deze machine eenmalig als beheerde sync host — de basis-DSN benoemt je databaseserver (zonder databasenaam) en verlaat de machine nooit; de token komt uit het dialoogvenster Sync hosts (de werkbalkknop Sync hosts op de pagina Database Sync). Eén koppeling per server: koppel naast elkaar met meerdere Entity Enricher-servers.
ee-database host run [--server URL]Beheerde modus: elke database sync die aan deze host is toegewezen wordt geclaimd, aangemaakt als die ontbreekt en automatisch gesynchroniseerd gehouden — geen koppeling per database, in één keer op alle gekoppelde servers (--server beperkt dit tot één). Een database die al aan een andere client is gekoppeld wordt gemeld, nooit overgenomen.
ee-database host status / host disconnect [--server URL]Toon of vergeet de hostkoppelingen van deze machine. Intrekken doe je aan serverzijde via de kaart Sync hosts.
ee-database statusToon de koppelingsstatus, server-URL en de gekoppelde databases.
ee-database disconnectVergeet de lokale inloggegevens van één koppeling. Trek server-side in via de UI.
ee-database versionAfdrukversie.

Inloggegevens worden opgeslagen met mode 600, één profiel per gekoppelde database, onder ~/.config/ee-database/profiles/ — koppel één keer per database, en met --database NAME kies je er een als er meerdere gekoppeld zijn. Liever helemaal geen automatisering? Dezelfde feed is gewoon REST: GET /api/databases//changes en daarna POST /api/databases//ack — zie Database Sync.

Open source

De client valt onder de MIT-licentie en staat in een openbare repository, zodat iedereen precies kan controleren wat er tegen hun database draait.

Broncode: github.com/TOT-Concept/ee-database

Releases: github.com/TOT-Concept/ee-database/releases — elke binary wordt vóór publicatie ondertekend met cosign.

Controleer het installatieprogramma: curl -fsSL https://entityenricher.ai/install-eedatabase.sh | less