Commit Graph
3456 Commits
Author SHA1 Message Date
dependabot[bot] e777764661 build(deps): bump actions/setup-java from 5.7.0 to 6.0.1
Bumps [actions/setup-java](https://github.com/actions/setup-java) from 5.7.0 to 6.0.1.
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](https://github.com/actions/setup-java/compare/b6effb05e454b25005698d916606bdc6ffcbf961...de7274f081f381c8f8158605e0321c36c376e2e6)

---
updated-dependencies:
- dependency-name: actions/setup-java
  dependency-version: 6.0.1
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-09-20 19:03:31 +00:00
pnokerandClaude Code 4cb3fd6440 refactor(db)!: unify dc3-db module naming around role names
The dc3-db aggregate mixed two naming axes and one axis-free module:
infrastructure used dc3-db-r2dbc-{core,runtime,postgres} (with "postgres"
sitting in a layer slot), the domain adapters used dc3-db-postgres-{domain}
(no "r2dbc" at all), and tck had no axis. PostgreSQL-only and R2DBC-only
are properties of the whole aggregate (dc3-db README, docs/db-dialects.md),
so the per-module prefixes carried no discriminating information — the
65 store classes already say R2dbc in their names.

New layout, one dc3-db-{role} pattern, aligned with the common-{domain} /
center-{domain} pairs they serve:

  dc3-db-r2dbc-core       -> dc3-db-core
  dc3-db-r2dbc-runtime    -> dc3-db-runtime  (absorbs the dialect)
  dc3-db-r2dbc-postgres   -> (merged into dc3-db-runtime)
  dc3-db-postgres-auth    -> dc3-db-auth
  dc3-db-postgres-manager -> dc3-db-manager
  dc3-db-postgres-data    -> dc3-db-data
  dc3-db-postgres-agentic -> dc3-db-agentic
  dc3-db-tck              -> unchanged

The dialect module held a single 12-line AutoConfiguration registering
StandardR2dbcDialect("postgres", ...) plus the r2dbc-postgresql driver;
both move into dc3-db-runtime (package io.github.pnoker.db.runtime.dialect,
registered in the runtime AutoConfiguration.imports, driver dependency
transferred). Its six dependents now rely on the runtime they already
pulled in. Java packages rename in step — io.github.pnoker.db.r2dbc.core
-> io.github.pnoker.db.core, io.github.pnoker.db.r2dbc.runtime ->
io.github.pnoker.db.runtime, io.github.pnoker.db.postgres.{auth,manager,
data,agentic} -> io.github.pnoker.db.{auth,manager,data,agentic} — so no
trace of the old axis survives outside git history.

Also fixes the stale module layout in docs/design/relational-r2dbc.md §6
(it still described stores living in dc3-common-*/repository, the
pre-7fde11134 arrangement) and ships migrations/02-schema-fingerprint-
resync.sql for existing volumes still carrying the pre-documentation
fingerprint marker.

Verified: full-reactor compile, dc3-db aggregate tests (-am), all six
service images rebuilt through the multi-stage Dockerfile (container
Maven package), WSL stack recreated with every center healthy, and an
end-to-end login + manager list smoke test through the gateway (JWT
cookie, offset/limit/sort paging).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-21 00:55:02 +08:00
pnokerandClaude Code fe041c34bd docs(db): document the runtime and observability initdb SQL
Bring 07-observability and 08-runtime up to the comment grammar the
other seed files (02-06) already follow — DDL text itself is untouched
(verified: comment- and whitespace-stripped comparison against HEAD is
identical for both files):

- 08: every table gets the "-- Table structure for" section banner, a
  file-level map of the runtime coordination blocks, per-column inline
  comments aligned within each table (mirroring the COMMENT ON
  statements), and one-line purpose comments above each index (claim
  scans, tenant timelines, sweepers). The stray compose-role note moves
  into the file header where it belongs.
- 07: the 1-hour cagg index and realtime ALTER get the same comments
  their 1-minute siblings already carry.

The fingerprint hash covers these files verbatim, comments included,
so dc3/bin/schema_fingerprint.py --sync rolls the embedded ddl_hash
and the four distributed defaults to the new canonical value
(8297d4b5… → 51468116…).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 23:38:06 +08:00
pnokerandClaude Code 41350a73df docs(brand): reposition IoT DC3 — Connect the Physical World to AI
Adopt the dc3.site canonical slogan across every surface: the platform
is an open-source Industrial IoT Runtime for Physical AI. Hero taglines
and tech-tag strips in all seven language banners regenerate from the
new copy (MCP tool gateway / safe / controllable / traceable replace
the edge-cloud and SENSE-DECIDE-ACT strips); READMEs follow — badge
line gains the live demo and industry-demo links, the AI section
rewrites around the MCP tool gateway loop (OAuth client registration,
per-tool authorization, audit trail), and the intro names the core
decoupling: drivers push normalized point data to the bus, applications
consume through one unified API. AGENTS.md carries the same one-paragraph
positioning for AI assistants.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:37 +08:00
pnokerandClaude Code 1cda1b959e fix(web): split ToolCard footer space by content, not 50/50
The footer's two clusters both carried flex: 1 1 280px, which starved
wider button rows (device = Add + Import + Search + Reset) and wrapped
the last button even when the whole footer row still had room. The
button cluster now takes exactly what its buttons need (flex 0 1 auto,
nowrap — a truly narrow viewport scrolls the row horizontally instead,
same pattern as the segmented filters above) and the pager cluster
stretches over the rest.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:37 +08:00
pnokerandClaude Code 5c35565d3f feat(web): extend the record-card tile grammar to ResponsiveRecordList
The shared table-to-card renderer (settings tables on phones) joins the
entity-icon-tile family: cardIcon/cardTone props mirror
EntityMobileCard's mobileCardIcon/mobileCardTone, the header tile +
hairline follow the ThingsCardHeader anatomy, titles adopt the card
title weight, and actions dock right stretching edge-to-edge on phones
— floating-action inset dropped like the entity cards. userConfig is
the first consumer (User glyph, blue tone).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:36 +08:00
pnokerandClaude Code 7621869fcc test(web): enforce the A5 radius and spacing contracts in CI
Now that every token migration has landed, lock them in:

- radius-contract.test.ts: every border-radius in src/ must resolve to
  the --dc3-radius-* scale (directly or through an Element Plus radius
  variable). Geometric circles (50%/100%), inherit and single-corner 0
  resets stay literal — hand-rolled px values are the exact drift this
  cleared once.
- spacing-contract.test.ts: macro spacing (page edges, card walls,
  section rhythm) must resolve to --dc3-space-* / --dc3-page-padding /
  --dc3-gutter. Semantic tokens defined exactly once in theme.scss; a
  whitelist of layout-bearing containers may only declare margin/
  padding/gap with tokens; clamp() in spacing and el-row :gutter
  values other than 8 are banned repo-wide (the JS prop cannot read
  CSS vars, so the literal must mirror --dc3-gutter's desktop value);
  a // spacing-exempt marker opts out line-by-line. Intra-component
  micro spacing stays out of scope this round.

Document the v8 spacing-system decision in
docs/design/frontend-three-terminal-ux.md and add the A5 rules to
dc3/agents/frontend.md so agents follow the scales.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:36 +08:00
pnokerandClaude Code 000c964bb0 style(web): groom native scrollbars into one slim theme-aware look
The app shell scrolls through el-scrollbar (overlay bars), but every
other overflow container — card bodies, tables, textareas, asides —
still rendered the raw browser bar. Give those one slim, quiet,
theme-aware appearance (6px track, border-token thumb, Firefox
scrollbar-width thin); el-scrollbar's own hiding rules keep their
higher specificity, so custom bars are unaffected.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:36 +08:00
pnokerandClaude Code e00017f9e7 perf(web): cache the resource tree stale-while-revalidate
The backend list_tree runs a ~1s full scan whenever its server cache
misses, and the tree only changes on registry sync or an explicit edit
— far rarer than page visits. Serve the cached tree instantly and
revalidate in the background (60s fresh window, single-flight promises
so concurrent visitors share one request); mutations through
resourceConfig invalidate the cache. At a few thousand nodes the right
next step is lazy loading (list_tree already filters by
parentResourceId), not more caching.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:36 +08:00
pnokerandClaude Code 0010bb931f fix(web): align page-sort and dictionary queries with the backend contract
Three contract mismatches:

- Page orders sent snake_case columns (create_time, group_index) while
  the R2DBC layer keys orders by the camelCase DTO field — default
  sortColumns and the shared usePagedList/useEntityListPage fallbacks
  move to createTime/groupIndex. The API store does not support
  createTime sorting at all, so apiConfig pins defaultOrderColumn to
  id for a stable default order.
- listDeviceStatus/listDriverStatus posted a full page object with
  orders copied in; the status endpoints take plain offset/limit.
  Compute the window from the current page instead.
- Bulk lookups requested limit: 1000 but the backend caps at
  PageRequest.MAX_LIMIT (200) — the resource/api name resolution and
  the MCP service-account picker now stay inside the cap (comments
  document the 200-definition completeness bound).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:36 +08:00
pnokerandClaude Code 04779a70cc fix(web): guard the point dictionary until a device is picked
The backend dictionary contract requires a parent device
(requireParent → "Parent ID is required"), so asking for points without
one is a guaranteed 4xx. Disable the point select until a device is
chosen (placeholder explains why), and short-circuit programmatic
dictionary triggers the same way. The range segmented also drops its
stale `select` prop.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:35 +08:00
pnokerandClaude Code 8daa359741 feat(web): route the point-value detail page, label cursor paging
The point-value detail was the system's only outlier: a drawer showing
raw JSON while every other entity (device/driver/point/profile) has a
routed detail page. Rebuild it on the shared contract — /point_value/
detail route (ROUTE_MENU_ALIASES maps it back to the pointValue nav
node), base-card shell, error/skeleton/empty states, structured
el-descriptions fields. PointValue.vue drops its detailData plumbing
and routes on card "detail".

Cursor-paged ToolCard footers get their own labels (common.nextPage/
prevPage) — "Next/Previous" read as wizard steps, but cursor-paged
history walks pages.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:35 +08:00
pnokerandClaude Code bee5b1f87a feat(web): agentic assistant full-screen workbench with sessions rail
The assistant panel gains an expanded mode: a full-screen workspace
with a permanent conversations column on the left — the same list the
history dropdown shows, one tap to switch sessions, rename/delete/new
actions docked in the rail header (rename moves into an anchored
popover). The resize handle hides while expanded, the panel transition
animates, and the brand mark renders on the shared icon-tile grammar.
Copy renames the surface from "DC3 Assistant" to "Agent"
(headerExpand/headerCollapse/sessionsTitle keys included).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:35 +08:00
pnokerandClaude Code 0370a42e61 feat(web): settings quick search and a drawer-free three-terminal nav
Settings sidebar:
- new SettingsMenuSearch — expanded rail gets an inline input filling
  the toolbar next to the collapse toggle; collapsed rail degrades to
  an equal-sized icon button whose popover carries the same input and
  results. Picking a result navigates WITHOUT expanding the rail
- the item mapping moves to useSettingsSidebarItems so the sidebar and
  the search read one source; the sidebar no longer force-refetches
  the menu tree on every settings visit (menuConfig mutations now
  invalidate the pinia cache instead — one ~1.5s list_tree saved per
  entry), and grows an expandAll mode that unfolds every group
- the tablet icon rail keeps a persisted "stay expanded" override
  (settingsRailExpanded, mirrors theme/density persistence)

Three-terminal navigation (A3):
- phones drop the hamburger + nav drawer entirely: the horizontal menu
  stays in the capsule as an icon-compact strip, primary navigation
  never leaves the header
- the header settings button doubles as the phone settings nav — it
  bubbles up the fully-expanded menu popover instead of navigating;
  the floating corner toggle and its drawer are gone
- language/theme fold behind one "..." chip popover on phones
- breadcrumbs with a nav payload (settings root, mid-level groups)
  open a layered picker popover listing the sibling pages — same
  bubble pattern — instead of navigating blind

Icon-only nav chips become circles to match the capsule's round
utility buttons. Tests follow: layout.test gains the phone-tier
assertions (no hamburger/drawer, folded preferences, popover nav),
the e2e responsive spec walks the new phone flow, and the ElPopover
stub renders its reference slot so popover triggers stay findable.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:34 +08:00
pnokerandClaude Code e93b600fe4 refactor(web): fix the card action order contract — browse, edit, state, delete
Card footers rendered their actions in whatever order each page happened
to grow them (delete/enable/disable first, browse last on several).
Declare the ladder once and align every card: detail (browse) → edit →
enable/disable (state) → delete (destructive last, popconfirm-guarded).
ThingsCardActions documents the contract in-template; DriverCard and
PointValueCard (detail → write) follow.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:02 +08:00
pnokerandClaude Code 56c4ed4ca6 feat(web): one icon-tile grammar for every card on the platform
Entity card headers rendered a zoo of legacy PNGs (device.png,
driver.png, point.png, ...) at fixed sizes with no tone. ThingsCardHeader
now takes an Element Plus icon name (legacy image URLs still work when
the value contains "/") drawn on a 44px tone-tinted tile — the same
glyph-block family as StatCard on Home — with a five-tone accent
palette: device purple, driver blue, point green, profile orange,
command blue, event red, point-value success.

The shared .entity-icon-tile class lands in global.scss for the mobile
record cards too: EntityMobileCard grows mobileCardIcon/mobileCardTone
config (EntityListConfig) so settings record lists render the same
tile anatomy, replacing the old selected/unselected point-info PNG
pair with an accent flip. AgenticAssistant's mark joins the family.
The nine common PNGs are deleted — nothing references them anymore.

Status chips normalize their enum codes to uppercase before comparing
(driver/device status maps carry lowercase values, so FAULT/ONLINE tags
never matched), and mobile action rows drop the floating-action inset
now that buttons dock edge-to-edge on phones.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:02 +08:00
pnokerandClaude Code 807556fbc9 refactor(web): replace BlankCard shells with a fluid entity card wall
Entity list pages (device/driver/profile/point/point-value/command/
event) nested el-row/el-col breakpoints inside a BlankCard wrapper,
which capped cards at lg/xl 4-up rungs, padded the wall with the
shell's own margins, and split the spacing mechanism between el-row
gutters and hand margins.

The wall is now a plain CSS grid (.entity-card-wall in global.scss):
repeat(auto-fill, minmax(min(380px, 100%), 1fr)) — the viewport earns a
column only once every card can stay at least 380px wide, so columns
step continuously (1→2→3→4→…) instead of snapping rungs, cards always
fill their track, and the wall's gap owns both axes through
--dc3-gutter. Empty/load-failed blocks span the whole wall.

.things-card and SkeletonCard drop their per-card margins so the
skeleton wall renders the exact geometry of the real one — no layout
shift when loading resolves; skeleton corners join the radius scale.
entity-page-error joins --dc3-gutter at the same time.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:01 +08:00
pnokerandClaude Code 734bd1ed69 refactor(web): land the A5 spacing and radius token system
theme.scss gains the semantic layer: --dc3-page-padding (16/12/8 stepped
tiers, deliberately not clamp() — a fluid edge never lands on a tier
value) and --dc3-gutter (8px card/section rhythm, 12px on phones), plus
the Element Plus radius mapping (--el-border-radius-base/small/round and
--el-popover-border-radius) defined once on :root so controls, nested
panels and every popper shell resolve through the --dc3-radius-* scale.

Sweep the hand-rolled values onto the tokens: home rows and error bars,
settings alarm overview, entity list pages, login chips, glass capsule,
chart blocks, AppPreferences — plus the redundant per-component radius
overrides dropped from global.scss's settings-main block (the :root
mapping now wins). ToolCard's margin joins --dc3-gutter and its card
body padding matches the CardShell family. el-row :gutter anchors get
sync comments since the JS prop cannot read CSS vars.

The radius-contract / spacing-contract guardrail tests and the A5 docs
land at the end of this series, after every token migration is in.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:01 +08:00
pnokerandClaude Code 914212c6cf chore(web): drop unreferenced home style.scss
The file only styled .home-statistic, which nothing renders anymore;
grep finds no remaining reference in src/ or tests/.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:01 +08:00
pnokerandClaude Code 5877f8244a feat(web): make the dashboard-card footer a family contract
The footer is no longer opt-in per card: DashboardCard now records a
data-freshness stamp ("Updated at HH:mm:ss") every time `loading`
settles without `error` — manual refresh, autoRefresh polls and
tab/range reloads all funnel through the same loading cycle, so every
trigger stamps correctly and consumers drop their own lastRefreshed
plumbing. The right side carries an explanatory line via the
`footerMeta` prop or `footer-meta` slot (ranking rules, window hints,
count digests); `:footer="false"` drops the strip, the legacy `footer`
slot still replaces both sides.

Migrate the home dashboard to the contract: Trend/Latency/Activity/
Alert cards pass footerMeta strings (new home.*.footer keys), the
AnalyticsTabs caption moves from between-tab-and-chart into the
footer's meta side (ellipsized, one line), and TopologySankey/
LiveDataFeed delete their hand-rolled "updated at" clones — the shared
stamp replaces them. common.updatedAt replaces home.liveFeed.updatedAt
(deduplicated into common) and StatCard gains the same hover-revealed
freshness line on the home stat tiles.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:01 +08:00
pnokerandClaude Code 3b2edfef1c chore(db): refresh R2DBC schema fingerprint after seed normalization
Roll the canonical clean-DDL fingerprint (713c2637… → 8297d4b5…) in the
runtime seed table and every deploy surface that pins it — docker-compose.yml,
docker-compose-dev.yml, env/dev.env, env/dev.env.sh — so startup
validation matches the batch of schema updates just landed (icon seed
re-mapping, whitespace/column-order normalization; 08-runtime also picks
up the alignment pass, no semantic DDL change).

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:00 +08:00
pnokerandClaude Code 9dba8bd075 feat(menu): re-map settings menu icons to their semantic domains
Twelve settings menus carried icons borrowed from unrelated domains
(Lock for roles, Discount for menus, ChatDotRound for model config,
Document duplicated across three history pages...). Re-map each to the
glyph that names its job — UserFilled/Medal/Paperclip/Box/Menu/
MagicStick/Shop/Postcard/Platform/Lightning/Position/Memo — unique per
group with no parent/child duplication.

Single source of truth, kept identical across four copies:

- initdb/02-iot-dc3-auth.sql seed (also drops the dead nav.home
  entry-point icons from route meta in views.ts — nav icons come from
  the dc3_menu tree, never from route records)
- new migrations/01-menu-icon-backfill.sql: initdb seeds only run on
  FIRST container start, so databases initialized before this change
  need the idempotent UPDATE backfill to converge
- settingsNav.ts frontend fallback + menuTree.ts static mock
- settings-menu-consistency.test.ts now parses menu_ext icons from the
  seed and enforces seed == fallback == mock, that every icon is a real
  @element-plus/icons-vue export, and per-group uniqueness

02-auth also picks up the whitespace normalization from the previous
commit's pass over the other seed files.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:00 +08:00
pnokerandClaude Code 1ba35acc32 style(db): normalize initdb SQL whitespace and alignment
Column-type alignment, SET ( vs SET(, and trailing whitespace across
extensions/data/manager/history/agentic/observability seeds — zero
semantic change (verified: git diff -w is empty). 02-auth and
08-runtime carry the same reformatting alongside their content changes
in the follow-up commits.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:00 +08:00
pnokerandClaude Code bc404d228d build(docker): bump dependency base images to the 2026.10 line
mariadb/mysql move off 2026.6, postgres/rabbitmq off 2026.5, so all
four dependency images follow the same 2026.10 base release line built
in dc3-docker. docker-compose-db.yml passes the new tag through.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:04:00 +08:00
pnokerandClaude Code 129d783861 build(docker): unbreak container builds (Maven resolver locks, pnpm 12)
Two independent container-build breakages:

- Root Dockerfile: with BuildKit cache mounts the Maven resolver's
  named lock factory fails on overlay-backed filesystems ("sync context
  factory" errors) even though only one Maven process runs per build.
  Switch the sync context factory to noop for the package step.

- dc3-web/Dockerfile: pnpm 12 dropped bin/pnpm.cjs while the corepack
  shim bundled with Node 22 still expects it, so `corepack prepare`
  died at the first pnpm invocation. Install pnpm directly via npm -g
  so the bin entry resolves.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:03:29 +08:00
pnokerandClaude Code ed81f90326 fix(db): build event-history page specs without an empty base SQL
R2dbcEventHistoryStore.findByPage started from DatabaseClient.sql("")
and chained .bind() calls while folding filters into a shared predicate
string. sql("") fails eagerly on the R2DBC SPI, so any code path that
touched the spec before the real SQL was attached blew up at runtime.

Fold every optional filter into the predicate first, then build the
COUNT and page specs separately, binding each parameter on the spec that
actually references it. Behavior (query shape, paging bounds, ordering)
is unchanged.

Co-Authored-By: Claude Code <noreply@anthropic.com>
2026-09-20 10:03:28 +08:00
pnoker 4428b1ceb8 ci: drop one-off mockito diagnostic step
The forced re-download proved the javaagent failure is not a corrupted
cache: freshly downloaded jars fail identically, so the diagnostic step
served its purpose and the investigation moves to an issue.
2026-09-19 19:25:24 +08:00
pnoker 4a9a65e258 ci: fix e2e ratchet baseline and purge corrupted cached jars
The e2e suite runs the verify lifecycle too, so its shallow checkout
also needs the origin/main baseline for spotless ratchetFrom. Unit,
integration and coverage jobs additionally restore a maven cache that
contains a truncated mockito jar from an earlier failed run; the
restore-key fallback keeps resurrecting it and -U never re-downloads a
file that already exists, so drop implausibly small jars before the
build.
2026-09-19 19:25:24 +08:00
pnoker a5fe1549d9 ci: run spotless and checkstyle through the verify lifecycle
The mixed 'initialize spotless:check' direct-goal invocation resolves
inter-module jars from remote repositories instead of the reactor and
fails within seconds on a clean cache — Backend CI on main has been red
since early September because of it. Both checks already bind to the
verify phase, so a plain skipped-tests verify run executes them with
normal reactor resolution (verified against an empty local repository).
2026-09-19 19:25:24 +08:00
pnoker 5009ee744b ci: fetch main baseline for the spotless ratchet in shallow checkouts
ratchetFrom origin/main (38204bf7d) needs an origin/main ref that the
default depth-1 PR checkout does not provide, so compile, Unit tests
and Integration tests all failed within seconds on the first PR since.
Fetch the main tip right after checkout in every affected job; the
ratchet only diffs the working tree against that one commit.
2026-09-19 19:25:24 +08:00
pnoker ac4bd7aa41 style: apply palantir format to cleanup branch sources 2026-09-19 19:25:24 +08:00
pnoker 4f40fc6846 docs(db): align dialect documentation with postgres-only runtime
docs/README.md still advertised a three-dialect selection guide that
db-dialects.md no longer contains, tsdb-abstraction.md documented a
MySQL upsert branch that no longer exists, and the r2dbc-postgres
README pointed at the removed dc3.db.type activation property.
2026-09-19 19:25:24 +08:00
pnoker 7302014c5c chore(build): remove orphan mysql and mariadb docker scaffolds
dependencies/mysql and dependencies/mariadb kept placeholder Dockerfiles
after the flag-day removed their seed scripts; no compose, helm, k8s or
CI build context referenced either image. The empty dc3-db-r2dbc-mysql
and dc3-db-r2dbc-mariadb module skeletons go with them.
2026-09-19 19:25:24 +08:00
pnoker d6b7cc23cd refactor(common)!: drop dead database profile constants
JDBC_AUTO_PROFILE, DB_TYPE, MYSQL_AUTO_PROFILE, POSTGRES_AUTO_PROFILE,
JDBC_PROFILE, POSTGRES_PROFILE, MYSQL_PROFILE and MARIADB_PROFILE had
zero references since the flag-day storage unification; the runtime
selects nothing anymore.
2026-09-19 19:25:24 +08:00
pnoker 683d50e039 refactor(db)!: remove dc3.db.type selector
docs/db-dialects.md and the flag-day design already declared
dc3.db.type removed, but the property still gated the only dialect
adapter. PostgresR2dbcDialectConfiguration now registers
unconditionally, dc3-center ships dc3-db-r2dbc-postgres as a plain
runtime dependency instead of a self-activating Maven profile, and
the cardinality guard keeps rejecting any count other than exactly
one R2dbcDialect bean.
2026-09-19 19:25:24 +08:00
pnoker e81366f3bf feat(common): warn on malformed ext json decode
Store json() helpers swallowed parse failures as silent nulls, so a
corrupted or shape-drifted extension column was invisible. JsonUtil
gains parseObjectQuietly(text, type, context): empty stays null, and
an undecodable value logs a warning with the column context and
returns null, keeping one bad row from failing an entire query. All
fourteen store helpers now delegate to it and pass their column name.
2026-09-19 19:25:24 +08:00
pnoker ed9f21d739 refactor(db): fail fast on unknown timestamp decode
Every store decoded timestamp columns through a private time(Object)
helper that silently returned null for unexpected driver types, hiding
decode breakage as missing values. The helpers now delegate to
DatabaseInstant.toLocalDateTimeUtc, which keeps null for null columns
and throws IllegalStateException on any non-null value of an
unsupported type, matching the R2dbcOperationRepository.instant
precedent.
2026-09-19 19:25:24 +08:00
pnoker d69bb57e9c refactor(db): remove unused r2dbc page and cursor executors
R2dbcPageExecutor and R2dbcCursorExecutor had zero production
adopters: every store executes count/items and keyset paging inline
inside SpringR2dbcPageTransaction snapshots. Dropping the dead
executors leaves one pagination implementation instead of two,
and the migration handoff checklist no longer lists them.
2026-09-19 19:25:24 +08:00
pnoker 0f6a4bfa13 refactor(db)!: drop mysql/mariadb dialect branches from postgres stores
The flag-day migration to reactive PostgreSQL left dead mysql/mariadb
arms behind dialect.name() switches in the per-domain postgres stores.
Every branch now collapses to its PostgreSQL arm: ON DUPLICATE KEY
upserts, DATE_FORMAT/TIMESTAMPDIFF analytics buckets, JSON_EXTRACT
expressions, INSERT IGNORE locks, and the UUID-to-BINARY(16) codec.
R2dbcPointValueLatestStore no longer silently falls back to MySQL
syntax for any non-postgres dialect name, and stores whose dialect
field became unused lose it (TCK constructor updated accordingly).
2026-09-19 19:25:24 +08:00
pnoker c840fbe85f chore(dc3-web): enforce eslint jsdoc gate and backfill api comments
Mirror the backend checkstyle javadoc gate in eslint: exported
functions, interfaces, types and classes must carry jsdoc with
matching @param/@returns tags and descriptions. Backfill the api,
config, utils, store, mock and composable layers so the gate starts
green.
2026-09-19 17:40:44 +08:00
pnoker 1847829415 chore(dc3-cli): enforce eslint jsdoc gate and backfill api comments
Mirror the backend checkstyle javadoc gate in eslint: exported
functions, interfaces, types and classes must carry jsdoc with
matching @param/@returns tags and descriptions. Backfill the full
cli surface so the gate starts green.
2026-09-19 17:40:39 +08:00
pnoker 5ca2cf67c4 chore(repo): complete license header coverage for typescript sources
java headers are generated and enforced by spotless licenseHeader from
the root copyright file; the typescript surfaces had no such control -
dc3-cli carried zero headers across 32 files and dc3-web was missing
one hand-written file:

- add scripts/add-license-header.mjs (shared by both packages) that
  reads the same root copyright and emits block comments for ts and
  html-comment headers for vue, with a --check mode for ci
- wire headers / headers:check npm scripts; unplugin-generated ambient
  d.ts files are exempt (the generator owns their file head)
- backfill all 32 dc3-cli sources and operation.ts / type.d.ts

verified: headers:check green on both packages, cli 67/67 tests +
build + lint, web 687/687 tests + lint + format
2026-09-19 15:37:47 +08:00
pnoker 33741fb333 build(deps): bump dc3-cli js-yaml to 4.3.2
supersedes dependabot #217 (stale develop base); js-yaml 4.3.2 carries
the security fix, verified locally with the full cli suite
2026-09-18 22:20:16 +08:00
pnoker 9482cf0be4 build(deps): bump dc3-cli vitest to 4.1.11
supersedes dependabot #216/#213 which targeted the stale develop
branch; verified locally: 67/67 tests, build and lint clean
2026-09-18 22:19:06 +08:00
pnoker 014f66ac19 build(deps): bump seven build plugins to latest
antrun 3.2.0, surefire 3.6.0, spotless 3.10.2, graalvm-native 1.1.13,
versions-plugin 2.22.0, compiler 3.16.0, jar 3.5.1

verified: clean package, dual quality gates, 5282/5282 unit tests
2026-09-18 21:32:31 +08:00
pnoker 5b74de8b6a build(deps): bump nine runtime dependencies to latest patch
bouncycastle 1.86, snakeyaml 2.7 (security-adjacent, first priority);
lombok 1.18.48, protobuf 4.36.2, grpc 1.84.0, springdoc 3.1.1,
swagger-core 2.2.55, freemarker 2.3.35, oshi 7.6.1

verified: clean package, 5282/5282 unit tests, 26/26 backend e2e
2026-09-18 21:28:43 +08:00
pnoker 21e0bae93c refactor(driver): collapse duplicated hex and checksum helpers into codecutil
five drivers carried private bytesToHex copies and three carried
hexToBytes variants, while mbus/dlt645 frames each implemented the same
sum checksum:

- codecutil.bytesToHex now uses hexformat uppercase, matching what all
  five private copies already emitted (zero display change)
- codecutil.hexToBytes added: whitespace-tolerant, blank-to-empty,
  mixed-case input
- codecutil.sumChecksum added as the shared mbus/dlt645 frame checksum
  and both frame classes delegate to it
- dlt645's inline hex loop replaced by codecutil.hexTobytes
- fins' private bcd copy kept deliberately: codecutil's bcd variant
  strips leading zeros, a different protocol semantic
2026-09-18 19:45:24 +08:00
pnoker c04d541bf6 chore(repo): normalize line endings for cross-platform clones
gitattributes only covered five file types; on a windows clone
(core.autocrlf=true) every other text file checks out as crlf, which
spotless's origin/main ratchet then treats as whole-repo changes and
the format gate fails everywhere. declare lf as the repository-wide
text convention with explicit crlf exceptions for bat/cmd/ps1, mark
the binary asset families, and renormalize (no content changes - the
tree was already lf)
2026-09-18 18:39:04 +08:00
pnoker 12dded2225 chore(repo): clear the remaining third-party boot warnings
- springdoc: declare api-docs/swagger-ui enabled explicitly; the boot
  reminder only fires on unset properties, so the intent-declaring
  values keep behavior identical and quiet all six services
- netty: add the macos dns native resolver to the gateway so the
  resolver does not log an error at boot on mac dev machines (the
  no-classifier jar bundles every arch and is inert on linux)
- hibernate-validator HV000271: spring-cloud-gateway 4.3.0 still uses
  container-level @Valid on its List properties. logger-level rules
  cannot suppress it because spring boot's logging re-init installs a
  second loggercontext that resets them, so drop the exact message
  with a turbo filter attached to every context loading this config;
  the class documents the upstream trigger for removal

live verification: five services plus gateway boot with zero warn and
zero error lines, virtual driver included; salt/login probe 200
2026-09-18 18:02:11 +08:00
pnoker b6726f7dc1 docs(agents): document the commit-msg hook now that it exists 2026-09-18 11:44:34 +08:00