10 Commits
Author SHA1 Message Date
pnoker 72e315ea96 style(db): normalize initdb formatting and order ddl before seeds
Join 1242 keyword-split statement lines (COMMENT/CREATE/ALTER/LOAD), move the dc3_identity_audit_log table section and the schema fingerprint INSERT so every script orders DDL before seed data, and drop one duplicated COMMENT ON COLUMN. Statement multiset verified identical apart from the intended dedup. The canonical fingerprint changes to e81e3562... and is synchronized via schema_fingerprint.py --sync into the embedded ddl_hash and all four distribution points; existing initialized databases require re-initialization (flag day).
2026-09-03 09:02:47 +08:00
pnoker 66aab58f20 build: standardize repository tooling and quality gates 2026-09-02 20:51:10 +08:00
pnoker eae86b58fc refactor(storage)!: unify platform persistence on reactive postgresql
- migrate auth, manager, data, and agentic persistence to R2DBC
- hard cut pagination, facade, gateway, web, and CLI contracts
- remove legacy database and TSDB adapters and document validation gates

BREAKING CHANGE: platform persistence now requires PostgreSQL 18 with TimescaleDB and the new reactive API contracts.
2026-09-01 22:03:16 +08:00
pnoker 769d1cb977 style: apply repository-wide formatting
- expand single-line Javadocs to multi-line blocks, rewrap Markdown prose, and reflow POM, YAML, and TypeScript formatting
- formatting only: no Java code lines changed, no build-file semantics changed
- verified: backend compile and check_documentation.py pass, pnpm check and pnpm lint:check pass, and the dc3 YAML files parse
2026-08-25 13:35:00 +08:00
pnoker 0ddb60f31c test(db): add the dual-dialect contract suite — postgres and mysql, 16/16
R2c of docs/design/storage-abstraction.md §3. dc3-db-tck runs one set of
mapper-level assertions against both engines with the real mapper XML —
the databaseIdProvider routing is part of what gets certified, not just
the SQL: the fenced latest-value upsert's three-level tiebreak (fencing
token, then time, then sequence, then message id), the state upsert +
same-transaction re-select shape, the three-step expired-lease claim
(lock-and-read FOR UPDATE SKIP LOCKED, flip offline, derive the
post-update view), the lease upserts' row-local increments (token moves
only on ownership change), the row-level revision triggers (insert and
meaningful update bump, trivial update does not), and the tool-catalog
query's encoded-JSON double-hop.

Harness notes worth keeping: one SqlSessionFactory per database mirrors
the production @DS wiring (state/latest/leases/catalog span four
databases with unqualified table names); the mapper XML loads through
XMLMapperBuilder with the affectData mybatis-plus DTD extension
stripped; postgres registers the timestamptz type handler. Both
harnesses learned to distrust podman: log-following never fires, so
mysql waits on the listening TCP port and postgres polls a real JDBC
handshake (the port opens during initdb's local-only phase and closes
again for the restart). The postgres harness mounts seed files 01..07
individually — 00's age/pgvector extensions exist only in the
production base image — with 05 trimmed at runtime to the
dc3_point_latest projection (the hypertable half needs the base
image's TimescaleDB function set; the dialect contract doesn't touch
it).

The catalog fixture plants its api row through a parameterized insert:
the escaped-JSON value must not travel through SQL text (MySQL's
default backslash escapes eat the \" the value depends on) nor bind
uniformly (PG rejects varchar->json, MySQL rejects the binary
Types.OTHER binding) — the fixture branches on the engine.

Selection guide published at docs/db-dialects.md (dialect matrix,
swap procedure, the semantic decisions the suite locks); the storage
design's status header moves to Implemented with an R1/R2 closeout
note.

Gates: db-tck 16/16 (8 postgres + 8 mysql), data/auth/manager suites
green (274 in data), e2e 26/26, full-repo compile green.
2026-08-24 19:13:24 +08:00
pnoker 76ae89370b feat(db): add the mysql seed — dual-engine initdb, row-level revision triggers
R2b of docs/design/storage-abstraction.md §3:

- PostgreSQL seed: the three driver-lease sequences retire. The fencing
  token and assignment version default to 1 and advance row-locally —
  per-device / per-driver monotonicity is the property the checks rely
  on, which the global sequences only delivered incidentally, and MySQL
  has no sequence objects. The three statement-level revision triggers
  (transition tables + INSERT .. ON CONFLICT, none of which MySQL can
  express) collapse into one row-level function with row-local +1 upserts
  — a shape both engines share.

- MySQL seed under dc3/dependencies/mysql/initdb/ (00-06), derived by
  dc3/dependencies/mysql/pg2mysql_seed.py: schemas become databases,
  TIMESTAMPTZ becomes DATETIME(6), TEXT/JSON literal defaults become
  expression defaults (MySQL 8 refuses literal defaults on BLOB/TEXT/
  JSON), operate-time plpgsql triggers become the ON UPDATE column
  attribute (explicit SETs keep winning), the revision family becomes
  row-level DELIMITER triggers, keyed TEXT columns widen to VARCHAR(191),
  partial indexes drop, and the embedded-JSON seed values load under
  NO_BACKSLASH_ESCAPES (MySQL string literals eat the backslashes the
  escaped-JSON content values depend on; PostgreSQL does not). 05 is
  hand-maintained: only the dc3_point_latest projection — a MySQL core
  requires an external time-series store, so the hypertable and cagg DDL
  have no counterpart by design.

- Compose: the optional stack gains a mysql:8.4 service (utf8mb4, seed
  mounted at docker-entrypoint-initdb.d, healthcheck); the app stack
  passes DC3_DB_TYPE through.

Verified by loading all seven files into a fresh mysql:8.4 container —
zero errors, five databases, table counts aligned with the PostgreSQL
seed (manager 24 incl. common, auth 24, data 12, agentic 6, history 1),
and the revision trigger proven live: insert bumps the owning driver's
revision to 1, an enable_flag flip bumps it again to 2.
2026-08-24 17:17:45 +08:00
pnoker fd159b7a36 fix(database): repair and validate PostgreSQL initialization 2026-08-18 08:15:12 +08:00
pnoker 956de3dd38 feat(driver)!: enforce lease-fenced durable telemetry
Use PostgreSQL leases and fencing for distributed ownership, require a durable SQLite outbox before RabbitMQ publication, and make Data Center ingestion transactional and idempotent.

BREAKING CHANGE: drivers require mandatory durable outbox configuration and use lease-aware ownership and telemetry contracts.
2026-08-18 00:50:57 +08:00
pnoker 6613929140 chore(sql): drop duplicated license header in init scripts
01/04/05-iot-dc3-*.sql each carried the AGPL license block twice; remove
the second copy.
2026-08-10 00:53:47 +08:00
Vickey 5131b37568 build(deploy): add postgres/rabbitmq dependency assets and regenerate openapi snapshots 2026-06-19 16:49:01 +08:00