Summary
Add include_last_changed_at: bool = False to ContentOptions. Surfaces Watch.last_changed_at as "Last changed: 2026-04-09" — gives recipients frequency context that a bare change notification lacks.
Context
Follows from #88 (notification content options Phase 1). The design doc listed last_changed_at under temporal context but the implementation only shipped check_interval. This adds the missing half. No schema migration needed.
Scope
Worker (src/workers/tasks.py):
- Add
last_changed_at to _watch_base_metadata(watch):
if watch.last_changed_at:
meta["last_changed_at"] = watch.last_changed_at.strftime("%Y-%m-%d")
Content builder (src/core/notifications/content.py):
- Add
include_last_changed_at: bool = False to ContentOptions
- Extend
_build_temporal_section(metadata, options) (or add a separate section) to render "Last changed: {date}" when last_changed_at is present and include_last_changed_at is True
Dashboard (src/dashboard/templates/partials/notification_content_options.html):
- Add checkbox alongside existing "Temporal context": "Last changed date"
- Consider grouping with
include_temporal_context under a single "Temporal" label
Notes
last_changed_at is None until the first change is detected — render silently omitted when absent
- ISO date format (
YYYY-MM-DD) per project conventions; no time component needed (date is sufficient for frequency context)
- Could be folded into the existing
include_temporal_context checkbox rather than a separate toggle — design decision at implementation time
Summary
Add
include_last_changed_at: bool = FalsetoContentOptions. SurfacesWatch.last_changed_atas "Last changed: 2026-04-09" — gives recipients frequency context that a bare change notification lacks.Context
Follows from #88 (notification content options Phase 1). The design doc listed
last_changed_atunder temporal context but the implementation only shippedcheck_interval. This adds the missing half. No schema migration needed.Scope
Worker (
src/workers/tasks.py):last_changed_atto_watch_base_metadata(watch):Content builder (
src/core/notifications/content.py):include_last_changed_at: bool = FalsetoContentOptions_build_temporal_section(metadata, options)(or add a separate section) to render"Last changed: {date}"whenlast_changed_atis present andinclude_last_changed_atis TrueDashboard (
src/dashboard/templates/partials/notification_content_options.html):include_temporal_contextunder a single "Temporal" labelNotes
last_changed_atisNoneuntil the first change is detected — render silently omitted when absentYYYY-MM-DD) per project conventions; no time component needed (date is sufficient for frequency context)include_temporal_contextcheckbox rather than a separate toggle — design decision at implementation time