fix(cli): resolve CLI-014..016 — re-triage update-command contract, doc-surface drift, table-column union
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
| Last reviewed | 2026-05-17 |
|
||||
| Reviewer | claude-agent |
|
||||
| Commit reviewed | `39d737e` |
|
||||
| Open findings | 3 |
|
||||
| Open findings | 0 |
|
||||
|
||||
## Summary
|
||||
|
||||
@@ -575,11 +575,27 @@ The CLI test suite went from 42 to 77 passing tests.
|
||||
|
||||
| | |
|
||||
|--|--|
|
||||
| Severity | Medium |
|
||||
| Category | Correctness & logic bugs |
|
||||
| Status | Open |
|
||||
| Severity | Low |
|
||||
| Category | Design-document adherence |
|
||||
| Status | Resolved |
|
||||
| Location | `src/ScadaLink.CLI/Commands/TemplateCommands.cs:77`, `src/ScadaLink.CLI/Commands/SiteCommands.cs:86`, `src/ScadaLink.CLI/Commands/ExternalSystemCommands.cs:40-42`, `src/ScadaLink.CLI/Commands/DataConnectionCommands.cs:39-40`, `src/ScadaLink.CLI/Commands/NotificationCommands.cs:40-41`, `src/ScadaLink.CLI/Commands/ApiMethodCommands.cs:79` |
|
||||
|
||||
**Re-triage 2026-05-17:** the finding was originally filed as a Medium "Correctness &
|
||||
logic bugs" issue, but verification against the Commons message contracts shows the
|
||||
**code is correct** and the defect is purely documentation drift. Every `Update*Command`
|
||||
record (`UpdateTemplateCommand`, `UpdateSiteCommand`, `UpdateDataConnectionCommand`,
|
||||
`UpdateExternalSystemCommand`, `UpdateNotificationListCommand`, `UpdateApiMethodCommand`,
|
||||
`UpdateTemplateAttribute/Alarm/ScriptCommand`, `UpdateRoleMappingCommand`,
|
||||
`UpdateSharedScriptCommand`, `UpdateDatabaseConnectionDefCommand`, `UpdateAreaCommand`)
|
||||
carries **non-nullable** "core" fields — they are *whole-entity replace* records, not
|
||||
sparse patches. Marking the corresponding `--name` / `--protocol` / `--script` flags
|
||||
`Required = true` is therefore the *correct* CLI behaviour: making them optional would
|
||||
let an omitted flag send `null`/empty and silently blank the field server-side. Adopting
|
||||
the sparse-patch model (recommendation option a) would require changing the Commons
|
||||
records and the server-side Management handlers — both outside this module's editable
|
||||
surface. Re-triaged to Low / Design-document adherence; resolved per recommendation
|
||||
option (b).
|
||||
|
||||
**Description**
|
||||
|
||||
The design doc presents `update` commands with all non-`--id` fields as optional, e.g.
|
||||
@@ -618,7 +634,20 @@ entity. Option (a) matches the documented surface and the typical CLI expectatio
|
||||
|
||||
**Resolution**
|
||||
|
||||
_Unresolved._
|
||||
Resolved 2026-05-17 (commit pending) per recommendation option (b). Verification of the
|
||||
Commons `Update*Command` records confirmed whole-replace is the intentional contract, so
|
||||
the CLI's `Required = true` flags are correct and were left unchanged. The in-repo
|
||||
`src/ScadaLink.CLI/README.md` — which is authoritative and previously listed every
|
||||
`update` core field as optional `[--name]` — was corrected: the core flags
|
||||
(`--name`/`--protocol`/`--script`/`--code`/`--emails`/`--endpoint-url`/`--auth-type`/
|
||||
`--data-type`/`--trigger-type`/`--priority`/`--connection-string`/`--ldap-group`/`--role`)
|
||||
are now marked `required: yes`, the command synopses drop the `[...]`, and each `update`
|
||||
section states that an update replaces the whole entity. Added
|
||||
`UpdateCommandContractTests` (10 tests) pinning the whole-replace contract — every
|
||||
listed `update` command's core flags must be `Required`, and the genuinely-sparse
|
||||
`external-system method update` must remain optional. Note: `docs/requirements/Component-CLI.md`
|
||||
also still shows these flags as optional, but it is outside this module's editable
|
||||
surface — that doc-side correction is owned by the docs surface.
|
||||
|
||||
### CLI-015 — `Component-CLI.md` command surface has drifted again in two places
|
||||
|
||||
@@ -626,8 +655,16 @@ _Unresolved._
|
||||
|--|--|
|
||||
| Severity | Low |
|
||||
| Category | Design-document adherence |
|
||||
| Status | Open |
|
||||
| Location | `docs/requirements/Component-CLI.md:75`, `docs/requirements/Component-CLI.md:125-126` (vs. `src/ScadaLink.CLI/Commands/TemplateCommands.cs:404-413`, `src/ScadaLink.CLI/Commands/DataConnectionCommands.cs:41`, `:86`) |
|
||||
| Status | Resolved |
|
||||
| Location | `docs/requirements/Component-CLI.md:75`, `docs/requirements/Component-CLI.md:125-126`, `src/ScadaLink.CLI/README.md` (vs. `src/ScadaLink.CLI/Commands/TemplateCommands.cs:404-413`, `src/ScadaLink.CLI/Commands/DataConnectionCommands.cs:41`, `:86`) |
|
||||
|
||||
**Re-triage 2026-05-17:** verification found the same two drifts also present in the
|
||||
in-repo `src/ScadaLink.CLI/README.md` (the authoritative reference): its
|
||||
`template composition delete` section used the non-existent `--template-id` /
|
||||
`--instance-name` form, and `data-connection create`/`update` documented only
|
||||
`--configuration` without the canonical `--primary-config` flag (`--configuration` is in
|
||||
fact an alias of `--primary-config`). The README is in this module's editable surface;
|
||||
`docs/requirements/Component-CLI.md` is not.
|
||||
|
||||
**Description**
|
||||
|
||||
@@ -655,7 +692,15 @@ documented elsewhere.
|
||||
|
||||
**Resolution**
|
||||
|
||||
_Unresolved._
|
||||
Resolved 2026-05-17 (commit pending). Both drifts were present in the in-repo
|
||||
`src/ScadaLink.CLI/README.md` and were corrected there (the README is this module's
|
||||
authoritative reference): `template composition delete` now documents the real single
|
||||
`--id <int>` form, and `data-connection create`/`update` now document `--primary-config`
|
||||
(with the `--configuration` alias noted) alongside `--backup-config` and
|
||||
`--failover-retry-count`. Added `CommandTreeTests.TemplateCompositionDelete_IsKeyedByIdOnly`
|
||||
pinning the composition-delete surface (`--id` present; `--template-id`/`--instance-name`
|
||||
absent). The corresponding edit to `docs/requirements/Component-CLI.md:75,125-126` is
|
||||
outside this module's editable surface and remains for the docs surface to apply.
|
||||
|
||||
### CLI-016 — `WriteAsTable` derives columns from the first array element only
|
||||
|
||||
@@ -663,7 +708,7 @@ _Unresolved._
|
||||
|--|--|
|
||||
| Severity | Low |
|
||||
| Category | Correctness & logic bugs |
|
||||
| Status | Open |
|
||||
| Status | Resolved |
|
||||
| Location | `src/ScadaLink.CLI/Commands/CommandHelpers.cs:184-200` |
|
||||
|
||||
**Description**
|
||||
@@ -687,4 +732,12 @@ rows, so no element's data is silently dropped.
|
||||
|
||||
**Resolution**
|
||||
|
||||
_Unresolved._
|
||||
Resolved 2026-05-17 (commit pending). Root cause confirmed — `WriteAsTable` derived the
|
||||
header set from `items[0].EnumerateObject()` only, dropping any property unique to a
|
||||
later element. The header set is now computed as the union of property names across
|
||||
*every* object element of the array, in first-seen order (a `HashSet` guards duplicates
|
||||
while an ordered list preserves column order). Rows already project against the header
|
||||
list and `OutputFormatter.WriteTable` pads missing cells, so heterogeneous arrays now
|
||||
render every column. Regression tests added in `TableHeaderUnionTests` (3 tests:
|
||||
later-element-only column included, first-seen column order preserved,
|
||||
first-element-extra column still rendered).
|
||||
|
||||
Reference in New Issue
Block a user