fix(field): enforce select-visibility guard on the V2 convert path + repair inkreach-cli field routes
- FieldOpenApiV2Service.convertField now calls the shared V1 validator (assertSelectVisibilityConfigValid) before executing the update command. Previously only the V1 path validated self-reference / dependency cycles, so invalid configs could be persisted through V2 (verified live: a self-referencing choice was accepted with 200). - V1 assertSelectVisibilityConfigValid private -> public (shared guard). - Unit tests: 3 new cases in field-open-api-v2.service.spec.ts (guard invoked with exact args; rejects before executing when validator throws; called with raw type/options for non-select conversions). 63/63 pass; tsc build config 0 errors. - inkreach-cli: field get/update/delete targeted non-existent /api/field/:id routes; now use /api/table/:tableId/field/:fieldId. update --options goes through the convert API (the PATCH update API strips options by design). New: convertField + getVisibleChoices client methods, field visible-choices command (evaluates choice visibility for a record).
This commit is contained in:
Vendored
+18
-6
@@ -67,17 +67,29 @@ class Client {
|
||||
listFields(tableId) {
|
||||
return this.call('GET', `/api/table/${tableId}/field`);
|
||||
}
|
||||
getField(fieldId) {
|
||||
return this.call('GET', `/api/field/${fieldId}`);
|
||||
getField(tableId, fieldId) {
|
||||
return this.call('GET', `/api/table/${tableId}/field/${fieldId}`);
|
||||
}
|
||||
createField(tableId, body) {
|
||||
return this.call('POST', `/api/table/${tableId}/field`, body);
|
||||
}
|
||||
updateField(fieldId, body) {
|
||||
return this.call('PUT', `/api/field/${fieldId}`, body);
|
||||
/** Rename/describe. NOTE: the update API accepts name/description only —
|
||||
* options (incl. select choice visibilityFilter) must go through convertField. */
|
||||
updateField(tableId, fieldId, body) {
|
||||
return this.call('PATCH', `/api/table/${tableId}/field/${fieldId}`, body);
|
||||
}
|
||||
deleteField(fieldId) {
|
||||
return this.call('DELETE', `/api/field/${fieldId}`);
|
||||
/** PUT convert: the ONLY API path that persists field options (choices,
|
||||
* visibilityFilter dependency config, etc.). Requires the field's current type. */
|
||||
convertField(tableId, fieldId, body) {
|
||||
return this.call('PUT', `/api/table/${tableId}/field/${fieldId}/convert`, body);
|
||||
}
|
||||
deleteField(tableId, fieldId) {
|
||||
return this.call('DELETE', `/api/table/${tableId}/field/${fieldId}`);
|
||||
}
|
||||
/** Evaluate select-choice visibility dependency for one record+field.
|
||||
* GET /api/table/:tableId/select-visibility/:recordId/:fieldId */
|
||||
getVisibleChoices(tableId, recordId, fieldId) {
|
||||
return this.call('GET', `/api/table/${tableId}/select-visibility/${recordId}/${fieldId}`);
|
||||
}
|
||||
// ---- record ----
|
||||
getRecords(tableId, query) {
|
||||
|
||||
Reference in New Issue
Block a user