From 5a82d660daa1d4b693ced90aacfc003ecb0c4521 Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Fri, 24 Apr 2026 00:06:42 +0100 Subject: [PATCH] feat(base): register formula property type in schema layer --- apps/server/src/core/base/base.schemas.ts | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/apps/server/src/core/base/base.schemas.ts b/apps/server/src/core/base/base.schemas.ts index b05b7fe6e..f5c687250 100644 --- a/apps/server/src/core/base/base.schemas.ts +++ b/apps/server/src/core/base/base.schemas.ts @@ -16,12 +16,14 @@ export const BasePropertyType = { CREATED_AT: 'createdAt', LAST_EDITED_AT: 'lastEditedAt', LAST_EDITED_BY: 'lastEditedBy', + FORMULA: 'formula', } as const; const SYSTEM_PROPERTY_TYPES: Set = new Set([ BasePropertyType.CREATED_AT, BasePropertyType.LAST_EDITED_AT, BasePropertyType.LAST_EDITED_BY, + BasePropertyType.FORMULA, ]); export function isSystemPropertyType(type: string): boolean { @@ -106,6 +108,21 @@ export const personTypeOptionsSchema = z export const emptyTypeOptionsSchema = z.object({}).passthrough(); +// AST is treated as an opaque JSON tree by the server at this layer — the +// shape is enforced at the formula package's parser, not at Zod. The Zod +// schema validates only the envelope so a malformed blob can't corrupt the +// column. Depth/content validation belongs to FormulaService. +export const formulaTypeOptionsSchema = z + .object({ + source: z.string().min(1).max(8192), + ast: z.any(), + resultType: z.enum(['number', 'string', 'boolean', 'date', 'null']), + dependencies: z.array(z.uuid()), + astVersion: z.literal(1), + formatOptions: z.record(z.string(), z.unknown()).optional(), + }) + .passthrough(); + const typeOptionsSchemaMap: Record = { [BasePropertyType.TEXT]: textTypeOptionsSchema, [BasePropertyType.NUMBER]: numberTypeOptionsSchema, @@ -122,6 +139,7 @@ const typeOptionsSchemaMap: Record = { [BasePropertyType.CREATED_AT]: emptyTypeOptionsSchema, [BasePropertyType.LAST_EDITED_AT]: emptyTypeOptionsSchema, [BasePropertyType.LAST_EDITED_BY]: emptyTypeOptionsSchema, + [BasePropertyType.FORMULA]: formulaTypeOptionsSchema, }; export function validateTypeOptions(