Skip to main content

Ticku v2.1.0

Release date: 2026-08-10

Email-to-ticket is substantially reworked: mailboxes now belong to the tenant rather than to a project, one mailbox can feed several projects through routing rules, and there are three ways to connect one — including a per-mailbox "Sign in with Microsoft" that needs no Global Admin consent. This release also adds followers, comment replies and reactions, and tightens Azure directory verification on every Microsoft sign-in.

⚠️ Breaking / Migration Steps

  • Per-tenant Azure mail credentials are gone. Email now authenticates with the platform SSO app registration against each tenant's registered entraDirectoryId. There is nothing for a tenant admin to type in. The MicrosoftMailConfig table is dead and pending cleanup.
  • Add Mail permissions to the SSO app. The app-only connection mode needs Mail.ReadWrite and Mail.Send application permissions with admin consent. Without them every app-only mail call returns 403. See Azure App Registration.
  • Inbox ownership flipped. ProjectEmailConfig.projectId (unique, one inbox per project) became EmailInbox.defaultProjectId (the fallback destination). The table keeps its name via @@map, so the rename costs no data movement — but anything reading projectId on it must be updated.
  • Set CRON_SECRET. The new email cycle calls /api/cron/email every 2 minutes and refuses unauthenticated triggers. It falls back to GRAPH_WEBHOOK_SECRET; if neither is set the worker skips the job entirely and no mail flows.
  • The daily webhook-renewal job was removed. The email cycle renews subscriptions as well as polling, so renewal now happens on a 2-minute cadence instead of daily.
  • Email can only target Support projects. Existing rows pointing elsewhere are grandfathered and still saveable as-is, but cannot be moved to a different non-Support project.
  • Run npm run db:migrate (migrate deploy) after updating.

✨ New

  • Email routing rules — one shared mailbox can feed many projects. Match on recipient address (aliases and plus-addressing) or sender domain, with recipient taking precedence and the inbox's default project as the fallback. Rules can override priority, acknowledgement, notification flags, subject folder, and assignee. A Simulate tool shows which rule would win before you commit to it. See Routing Rules.
  • Three connection modes — app-only Microsoft Graph (push, seconds), per-mailbox delegated OAuth (polled, no Global Admin needed), and IMAP/SMTP with a password (polled; not usable against Microsoft 365). See Connection Modes.
  • Followers — subscribe anyone to a single ticket or sub-task without giving them the project. A follower from outside the organization gets a minimal guest membership that grants nothing beyond the followed item. See Followers.
  • Comment replies and reactions — comments thread via replies, and any comment can be reacted to with an emoji (one per person, changing rather than stacking). New COMMENT_REPLY, COMMENT_REACTION, and FOLLOWER_ADDED notification events. Reactions are in-app only.
  • Auto-assign on comment — a non-Viewer commenting on an open ticket or sub-task they didn't create takes ownership of it.
  • Commit id capture — the Dev Fixed → Review transition can record the commit a fix shipped in, alongside a review note.
  • Work Schedule table — planned work per assignee (project, ticket, planned start/end, status, priority) in Analytics, plus a Monthly Timesheet Excel/PDF export with a daily hours grid. See Analytics.
  • Due-date filtersdueby: and duewithin: on the dashboard filter bar.
  • Product tour — a guided walkthrough per screen, launched from the header. It never auto-opens.

🛠 Improved

  • Azure directory verification on every sign-in. The tid check previously ran only at account creation, so any returning user — a password signup, a Teams user, a guest — could sign in via Microsoft without ever passing it. It now runs on every Microsoft sign-in, and a tenant with no registered directory adopts one from its designated first admin (trust on first use). Enforcement is behind ENTRA_TID_ENFORCE, off by default: a mismatch is logged but allowed until you turn it on. See Authentication.
  • Outbound email is now opt-in per event. Comments, status changes, and acknowledgements each have their own toggle. Notify on comment defaults to off — comments carry no internal/public flag, so the previous unconditional behaviour mailed internal team discussion to the customer verbatim. An agent opts a single comment in by writing @creator.
  • Assignment notifications folded into status changes. Assigning auto-transitions OPEN → ASSIGNED, so a separate assignment toggle made the same real-world event send different mail depending on which control the agent used.
  • Sub-tasks in global search, plus display-ID lookup — EMA-15.2 or 15.2 jumps straight to a sub-task.
  • Clickable ticket and sub-task mentions in comments and the rich-text editor.
  • Health reporting that doesn't lie. A poll cycle that ingests successfully and then fails later now records its progress; previously a late error hid earlier success, so an inbox reported "Not yet polled" while it was actively creating tickets.
  • Settings shell — Notifications, Analytics, and Bulk Upload now share a consistent settings layout.
  • Notification read state fixes and escalation notification tuning.

🗑 Removed

  • Auto-create ticket toggle. With it off, mail produced no ticket and no record while both transports still marked it read — messages vanished silently. Ticket creation is now unconditional.
  • Per-inbox allowed/blocked sender domains. They duplicated routing and fought it: a domain missing from the allow-list had its routing rule rejected before the rule was ever consulted, with nothing to indicate why. The allow-list was also suppressing bounce messages by accident. Blocking a sender is the mail provider's job.

Both remain as unused columns pending a cleanup migration.

📚 Documentation

The Email-to-Ticket guide is now a five-page section covering the pipeline, connection modes, inbox settings, routing, and troubleshooting. Screenshots have been added throughout the user and admin guides, captured by a committed, re-runnable script.