docs(ipsen-movein): correct inbound DB helper to async QuerySingleAsync in design doc
The IpsenMES MoveIn design-doc pseudocode and helper-surface sketch used the synchronous, read-only `Database.QuerySingle<T>`/`Query`. The shipped InboundDatabaseHelper is async and write-capable: `await QuerySingleAsync<T>`, `QueryAsync`, `ExecuteAsync` (InboundAPI-026/027). Three inbound methods authored from this draft (IpsenMESMoveIn, MesMoveIn, MesMoveOut) failed Roslyn compilation in production until corrected to `await Database.QuerySingleAsync<...>(...)` (2026-06-25). Fix the pseudocode, the helper-surface bullet, and the inline reference, and add a dated correction note pointing at the authoritative Component-InboundAPI.md surface.
This commit is contained in:
@@ -74,16 +74,26 @@ receiver is ready to accept a MoveIn.
|
|||||||
## 4. Components
|
## 4. Components
|
||||||
|
|
||||||
### A. ScadaBridge source change — inbound read-only DB helper
|
### A. ScadaBridge source change — inbound read-only DB helper
|
||||||
- New `InboundDatabaseHelper` backed by `IDatabaseGateway`, surface:
|
- New `InboundDatabaseHelper` backed by `IDatabaseGateway`, surface (async — every call is
|
||||||
`T? QuerySingle<T>(string conn, string sql, object? args = null)` and
|
awaited and bound to the method deadline):
|
||||||
`IReadOnlyList<IReadOnlyDictionary<string, object?>> Query(string conn, string sql, object? args = null)`.
|
`Task<T?> QuerySingleAsync<T>(string conn, string sql, object? args = null)`,
|
||||||
**No write methods.**
|
`Task<IReadOnlyList<IReadOnlyDictionary<string, object?>>> QueryAsync(string conn, string sql, object? args = null)`,
|
||||||
|
and `Task<int> ExecuteAsync(string conn, string sql, object? args = null)` (writes are supported —
|
||||||
|
see the correction below).
|
||||||
- Add `Database` property to `InboundScriptContext`; construct it in `InboundScriptExecutor`
|
- Add `Database` property to `InboundScriptContext`; construct it in `InboundScriptExecutor`
|
||||||
from a service scope (gateway is scoped). Add the helper's assembly to the script
|
from a service scope (gateway is scoped). Add the helper's assembly to the script
|
||||||
`ScriptOptions.WithReferences(...)` and confirm `ForbiddenApiChecker` still passes (the script
|
`ScriptOptions.WithReferences(...)` and confirm `ForbiddenApiChecker` still passes (the script
|
||||||
references only `Database.QuerySingle`, never `System.Data`).
|
references only `Database.QuerySingleAsync`, never `System.Data`).
|
||||||
- Unit tests with a fake `IDatabaseGateway`.
|
- Unit tests with a fake `IDatabaseGateway`.
|
||||||
|
|
||||||
|
> **Correction (2026-06-25).** The shipped `InboundDatabaseHelper` is **async** —
|
||||||
|
> `QuerySingleAsync<T>` / `QueryAsync` / `ExecuteAsync`, each `await`ed — not the synchronous
|
||||||
|
> `QuerySingle`/`Query` sketched in the original draft above, and **writes are supported**
|
||||||
|
> (InboundAPI-026) rather than read-only. Scripts MUST call `await Database.QuerySingleAsync<T>(...)`.
|
||||||
|
> Three deployed methods (`IpsenMESMoveIn`, `MesMoveIn`, `MesMoveOut`) were authored from the old
|
||||||
|
> `Database.QuerySingle` spelling and failed Roslyn compilation in production until corrected
|
||||||
|
> (2026-06-25). The authoritative surface lives in `docs/requirements/Component-InboundAPI.md`.
|
||||||
|
|
||||||
### B. Rewrite inbound `/api/IpsenMESMoveIn` script (data, via management API)
|
### B. Rewrite inbound `/api/IpsenMESMoveIn` script (data, via management API)
|
||||||
Pseudocode (always returns the 3-field shape; never throws out):
|
Pseudocode (always returns the 3-field shape; never throws out):
|
||||||
```csharp
|
```csharp
|
||||||
@@ -96,7 +106,7 @@ try {
|
|||||||
var side = suf == "A" ? "Left" : suf == "B" ? "Right" : null;
|
var side = suf == "A" ? "Left" : suf == "B" ? "Right" : null;
|
||||||
if (side == null) return new { WasSuccessful = false, ErrorText = $"Unsupported side '{suf}'", BatchID = 0 };
|
if (side == null) return new { WasSuccessful = false, ErrorText = $"Unsupported side '{suf}'", BatchID = 0 };
|
||||||
|
|
||||||
var code = Database.QuerySingle<string>("BTDB",
|
var code = await Database.QuerySingleAsync<string>("BTDB",
|
||||||
"SELECT TOP 1 Code FROM dbo.Machine WHERE SAPID=@s", new { s = sap });
|
"SELECT TOP 1 Code FROM dbo.Machine WHERE SAPID=@s", new { s = sap });
|
||||||
if (string.IsNullOrEmpty(code)) return new { WasSuccessful = false, ErrorText = $"No machine for SAP {sap}", BatchID = 0 };
|
if (string.IsNullOrEmpty(code)) return new { WasSuccessful = false, ErrorText = $"No machine for SAP {sap}", BatchID = 0 };
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user