Skip to content

sys_job.timezone and sys_report_schedule.timezone disagree with each other and neither is validated — the platform's own IANA columns predate valueDomain #15872

Description

@zhuangjianguo

Found while implementing #14238 (maintainer ruling A: sys_business_unit.timezone and sys_organization.timezone, both text / optional / maxLength: 64 / valueDomain: 'iana_time_zone' / no default). Retrofitting the two older columns was explicitly outside that ruling's scope, so it is carded here rather than widened into that PR. Unassigned — for triage.

The reading

Measured on origin/main at 7b6825477, each file individually (a lane-wide grep for time_?zone returns 20+ hits and is not a reading about a file):

object declaration bound default valueDomain
sys_jobpackages/platform-objects/src/audit/sys-job.object.ts:64 Field.text({ required: false, maxLength: 100 }) 100 none none
sys_report_schedulepackages/platform-objects/src/audit/sys-report-schedule.object.ts:81 Field.text({ required: false, maxLength: 64, defaultValue: 'UTC' }) 64 'UTC' none

grep -c valueDomain in both files = 0. So the card #14238 was raised on — "every app invents the column differently" — is already true inside the platform's own objects, in three dimensions at once (length, default, validation), and since #14168 / #15161 the platform has the one declaration that closes the third dimension and these two columns do not carry it.

Consequence

A write of Mars/Olympus, UTC+8 or China Standard Time to either column is stored. Whatever reads the column at schedule time (service-job for sys_job, plugin-reports for sys_report_schedule) meets the bad value later, far from its cause. Not measured here: which reader consumes each column and what it does with a non-member (throws, falls back to UTC, or schedules at a wrong instant) — that is this card's first step, and it decides the severity.

Published surface (measured, Zone-1 rule)

Both columns are in the built packages/platform-objects/dist/audit/index.js / index.mjs (timezone ×2) and dist/audit/index.d.ts / index.d.mts (×3). content/docs/** mentions of either column's timezone: 0. So this is a published surface by the dist measurement, and a docs-absent one.

Proposed shape (for the implementing seat to verify, not a ruling)

  • Declare valueDomain: 'iana_time_zone' on both. It is the transition-gate class (min / max / maxLength): only a WRITTEN non-member is refused; stored values are never re-read, so no data migration and no ADR-0087 prescription.
  • Converge the bound on 64, the value No platform object carries a timezone, so every app that computes a date boundary has to invent one — and each will invent it differently #14238 chose and justified: the enumeration's longest name on the repo's Node baseline is 30 characters (America/Argentina/Rio_Gallegos), the longest tzdb link 32 (America/Argentina/ComodRivadavia), and the tzdb caps each path component at 14 — 64 is twice the domain's real ceiling. Narrowing 100 → 64 on sys_job needs the check-keyed-text-bounds family and a look at what the column physically holds.
  • The default is a consumer semantic (sys_report_schedule says UTC, sys_job says nothing); keep each as its reader expects unless the reader says otherwise.

Both objects are isSystem; the change widens a declared shape on a published package, so the changeset is at least minor and the review tier is a contract question for the PM, not for this card.

Re-check

git show origin/main:packages/platform-objects/src/audit/sys-job.object.ts | sed -n '64,69p'
git show origin/main:packages/platform-objects/src/audit/sys-report-schedule.object.ts | sed -n '81,87p'
git show origin/main:packages/platform-objects/src/audit/sys-job.object.ts | grep -c valueDomain              # 0
git show origin/main:packages/platform-objects/src/audit/sys-report-schedule.object.ts | grep -c valueDomain  # 0

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions