- method-level @PreAuthorize rejections propagated to the generic
handler and returned http 500; add an access-denied mapping so
permission failures read as 403 problem details
- actuator: only /actuator/health stays public, the rest require
authentication in pre/pro (dev keeps prometheus open for local
scraping); document why csrf is safely disabled
- centers: exclude the grpc oauth2 resource-server autoconfiguration
per service (not in the shared web profile, which outranks the
gateway's own excludes) and add the resource-server/jose deps so
annotation introspection resolves cleanly at boot
Relocate all 64 R2dbc*Store implementations from dc3-common-{auth,manager,data,agentic} repositories into new dc3-db-postgres-{auth,manager,data,agentic} adapter modules (package io.github.pnoker.db.postgres.<domain>), each registered through its own AutoConfiguration. Reactive*Store ports and filter types stay in the business modules; services are untouched. Drops stale MyBatis wording from AGENTS.md and init runner javadoc.
- 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.
The history JDBC url sets only currentSchema=dc3_history, so any
object the history connection must resolve outside its own schema
(extension functions, shared types, public tables) fails with the
default search_path stripped to a single entry. Append public to the
currentSchema list across the dev/pre/pro/test profiles so unqualified
names in the history route resolve against dc3_history first and fall
back to public, matching standard PostgreSQL search-path semantics.
Co-Authored-By: Claude <noreply@anthropic.com>
- Spring Boot 4.0.7 -> 4.1.1, Spring Cloud 2025.1.2 -> 2025.1.3,
Spring AI 2.0.0 -> 2.0.1, springdoc 3.0.3 -> 3.1.0
- Migrate gRPC starters to the Boot-owned spring-boot-starter-grpc-client/server
line (org.springframework.grpc starter stops at 1.0.3 and mixes badly with the
spring-grpc-core 1.1.1 managed by the Boot 4.1 BOM), and move the
spring.grpc.channels.* YAML keys to the new spring.grpc.channel.* format
- Refresh driver protocol libraries (modbus4j 3.1.0, jSerialComm 2.11.4,
bacnet4j 6.1.1, gurux-dlms 4.0.96, j60870 1.8.0, snmp4j 3.13.1) and drop the
flow-control overrides removed from the modbus4j SerialPortWrapper interface
- Refresh jackson 2.x/3.x, protobuf, okhttp, micrometer, oshi, sqlite-jdbc,
swagger-core, instancio, mockito, logstash-logback-encoder 9.0 and the
graalvm native plugin; keep commons-io (broken timestamp-version candidate)
and j-interop 2.0.4 (legacy major) pinned
Co-Authored-By: Claude <noreply@anthropic.com>
- derive pagination DbType from the selected dc3-db adapter with a fail-fast
when a non-default dc3.db.type lacks its adapter jar
- skip postgres profile activation for mariadb, not just mysql
- fork OAuthMcpMapper/AlertMapper statements for mysql and mariadb
(CAST AS JSON, ::text casts, ODKU value references)
- honor GET_LOCK verdict in resource registry sync instead of assuming
acquisition on every engine
- pg2mysql_seed.py: convert partial unique indexes to stored generated guard
columns instead of dropping them; add 99-iot-dc3-grants.sql
- add DC3_DB_URL/DC3_DB_HISTORY_URL per-service overrides in center configs
- cover the new mapper forks in the db TCK; fix AGPL headers in spring
metadata files
- add the canonical AGPL header to the six agentic application yml files and the two python scripts that lacked one
- add the header to all 79 kustomize, helm, and grafana yaml files, including the k8s driver template which regenerates the 36 driver manifests
- verified: the k8s yaml files parse (multi-document aware), the python scripts compile, and the regenerated drivers differ only by the header
A comment-health audit driven by an AST scanner (regex scanners kept
false-positiving on annotation-separated javadoc; the AST pass with
constructor and @Override-implementation exemptions is what produced a
trustworthy worklist) ended with a much smaller true gap than the raw
numbers suggested: class-level javadoc is already at 100% repository-wide.
What actually gets filled here:
- AnalyticsModel: all 30 nested records of the S19 analytics facet get
maintainer-voice javadoc (the @Schema descriptions serve the API side;
these serve code readers).
- The whole entity/ext family (29 files, 47 nested classes): every
Content/Ui/Validation/Security/AppliesTo/Template/Dedup/... schema
class states what it actually holds — read from the fields, not
templated.
- Adapter families: the @Bean methods of all six MQ adapters, all four
TSDB adapters and the three DB dialect adapters get one-line
maintainer docs (what binds to what, what is overridable).
- Nested support types across data/agentic/constant/public/facade:
NotifyBindKey, CacheTuning, Credential, dashboard VOs' Item/BucketVO,
ExpireListener (plus its null-doc placeholder javadoc replaced with a
real contract), agentic chat/stream VOs' choice/delta/usage shapes,
tool-context records, RequestHeader envelopes, FleetSummary,
visualization Type/Scale codes.
- PointValueSampleConverter's boundary methods now state the port-side
contract (quality default injection point, batch order preservation).
Comment drift fixed: the class javadoc of the can/mqtt/opc-da driver
skeletons claimed "see TODO markers in method bodies" — those markers
do not exist; the claims are corrected to plain work-in-progress notes.
The genuine TODOs (zigbee API verification, lwm2m lookup, ethernet-ip
CIP framing, CAN JNI) stay: they mark real unimplemented behavior.
Vendored-code boundary: the opc-da module carries a ported
org.openscada library (46 files, package org.openscada.*). Its trivial
accessors stay bare on purpose — filler comments on get/set pairs are
exactly the kind of noise this pass exists to remove — but the
non-obvious JIStruct wire-decoder methods (getStruct/fromStruct
FILETIME + three DO wrappers) now document the COM bridge shape.
Gates: full-repo compile green; data/model/constant/agentic/public
test suites green.
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.
Prose rewrapping and table reflow from a project-wide markdown pass;
no content changes. Also reverts two formatter mistakes: restores
MD5(password) in dc3-web/AGENTS.md and drops spurious spaces after
CJK punctuation in README.zh.md / README.ja.md.
Covers root guides (AGENTS/CONTRIBUTING/SECURITY/README.*), module
READMEs across dc3-api/center/common/driver/e2e/gateway, the nginx
guide, dc3/doc/{README,TITLE}.md, and dc3-web docs.
Remove configuration duplicated verbatim by the auto-activated shared profile bases: the dc3-center-manager gRPC channel in several drivers, the management.* block in center/gateway services, the gateway swagger-ui.path, duplicate logging sub-packages, and dead dc3.driver.mqtt config in dc3-center-data (no dc3-common-mqtt dependency). spring.env/spring.group are kept (consumed by RabbitmqEnvironmentConfig/WebFluxSecurityConfig/HmacAuthConfig). Effective configuration unchanged; validated via YAML parse + Maven process-resources.
Co-Authored-By: Claude <noreply@anthropic.com>
The dal/auth/data/manager mapper packages are already scanned by the
common-layer @AutoConfiguration classes (DalConfig, AuthInitRunner,
DataInitRunner, ManagerInitRunner), which are auto-registered via
AutoConfiguration.imports and loaded because center-single depends on all
of those common modules. The explicit @MapperScan on SingleApplication
just re-declared the same four packages — note it omitted agentic.mapper,
yet agentic mappers work fine, proving the common auto-config is what does
the scanning. The other four center apps carry no @MapperScan either.
Drop the annotation and the SingleApplicationTest assertion that only
pinned its literal presence. Verified: `mvn test` on center-single passes.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
SingleApplication had a javadoc block wedged between @SpringBootApplication
and @MapperScan, which attaches to the annotation rather than the class
and duplicates the class-level javadoc. The @MapperScan already conveys
its own meaning, so remove the misplaced block.
Document 31 modules that had no README: dc3-center-agentic, dc3-e2e,
common modules (agentic, sql, test, resource-registrar) and the facade
subsystem (api/grpc/local-auth/local-data/local-manager), plus 21
drivers. Content is grounded in each module's pom/yaml/source; WIP
skeleton drivers (can, dlms, ethernet-ip, iec104, lwm2m, zigbee) are
flagged as such.
The Spring @Scheduled sweeper these supported was migrated to RabbitMQ
TTL+DLX; the bean and @EnableScheduling were left orphaned. Scheduled
work in center-data runs on Quartz.
Update auth, gateway, architecture, quickstart, changelog, and superpowers design documents for the Principal identity model and OAuth-backed MCP server.
Make the REST API documentation actually reachable end-to-end:
- Upgrade springdoc to 3.0.3 (Spring Boot 4 / Spring Framework 7 compatible)
and pin swagger-core 2.2.47 to resolve the Spring AI conflict.
- Register SpringDocConfig and WebFluxSecurityConfig as @AutoConfiguration so
they load (they sit in io.github.pnoker.common.config, which centers do not
component-scan); add the global OpenAPI info + X-Auth security schemes.
- Add per-module GroupedOpenApi beans (auth/manager/data/agentic) and gateway
aggregation routes + swagger-ui.urls for a single federated Swagger UI.
- Fix the security chain: guard WebFluxSecurityConfig off the gateway, supply a
permissive default PermissionProvider, register the @perm bean, and correct
the token-path whitelist (base-path is stripped before the chain).
- Whitelist doc paths; disable docs in the production profile.
- Register swagger-ui webjar resources (default static mappings are disabled).
Add rollbackFor=Exception.class to all 23 @Transactional annotations across
9 service files to ensure checked exceptions trigger rollback. Spring
defaults to rollback only on RuntimeException/Error.
Add a named ThreadPoolTaskScheduler bean (pool=4, prefix=dc3-schedule-)
in DataApplication to replace the default single-threaded scheduler that
could block all @Scheduled tasks when one hangs.
Remove DEFAULT_KEY and DEFAULT_PASSWORD constants from AlgorithmConstant.
Require DC3_SECURITY_KEY env var at startup — fail with IllegalStateException
if not configured instead of silently falling back to a well-known string.
Remove hardcoded default HMAC secret from HmacAuthProperties. Log a warning
when request signing is disabled in WebFilterConfig.
Require DC3_SECURITY_DEFAULT_PASSWORD for password reset operations instead
of falling back to the hardcoded 'dc3dc3dc3'.
Replace all YAML password fallback values (dc3dc3dc3) with empty defaults so
misconfigured deployments fail at connection time with a clear error rather
than silently connecting with a well-known password.
Replace local Caffeine cache as the source of truth for driver and
device online status with dc3_entity_state, a persistent state lease
table backed by PostgreSQL.
- Add EntityStateDO/Mapper/Manager persistence stack.
- Add EntityStateExpiryScanner that scans expire_time every 15 seconds
with lease_version recheck to avoid stale alarm writes.
- Dual-write heartbeat path: DriverStateServiceImpl and
DeviceStateServiceImpl now write dc3_entity_state first, then local
cache.
- All status queries (controllers, gRPC server, local facade,
SystemHealthServiceImpl) read from dc3_entity_state. Rows missing or
past expire_time return offline.
- OfflineExpiryListener gains a DB dedup check to skip expiry events
already handled by the scanner.
- Add @EnableScheduling to DataApplication.
- Add design doc docs/design/entity-state.md with full DDL.
This resolves restart state loss, multi-instance inconsistency, and
races between expiry checks and fresh heartbeats.
Refresh module READMEs, AGENTS.md, CONTRIBUTING.md, and dc3/doc/
guides to reflect the unified Dockerfile, consolidated compose stacks,
and updated build instructions.
Replace 14 individual Dockerfiles with a single unified Dockerfile at
the repo root using multi-stage BuildKit targets. Maven build runs
inside the builder stage so no host JDK is required.
Update @since from 2022.1.0 to 2016.10.1 and @version from 2026.5.5
to 2026.5.17 across all Java source files to reflect the actual
project start date.
Replace shared SERVER_PORT/GRPC_SERVER_PORT with per-service
DC3_GATEWAY_PORT, DC3_AUTH_PORT, DC3_AUTH_GRPC_PORT, etc. in
application.yml and Dockerfiles. Prevents port conflicts when
loading the same env file for multiple local services.