diff --git a/en/docs/slices/01-hello-world.md b/en/docs/slices/01-hello-world.md index 8e11be8..41845a1 100644 --- a/en/docs/slices/01-hello-world.md +++ b/en/docs/slices/01-hello-world.md @@ -261,7 +261,7 @@ End of trace. ## Open verification items -Read flow live-corroborated; save flow still pending. +Read flow + save flow both live-corroborated; SQL-layer capture remains. 1. ~~**A live captured read.**~~ **CLOSED** — clicking 系统常量配置 in BACK (`http://118.178.19.35:8597`, admin/123, edition `基础版/8s`) produced @@ -275,27 +275,49 @@ Read flow live-corroborated; save flow still pending. `/xtmkpz` rather than navigating to `/xtclpz` — confirming that URL fragments are display state, not route drivers (the SPA loads the form on demand from the sidebar click). -2. **A live captured save (partial).** Endpoint + URL + method - live-corroborated: clicking 新增 → 保存 in BACK's 系统常量配置 fired - `POST /xlyEntry/business/addUpdateDelBusinessData?sModelsId=13` → - 200 OK. (No DB mutation in our test because the audit-tag value - change didn't propagate through the SPA's Vue model — the save - ran on the original row state.) The exact request **body** the - SPA sends is the next thing to capture; for now the documented - shape rests on `BusinessBaseController.java:161-163` Javadoc. - The SPA also fires `POST /business/addSysLocking` when entering - edit mode (optimistic-lock) — see +2. ~~**A live captured save.**~~ **CLOSED — endpoint, URL, response, + and DB side-effect verified live.** In BACK's 系统常量配置: row + selected → 修改 → typed an audit-tag suffix into the sChinese cell + via real keystroke → 保存 → captured network POST: + ``` + POST /xlyEntry/business/addUpdateDelBusinessData?sModelsId=13 → 200 OK + ``` + `sModelsId=13` is the parent module id, sent only as a query param + (no path variable — confirmed via the SPA bundle's + `saveData({token, value, sModelsId})` call site at + `business/addUpdateDelBusinessData?sModelsId=" + sModelsId`). + **DB side-effect verified**: directly after the save, + `SELECT sChinese FROM gdsformconst WHERE sId='20260123…' ` + returned the modified value with the audit-tag suffix appended + (since reverted). This empirically confirms the universal-CRUD + path: the body's `updateData[].column.sChinese` field landed in + the named column on the named `sTable`. + **Body shape** (still rests on the Javadoc at + `BusinessBaseController.java:161-163` plus the SPA's `value` + parameter — the exact byte sequence the SPA serializes wasn't + captured because the SPA's `whatwg-fetch` polyfill cached the + `XMLHttpRequest` constructor at startup and bypasses any + post-startup XHR monkey-patch): + ```json + { + "addData": [{"sTable": "", "column": {"sId": "", ...}}], + "updateData": [{"sTable": "
", "column": {"sId": "", ...}}], + "delData": [{"sTable": "
", "column": {"sId": "", ...}}] + } + ``` + The SPA also fires `POST /business/addSysLocking?sModelsId=13` + when entering edit mode (optimistic-lock — visible in the same + network capture); see [internal API](../api-reference/internal.md#the-universal-crud-surface-business). -3. **The exact SQL emitted by save/delete**, captured from `syslog4j` or a - MyBatis debug log, to close the loop end-to-end. +3. **The exact SQL emitted by save/delete**, captured from `syslog4j` + or a MyBatis debug log, to close the loop at the SQL layer. + *(Future-work backlog item — `syslog4j` is wired but the dev DB's + logging level doesn't include MyBatis statements; a deployment with + MyBatis debug logging on would capture this directly.)* 4. ~~**`sTable` validation in `addUpdateDelBusinessData`.**~~ **CLOSED** — the runtime does **not** cross-check the frontend-supplied `sTable` - against the form's authorised backing tables (see the security note in - step 4 of [The trace, with observed evidence](#4-user-edits-a-row-clicks-save) + against the form's authorised backing tables (see the security note + in step 4 of [The trace, with observed evidence](#4-user-edits-a-row-clicks-save) above). Captured as a maintainer concern; mitigations exist (tenant scoping, optional pre/post-save proc validation) but the framework itself doesn't enforce. - -Items 2 and 3 require an actual save mutation captured at the body / -SQL level — deferred to avoid mutating shared dev-DB state with -audit-tag noise.