fix: align conversational persistence validators

This commit is contained in:
Jesse_Chen
2026-07-20 23:42:37 +08:00
parent c883c401aa
commit ae41023b96
6 changed files with 485 additions and 58 deletions
@@ -1,16 +1,27 @@
import { z } from "zod";
const POSTGRES_JSON_DECIMAL_SCALE = 1_000_000;
const POSTGRES_JSON_MIN_FRACTION = 1 / POSTGRES_JSON_DECIMAL_SCALE;
const POSTGRES_JSON_MAX_DECIMAL_PLACES = 6;
const POSTGRES_JSON_MIN_FRACTION = 0.000001;
const POSTGRES_JSON_MAX_FRACTION_MAGNITUDE = 1_000_000;
function canonicalJsonDecimalPlaces(value: number): number | null {
const serialized = JSON.stringify(value);
const match = /^-?\d+(?:\.(\d+))?(?:e([+-]?\d+))?$/i.exec(serialized);
if (!match) return null;
const fractionLength = match[1]?.length ?? 0;
const exponent = Number(match[2] ?? 0);
return Math.max(0, fractionLength - exponent);
}
function postgresStableJsonNumber(value: number): boolean {
if (!Number.isFinite(value)) return false;
if (Number.isSafeInteger(value)) return true;
const magnitude = Math.abs(value);
const decimalPlaces = canonicalJsonDecimalPlaces(value);
return magnitude >= POSTGRES_JSON_MIN_FRACTION
&& magnitude <= POSTGRES_JSON_MAX_FRACTION_MAGNITUDE
&& Number.isSafeInteger(value * POSTGRES_JSON_DECIMAL_SCALE);
&& decimalPlaces !== null
&& decimalPlaces <= POSTGRES_JSON_MAX_DECIMAL_PLACES;
}
function postgresJsonNumbersAreStable(
@@ -37,7 +37,7 @@ const birthplaceSchema = boundedJson(z.object({
}
}), 4_096);
const clueSchema = z.string().max(240).nullable();
const clueSchema = boundedText(240).nullable();
const commonBirthFields = {
birthDate: birthDateSchema,
birthTimeClue: clueSchema,