offon · company‑wide work management system

Period  — Present

An internal Lukuku product I designed, built and operate.

System that handles everything from attendance to CRM in Slack
and serves as the MCP access point for AI agents

Next.js 16React 19TypeScriptPrismaPostgreSQLVercelMCPOAuth 2.1

  • Slack commands for attendance and break records, correction requests and approvals
  • Automatic calculations for overnight work, holiday exclusions, leave grants and carry‑over
  • Table, kanban, calendar and Gantt views of tasks and assignee status
  • Reminders asking assignees for updates on the next follow‑up date
  • Meeting room bookings and reminders 10 minutes before meetings
  • Agent search backed by about 390,000 lines of Slack conversation

Requests copied into another tool

Problem
PMs and developers copied requests from Slack and email into a task tool. Most requests that needed checking were emails, and half of them were notification emails.
Solution
Built an inbox that turns requests into tasks with their original text and attachments, or links them to existing work. Messages in the same thread attach to existing tasks, while automated emails are excluded. When the rules first ran, 59 waiting emails were sorted without anyone touching them. Addresses dismissed in two or more different threads are filtered out from then on.

How much access to give agents

Problem
Separate DB and Slack permissions for every agent would scatter access controls. Requester identities supplied in headers could also be forged.
Solution
offon also serves as an OAuth 2.1 authorization server and accepts identity only from the token. Employees use the existing Slack login, and writes stay within the requester's permissions. Employees can use 21 tools with one login and no installation or API key.

Leave requests arriving at the same time

Problem
When the agent handled leave in Slack on an employee's behalf, the same request could arrive twice. Two simultaneous requests to cancel the same leave both succeeded, taking the used leave balance from 1 day to −1 day.
Solution
I also reproduced two requests for the same day both going through with only one day of leave left. Now only one of the overlapping requests is processed and the other is rejected as a conflict. I added 9 checks that run through the API routes against a real PostgreSQL database. In the same reproduction, the second request is rejected with 409.

A feature users could not find

Problem
Task assignment rules lived only on the server, so users could not find the feature on screen and only saw errors.
Solution
I surfaced the rules in the interface too. I now treat a feature people cannot find as a missing feature. Fixed on the day it was reported.