WIP - update records fixes

This commit is contained in:
Francisco Gaona
2026-01-13 19:22:41 +01:00
parent d00e26ad27
commit 414d73daef
3 changed files with 67 additions and 22 deletions

View File

@@ -1,7 +1,38 @@
import { Model, ModelOptions, QueryContext, snakeCaseMappers } from 'objection'; import { Model, ModelOptions, QueryContext } from 'objection';
export class BaseModel extends Model { export class BaseModel extends Model {
static columnNameMappers = snakeCaseMappers(); /**
* Use a minimal column mapper: keep property names as-is, but handle
* timestamp fields that are stored as created_at/updated_at in the DB.
*/
static columnNameMappers = {
parse(dbRow: Record<string, any>) {
const mapped: Record<string, any> = {};
for (const [key, value] of Object.entries(dbRow || {})) {
if (key === 'created_at') {
mapped.createdAt = value;
} else if (key === 'updated_at') {
mapped.updatedAt = value;
} else {
mapped[key] = value;
}
}
return mapped;
},
format(model: Record<string, any>) {
const mapped: Record<string, any> = {};
for (const [key, value] of Object.entries(model || {})) {
if (key === 'createdAt') {
mapped.created_at = value;
} else if (key === 'updatedAt') {
mapped.updated_at = value;
} else {
mapped[key] = value;
}
}
return mapped;
},
};
id: string; id: string;
createdAt: Date; createdAt: Date;

View File

@@ -179,6 +179,7 @@ export class DynamicModelFactory {
* Convert a field definition to JSON schema property * Convert a field definition to JSON schema property
*/ */
private static fieldToJsonSchema(field: FieldDefinition): Record<string, any> { private static fieldToJsonSchema(field: FieldDefinition): Record<string, any> {
const baseSchema = () => {
switch (field.type.toUpperCase()) { switch (field.type.toUpperCase()) {
case 'TEXT': case 'TEXT':
case 'STRING': case 'STRING':
@@ -226,6 +227,18 @@ export class DynamicModelFactory {
default: default:
return { type: 'string' }; return { type: 'string' };
} }
};
const schema = baseSchema();
// Allow null for non-required fields so optional strings/numbers don't fail validation
if (!field.isRequired) {
return {
anyOf: [schema, { type: 'null' }],
};
}
return schema;
} }
/** /**

View File

@@ -1179,7 +1179,8 @@ export class ObjectService {
objectApiName, objectApiName,
editableData, editableData,
); );
await boundModel.query().where({ id: recordId }).update(normalizedEditableData); // Use patch to avoid validating or overwriting fields that aren't present in the edit view
await boundModel.query().patch(normalizedEditableData).where({ id: recordId });
const record = await boundModel.query().where({ id: recordId }).first(); const record = await boundModel.query().where({ id: recordId }).first();
await this.indexRecord(resolvedTenantId, objectApiName, objectDefModel.fields, record); await this.indexRecord(resolvedTenantId, objectApiName, objectDefModel.fields, record);
return record; return record;