- 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.
- include dc3-db in the make deploy artifact set alongside common/mq/tsdb
- sample DC3_DB_TYPE/DC3_TSDB_TYPE and external-store ports in .env.example
- expose mysql/mariadb/tdengine/influxdb/iotdb/jaeger in the compose stacks
- update AGENTS.md module map and module-ownership guidance
- add the missing AGPL header to the oracle driver service
Phase 1b of docs/design/tsdb-abstraction.md: every point-value read and
write now flows through the dc3-tsdb port, and dc3-common-repository is
deleted outright (no compat aliases).
Write path — new PointValueIngestService orchestration in dc3-common-data:
the stale-owner lease guard leaves the history INSERT's cross-schema join
and resolves the active owner per distinct device through the existing
DeviceFacade.getActiveOwner chain; a caffeine-backed ingest idempotency
window (dc3.data.ingest.*, marked only after both writes commit) absorbs
MQ redeliveries now that the message_id unique index is retired; the
batch lands via TsdbStore.append (natural series+time upsert, INGEST_ORDER
kept for the fenced dc3_point_latest upsert).
Read path — history via last(), page() resolves name/enable filters to
series keys through relational metadata (tenant-wide when unrestricted,
cursor offset emulation capped at 10k) with count() for totals; the alarm
window backend becomes TsdbWindowDataSource over aggregate()/history().
Dashboards — all nine data-side hypertable statements move to the S13
analytics facet (count/bucketedCount/countByDimension/latencyHistogram/
lastSeenPerSeries) plus the dc3_point_latest projection for latestStream;
the manager topology statement crosses into the data center via a new
ListSeriesVolumes RPC backed by the new S13-5 seriesCounts primitive (a
point shared by several devices needs per-series counts, which
single-dimension grouping cannot reconstruct); both cross-schema joins
are gone.
Port/adapter — seriesCounts added with a TCK case (23 total); series
filters compile to row-value IN lists chunked at 500 pairs; bootstrap
adds the quality column idempotently and retires uk_point_value_event so
existing deployments converge on the new upsert; the adapter binds the
application-provided tsdbDataSource bean (the history dynamic-datasource
entry) instead of the routing primary.
Timestamps — BO<->Instant conversion is pinned to
TimeConstant.DEFAULT_ZONEID (the platform canonical zone the latest
projection type handler already writes with); the design note's "lock
UTC" is amended accordingly, together with the lease-guard and S13-5
deviations recorded in §6.2.
Seed/deploy — 05-iot-dc3-history.sql gains the quality column and swaps
the unique index; compose carries DC3_TSDB_TYPE; make deploy publishes
dc3-tsdb.
Also fixed along the way: root pom never managed dc3-mq-core (latent,
masked by full-reactor builds); PointValueMapper ran unrouted on the
master datasource (now @DS("history")); latestStream name enrichment
looked up a Long-keyed map with String keys.
Gates: tsdb TCK 23/23, dc3-common-data 262/262, e2e 26/26 including the
unmodified PostgresHypertableIT; full reactor green except dc3-mq-tck's
kafka/pulsar container-startup flake, reproduced identically twice and
unrelated to this change.
The broker-selection family (port + six certified adapters + tck) is a
deployment selection, not shared plumbing, so it moves out of dc3-common
into a top-level dc3-mq aggregator beside dc3-api — the same standing as
the gRPC contract layer, and a template for future pluggable families
(storage is next on the design board).
- dc3-common-mq -> dc3-mq/dc3-mq-core (port: API + core runtime)
- dc3-common-mq-{rabbitmq,kafka,rocketmq,pulsar,activemq,mqtt,tck} ->
dc3-mq/dc3-mq-{...}; no compatibility aliases — every coordinate is
renamed everywhere in one commit (business poms, coverage, root
dependency management)
- dc3-common sheds eight modules back to plain shared plumbing; the
device-access dc3-common-mqtt stays by design (protocol stack, not a
broker selection)
- Java packages deliberately stay io.github.pnoker.common.mq.* — the
facade modules set the precedent that packages do not track module
homes, keeping this a pom-only, zero-source refactor
- make deploy now publishes dc3-api + dc3-common + dc3-mq (third-party
driver authors compile against the port transitively)
- docs/mq-brokers.md and the design's module layout follow the new home
Verified: full-repo test-compile green; constant/data/driver/manager
unit suites unchanged and green (255/144/291); the rabbitmq contract
suite passes 12/12 from the new coordinates against a live broker,
proving adapter wiring survived the move.
* chore(docs): move docs site to standalone pnoker/iot-dc3-docs repo
The VitePress docs site now lives in pnoker/iot-dc3-docs and serves docs.dc3.site from there. Remove the in-repo docs/ and all docs-only build/deploy wiring so nothing dangles.
- delete docs/ (source moved to pnoker/iot-dc3-docs)
- delete .github/workflows/docs.yml (deploy owned by iot-dc3-docs)
- drop npm /docs dependabot block; clean codeql/.gitignore docs paths
- remove Makefile docs-* targets
- relocate AI testing policy into dc3-web/tests/ so the required Web guardrail test is self-contained (was reading ../docs/...)
- rewire README image refs (7 READMEs) and in-repo doc links (README.ai.md, AGENTS.md, dc3/doc/README.md) to https://docs.dc3.site / the new repo
dc3/doc/{TITLE,CHANGE,USAGE}.md STAY - release tooling (make changelog, docker-ci) regenerates them; the docs repo snapshots them.
* fix(docs): repair pre-existing broken doc links found during migration
- 8 READMEs: /en|zh/introduction/technology-stack -> /en|zh/development/technology-stack (page lives under development/, not introduction/)
- dc3-web/tests/README.md: ../docs/test-debugging.md (missing) -> https://docs.dc3.site/en/frontend/test-debugging
* ci(dependabot): add cargo ecosystem, groups, and clean up stale docker directories
* docs(ai): add spring-ai-deep-dive cross-references in en and zh indexes
* docs(community): add english FAQ and frontend developer guide
* chore(issue-templates): translate all templates to english
* ci(docker): add 20 missing driver images to Dockerfile, compose, and Makefile
* fix(docs): remove Vue template syntax from panorama SVGs so they render
* docs(ai): add spring-ai-deep-dive pages in en and zh
Generate <op>-<stack>[-<registry>] compose shortcuts and test/coverage
targets in the Makefile, remove the install-hooks target and the
.githooks commit-msg linter, and document the design.
Remove the test/coverage, app/dev, and compose-* alias targets along
with their check-* guards, and drop the matching .PHONY and MVN_SUB
entries. Reorder deploy and install-hooks under the trimmed target set.
- Add docs/development/api-documentation.md describing the Swagger UI layout,
per-center grouping, auth headers, and production exposure.
- Add a `make openapi` target + dc3/bin/export_openapi.sh to snapshot each
center's OpenAPI JSON from a running stack.
- Update AGENTS.md: OpenAPI/Swagger conventions, and correct the enum-suffix
examples (multi-valued sets use *TypeEnum, not *FlagEnum).
Makefile now defaults MVN_SETTINGS to .mvn/settings.xml (Aliyun mirror) so
`make package` works without manual settings override. Also fix pre-existing
test compilation errors where service method signatures gained tenantId
parameters but the corresponding test mocks were not updated.
- Makefile: MVN_SETTINGS ?= .mvn/settings.xml
- pom.xml: re-apply dependency version bumps (surefire 3.5.6, jacoco 0.8.15,
tools.jackson 3.1.4, jaxb 4.0.9, jna 5.19.0, graalvm 1.1.1,
maven-dependency-plugin 3.11.0)
- Fix 7 test files with missing tenantId parameters in service mock calls
Parametrize JDK/JRE base images via build args in Dockerfile, replace
hardcoded GC/dump env vars with per-service path variables, fix APM
port. Simplify Makefile registry options to global|cn, add SERVICES
and GROUP selectors for targeted compose operations.
Add the first batch of unit tests under dc3-common-public covering the
core "stateless function" surface used everywhere else in the platform:
- ArithmeticUtilTest: precise add/subtract/multiply/divide/round across
BigDecimal/float/double overloads, plus scale-bound rejections and
division by zero.
- DecodeUtilTest: UTF-8 round-trips, MD5 stability and salting,
Base64 byte/string round-trips and hex en/decoding.
- HmacAuthSignerTest: enabled/disabled state derivation from the secret,
hex digest stability, mismatched-payload + mismatched-secret behavior,
null-payload guards and constant-time verification on length mismatch.
- JsonUtilTest: parseObject/parseArray from String/byte[]/InputStream/
TypeReference, isJson validation, toJsonString/Bytes round-trip and
unknown-property tolerance.
- KeyUtilTest: AES and RSA encrypt/decrypt round-trips, JWT signing
followed by salt/subject/tenant rejection paths.
The Makefile test/test-it/test-e2e/coverage targets get an explicit
-Dmaven.test.skip=false override because .mvn/maven.config sets the
flag globally so `mvn package` does not run tests; without the override
the new targets would silently produce empty reports.
dc3-common-public/pom.xml declares spring-boot-starter-test test-scope.
Verified locally: 77 new test cases run via `make test`, all green.
Wire the test toolchain into developer-facing entry points and CI:
- Makefile gains test, test-it, test-e2e and coverage targets; the help
banner advertises them alongside the existing build commands so
contributors do not need to memorise the underlying mvn invocations.
- A new Test workflow runs three sequenced jobs: unit (mvn test, skipping
the integration phase), integration (mvn verify, skipping unit phase,
running with TESTCONTAINERS_REUSE_ENABLE=true), and a final coverage
job that downloads both jacoco .exec artifacts and rebuilds the
aggregate report from dc3-coverage.
- A new E2E workflow runs make test-e2e on develop/release/main pushes
and on manual dispatch, with a 90 minute timeout that accommodates
cold compose start-up plus the full critical path battery.
- The existing CI workflow keeps its fast-fail compile job unchanged so
PR feedback latency stays low; tests are now owned exclusively by
the new Test workflow.