Reinover

From contract to invoice.

Freelance · solo

Built with

  • TypeScript
  • Next.js
  • tRPC
  • Drizzle ORM
  • PostgreSQL
  • Row Level Security
  • Redis
  • BullMQ
  • WebSockets
  • Clerk
  • Docker
Reinover's scheduler: a weekly grid of crews and appointments

The brief

Reinover runs a commercial cleaning company in Hannover contracts, recurring jobs, a field crew and monthly invoices. The day-to-day of a business like this usually scatters across spreadsheets, paper and phone calls. Reinover gathers it into one system, from contract to paid invoice. Designed and built single-handedly and live, in real use.

Reinover's operations cockpit: revenue, today's jobs, open items and live activity
The operations cockpit.

One platform, three apps

The platform

Three interfaces for three roles, from one codebase: a back-office for operators, a self-service portal for customers, and a mobile app for the cleaners on site. All share one type-safe API, one data model and one design system a single identity, no per-app drift.

The mobile field app on three phones: today's jobs, a job's detail with its task list, and notifications
The mobile app for the team on site — one of three interfaces from one codebase.

From job to invoice

Workflow

Contracts generate recurring jobs automatically. A planner proposes crews by skill, conflicts and workload; the cleaners complete their jobs in the app. Invoices follow generated automatically, rendered as PDFs, and tracked across their whole lifecycle to ‘paid’.

The scheduler with optimization suggestions that resolve conflicts and raise utilisation
Automatic crew suggestions for a job, scored by suitability and workload
The planner proposes crews by suitability, conflicts and workload — assignment in one click.

What runs when nobody is looking

Background

Invoices don't happen inside a web request. A separate service plans the runs, a Redis-backed queue works through them, and a renderer turns them into PDFs. Because this part handles money, every step sits behind an idempotency key: a repeated run doesn't produce a second invoice, and a payment attempt delivered twice doesn't book twice. Invoice numbers come from their own per-tenant sequence, so there are no gaps and no duplicates. Reminders and recurring billing go the same way.

Enterprise-grade, by one engineer

Under the hood

Under the surface, the platform behaves like enterprise software. A tRPC API with shared Zod schemas makes the API contract the type system, so the three apps can't drift apart. Business logic lives in its own domain layer, decoupled from the interface and testable on its own. Data access goes through Drizzle, sign-in through Clerk. Tenants are kept apart by Postgres row-level security, a per-request org context and consistently org-scoped queries, with a two-level, deny-by-default permission model on top. Live updates run through an outbox-backed, idempotent event relay into LISTEN/NOTIFY and WebSockets.

Four languages, including Arabic

Reach

The whole platform speaks four languages German, English, Arabic and Turkish with full right-to-left layout for Arabic and light and dark themes on every screen. From one design system, with no per-app exceptions. For a workforce as diverse as the city it serves.

The customer portal in dark mode: a completed job with tasks, notes and a rating
The customer portal in light mode: the overview with appointments, balance due and the latest invoice
The same interface in light and dark — from one theme-aware design system.