@galadrim/galadmin 0.2.9 → 0.2.11-alpha.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agents/report/blockers.json +1 -0
- package/.agents/report/failures/2026-09-23-api-user-filter-contract.md +31 -0
- package/.agents/report/failures/2026-09-23-api-values-contract.md +25 -0
- package/.agents/report/failures/2026-10-01-cycle-02-create-callback-contract.md +17 -0
- package/.agents/report/failures/2026-10-01-cycle-06-delete-callback-id-contract.md +17 -0
- package/.agents/report/failures/2026-10-01-cycle-07-panel-delete-callback-id-contract.md +24 -0
- package/.agents/report/failures/2026-10-01-cycle-13-update-callback-id-contract.md +17 -0
- package/.agents/report/failures/2026-10-01-cycle-15-rich-text-upload-boundary-contract.md +24 -0
- package/.agents/report/failures/2026-10-03-cycle-06-record-import-parser-contract.md +11 -0
- package/.agents/report/failures/2026-10-03-cycle-07-panel-import-parser-contract.md +24 -0
- package/.agents/report/failures/2026-10-07-resume-cycle-02-api-assembly-contract.md +46 -0
- package/.agents/report/port/2026-09-23-api-config-enrichment.md +13 -0
- package/.agents/report/port/2026-09-23-api-file-upload.md +11 -0
- package/.agents/report/port/2026-09-23-api-query-authorization.md +14 -0
- package/.agents/report/port/2026-09-23-api-request-configuration.md +11 -0
- package/.agents/report/port/2026-09-23-database-manager.md +13 -0
- package/.agents/report/port/2026-10-01-api-adjacent-record-id.md +9 -0
- package/.agents/report/port/2026-10-01-cycle-01-api-config-route.md +9 -0
- package/.agents/report/port/2026-10-01-cycle-03-custom-action.md +9 -0
- package/.agents/report/port/2026-10-01-cycle-04-custom-component.md +7 -0
- package/.agents/report/port/2026-10-01-cycle-05-custom-query.md +7 -0
- package/.agents/report/port/2026-10-01-cycle-08-bulk-delete.md +9 -0
- package/.agents/report/port/2026-10-01-cycle-09-duplicate-record.md +9 -0
- package/.agents/report/port/2026-10-01-cycle-10-notification-badges.md +9 -0
- package/.agents/report/port/2026-10-01-cycle-11-record.md +7 -0
- package/.agents/report/port/2026-10-01-cycle-12-search-companies.md +11 -0
- package/.agents/report/port/2026-10-01-cycle-14-upload-file.md +7 -0
- package/.agents/report/port/2026-10-03-cycle-01-create-record.md +11 -0
- package/.agents/report/port/2026-10-03-cycle-02-delete-record.md +11 -0
- package/.agents/report/port/2026-10-03-cycle-03-panel-delete-record.md +11 -0
- package/.agents/report/port/2026-10-03-cycle-04-update-record.md +11 -0
- package/.agents/report/port/2026-10-03-cycle-05-api-values.md +11 -0
- package/.agents/report/port/2026-10-06-cycle-01-record-import.md +9 -0
- package/.agents/report/port/2026-10-06-cycle-03-rich-text-upload.md +7 -0
- package/.agents/report/port/2026-10-06-cycle-04-user-filters.md +11 -0
- package/.agents/report/port/2026-10-06-resume-cycle-01-panel-import.md +9 -0
- package/.agents/report/port/2026-10-07-cycle-01-api-assembly.md +16 -0
- package/.agents/report/port/2026-10-07-cycle-02-index-entry-point.md +13 -0
- package/.agents/report/remediation/2026-10-02-api-user-filter-remediation.md +71 -0
- package/.agents/report/remediation/2026-10-02-api-values-remediation.md +17 -0
- package/.agents/report/remediation/2026-10-03-callback-id-contract-remediation.md +36 -0
- package/.agents/report/remediation/2026-10-06-import-parser-remediation.md +41 -0
- package/.agents/report/remediation/2026-10-06-rich-text-upload-remediation.md +33 -0
- package/.agents/report/remediation/2026-10-07-api-assembly-remediation.md +32 -0
- package/.agents/skills/port-javascript-to-typescript/SKILL.md +42 -0
- package/.agents/skills/port-javascript-to-typescript/agents/openai.yaml +3 -0
- package/.agents/skills/port-javascript-to-typescript/references/blockers.md +31 -0
- package/.agents/skills/port-javascript-to-typescript/references/planning.md +43 -0
- package/.agents/skills/port-javascript-to-typescript/references/porting.md +9 -0
- package/.agents/skills/port-javascript-to-typescript/references/reporting.md +24 -0
- package/.agents/skills/port-javascript-to-typescript/references/rules.md +8 -0
- package/.agents/skills/port-javascript-to-typescript/references/selection.md +16 -0
- package/.agents/skills/port-javascript-to-typescript/references/tools.md +20 -0
- package/.agents/skills/port-javascript-to-typescript/scripts/check.sh +17 -0
- package/.agents/skills/port-javascript-to-typescript/scripts/graph.sh +30 -0
- package/.agents/skills/port-javascript-to-typescript/scripts/madge.json +12 -0
- package/.agents/skills/port-javascript-to-typescript/scripts/oxlint.json +14 -0
- package/.agents/skills/port-javascript-to-typescript/scripts/test-tools.cjs +76 -0
- package/.github/actions/version-bump/action.yml +41 -0
- package/.github/workflows/alpha.yml +53 -0
- package/.github/workflows/ci.yml +36 -0
- package/.github/workflows/main.yml +14 -42
- package/AGENTS.md +5 -0
- package/README.md +41 -4
- package/dist/api/authorization.d.ts +38 -0
- package/dist/api/authorization.js +74 -0
- package/dist/api/authorization.js.map +1 -0
- package/dist/api/config.d.ts +42 -0
- package/dist/api/config.js +105 -0
- package/dist/api/config.js.map +1 -0
- package/dist/api/filterUser.d.ts +2 -0
- package/dist/api/filterUser.js +24 -0
- package/dist/api/filterUser.js.map +1 -0
- package/dist/api/importRecords.d.ts +1 -0
- package/dist/api/importRecords.js +16 -0
- package/dist/api/importRecords.js.map +1 -0
- package/dist/api/queries.d.ts +48 -0
- package/dist/api/queries.js +139 -0
- package/dist/api/queries.js.map +1 -0
- package/dist/api/request.d.ts +29 -0
- package/dist/api/request.js +3 -0
- package/dist/api/request.js.map +1 -0
- package/dist/api/routes/adjacentRecordId.d.ts +10 -0
- package/dist/api/routes/adjacentRecordId.js +13 -0
- package/dist/api/routes/adjacentRecordId.js.map +1 -0
- package/dist/api/routes/config.d.ts +3 -0
- package/dist/api/routes/config.js +27 -0
- package/dist/api/routes/config.js.map +1 -0
- package/dist/api/routes/createRecord.d.ts +19 -0
- package/dist/api/routes/createRecord.js +93 -0
- package/dist/api/routes/createRecord.js.map +1 -0
- package/dist/api/routes/customAction.d.ts +17 -0
- package/dist/api/routes/customAction.js +35 -0
- package/dist/api/routes/customAction.js.map +1 -0
- package/dist/api/routes/customComponent.d.ts +3 -0
- package/dist/api/routes/customComponent.js +34 -0
- package/dist/api/routes/customComponent.js.map +1 -0
- package/dist/api/routes/customQuery.d.ts +7 -0
- package/dist/api/routes/customQuery.js +33 -0
- package/dist/api/routes/customQuery.js.map +1 -0
- package/dist/api/routes/deleteRecord.d.ts +9 -0
- package/dist/api/routes/deleteRecord.js +46 -0
- package/dist/api/routes/deleteRecord.js.map +1 -0
- package/dist/api/routes/deleteRecordFromPanel.d.ts +10 -0
- package/dist/api/routes/deleteRecordFromPanel.js +36 -0
- package/dist/api/routes/deleteRecordFromPanel.js.map +1 -0
- package/dist/api/routes/deleteRecords.d.ts +9 -0
- package/dist/api/routes/deleteRecords.js +12 -0
- package/dist/api/routes/deleteRecords.js.map +1 -0
- package/dist/api/routes/duplicateRecord.d.ts +17 -0
- package/dist/api/routes/duplicateRecord.js +55 -0
- package/dist/api/routes/duplicateRecord.js.map +1 -0
- package/dist/api/routes/foreignSelectRecords.d.ts +10 -0
- package/dist/api/routes/foreignSelectRecords.js +61 -0
- package/dist/api/routes/foreignSelectRecords.js.map +1 -0
- package/dist/api/routes/notificationBadges.d.ts +6 -0
- package/dist/api/routes/notificationBadges.js +31 -0
- package/dist/api/routes/notificationBadges.js.map +1 -0
- package/dist/api/routes/record.d.ts +7 -0
- package/dist/api/routes/record.js +32 -0
- package/dist/api/routes/record.js.map +1 -0
- package/dist/api/routes/records.d.ts +14 -0
- package/dist/api/routes/records.js +57 -0
- package/dist/api/routes/records.js.map +1 -0
- package/dist/api/routes/recordsExport.d.ts +13 -0
- package/dist/api/routes/recordsExport.js +67 -0
- package/dist/api/routes/recordsExport.js.map +1 -0
- package/dist/api/routes/recordsImport.d.ts +4 -0
- package/dist/api/routes/recordsImport.js +100 -0
- package/dist/api/routes/recordsImport.js.map +1 -0
- package/dist/api/routes/searchCompanies.d.ts +17 -0
- package/dist/api/routes/searchCompanies.js +72 -0
- package/dist/api/routes/searchCompanies.js.map +1 -0
- package/dist/api/routes/subrecordsImport.d.ts +4 -0
- package/dist/api/routes/subrecordsImport.js +94 -0
- package/dist/api/routes/subrecordsImport.js.map +1 -0
- package/dist/api/routes/updateRecord.d.ts +13 -0
- package/dist/api/routes/updateRecord.js +55 -0
- package/dist/api/routes/updateRecord.js.map +1 -0
- package/dist/api/routes/uploadFile.d.ts +3 -0
- package/dist/api/routes/uploadFile.js +13 -0
- package/dist/api/routes/uploadFile.js.map +1 -0
- package/dist/api/routes/uploadFileFromBetterRichTextInput.d.ts +3 -0
- package/dist/api/routes/uploadFileFromBetterRichTextInput.js +33 -0
- package/dist/api/routes/uploadFileFromBetterRichTextInput.js.map +1 -0
- package/dist/api/uploadFile.d.ts +4 -0
- package/dist/api/uploadFile.js +209 -0
- package/dist/api/uploadFile.js.map +1 -0
- package/dist/api/values.d.ts +6 -0
- package/dist/api/values.js +88 -0
- package/dist/api/values.js.map +1 -0
- package/dist/api.d.ts +8 -27
- package/dist/api.js +80 -1389
- package/dist/api.js.map +1 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +8 -2
- package/dist/index.js.map +1 -1
- package/dist/tsconfig.strict.tsbuildinfo +1 -0
- package/dist/types/config.d.ts +17 -7
- package/dist/types/config.js +4 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/database.d.ts +1 -0
- package/dist/types/database.js +3 -0
- package/dist/types/database.js.map +1 -0
- package/dist/utils/dbManager.d.ts +32 -7
- package/dist/utils/dbManager.js +59 -7
- package/dist/utils/dbManager.js.map +1 -1
- package/package.json +12 -2
- package/src/api/authorization.ts +129 -0
- package/src/api/config.ts +152 -0
- package/src/api/filterUser.ts +28 -0
- package/src/api/importRecords.ts +16 -0
- package/src/api/queries.ts +194 -0
- package/src/api/request.ts +31 -0
- package/src/api/routes/adjacentRecordId.ts +20 -0
- package/src/api/routes/config.ts +15 -0
- package/src/api/routes/createRecord.ts +131 -0
- package/src/api/routes/customAction.ts +60 -0
- package/src/api/routes/customComponent.ts +44 -0
- package/src/api/routes/customQuery.ts +53 -0
- package/src/api/routes/deleteRecord.ts +59 -0
- package/src/api/routes/deleteRecordFromPanel.ts +58 -0
- package/src/api/routes/deleteRecords.ts +28 -0
- package/src/api/routes/duplicateRecord.ts +73 -0
- package/src/api/routes/foreignSelectRecords.ts +80 -0
- package/src/api/routes/notificationBadges.ts +47 -0
- package/src/api/routes/record.ts +48 -0
- package/src/api/routes/records.ts +91 -0
- package/src/api/routes/recordsExport.ts +92 -0
- package/src/api/routes/recordsImport.ts +115 -0
- package/src/api/routes/searchCompanies.ts +96 -0
- package/src/api/routes/subrecordsImport.ts +114 -0
- package/src/api/routes/updateRecord.ts +74 -0
- package/src/api/routes/uploadFile.ts +16 -0
- package/src/api/routes/uploadFileFromBetterRichTextInput.ts +41 -0
- package/src/api/uploadFile.ts +249 -0
- package/src/api/values.ts +96 -0
- package/src/api.ts +94 -1578
- package/src/front/ckeditor5-build/node_modules/semver/bin/semver.js +0 -0
- package/src/index.ts +42 -25
- package/src/types/config.ts +17 -7
- package/src/types/database.ts +2 -0
- package/src/utils/dbManager.ts +99 -14
- package/tests/api-helpers.test.ts +59 -0
- package/tests/dbManager.test.ts +16 -1
- package/tests/helpers/fakeDb.ts +9 -7
- package/tests/integration/authorizationBoundary.integration.test.ts +57 -0
- package/tests/integration/configEnrichment.integration.test.ts +79 -0
- package/tests/integration/customComponentBoundary.integration.test.ts +58 -0
- package/tests/integration/dbManager.integration.test.ts +105 -3
- package/tests/integration/importParserChild.cjs +55 -0
- package/tests/integration/indexRuntime.integration.test.ts +22 -0
- package/tests/integration/indexRuntimeChild.cjs +110 -0
- package/tests/integration/queries.integration.test.ts +88 -0
- package/tests/integration/requestConfig.integration.test.ts +118 -0
- package/tests/integration/routes.authorization.integration.test.ts +1 -0
- package/tests/integration/routes.config.integration.test.ts +39 -1
- package/tests/integration/routes.crud.integration.test.ts +233 -1
- package/tests/integration/routes.custom.integration.test.ts +119 -0
- package/tests/integration/routes.foreign.integration.test.ts +3 -2
- package/tests/integration/routes.importExport.integration.test.ts +308 -6
- package/tests/integration/routes.integration.test.ts +4 -0
- package/tests/integration/routes.records.integration.test.ts +82 -6
- package/tests/integration/routes.upload.integration.test.ts +178 -0
- package/tests/integration/userFilters.integration.test.ts +225 -0
- package/tsconfig.json +1 -1
- package/tsconfig.strict.json +45 -0
- package/dist/front/ckeditor5-build/src/ckeditor.d.ts +0 -43
- package/dist/front/ckeditor5-build/src/ckeditor.js +0 -130
- package/dist/front/ckeditor5-build/src/ckeditor.js.map +0 -1
- package/dist/tsconfig.tsbuildinfo +0 -1
- package/src/front/ckeditor5-build/node_modules/.bin/semver +0 -12
- package/src/front/ckeditor5-build/node_modules/.bin/semver.cmd +0 -17
- package/src/front/ckeditor5-build/node_modules/.bin/semver.ps1 +0 -28
|
@@ -0,0 +1 @@
|
|
|
1
|
+
[]
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# API user filter contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api.ts](../../../src/api.ts), which serves record lists, foreign options, and exports with user access filters.
|
|
4
|
+
|
|
5
|
+
Date: 2026-09-23. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** root sessions have no `userId`; `filtersFromUser` requires `number`.
|
|
8
|
+
|
|
9
|
+
Root login sets `{ role: "root" }` at [src/index.ts:86](../../../src/index.ts#L86). Current calls forward the absent ID at [src/api/routes/records.ts:28](../../../src/api/routes/records.ts#L28), [src/api/routes/foreignSelectRecords.ts:29](../../../src/api/routes/foreignSelectRecords.ts#L29), and [src/api/routes/recordsExport.ts:26](../../../src/api/routes/recordsExport.ts#L26). Contracts require `(userId: number, role?: string) => string` at [src/types/config.ts:92](../../../src/types/config.ts#L92), [src/types/config.ts:108](../../../src/types/config.ts#L108), and [src/types/config.ts:240](../../../src/types/config.ts#L240).
|
|
10
|
+
|
|
11
|
+
Illustrative call: `filtersFromUser(undefined, 'root')`. The historical strict probe rejected the argument and assignment of a required-number callback to a signature accepting missing IDs. It did not establish a runtime request failure. Existing required-number consumers include [tests/integration/routes.importExport.integration.test.ts:160](../../../tests/integration/routes.importExport.integration.test.ts#L160).
|
|
12
|
+
|
|
13
|
+
**help:** supply an external access-policy decision for sessions without user IDs, including filter execution, callback input, and compatibility with required-number consumers.
|
|
14
|
+
|
|
15
|
+
**cleanup:** attempt package/config edits restored; source and tests untouched; earlier accepted work and user edits preserved.
|
|
16
|
+
|
|
17
|
+
**evidence (historical):** cleanup build/strict compilation passed; integration tests were not repeated. Retained acceptance: database manager report ([.agents/report/port/2026-09-23-database-manager.md](../port/2026-09-23-database-manager.md)).
|
|
18
|
+
|
|
19
|
+
## 2026-10-03 retry — cycle 8
|
|
20
|
+
|
|
21
|
+
Scope: foreignSelectRecords.ts, records.ts, and recordsExport.ts. Outcome: ABORT.
|
|
22
|
+
|
|
23
|
+
error: the [approved FilterUser retry guidance](../remediation/2026-10-02-api-user-filter-remediation.md) resolves root sessions but requires numeric regular-user IDs without a compatibility policy for authenticated string/UUID IDs. Login at [src/index.ts:110](../../../src/index.ts#L110) copies the configured database ID unchanged. AuthRole.idField names an arbitrary column; DatabaseRow permits strings. Session revalidation at [src/index.ts:138](../../../src/index.ts#L138) binds the original ID without numeric restriction.
|
|
24
|
+
|
|
25
|
+
Concrete current producer: `{id: "00000000-0000-4000-8000-000000000001"}` with role editor and idField id yields `{role: "editor", userId: "00000000-0000-4000-8000-000000000001"}`. Existing list, foreign-option and export callbacks receive this ID and role unchanged. The mandated RegularUser numeric check fails. This was a login-assignment source-operation probe, not a full authentication/database observation. Existing UUID CRUD tests do not establish session-policy coverage.
|
|
26
|
+
|
|
27
|
+
Rejecting these sessions, skipping their filters, coercing IDs, claiming a false number or widening the prescribed type would exceed the supplied guidance, which says: “Do not fabricate root IDs, coerce database IDs, add type assertions, or silently change invalid-session behavior. Report any unresolved session validation policy.” Missing/null/invalid sessions also need defined handling; the UUID example alone blocks acceptance.
|
|
28
|
+
|
|
29
|
+
help: supply an explicit regular string/UUID-ID compatibility policy and invalid-session behavior, including authorized callback/filter, HTTP and session handling. Then retry the entire three-route/declaration/test group together.
|
|
30
|
+
|
|
31
|
+
cleanup: all three attempted strict entries removed; production, tests and earlier accepted work unchanged. No implementation or acceptance review claimed. Cleanup strict compilation passes. The unchanged accepted baseline has 138 unit and 674 integration tests passing, with 4 preexisting skipped tests excluded. Local planning/probe evidence: /tmp/galadmin-port-20261003/cycle08/.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
# API expression result contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/values.ts](../../../src/api/values.ts), which evaluates record expressions and formats export and insertion values.
|
|
4
|
+
|
|
5
|
+
Date: 2026-09-23. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** unrestricted expression results have no checked domain contract that preserves CSV and JSON behavior.
|
|
8
|
+
|
|
9
|
+
Direct `eval` returns unchecked values at [src/api/values.ts:45](../../../src/api/values.ts#L45). CSV concatenates them at [src/api/routes/recordsExport.ts:63](../../../src/api/routes/recordsExport.ts#L63); foreign options serialize them as JSON labels at [src/api/routes/foreignSelectRecords.ts:51](../../../src/api/routes/foreignSelectRecords.ts#L51). Expression configuration declares text without a result restriction.
|
|
10
|
+
|
|
11
|
+
Historical probe example:
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
const data = { reads: 0 };
|
|
15
|
+
const value = evalExpression('({get label(){ return ++data.reads; }})', data);
|
|
16
|
+
JSON.stringify({ label: value }); // '{"label":{"label":1}}'
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The call succeeded; returning or concatenating `value` read no getter. Recursive validation adds a read and can change serialization. Scalar validation rejects supported objects/arrays/functions. Other probes preserved cyclic-object identity and CSV coercion; functions became CSV source text but omitted JSON labels, undefined labels were omitted, and null labels remained. `getFormattedValue` instead maps null/undefined to `""` and adds an own undefined `options` field outside the database-row domain ([src/api/values.ts:4](../../../src/api/values.ts#L4)). Moving direct `eval` changes access to `data`, `statement`, and `varString`.
|
|
20
|
+
|
|
21
|
+
**help:** supply an external supported-result policy and authorize observable restrictions, or revise the boundary requirement; cover CSV/JSON conversion, getter reads, identity, undefined fields, and evaluation scope.
|
|
22
|
+
|
|
23
|
+
**cleanup:** strict entry removed; source, tests, packages, and configuration restored. Earlier acceptance: file upload report ([.agents/report/port/2026-09-23-api-file-upload.md](../port/2026-09-23-api-file-upload.md)).
|
|
24
|
+
|
|
25
|
+
**evidence (historical):** original-source probes passed, including after rollback and independent review; cleanup build/strict compilation passed. Full suites were not repeated.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Create callback result contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/createRecord.ts](../../../src/api/routes/createRecord.ts), which inserts view/panel records and sends the insertion ID and data to callbacks.
|
|
4
|
+
|
|
5
|
+
Date: 2026-10-01. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** this PostgreSQL INSERT returns no `insertId`; create callbacks require `id: number`.
|
|
8
|
+
|
|
9
|
+
The route forwards `r.insertId` at [src/api/routes/createRecord.ts:85](../../../src/api/routes/createRecord.ts#L85). The INSERT has no RETURNING clause; PostgreSQL exposes a row array ([src/utils/dbManager.ts:68](../../../src/utils/dbManager.ts#L68)). TableView, TablePanel, and GalleryPanel require `{ id: number; data: any }` at [src/types/config.ts:262](../../../src/types/config.ts#L262), [src/types/config.ts:329](../../../src/types/config.ts#L329), and [src/types/config.ts:354](../../../src/types/config.ts#L354).
|
|
10
|
+
|
|
11
|
+
Illustrative rejected call: `createCallbackFunction({ id: undefined, data: { fruitName: 'pomme' } })`. Historical real-database tests observed successful insertion with this missing callback ID, not a callback crash; current coverage records it at [tests/integration/routes.crud.integration.test.ts:434](../../../tests/integration/routes.crud.integration.test.ts#L434). A wider public input rejects existing required-number consumers.
|
|
12
|
+
|
|
13
|
+
**help:** supply an external insertion-result/callback policy for backends without `insertId`, with authorization and compatibility guidance for required-number consumers.
|
|
14
|
+
|
|
15
|
+
**cleanup:** strict entry, temporary tests, and package edits restored; production source unchanged.
|
|
16
|
+
|
|
17
|
+
**evidence (historical):** 105 integration tests passed in 2 suites; 4 skipped. Cleanup build/strict compilation passed. Temporary tests removed; raw logs and diffs unavailable.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Delete callback ID contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/deleteRecord.ts](../../../src/api/routes/deleteRecord.ts), which selects/deletes a view record and passes its ID and deleted record to callbacks.
|
|
4
|
+
|
|
5
|
+
Date: 2026-10-01. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** UUID deletion passes a string ID; TableView requires `id: number`.
|
|
8
|
+
|
|
9
|
+
The route forwards the primary value at [src/api/routes/deleteRecord.ts:42](../../../src/api/routes/deleteRecord.ts#L42); the contract is `{ id: number; deletedRecord?: any }` at [src/types/config.ts:266](../../../src/types/config.ts#L266). The frontend sends the database key unchanged at [src/front/src/components/ActionsButton.js:33](../../../src/front/src/components/ActionsButton.js#L33).
|
|
10
|
+
|
|
11
|
+
Illustrative rejected call: `view.deleteCallbackFunction({ id: '00000000-0000-4000-8000-000000000001', deletedRecord: { fruitName: 'pomme' } })`. Historical MySQL/mysql2/PostgreSQL characterization observed successful UUID deletion and the identical callback string, not a callback crash. Widening the public input rejects required-number consumers.
|
|
12
|
+
|
|
13
|
+
**help:** supply an external numeric/string callback-ID policy, with authorization and compatibility guidance for required-number consumers.
|
|
14
|
+
|
|
15
|
+
**cleanup:** strict entry and temporary tests restored; production source unchanged. Retained baseline: custom query report ([.agents/report/port/2026-10-01-cycle-05-custom-query.md](../port/2026-10-01-cycle-05-custom-query.md)).
|
|
16
|
+
|
|
17
|
+
**evidence (historical):** 107 integration tests passed; 4 skipped. Cleanup build/strict compilation passed. Temporary UUID tests removed; raw logs and diffs unavailable.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Panel delete callback ID contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/deleteRecordFromPanel.ts](../../../src/api/routes/deleteRecordFromPanel.ts), which selects a table/gallery panel by ID, deletes its record, and calls its callback.
|
|
4
|
+
|
|
5
|
+
Date: 2026-10-01. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** panel UUID deletion passes a string ID; panel callbacks require `id: number`.
|
|
8
|
+
|
|
9
|
+
The route forwards the primary value at [src/api/routes/deleteRecordFromPanel.ts:34](../../../src/api/routes/deleteRecordFromPanel.ts#L34). TablePanel requires `{ id: number }` ([src/types/config.ts:331](../../../src/types/config.ts#L331)); GalleryPanel requires `{ id: number; deletedRecord?: any }` ([src/types/config.ts:356](../../../src/types/config.ts#L356)). Both frontend panels send database keys unchanged.
|
|
10
|
+
|
|
11
|
+
Illustrative rejected call:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
const payload = { id: '00000000-0000-4000-8000-000000000001', deletedRecord: { fruitName: 'pomme' } };
|
|
15
|
+
panel.deleteCallbackFunction(payload);
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Six historical cases covered table/gallery panels on MySQL/mysql2/PostgreSQL: deletion succeeded and callbacks received the same string and deletedRecord. No callback crash was observed. Widening the public input rejects required-number consumers.
|
|
19
|
+
|
|
20
|
+
**help:** supply an external numeric/string panel callback-ID policy, with authorization and compatibility guidance for required-number consumers.
|
|
21
|
+
|
|
22
|
+
**cleanup:** strict entry and temporary tests restored; production source unchanged. Retained baseline: custom query report ([.agents/report/port/2026-10-01-cycle-05-custom-query.md](../port/2026-10-01-cycle-05-custom-query.md)).
|
|
23
|
+
|
|
24
|
+
**evidence (historical):** 110 integration tests passed; 4 skipped. Cleanup build/strict compilation passed. Temporary UUID tests removed; raw logs and diffs unavailable.
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
# Edit callback ID contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/updateRecord.ts](../../../src/api/routes/updateRecord.ts), which updates a view record and passes its primary ID and data to callbacks.
|
|
4
|
+
|
|
5
|
+
Date: 2026-10-01. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** route-parameter/UUID IDs are strings; TableView edit callbacks require `id: number`.
|
|
8
|
+
|
|
9
|
+
The route forwards the primary value at [src/api/routes/updateRecord.ts:52](../../../src/api/routes/updateRecord.ts#L52); the contract is `{ id: number; data: any }` at [src/types/config.ts:264](../../../src/types/config.ts#L264). The frontend sends its route parameter unchanged at [src/front/src/pages/EditRecord.js:45](../../../src/front/src/pages/EditRecord.js#L45).
|
|
10
|
+
|
|
11
|
+
Illustrative rejected call: `view.editCallbackFunction({ id: '00000000-0000-4000-8000-000000000001', data: { fruitName: 'pomme' } })`. Historical MySQL/mysql2/PostgreSQL characterization observed a persisted UUID update and the identical callback string, not a callback crash. Widening the public input rejects required-number consumers.
|
|
12
|
+
|
|
13
|
+
**help:** supply an external numeric/route-parameter/UUID callback-ID policy, with authorization and compatibility guidance for required-number consumers.
|
|
14
|
+
|
|
15
|
+
**cleanup:** strict entry and temporary tests restored; production source unchanged. Retained baseline: company search report ([.agents/report/port/2026-10-01-cycle-12-search-companies.md](../port/2026-10-01-cycle-12-search-companies.md)).
|
|
16
|
+
|
|
17
|
+
**evidence (historical):** 119 integration tests passed; 4 skipped. Cleanup build/strict compilation passed. Temporary UUID tests removed; raw logs and diffs unavailable.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Rich-text upload header contract
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/uploadFileFromBetterRichTextInput.ts](../../../src/api/routes/uploadFileFromBetterRichTextInput.ts), which checks writable-view access, parses JSON upload settings, and calls the shared uploader.
|
|
4
|
+
|
|
5
|
+
Date: 2026-10-01. Outcome: ABORT.
|
|
6
|
+
|
|
7
|
+
**error:** parsed JSON cannot establish `FileUploadProperties` while preserving recorded invalid-field behavior.
|
|
8
|
+
|
|
9
|
+
The route forwards parsed settings at [src/api/routes/uploadFileFromBetterRichTextInput.ts:14](../../../src/api/routes/uploadFileFromBetterRichTextInput.ts#L14). `uploadFile(column, fileParamName, req, res)` requires `FileUploadProperties` ([src/api/uploadFile.ts:39](../../../src/api/uploadFile.ts#L39)), including callable `pathTransform` ([src/types/config.ts:156](../../../src/types/config.ts#L156), [src/types/config.ts:162](../../../src/types/config.ts#L162)). Frontend JSON serialization omits functions ([src/front/src/components/inputs/BetterRichTextInput.js:20](../../../src/front/src/components/inputs/BetterRichTextInput.js#L20)).
|
|
10
|
+
|
|
11
|
+
Illustrative rejected calls:
|
|
12
|
+
|
|
13
|
+
```ts
|
|
14
|
+
uploadFile(0, 'upload', req, res);
|
|
15
|
+
uploadFile({ s3Config: { host: 's3.example.com', accessKeyId: 'k', secretAccessKey: 's', bucket: 'b', pathTransform: 7 } }, 'upload', req, res);
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
Historical authorized multipart requests observed HTTP 200 and correct local bytes for header `0`. Numeric `pathTransform` caused one mocked S3 send before the helper called `7` ([src/api/uploadFile.ts:179](../../../src/api/uploadFile.ts#L179)) and returned HTTP 500. This was an observed runtime failure after a storage call; actual remote storage was not established. Rejecting before upload changes timing/side effects; dropping the field changes failure to success. Primitive normalization does not solve the callable-field conflict.
|
|
19
|
+
|
|
20
|
+
**help:** supply an external JSON policy for primitive normalization, invalid optional fields, status/error responses, and rejection before storage; authorize shared-contract changes and preserve writable-view authorization ordering.
|
|
21
|
+
|
|
22
|
+
**cleanup:** strict entry and temporary tests restored; production source unchanged. Retained baseline: upload route report ([.agents/report/port/2026-10-01-cycle-14-upload-file.md](../port/2026-10-01-cycle-14-upload-file.md)).
|
|
23
|
+
|
|
24
|
+
**evidence (historical):** 87 upload integration tests passed; none skipped, including six added MySQL/mysql2/PostgreSQL executions with real multipart/filesystem handling. Cleanup build/strict compilation passed. Temporary tests removed; raw logs and diffs unavailable.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Record import parser-element contract — cycle 6
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/recordsImport.ts:29](../../../src/api/routes/recordsImport.ts#L29), which imports configurable parser results. Outcome: ABORT.
|
|
4
|
+
|
|
5
|
+
error: parseImportFile promises Promise<any[]> without an element-shape contract. Receiving unknown[] makes strict compilation reject the for-in loop at [src/api/routes/recordsImport.ts:39](../../../src/api/routes/recordsImport.ts#L39) and indexed access at [src/api/routes/recordsImport.ts:52](../../../src/api/routes/recordsImport.ts#L52). A Record<string, unknown>[] assertion would trust an unchecked external result.
|
|
6
|
+
|
|
7
|
+
The exact original column loop with parser result ["ab"] produces columns ["0", "1"] and field values ["a", "b"]. Inherited record keys are also included. With [null, {id: 1}], column gathering succeeds, then the original indexed read throws TypeError inside the existing catch. These are source-operation probes, not a full HTTP/database observation. Object-only validation, filtering, or boxing would change processed values or error timing. Existing object-row fixtures do not define all supported configurable parser results; the evaluator remediation does not authorize parser-element restrictions.
|
|
8
|
+
|
|
9
|
+
help: supply an external supported parser-element policy, including compatibility and error behavior for primitives/null/custom objects, or explicitly authorize an unchecked JavaScript property-access boundary exception. This decision also affects panel imports; each route needs its own checks. Preserve inherited keys, field identity, getters and authorization order unless a specific change is approved.
|
|
10
|
+
|
|
11
|
+
cleanup: the attempt's strict entry was removed. Production source, tests, packages and prior accepted groups remain unchanged. Cleanup strict compilation passes; the unchanged accepted baseline has 138 unit and 674 integration tests passing, with 4 existing skipped tests excluded from pass counts. No implementation or acceptance review was claimed. Detailed local planning/probe evidence: /tmp/galadmin-port-20261003/cycle06/.
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Panel import parser-element contract — cycle 7
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/subrecordsImport.ts:44](../../../src/api/routes/subrecordsImport.ts#L44), which imports parser results into a configured panel. Outcome: ABORT.
|
|
4
|
+
|
|
5
|
+
error: panel parseImportFile promises Promise<any[]> without an element-shape policy. Authorization, createConfig and parent-ID checks do not constrain those entries. The original for-in loop at [src/api/routes/subrecordsImport.ts:57](../../../src/api/routes/subrecordsImport.ts#L57) and record[x] at [src/api/routes/subrecordsImport.ts:76](../../../src/api/routes/subrecordsImport.ts#L76) cannot operate on unknown[] under strict compilation without an unsupported shape claim or runtime change.
|
|
6
|
+
|
|
7
|
+
This route independently has the same primitive/inherited/null behavior evidenced in the [whole-record parser failure](2026-10-03-cycle-06-record-import-parser-contract.md): ["ab"] yields numeric property keys and string field values; inherited keys participate; null entries with keys from another row fail later during value access. Unchanged operation/strict probes were reused. These probes do not claim full HTTP/database execution. Valid panel configuration and parent IDs do not establish an object-only parser result.
|
|
8
|
+
|
|
9
|
+
help: supply an externally approved parser-element policy or a specific unchecked property-boundary exception covering both import routes. Include primitive/null/custom-object compatibility, errors, inherited keys, getter/identity effects and authorization order. Each route still requires its own acceptance checks.
|
|
10
|
+
|
|
11
|
+
cleanup: the attempt's strict entry was removed; production source/tests/packages and prior accepted groups remain unchanged. Cleanup strict compilation passes. The unchanged accepted baseline retains 138 unit and 674 integration tests passing, with 4 preexisting skipped tests excluded. No implementation or acceptance review was claimed. Local planning evidence: /tmp/galadmin-port-20261003/cycle07/plan.md.
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
## 2026-10-06 retry — cycle 2
|
|
15
|
+
|
|
16
|
+
Scope: [src/api/routes/subrecordsImport.ts:25](../../../src/api/routes/subrecordsImport.ts#L25), which checks panel authorization before parsing imports. Outcome: ABORT.
|
|
17
|
+
|
|
18
|
+
**error:** typed panel lookup exposes TS2345 at `canWriteView(panel, roleOf(req))`. The helper requires optional `roles: string[]` ([src/api/authorization.ts:32](../../../src/api/authorization.ts#L32)); [BaseTypePanel](../../../src/types/config.ts#L291) and request panel declarations omit the property. Request enrichment preserves undeclared extras without validation. The parser-only remediation cannot establish an authorization property contract.
|
|
19
|
+
|
|
20
|
+
Observed unchanged-helper calls with caller role `"edit"`: no roles/null/false permit access; `["editor"]` denies; `"editor"` permits substring matching; numeric `7` throws `TypeError`. These are pure consumer probes, not full panel HTTP/database observations. Existing real-database fixtures establish absent/array examples only. An optional-string-array intersection assertion would hide the unresolved property contract.
|
|
21
|
+
|
|
22
|
+
**help:** provide an external panel-roles contract and compatibility/error policy, or authorize a narrow validation boundary. Changes to public panel declarations or authorization behavior require guidance beyond the parser-shape exception. The supplied remediation explicitly requires reporting additional conflicts.
|
|
23
|
+
|
|
24
|
+
**checks:** original-source characterization passed 138 preservation tests and failed only 48 expected parser-policy tests, with no skips. Implementation build failed; integration had 13 compilation-failed suites and only 22 unrelated tests ran. Source/tests/strict entries were restored exactly to the accepted cycle-1 state; cleanup build/strict pass. The retained accepted baseline has 149 unit and 779 integration tests passing, with 4 preexisting skipped tests excluded. Detailed evidence and failed diff: `/tmp/ts-port-20261006/cycle02/` (session-local).
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# API assembly contract — resumed cycle 2
|
|
2
|
+
|
|
3
|
+
Goal: give [src/api.ts:55](../../../src/api.ts#L55) strict types while preserving how it filters request configuration and registers routes. The attempt stopped before production changes. No new strict file was accepted.
|
|
4
|
+
|
|
5
|
+
## Why the attempt stopped
|
|
6
|
+
|
|
7
|
+
The proposed API factory takes a `DbManager`. The test helper [tests/helpers/app.ts:38](../../../tests/helpers/app.ts#L38) instead passes a `FakeDb`:
|
|
8
|
+
|
|
9
|
+
```ts
|
|
10
|
+
api(db, config);
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
At the time of the attempt, `FakeDb` had no `init` method. After adding `init` in a compiler probe, a second error appeared: its query result made `err`, `rows`, and `fields` optional. [DbManager's result type](../../../src/utils/dbManager.ts#L12) requires all three keys, although `rows` and `fields` can contain `undefined`. Some fake results omitted `fields` entirely.
|
|
14
|
+
|
|
15
|
+
These were compiler errors, including TS2345, even with the tests' existing `strict: false` setting. No route or database runtime failure was observed. The attempt stopped because changing the mock required an exception to [AGENTS.md](../../../AGENTS.md)'s "Never mock the database" rule.
|
|
16
|
+
|
|
17
|
+
**Update, 2026-10-07:** the user approved updating the existing mock. [FakeDb now implements DbManager](../../../tests/helpers/fakeDb.ts#L20), has a no-op `init`, and [returns all three result keys](../../../tests/helpers/fakeDb.ts#L42). All 149 unit tests passed after this change. This resolves the fake's interface mismatch; the API migration has not been retried.
|
|
18
|
+
|
|
19
|
+
## The remaining type question
|
|
20
|
+
|
|
21
|
+
A column can have [roles](../../../src/types/config.ts#L29) and omit its [name](../../../src/types/config.ts#L38). For example:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
{ label: "Computed value", roles: ["editor"] }
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
For a caller without the `editor` role, [src/api.ts:99](../../../src/api.ts#L99) collects the missing name:
|
|
28
|
+
|
|
29
|
+
```ts
|
|
30
|
+
__hiddenColumns: view.columns
|
|
31
|
+
.filter((column) => !allowed(column))
|
|
32
|
+
.map((column) => column.name),
|
|
33
|
+
// The example produces [undefined].
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The current declarations in [request.ts](../../../src/api/request.ts#L19) and [authorization.ts](../../../src/api/authorization.ts#L106) say `string[]`, which does not describe this result.
|
|
37
|
+
|
|
38
|
+
The value also affects callers. [stripHiddenColumns](../../../src/api/authorization.ts#L118) uses `delete record[name]`, and [touchesHiddenColumn](../../../src/api/authorization.ts#L128) checks whether a payload has that property. JavaScript converts an `undefined` property key to the string `"undefined"`. Read responses can therefore lose that property, and create/update requests containing it can receive HTTP 403. [Record imports](../../../src/api/routes/recordsImport.ts#L55) use `includes` instead, which does not make this conversion.
|
|
39
|
+
|
|
40
|
+
**Update, 2026-10-07:** the user chose to filter nullish names when building `__hiddenColumns`, retaining `string[]`. The [remediation report](../remediation/2026-10-07-api-assembly-remediation.md) records the approved behavior change and retry checks. The production filter has not been applied.
|
|
41
|
+
|
|
42
|
+
## Checks and cleanup
|
|
43
|
+
|
|
44
|
+
The stopped attempt restored its test and strict entries to accepted commit `c2415f6`. Production source remained unchanged. Cleanup build and existing strict checks passed. Five real-MySQL tests of the original behavior passed with no skips. The accepted baseline had 149 unit and 989 integration passes, with 4 preexisting skips. These results do not establish acceptance of the proposed API typing.
|
|
45
|
+
|
|
46
|
+
The attempt's plan, compiler probes, tests, diff, and cleanup logs are in `/tmp/ts-port-resume-20261006/cycle02/` (session-local). The later `FakeDb` update passed 149 unit tests; the full migration checks still need to run during retry.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# TypeScript port: API configuration enrichment
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-23. Outcome: ACCEPT (bounded checkpoint).
|
|
4
|
+
|
|
5
|
+
Ported [src/api/config.ts:1](../../../src/api/config.ts#L1), which adds schema metadata, select options, IDs, and file URLs to configuration.
|
|
6
|
+
|
|
7
|
+
- `type`: SchemaColumn ([src/api/config.ts:21](../../../src/api/config.ts#L21)) describes database column metadata; EnrichmentConfig ([src/api/config.ts:18](../../../src/api/config.ts#L18)) describes the mutable configuration fields used during enrichment.
|
|
8
|
+
- `attention`: #PORTING-EDIT: schema results ([src/api/config.ts:36](../../../src/api/config.ts#L36)). Driver results cannot establish the required row and text metadata types without a runtime check. Invalid row shapes or non-text uppercase metadata now throw `TypeError` before configuration mutation; PostgreSQL lowercase metadata remains unmatched. Decoder test ([tests/integration/configEnrichment.integration.test.ts:49](../../../tests/integration/configEnrichment.integration.test.ts#L49)) checks numeric `TABLE_NAME` and unchanged configuration.
|
|
9
|
+
- `attention`: #PORTING-EDIT: enum options ([src/api/config.ts:54](../../../src/api/config.ts#L54)). JSON parsing does not establish `string[]`. Enum metadata such as `enum(1)` now throws `TypeError` before options are assigned; prior ID, required, and data-type mutations remain. Invalid enum test ([tests/integration/configEnrichment.integration.test.ts:49](../../../tests/integration/configEnrichment.integration.test.ts#L49)) checks this failure; valid metadata test ([tests/integration/configEnrichment.integration.test.ts:34](../../../tests/integration/configEnrichment.integration.test.ts#L34)) checks options, required inference, and stable IDs.
|
|
10
|
+
|
|
11
|
+
`checks`: recorded strict/build PASS; integration 519 passed/4 skipped; warning scan 0 diagnostics.
|
|
12
|
+
|
|
13
|
+
The user-filter contract failure ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)) remains unresolved.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# TypeScript port: API file uploads
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-23. Outcome: ACCEPT (one-file commit checkpoint).
|
|
4
|
+
|
|
5
|
+
Ported [src/api/uploadFile.ts:39](../../../src/api/uploadFile.ts#L39), which parses multipart files and stores them in S3, GCP, SFTP, or the local filesystem for both upload routes.
|
|
6
|
+
|
|
7
|
+
- `attention`: #PORTING-EDIT: missing file ([src/api/uploadFile.ts:21](../../../src/api/uploadFile.ts#L21)). Multiparty permits an absent file array, so types alone cannot make metadata access safe. All four storage paths now return HTTP 400 with `Missing upload file` when parsing succeeds without the requested file, instead of throwing or rejecting; parse errors still return HTTP 500 first. HTTP tests ([tests/integration/routes.upload.integration.test.ts:123](../../../tests/integration/routes.upload.integration.test.ts#L123)) check each storage path before SDK calls.
|
|
8
|
+
|
|
9
|
+
`checks`: recorded strict/build PASS; unit 134 passed; integration 567 passed/4 skipped; warning scan 0 diagnostics.
|
|
10
|
+
|
|
11
|
+
The user-filter contract failure ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)) remains unresolved.
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
# TypeScript port: API queries and authorization
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-23. Outcome: ACCEPT (commit checkpoint).
|
|
4
|
+
|
|
5
|
+
Ported [src/api/queries.ts:1](../../../src/api/queries.ts#L1) and [src/api/authorization.ts:1](../../../src/api/authorization.ts#L1), which build record queries and determine write access to configured views.
|
|
6
|
+
|
|
7
|
+
- `type`: RecordQueryParams ([src/api/queries.ts:7](../../../src/api/queries.ts#L7)) describes query inputs, including nullable filters/order and optional columns; RecordQueryResult ([src/api/queries.ts:23](../../../src/api/queries.ts#L23)) separates successful rows/count/input from an error-only result. It retains input identity and PostgreSQL count strings.
|
|
8
|
+
- `attention`: #PORTING-EDIT: record rows ([src/api/queries.ts:38](../../../src/api/queries.ts#L38)). The database result union also permits absent rows, mutation headers, and nested results, so it cannot be treated as flat records by types alone. Record queries now throw `TypeError` for these shapes. Real-engine rejection tests ([tests/integration/queries.integration.test.ts:51](../../../tests/integration/queries.integration.test.ts#L51)) cover PostgreSQL absent rows and MySQL nested results/headers; valid-result test ([tests/integration/queries.integration.test.ts:17](../../../tests/integration/queries.integration.test.ts#L17)) checks rows, count values, and input identity.
|
|
9
|
+
- `attention`: #PORTING-EDIT: session role ([src/api/authorization.ts:22](../../../src/api/authorization.ts#L22)). Stored session data does not establish a text role. Missing/null/non-object users and non-text roles now produce `undefined`; declared role lists deny them and roleless views allow them. Role test ([tests/integration/authorizationBoundary.integration.test.ts:13](../../../tests/integration/authorizationBoundary.integration.test.ts#L13)) and anonymous HTTP test ([tests/integration/authorizationBoundary.integration.test.ts:50](../../../tests/integration/authorizationBoundary.integration.test.ts#L50)) check these decisions.
|
|
10
|
+
- `attention`: #PORTING-EDIT: view index ([src/api/authorization.ts:48](../../../src/api/authorization.ts#L48)). An external property key can select array metadata or prototype properties, which are not views. Lookup now permits only canonical in-range indices; body precedence and coercion of `0`, `"0"`, `[0]`, and objects to `"0"` remain. Lookup test ([tests/integration/authorizationBoundary.integration.test.ts:24](../../../tests/integration/authorizationBoundary.integration.test.ts#L24)) checks identity/coercion; HTTP test ([tests/integration/authorizationBoundary.integration.test.ts:36](../../../tests/integration/authorizationBoundary.integration.test.ts#L36)) checks that rejected keys cause no writes.
|
|
11
|
+
|
|
12
|
+
`checks`: recorded strict/build PASS; unit 134 passed; integration 534 passed/4 skipped; warning scan 0 diagnostics.
|
|
13
|
+
|
|
14
|
+
The user-filter contract failure ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)) remains unresolved.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# TypeScript port: request configuration
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-23. Outcome: ACCEPT (one-file commit checkpoint).
|
|
4
|
+
|
|
5
|
+
Ported [src/api/request.ts:1](../../../src/api/request.ts#L1), which declares the configuration attached to Express requests.
|
|
6
|
+
|
|
7
|
+
- `type`: RequestConfig ([src/api/request.ts:22](../../../src/api/request.ts#L22)) replaces `config?: any` with a shape derived from public `Config`; it remains optional before middleware attaches it. RequestView ([src/api/request.ts:16](../../../src/api/request.ts#L16)), RequestPanel ([src/api/request.ts:11](../../../src/api/request.ts#L11)), and RequestColumn ([src/api/request.ts:9](../../../src/api/request.ts#L9)) retain variant requirements and admit existing optional operation fields and enrichment IDs.
|
|
8
|
+
|
|
9
|
+
`checks`: recorded strict/build PASS; integration 571 passed/4 skipped; warning scan 0 diagnostics.
|
|
10
|
+
|
|
11
|
+
The user-filter ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)) and value-expression ([.agents/report/failures/2026-09-23-api-values-contract.md](../failures/2026-09-23-api-values-contract.md)) contract failures remain unresolved.
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# TypeScript port: database manager
|
|
2
|
+
|
|
3
|
+
Date: 2026-09-23. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/utils/dbManager.ts:1](../../../src/utils/dbManager.ts#L1), which selects the SQL driver, converts PostgreSQL queries, and returns checked query results. Supporting runtime checks changed [src/index.ts:93](../../../src/index.ts#L93), which remained outside strict coverage.
|
|
6
|
+
|
|
7
|
+
- `type`: DatabaseValue and DatabaseRow ([src/utils/dbManager.ts:5](../../../src/utils/dbManager.ts#L5)) describe scalar, date, binary, and recursive JSON values in rows. QueryRows ([src/utils/dbManager.ts:9](../../../src/utils/dbManager.ts#L9)) includes rows, mutation headers, and multiple results; QueryResult ([src/utils/dbManager.ts:12](../../../src/utils/dbManager.ts#L12)) returns `err: Error | null`, with rows and field metadata that can be `undefined`.
|
|
8
|
+
- `attention`: #PORTING-EDIT: driver results ([src/utils/dbManager.ts:60](../../../src/utils/dbManager.ts#L60)). Driver data cannot establish the result union without runtime validation. Unsupported row/field shapes now throw `TypeError`; absent rows become `undefined`. Functions, symbols, and undefined column values are rejected; supported values and result references remain. Value tests ([tests/integration/dbManager.integration.test.ts:68](../../../tests/integration/dbManager.integration.test.ts#L68)), mutation/multiple-result tests ([tests/integration/dbManager.integration.test.ts:85](../../../tests/integration/dbManager.integration.test.ts#L85)), and PostgreSQL multiple-result test ([tests/integration/dbManager.integration.test.ts:106](../../../tests/integration/dbManager.integration.test.ts#L106)) cover supported shapes.
|
|
9
|
+
- `attention`: #PORTING-EDIT: successful error value ([src/utils/dbManager.ts:347](../../../src/utils/dbManager.ts#L347)). The drivers return different absence values, so a type-only port cannot promise `Error | null`. Success now returns `err: null`, including PostgreSQL's former `undefined`; callers retain their truthiness checks. MySQL and PostgreSQL tests ([tests/integration/dbManager.integration.test.ts:32](../../../tests/integration/dbManager.integration.test.ts#L32)) check the common success value.
|
|
10
|
+
- `attention`: #PORTING-EDIT: login results ([src/index.ts:93](../../../src/index.ts#L93)). The checked query union does not guarantee user rows or text passwords. Login now ignores non-array/nested results and compares only stored text passwords. HTTP authentication test ([tests/integration/dbManager.integration.test.ts:159](../../../tests/integration/dbManager.integration.test.ts#L159)) checks numeric password rejection and text password success.
|
|
11
|
+
- `attention`: #PORTING-EDIT: account existence ([src/index.ts:148](../../../src/index.ts#L148)). Mutation headers cannot establish account existence through `length`. Session validation now requires an array with at least one element; session test ([tests/integration/dbManager.integration.test.ts:159](../../../tests/integration/dbManager.integration.test.ts#L159)) checks revocation after account deletion.
|
|
12
|
+
|
|
13
|
+
`checks`: recorded strict/build PASS; unit 134 passed; integration 516 passed/4 skipped.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TypeScript port: adjacent record ID route
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT, first review round.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/adjacentRecordId.ts:1](../../../src/api/routes/adjacentRecordId.ts#L1), which returns the selected record ID at `position + offset`.
|
|
6
|
+
|
|
7
|
+
`checks`: recorded strict/build PASS; unit 134 passed; integration 586 passed/4 skipped; warning scan 0 diagnostics; raw logs unavailable.
|
|
8
|
+
|
|
9
|
+
The user-filter ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)) and value-expression ([.agents/report/failures/2026-09-23-api-values-contract.md](../failures/2026-09-23-api-values-contract.md)) contract failures remain unresolved.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TypeScript port: configuration route (cycle 1 of 10)
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT, first review round.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/config.ts:1](../../../src/api/routes/config.ts#L1), which removes credentials/authentication settings and serializes the request configuration.
|
|
6
|
+
|
|
7
|
+
`checks`: recorded strict/build PASS; unit 134 passed; integration 588 passed/4 skipped; warning scan completed with 1 accepted non-null warning; raw logs unavailable.
|
|
8
|
+
|
|
9
|
+
The user-filter ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)) and value-expression ([.agents/report/failures/2026-09-23-api-values-contract.md](../failures/2026-09-23-api-values-contract.md)) contract failures remain unresolved.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TypeScript port: custom action route (cycle 3 of 10)
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT, first review round.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/customAction.ts:1](../../../src/api/routes/customAction.ts#L1), which loads selected records and calls configured actions in order until an action returns a truthy result.
|
|
6
|
+
|
|
7
|
+
`checks`: recorded strict/build PASS; unit 134 passed; integration 597 passed/4 skipped; warning scan completed with 3 accepted non-null warnings; raw logs unavailable.
|
|
8
|
+
|
|
9
|
+
The user-filter ([.agents/report/failures/2026-09-23-api-user-filter-contract.md](../failures/2026-09-23-api-user-filter-contract.md)), value-expression ([.agents/report/failures/2026-09-23-api-values-contract.md](../failures/2026-09-23-api-values-contract.md)), and create-callback ([.agents/report/failures/2026-10-01-cycle-02-create-callback-contract.md](../failures/2026-10-01-cycle-02-create-callback-contract.md)) failures remain unresolved.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# TypeScript port: custom component route — cycle 4
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/customComponent.ts:8](../../../src/api/routes/customComponent.ts#L8). Bundles a configured frontend component with Rollup and sends its generated code.
|
|
6
|
+
|
|
7
|
+
checks: Recorded strict/build pass; 134 unit tests and 605 integration tests passed, 4 existing skips; no warnings. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# TypeScript port: custom query route — cycle 5
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/customQuery.ts:13](../../../src/api/routes/customQuery.ts#L13). Runs allowed read-only SQL templates with bound record IDs and applies panel formatters.
|
|
6
|
+
|
|
7
|
+
checks: Recorded strict/build pass; 134 unit tests and 611 integration tests passed, 4 existing skips; 3 accepted configuration/panel non-null warnings. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TypeScript port: bulk delete route — cycle 8
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/deleteRecords.ts:10](../../../src/api/routes/deleteRecords.ts#L10). Deletes selected records with bound primary-key values.
|
|
6
|
+
|
|
7
|
+
type: RequestBody ([src/api/routes/deleteRecords.ts:5](../../../src/api/routes/deleteRecords.ts#L5)) accepts string or numeric view indices and database-valued primary keys, including UUIDs.
|
|
8
|
+
|
|
9
|
+
checks: Recorded strict/build pass; 134 unit tests and 617 integration tests passed, 4 existing skips; 1 accepted configuration non-null warning. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TypeScript port: duplicate record route — cycle 9
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/duplicateRecord.ts:16](../../../src/api/routes/duplicateRecord.ts#L16). Copies configured parent and foreign-table fields after writable-table authorization.
|
|
6
|
+
|
|
7
|
+
type: RequestBody ([src/api/routes/duplicateRecord.ts:6](../../../src/api/routes/duplicateRecord.ts#L6)) describes the target table, database-valued primary key, copied fields and foreign tables.
|
|
8
|
+
|
|
9
|
+
checks: Recorded strict/build pass; 134 unit tests and 623 integration tests passed, 4 existing skips; no warnings; successful PostgreSQL duplication remains unsupported. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# TypeScript port: notification badges route — cumulative cycle 10
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/notificationBadges.ts:10](../../../src/api/routes/notificationBadges.ts#L10). Runs view/subview badge queries and returns values that meet configured display conditions.
|
|
6
|
+
|
|
7
|
+
type: NotificationBadges ([src/api/routes/notificationBadges.ts:8](../../../src/api/routes/notificationBadges.ts#L8)) maps configuration IDs to database field values or `undefined`.
|
|
8
|
+
|
|
9
|
+
checks: Recorded strict/build pass; 134 unit tests and 632 integration tests passed, 4 existing skips; 1 accepted configuration non-null warning. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# TypeScript port: single record route — cumulative cycle 11
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/record.ts:13](../../../src/api/routes/record.ts#L13). Reads one record with configured select/join expressions and applies column formatters.
|
|
6
|
+
|
|
7
|
+
checks: Recorded strict/build pass; 134 unit tests and 635 integration tests passed, 4 existing skips; 2 accepted configuration/columns non-null warnings. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# TypeScript port: company search route — cumulative cycle 12
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/searchCompanies.ts:66](../../../src/api/routes/searchCompanies.ts#L66). Searches the SIRENE service and returns the first 30 active company suggestions.
|
|
6
|
+
|
|
7
|
+
type: JsonValue and JsonObject ([src/api/routes/searchCompanies.ts:4](../../../src/api/routes/searchCompanies.ts#L4)) retain raw JSON and absent properties; CompanySuggestion ([src/api/routes/searchCompanies.ts:6](../../../src/api/routes/searchCompanies.ts#L6)) describes copied fields without promising strings.
|
|
8
|
+
|
|
9
|
+
attention: Boundary validation ([src/api/routes/searchCompanies.ts:41](../../../src/api/routes/searchCompanies.ts#L41)) establishes the shape of an Axios `unknown` response; types alone cannot validate it. The iterative worklist accepts deep JSON without stack overflow, retaining arrays, objects, raw fields and supported response behavior. Malformed results still return `[]`. The 10,000-level test ([tests/integration/routes.custom.integration.test.ts:376](../../../tests/integration/routes.custom.integration.test.ts#L376)) covers depth handling. No `#PORTING-EDIT` marker exists; the original report records unchanged supported JSON behavior.
|
|
10
|
+
|
|
11
|
+
checks: Recorded strict/build pass; 134 unit tests and 653 integration tests passed, 4 existing skips; no warnings. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# TypeScript port: standard upload route — cumulative cycle 14
|
|
2
|
+
|
|
3
|
+
Date: 2026-10-01. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
Ported [src/api/routes/uploadFile.ts:5](../../../src/api/routes/uploadFile.ts#L5). Finds the configured upload column and delegates parsing, storage and responses to the upload helper.
|
|
6
|
+
|
|
7
|
+
checks: Recorded strict/build pass; 134 unit tests and 659 integration tests passed, 4 existing skips; 3 accepted configuration/columns/lookup-element non-null warnings. No rerun; raw logs unavailable.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Create-record strict migration — cycle 1
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/createRecord.ts:9](../../../src/api/routes/createRecord.ts#L9), which inserts view/panel records and forwards callback payloads. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
type: RequestBody and ResponseBody describe record creation indices, database-valued input and existing success/error responses. The factory reuses DbManager and DatabaseRow; the source is now explicitly accepted by tsconfig.strict.json. UUID 9 declarations come from @types/uuid 9.0.8.
|
|
6
|
+
|
|
7
|
+
attention: the temporary callback ID assertion at [src/api/routes/createRecord.ts:111](../../../src/api/routes/createRecord.ts#L111) follows the [approved remediation](../remediation/2026-10-03-callback-id-contract-remediation.md) and issue #45. It preserves PostgreSQL's undefined ID; it does not validate a number. Existing callback signatures and runtime behavior remain. Local configuration, clone, and insertion-result assertions preserve their producer contracts and existing failure points.
|
|
8
|
+
|
|
9
|
+
checks: strict compilation, compiler closure, ordinary build, warning scan, and planner review passed; 134 unit tests and 662 integration tests passed in all 16 suites, with 4 preexisting skipped tests excluded from passing counts. Twelve non-null warnings were reviewed against middleware, configured panel, callback, and driver producers. The new panel callback rejection test passed against the original route on all three backends before migration. No behavior changes.
|
|
10
|
+
|
|
11
|
+
Resolves the [earlier create callback failure](../failures/2026-10-01-cycle-02-create-callback-contract.md). Detailed check and review evidence: /tmp/galadmin-port-20261003/cycle01/.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Delete-record strict migration — cycle 2
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/deleteRecord.ts:6](../../../src/api/routes/deleteRecord.ts#L6), which selects and deletes a record and forwards deletion callbacks. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
type: RequestBody owns string/numeric view indices and database-valued primary keys. The factory reuses DbManager/DatabaseRow and explicit request/response types. The route is accepted by tsconfig.strict.json. Local SELECT-array and configuration assertions retain established driver/middleware contracts and original failure behavior.
|
|
6
|
+
|
|
7
|
+
attention: the temporary ID assertion at [src/api/routes/deleteRecord.ts:54](../../../src/api/routes/deleteRecord.ts#L54) follows the [approved remediation](../remediation/2026-10-03-callback-id-contract-remediation.md) and issue #45. UUID callback IDs remain strings at runtime; this assertion does not validate a number. All production changes erase at compilation.
|
|
8
|
+
|
|
9
|
+
checks: strict compilation, compiler closure, build, warning scan, and planner review passed; 134 unit tests and 665 integration tests passed across all 16 suites, with 4 preexisting skipped tests excluded from passing counts. The configuration non-null warning was justified by middleware ordering. The UUID callback regression passed against the original route on all three backends and verifies payloads, deletedRecord, callback receiver, HTTP rejection swallowing, and persistence.
|
|
10
|
+
|
|
11
|
+
Resolves the [earlier delete callback failure](../failures/2026-10-01-cycle-06-delete-callback-id-contract.md). Detailed local check and review evidence: /tmp/galadmin-port-20261003/cycle02/.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Panel record deletion strict migration — cycle 3
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/deleteRecordFromPanel.ts:6](../../../src/api/routes/deleteRecordFromPanel.ts#L6), which selects/deletes table or gallery panel rows and invokes deletion callbacks. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
type: RequestBody owns view/panel identifiers and database-valued primary keys. DeleteCallbackPayload retains the existing deletedRecord property, including undefined for absent rows. The factory reuses DbManager/DatabaseRow and explicit request/response types; tsconfig.strict.json now accepts the route.
|
|
6
|
+
|
|
7
|
+
attention: the callback ID assertion at [src/api/routes/deleteRecordFromPanel.ts:53](../../../src/api/routes/deleteRecordFromPanel.ts#L53) follows [approved remediation](../remediation/2026-10-03-callback-id-contract-remediation.md) and issue #45. UUID IDs remain strings at runtime; it does not validate a number. A narrow function-member signature assertion permits the already-sent deletedRecord field without changing public callback contracts or member receiver. All production edits erase at compilation.
|
|
8
|
+
|
|
9
|
+
checks: strict compilation, compiler closure, build, warning scan, and planner review passed; 134 unit tests and 671 integration tests passed in all 16 suites, with 4 preexisting skipped tests excluded from pass counts. Three non-null warnings were justified by configured/enriched panel and middleware producers. Original-source table/gallery UUID regression passed on all three backends; it verifies payloads, callback receiver, swallowed HTTP failures, deletion, and repeated missing-row callbacks with success responses.
|
|
10
|
+
|
|
11
|
+
Resolves the [earlier panel callback failure](../failures/2026-10-01-cycle-07-panel-delete-callback-id-contract.md). Detailed local evidence: /tmp/galadmin-port-20261003/cycle03/.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# Update-record strict migration — cycle 4
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/routes/updateRecord.ts:8](../../../src/api/routes/updateRecord.ts#L8), which normalizes update fields, persists changes, and forwards edit callbacks. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
type: RequestBody owns view indices, database-valued primary keys and partial database fields. previousData stays unknown at the opaque forwarded request boundary. DbManager/DatabaseRow and explicit response types replace loose inputs; tsconfig.strict.json accepts the route.
|
|
6
|
+
|
|
7
|
+
attention: the ID assertion at [src/api/routes/updateRecord.ts:66](../../../src/api/routes/updateRecord.ts#L66) follows [approved remediation](../remediation/2026-10-03-callback-id-contract-remediation.md) and issue #45. UUID and route-parameter strings remain unchanged; this is not number validation. Configuration/database initialization assertions preserve original property access and failures. All production edits erase at compilation.
|
|
8
|
+
|
|
9
|
+
checks: strict compilation, compiler closure, build, warning scan, and planner review passed; 134 unit tests and 674 integration tests passed in all 16 suites, with 4 preexisting skipped tests excluded from pass counts. Two non-null warnings were justified by middleware and manager initialization. Original-source UUID regression passed on all three backends, checking persisted updates, normalized data, exact function payload/receiver, and unchanged HTTP previousData.
|
|
10
|
+
|
|
11
|
+
Resolves the [earlier edit callback failure](../failures/2026-10-01-cycle-13-update-callback-id-contract.md). Detailed local evidence: /tmp/galadmin-port-20261003/cycle04/.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
# API value formatting strict migration — cycle 5
|
|
2
|
+
|
|
3
|
+
Scope: [src/api/values.ts:7](../../../src/api/values.ts#L7), which evaluates expressions and formats exported/imported field values. Outcome: ACCEPT.
|
|
4
|
+
|
|
5
|
+
type: FormattingColumn reuses existing callback/text/options owners. evalExpression accepts Record<string, unknown> and returns unknown; getFormattedValue returns Promise<unknown> under [approved boundary guidance](../remediation/2026-10-02-api-values-remediation.md). The insertion formatter uses unknown at the unchecked parseImportFile field boundary, replacing explicit any. tsconfig.strict.json accepts the module.
|
|
6
|
+
|
|
7
|
+
attention: optional column names retain JavaScript property-key conversion through String(name). Direct eval remains in its original scope with unchanged repeated reads, quoting, identity, coercion and exception behavior; options mutation and arbitrary result fallthrough remain unchanged. No sanitization or assertions were added.
|
|
8
|
+
|
|
9
|
+
checks: strict compilation, compiler closure, build, warning scan, and planner review passed; 138 unit tests and 674 integration tests passed in all 16 suites, with 4 preexisting skipped tests excluded from pass counts. Warning scan returned zero diagnostics. Four new mock-free helper tests passed against original source and cover direct-eval locals, changing getters, lazy/cyclic/function results, CSV/JSON coercion, options identity/mutation, absent-name lookup and insertion fallthrough.
|
|
10
|
+
|
|
11
|
+
Resolves the [earlier expression-result failure](../failures/2026-09-23-api-values-contract.md). Detailed local evidence: /tmp/galadmin-port-20261003/cycle05/.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
# Record import parser boundary — cycle 1
|
|
2
|
+
|
|
3
|
+
Scope: `src/api/routes/recordsImport.ts` and `src/api/importRecords.ts`, which validate configured parser output before importing records. Outcome: accepted strict coverage after resolving the [prior parser contract failure](../failures/2026-10-03-cycle-06-record-import-parser-contract.md) with [approved guidance](../remediation/2026-10-06-import-parser-remediation.md).
|
|
4
|
+
|
|
5
|
+
**type:** [src/api/importRecords.ts:1](../../../src/api/importRecords.ts#L1) exposes `isImportRecords(value: unknown): value is Record<string, unknown>[]`. The indexed shape guard permits custom object prototypes and unchecked field values, preserves original arrays/records, and visits sparse holes. The route uses `DbManager` and `string[]` column names; assertions preserve existing multipart indexing, initialized database type and optional affected-row response behavior.
|
|
6
|
+
|
|
7
|
+
**attention:** [src/api/routes/recordsImport.ts:32](../../../src/api/routes/recordsImport.ts#L32) marks rejection of non-array parser results and non-object/null/array/function elements with HTTP 400 before column enumeration or insertion. This is the sole runtime change authorized by the remediation. Inherited keys, getter/field identity and timing, parser receiver/arguments, empty results, authorization, parser exceptions, SQL errors and PostgreSQL response behavior remain covered by real-database tests. Original-source characterization passed 69 tests and failed only 48 expected policy assertions.
|
|
8
|
+
|
|
9
|
+
**checks:** ordinary build, strict `--noEmit`, compiler closure, 149 unit tests, 779 real-database integration tests and planner review passed; 4 preexisting skipped tests excluded. Warning scan: 11 non-null assertions reviewed against producer/caller evidence; no added `any` or suppressions. Detailed plan, diff, review and command evidence: `/tmp/ts-port-20261006/cycle01/` (session-local).
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
# Configured rich-text upload — cycle 3
|
|
2
|
+
|
|
3
|
+
Scope: `src/api/routes/uploadFileFromBetterRichTextInput.ts`, which authorizes the selected configured rich-text column and forwards its server-owned upload settings. Outcome: accepted strict coverage, resolving the [historical client-header failure](../failures/2026-10-01-cycle-15-rich-text-upload-boundary-contract.md) using [server-configured retry guidance](../remediation/2026-10-06-rich-text-upload-remediation.md).
|
|
4
|
+
|
|
5
|
+
**type:** [src/api/routes/uploadFileFromBetterRichTextInput.ts:19](../../../src/api/routes/uploadFileFromBetterRichTextInput.ts#L19) preserves digit-string lookup with erased config/index assertions. [line 32](../../../src/api/routes/uploadFileFromBetterRichTextInput.ts#L32) safely widens the declared roles receiver to readonly `(string | undefined)[]`, retaining the original negative `includes` test. [line 36](../../../src/api/routes/uploadFileFromBetterRichTextInput.ts#L36) reuses the declared optional `BetterRichTextColumn.fileUploadProperties` contract through a narrow same-object alias where open `StandardColumn.dataType` prevents discriminant narrowing. Settings identity, getters, callable transforms, target responses and ignored legacy headers remain unchanged; no new runtime behavior.
|
|
6
|
+
|
|
7
|
+
**checks:** ordinary build, strict `--noEmit`, compiler closure, 149 unit tests, 782 real-database integration tests and planner review pass; 4 preexisting skips excluded. Original upload/authorization characterization passed 236 tests. Warning scan's single `req.config!` is justified by unconditional upstream middleware. The clean full integration run is authoritative; an earlier overlapping-process run was discarded after stopping both task-started test process groups. Complete plan, diff, review, hashes and full check logs: `/tmp/ts-port-20261006/cycle03/` (session-local).
|