01 · Web app and Telegram Mini App · 2026

ITSM PRO

A ticketing system for an iiko dealer, covering service and retail. One address serves both the web app and the mini app inside Telegram.

Role Whole cycle: product, backend, frontend, bot, server
Timeline 6 weeks to a production server
Status In use by the client, real tickets
Stack Node.js · TypeScript · React · grammY

The problem

A company with two arms — service and retail. Tickets lived in chat threads: a broken till, an out-of-date price list and a request to visit a site all sat in one conversation, mixed together. There was no place where a task had a deadline, an owner and a history.

The client works out of Telegram and had no intention of leaving it. So the mini app is the main entrance and the website is secondary: the same address, the same database, and no separate build for the messenger.


What it does
01

Tasks and statuses

Six states — new, in progress, deferred to a date, awaiting reply, cancelled, resolved. Three priorities, project blocks, several assignees, links between tasks, and deadline reminders that repeat.

02

Discussion and attachments

A thread inside each task, files up to 25 MB, around forty formats on an extension allowlist, and an unread counter. The history stays with the task rather than in a chat someone has scrolled past.

03

Tickets by voice

One dictated sentence becomes a draft: who it is for, what to do, by when, how urgent and under which block. A person checks it and creates the task.

04

Telegram notifications

A message with a button that opens the task straight in the mini app. Events are picked with checkboxes on each task and frequent messages are merged — the bot does not turn into spam.

05

Access rights

Groups with checkboxes instead of numbered roles: the owner creates their own. Visibility has three steps — your own tasks, your department, the whole company.

06

Reports

The work plan as a Gantt chart: dependency arrows, a “today” line, grouping by project. Alongside it, analytics — day-by-day trends, breakdowns by person and block, overruns. Refreshed every fifteen seconds.

How it started
9:41Telegram · mini app
Task No. 418 Edit
Receipt not printing, till No. 3 on Tverskaya
Assignee A. Volkova
Due today, 15:00
Priority High
Block Service · retail
Discussion · 4 I. Petrov — Replaced the roll, the receipt still comes out blank A. Volkova — Bringing a replacement printer, will be there by 14:30 inspection_report.pdf · 240 KB
ResolvedDefer
A task card in the mini app: assignee, deadline, discussion and attachments on one screen.
itsm.example.com/plan
Work plan August 2026 · 23 tasks
Task 0507091113
Database migration to the new server
Retail training
Stock count
EGAIS setup, new site
Till hardware acceptance
Solid — on timeHatched — overdueLine — today
The work plan on the web: an overrun is marked by hatching as well as colour, so it reads with colour blindness.

Engineering decisions I am glad about
01

Speech parsing without an external LLM

Rules and dictionaries instead of somebody else’s API. It understands inflected names, “by tomorrow, before 3pm”, “by Friday”, “in two hours”, “15 August”, plus priority and block. Masculine and feminine forms are told apart by case, so a task for Aleksandra Volkova does not go to Aleksandr Volkov. Zero cost per ticket and no dependence on anyone else’s uptime.

02

The model was chosen by measurement

Whisper was benchmarked on the production hardware — two cores, no GPU. Small: 12 seconds per phrase. Medium: 32. Large-v3-turbo: 30. The transcribed text was identical. I kept small and wrote the measurements into the README, so the next person does not overturn the decision blind.

03

Speed instead of waiting

The server answers in 0.4–0.6 seconds, and you can feel it. Sections are cached for the session: returning to a tab paints instantly and fresh data follows. On a first open a placeholder holds the space, so the page height does not jump under the cursor.

04

Colour everyone can read

I ran the chart palette through a validator: in the dark theme, red and green sit at ΔE 3.9 under colour blindness — an overdue task and a resolved one are indistinguishable. Overruns got hatching, and the status is repeated in words everywhere it appears.

Result

Deployed to a production server over HTTPS. The client runs real tickets through it and gets notifications in Telegram.


Similar problem? Tell me in one message.