fix(compliance): correct is_overdue_for_review date math — CEL has no Timestamp+int#92
Merged
Merged
Conversation
… Timestamp+int (#84) `is_overdue_for_review` was: daysFromNow(0) > record.last_assessed_at + record.review_frequency_days * 86400000 The formula engine is CEL, where dates are Timestamps and there is NO `Timestamp + int` operator — so `last_assessed_at + N` (and the whole RHS) evaluated to null for every control that HAS a last_assessed_at. The result: only never-assessed controls (the `last_assessed_at == null` branch) ever flagged as overdue; a control assessed long ago but past its review cadence never did. The `* 86400000` (a "days → epoch ms" conversion) was doubly wrong: CEL date arithmetic is day-granular via builtins, not millisecond epochs. Fix — use the CEL `addDays(date, n)` builtin and a Timestamp comparison: addDays(record.last_assessed_at, record.review_frequency_days) < today() i.e. overdue when the next-review date (last assessment + cadence days) is already in the past. Boot-verified against a fresh dev server (@objectstack 15.1.1, 0 errors) — all eight seeded controls now compute correctly: - GDPR Art.32 (assessed ~200d ago, 180d cadence) → overdue = true [was false] - HIPAA §164.308(a)(1) (~40d ago, 365d), CC6.1/CC7.1/CC8.1 (<90d), A.5.1 (100d/180d) → overdue = false - A.8.16 / 164.312(a)(1) (never assessed) → overdue = true The "Overdue for Review" list view (filter is_overdue_for_review = true) now surfaces stale-but-assessed controls, not just never-assessed ones. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BZguyAaQbyUpwMZ2gMLaAP
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Bug
compliance_control.is_overdue_for_review之前是:formula 引擎是 CEL,日期是 Timestamp,而 CEL 没有
Timestamp + int运算符 —— 所以只要 control 有last_assessed_at,整个右边就求值为 null。后果:只有「从未评估」(last_assessed_at == null分支)的 control 会被标为逾期;评估过但早已超过复评周期的 control 永远不会被标出来。* 86400000(把天数当成 epoch 毫秒)也是错的 —— CEL 的日期运算是按天、走 builtin 的,不是毫秒 epoch。这个字段是「复评逾期」列表视图(
is_overdue_for_review = true)的过滤条件,而 seed 里的 GDPR Art.32(约 200 天前评估、周期 180 天,description 明说 "Past review-frequency window")正是用来演示它的 —— 之前一直没被标出来。修复
改用 CEL 的
addDays(date, n)builtin + Timestamp 比较:即:当「下次复评日期(上次评估 + 周期天数)」已经过去时,判为逾期。
验证(fresh dev server,@objectstack 15.1.1,0 错误)
8 个 seed control 全部正确:
说明
last_assessed_at),独立成 PR。hr模板也存在(hr_document的到期状态、hr_employee的司龄用了today() ± N/today() - date)—— 我会单独发 PR 修 hr,同样的根因(CEL 日期运算要走addDays/daysFromNow等 builtin,不能用+/-)。Generated by Claude Code