v0.10.0 Latest Since v0.10.0

Ticket schedules + personal tasks

Recurring ticket templates fired on a cron schedule with an audit ledger, and owner-scoped personal tasks with one-off or recurring due dates.

Ticket schedules

ticket_schedules: a template plus a schedule. Presets (daily / weekly / monthly by day-of-month / monthly nth weekday / yearly) compile to cron internally; raw cron is the escape hatch. Timezone-aware via cron-parser. End condition: indefinite, after N fires, or until a date.

Template fields: project, title, description (both encrypted via FIELD_MAP), impact, urgency, optional assignee, optional requestor (submitted_by override), contacts, follower_ids[] (auto-added on every fire), runbook_article_id (starts a ticket_runbook_runs row on every fire).

Fire path materializes a real ticket: internal_ref, encrypted patch, contacts, deduped followers, SLA policy, blind index. Description @mentions are not dispatched on create (repeated fires would spam); comment mentions on the fired ticket work as usual.

ticket_schedule_runs records every fire (ok / error + message). The scheduler ticks every 60 s; a failure still advances next_fire_at so a broken template never busy-loops.

GET/POST/PATCH/DELETE  /api/ticket-schedules
POST                   /api/ticket-schedules/preview     — next N fire times
GET                    /api/ticket-schedules/:id/runs

Admin → Schedules. Bulk Entra import (pick users from the directory, add in one shot) ships alongside.

Personal tasks

tasks + task_completions. Owner-scoped, no fanout, no SLA. Encrypted title + body. recurrence_kind in (once, preset, cron); presets compile to cron with the same helper the schedules use. Optional ticket_id (ON DELETE SET NULL) so a task created from a ticket page carries the source ref.

GET/POST/PATCH/DELETE  /api/tasks
POST                   /api/tasks/:id/complete      — records a completion, advances next_due_at
POST                   /api/tasks/:id/skip          — recurring only
POST                   /api/tasks/:id/reschedule    — postpones the current occurrence

UI: /tasks (pending / completed / cancelled chips, markdown viewer, edit modal with preset / cron / one-off picker, reschedule + skip). Sidebar Tasks entry. Dashboard My tasks card with Overdue / Due today / Tomorrow and an inline complete checkbox. Global New menu in the header creates a ticket or a task from anywhere.