Skip to content

fix(#117): adopt Knex migrations as single schema authority#118

Open
vrkothekar wants to merge 9 commits into
mainfrom
fix/issue-117-knex-migrations
Open

fix(#117): adopt Knex migrations as single schema authority#118
vrkothekar wants to merge 9 commits into
mainfrom
fix/issue-117-knex-migrations

Conversation

@vrkothekar

Copy link
Copy Markdown
Collaborator

Summary

Closes #117.

Replaces the dual inline-schema approach (dag.js CREATE TABLE blocks + knex-adapter.js _ensureSchema()) with a single Knex migration file as the authoritative schema source.

  • node/src/db/migrations/000_baseline.js — 24-table baseline migration, replaces all CREATE TABLE IF NOT EXISTS and ad-hoc ALTER TABLE guards from both stores. Column names are client-conditional where needed (ctid on SQLite / tip_ctid on all server-side DBs).
  • node/knexfile.js — full 5-driver config (better-sqlite3, pg, mysql2, mssql, oracledb), mirrors env vars from knex-adapter.js.
  • node/src/db/knex-adapter.js_ensureSchema() removed; replaced with knex.migrate.latest().
  • node/src/dag.js — inline CREATE TABLE block and ALTER TABLE backfill guards removed; SQLite schema now driven by the same Knex migration file.
  • .gitignore — local mixed-DB test artifacts excluded.

Oracle / MSSQL compatibility fixes (found during local integration test)

Engine Error Fix
Oracle ORA-02329: entity_id TEXT in composite PK → Oracle maps t.text() to CLOB, which cannot be a primary key Changed to t.string("entity_id", 128) — sufficient for all TIP IDs (≤30 chars)
Oracle ORA-01408: idx_entity_keys_time duplicates PK columns (entity_type, entity_id, valid_from_ts) exactly Removed the redundant index; PK already implies this index
MSSQL nvarchar(max) cannot be part of a PRIMARY KEY constraint Same fix — t.string("entity_id", 128) resolves both engines
MariaDB Connected on port 5432 instead of 3306 DB_PORT env override added to compose (node-2.env carried the postgres port from registration)

Verification

Tested locally with a 5-engine cluster (Postgres / MariaDB / Oracle Free 23ai / SQL Server 2022 / SQLite) — all nodes connected to their respective engines, migrations applied, 26 tables created on each, tip_ctid / ctid column name correct per engine, all 5 nodes advancing in consensus at identical rounds (spread = 0).

Test plan

  • Deploy to a fresh node (Postgres) — verify knex_migrations table created and schema matches prior hand-written schema
  • Deploy to SQLite node — verify ctid column (not tip_ctid) in content, prescan_reviews, prescan_jobs
  • Confirm no regression on existing node data — knex.migrate.latest() is a no-op when migration is already applied
  • Run npm test in node/ — all existing tests pass

theailab-org and others added 9 commits June 16, 2026 12:58
Adds a banner near the top of the README pointing to the published
Whitepaper at theailab.org/whitepaper, and updates the Links table
with the canonical Whitepaper URL, the PDF download URL, and the
errata channel. Also corrects the Protocol Spec link to v5.0.

The Whitepaper is the canonical public specification of the TIP
Protocol. The Protocol Spec (CTID v5.0) remains the technical
reference for endpoint contracts and message formats.

License: Whitepaper is CC BY 4.0. Implementations remain under
TIPCL-1.0 with conversion to Apache 2.0 on Jan 1, 2031.
…inks table

The TIP Protocol Whitepaper, Version 1.0 is now permanently archived
on Zenodo (operated by CERN) with a citable DOI. This README update
surfaces the DOI as a discoverable badge at the top of the page,
adds the author's ORCID iD alongside the Wikidata QID, and adds
three rows to the Links table for the Version DOI, the Concept
DOI, and the Zenodo record URL.

The full citation in the README banner now uses the canonical
Zenodo title ("Trust Identity Protocol (TIP): An Open Standard for
Verified Human Identity and Content Provenance on the Internet")
and ends with the DOI URL, so anyone clicking the citation can
resolve to the permanent record.

The DOI badge surfaces in the GitHub repository preview and in any
README mirror.
Lifts the entire _ensureSchema() body from knex-adapter.js into a
proper initial migration. All 24 tables created in dependency order;
platform_links uses its final schema (unlinked_at/unlink_tx_id) with
the hotfix alterTable block omitted. down() drops in reverse order.
…n-pg servers

knexfile.js now mirrors knex-adapter.js connection logic: reads DB_DRIVER /
DB_HOST / DB_NAME / DB_* env vars (same as the app) and exports five named
environments (sqlite, pg, mariadb, mssql, oracle) plus a `development`
default that follows DB_DRIVER. TIP_PG_* vars removed.

000_baseline.js: ctid column condition changed from `=== "pg"` to
`=== "better-sqlite3"`. Only the SQLite path (dag.js SQLiteStore) uses
the column name `ctid`; knex-adapter always references `tip_ctid` for
every server-side DB, so mariadb/mssql/oracledb must also get `tip_ctid`
or every content/prescan query fails on those engines.
…SSQL

entity_id was t.text() → Oracle maps this to CLOB (ORA-02329: LOB cannot
be primary key) and MSSQL maps it to nvarchar(max) (cannot be part of a
PRIMARY KEY constraint).  Changed to t.string("entity_id", 128) — TIP IDs
are ≤30 chars so 128 is ample.

Also remove idx_entity_keys_time: it duplicates the PK column list exactly,
which Oracle rejects with ORA-01408 (column list already indexed).

Add docker-compose.mixed-db.yml + scripts/start-mixed-db.sh +
scripts/verify-mixed-db.sh — a 5-engine integration test cluster
(Postgres/MariaDB/Oracle/MSSQL/SQLite) verified at 21/21 checks,
all nodes advancing at identical consensus rounds with spread=0.

Tested with DB_PORT: "3306" fix for node2 (MariaDB): node-2.env carried
DB_PORT=5432 from postgres-backed node1 registration; the compose env
override was missing.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Adopt Knex migrations as the single schema authority (retire inline CREATE TABLE / ALTER)

2 participants