Skip to content

examples/app-todo: is_completed and is_overdue are readonly flags that nothing ever maintains — permanently false, and one of them is read by a hook #7226

Description

@os-help

Found while implementing #7036. Observation-class, filed unassigned: nothing a user hits today reports a wrong answer, but the fields are inert in a way that reads as working.

What is there

examples/app-todo/src/objects/task.object.ts:

is_completed: Field.boolean({ label: 'Is Completed', defaultValue: false, readonly: true }),
is_overdue:   Field.boolean({ label: 'Is Overdue',   defaultValue: false, readonly: true }),

Both are readonly, so a non-system caller's write to either is stripped on both write paths. Nothing else in the app writes them: no hook leg, no flow node, no action handler, and the seed data sets neither. They are therefore false on every row for the life of the app.

is_overdue additionally has a reader: the afterUpdate leg of src/objects/task.hook.ts logs when a task "became overdue", gated on data.is_overdue && previous && !previous.is_overdue. That condition can never be true, so the branch is unreachable. (#7036 repairs how that leg reads its record but does not change this.)

is_completed is the one with a visible partner: after #7036 the app maintains completed_date on the completion transition, so a reader comparing the two now sees a task with a completion date and is_completed: false.

Why it is a finding rather than a defect

No user-facing surface currently branches on either flag — no view filter, dashboard, report or dataset in the app reads them (is_overdue's only reader is the log line above). So nothing produces a wrong answer today; the cost is that a shipped reference app declares two derived flags and derives neither, which is the pattern an AI author copies.

Shape of the fix, if it is wanted

Three readings, and the choice is an app-semantics call rather than an obvious repair:

  • Maintain themis_completed in the same beforeUpdate leg that stamps completed_date (they are the same transition); is_overdue needs a clock, so it belongs to a scheduled flow rather than a record hook.
  • Derive them — make both formula fields, so they cannot drift from status/due_date and are visible to list views without anything writing them.
  • Remove them — if the example does not mean to demonstrate derived flags, status and due_date already carry the information.

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