Featured Work AZ Consulting CRM Internal platform · Under NDA

AZ Consulting GmbH CRM

Developed as a solo developer project for AZ Consulting GmbH. The system is used internally by 4 end users (3 employees and 1 manager) for daily operations.

A role-aware CRM aligned with how AZ Consulting works — across MPU assessments, Verfahrensbeistand mandates (child advocacy & family court), and sworn translations. It replaced an outdated ASP.NET / SQL Server system with a React & Node.js SPA over roughly three weeks, including a structured migration of existing clients, cases, and documents (1,000+ records, 20,000+ files, ~19 GB), plus GoBD-oriented invoicing and a unified dossier ledger. Cutover was rehearsed on test data before go-live.

Role Lead Full-Stack Developer (solo-built project)
Timeline ~3 weeks build · in use since 2026
Status Internal · 4 users (3 staff + 1 manager)
1,000+ client records Migrated from legacy system
20,000+ documents Re-linked across 19 GB
3 practices MPU · VB & Gericht · Übersetzungen
— at cutover No loss reported (reconciled)
GoBD billing Immutable invoices · unified ledgers
~3 weeks Concept → handover
01
Context

Legacy tools that no longer matched daily work

AZ Consulting GmbH runs three separate practice areas under one roof — MPU assessments, Verfahrensbeistand work (child advocacy and family-court representation, including Jugendamt coordination), and sworn translations. Each practice has its own workflows, documents, and deadlines. Four internal users (3 employees + 1 manager) needed a platform that reflected those differences instead of forcing a single generic shape onto all three.

The legacy system had been in use for years, but it no longer matched daily work. Searching for a client took multiple clicks where a typed query would have been enough. Court dates lived apart from case files. Translator assignments lived in spreadsheets. Audit trails were missing or too noisy to use reliably. The brief was to build a CRM around how those four users work — and migrate existing clients, cases, and documents into it.

  • One platform for three different practices, side by side
  • A migration path designed to avoid disrupting active client cases
  • Search and filters that match how staff look for records
  • Automated backups with status visible in the UI
  • An audit trail scoped per workflow — not one tangled global event log
02
Foundation

Planned migration from the start

The new CRM had to launch with existing clients, cases, and documents already migrated — without running parallel systems or catching up later. Migration was treated as a core feature: planned and verified end-to-end before go-live.

  1. W1

    Mapping how the team works

    Before writing code, I mapped daily work with the four internal users (3 employees + 1 manager) — how MPU files flow, what makes a court case different from a translation job, and where the legacy system slowed them down. The new data model was designed around those workflows, not around the database being replaced.

  2. W2

    Developing the platform, moving the data

    Module by module, the platform was built: client records, case files, documents, calendar, search. In parallel, the migration pipeline was rehearsed against test copies of the old database until record counts matched, documents were re-linked, and financial history was reconciled against the legacy totals.

  3. W3

    Weekend cutover and Monday go-live

    Cutover ran over a weekend. By Monday morning, more than 1,000 client records and 20,000+ documents (around 19 GB) were in the new system — with the legacy system kept read-only for a week as a fallback. After handover, the 4 internal users continued client work in the new CRM.

03
Operations

Central dashboard — KPIs and live operational overview

The dashboard is the daily entry point: open work, appointments, and selected financial indicators in one place — filtered by role so staff see what they need for operations without exposing executive-only figures.

Live operational overview

Counts and lists for open dossiers, appointments due today, and outstanding tasks are loaded from the same APIs used in the modules — not a separate reporting database.

RBAC on revenue KPIs

AGENT users see operational widgets only. Revenue / Umsatz KPIs stay on the server behind ADMIN checks — hiding a chart in the UI is not treated as access control.

Hybrid OPOS monitoring

Open-item (OPOS) status combines invoice ledger balances with dossier-level rest amounts, so overdue and partially paid cases surface next to the operational queue.

Same numbers as the dossier

KPI tiles reuse the dossier ledger math (Vertragssumme, paid, Restbetrag). Admins do not get a second, divergent finance view.

04
Practice

MPU Management, structured around the case

Medical-psychological assessments are paperwork-heavy and deadline-sensitive. A case can carry weeks of correspondence, expert reports, scheduling, and document dependencies. The MPU module keeps related material under a single client view so documents and deadlines are easier to track together.

Case timeline per client

Meetings, documents, deadlines, and status updates for an MPU case are shown on a single timeline, so context does not have to be rebuilt from email threads or other systems.

Document workflows that match reality

From intake through the final assessment, the document set required for each MPU stage is tracked automatically. Missing files surface as prompts, which makes gaps easier to notice earlier in the process.

Deadlines in the shared calendar

Submission deadlines, follow-up reminders, and linked court dates sit in the integrated calendar — one place to check, without a separate reminder tool.

Role-scoped access for sensitive MPU data

MPU records are sensitive. Access is scoped per role, and documents are served through an authenticated proxy so direct file URLs are not exposed to the browser.

1 Case data, documents, dates, and the audit trail live in one module view.

05
Practice

VB & Gericht — mandates, hearings, and parties

Verfahrensbeistand work depends on careful coordination — between the child whose interests are represented, the parents on each side, the Jugendamt (Youth Welfare Office), and the family court. The VB & Gericht module gives the team a structured view of active mandates and the parties involved.

Parties linked to the mandate

Each mandate stores its constellation — child, both parents, Jugendamt contacts, court file references — as first-class records on the case, so details do not have to be reconstructed from scattered notes.

Hearings and case file, side by side

Family-court hearings, conciliation appointments, and home visits are linked directly to the mandate. Opening one also surfaces the related documents, parties, and prior history.

Jugendamt correspondence on the mandate

Incoming and outgoing communication with the Jugendamt is stored against the mandate it belongs to, which reduces the need to reconstruct context from inboxes.

Report deadlines on the calendar

Verfahrensbeistand report deadlines appear in the integrated calendar, with the case file one click away when writing the report. Reschedules update linked entries to reduce orphan dates.

06
Practice

Allgemeine Beratung — lightweight consulting dossiers

Not every mandate needs MPU stages or court party graphs. Allgemeine Beratung keeps a separate, thinner dossier type for general consulting work — with soft-delete so closed files can be removed from daily lists without hard-erasing history.

Separate from heavy workflows

Consulting dossiers stay outside the MPU document pipelines and VB/Gericht party models, so the UI and validation stay proportional to simpler cases.

Soft-delete support

Records can be soft-deleted (hidden from default lists, retained for audit/recovery) instead of immediate hard delete — aligned with how the rest of the CRM treats sensitive client data.

07
Practice

Sworn translations, from request to delivery

Translation work has its own workflow: external sworn translators, language pairs, certified documents, billing per page. The Übersetzungen module is built around that model instead of forcing it into a generic case shape.

Translator directory

Sworn translators used by the consultancy — with language pairs, availability, and assignment history — are kept in a directory so assignments do not require searching old emails.

Per-document tracking

Each document follows its own path: incoming, assigned, translated, certified, delivered. Status is visible from related cases.

Separate translations module

Translations are managed as standalone records with their own appointments and client data, kept separate from MPU and court cases.

Billing fields stored on the document

Pages, language pair, certification status, and translator fee live with the document itself, so invoicing has the line-item data available and changes stay traceable.

08
Practice

Dolmetscher — court interpreter files

Court interpreting is handled as its own domain — not folded into sworn translations. Interpreter dossiers track court associations, hearing schedules, and a dedicated document vault for that workflow.

Court associations

Each interpreter file can store linked courts and file references so assignments stay attached to the right Gericht without reconstructing context from mail.

Scheduling for hearings

Interpreter appointments link into the shared planning calendar, filtered as their own practice so they do not drown in MPU or VB dates.

Dedicated document vault

Documents for interpreter work live under the Dolmetscher dossier with the same authenticated proxy path used elsewhere — isolated from translation and MPU vaults at the record level.

Isolated domain

Separating interpreters from Übersetzungen keeps language-pair / page billing models from colliding with court-session logistics.

09
Internal planning

Interne Planung — week grid, boards, and calendar sync

Beyond case-linked appointments, the sidebar module Interne Planung covers operational week planning: a KW week grid, internal spreadsheet-style boards, and token-gated iCal/Webcal feeds for external calendar apps.

KW week grid

Staff plan by calendar week (KW). The grid shows capacity and appointments across practices without leaving the CRM for a separate spreadsheet.

Internal planning boards

Spreadsheet-style boards hold internal planning rows (staff, slots, notes) that are not the same as client case files — kept for operational coordination inside the authenticated app.

Token-gated iCal / Webcal

External apps (Outlook, Google Calendar, Apple Calendar) can subscribe via iCal/Webcal URLs gated by per-user tokens — so a shared public calendar URL is not required.

Case-linked appointments remain

Module appointments (MPU, court, interpreters, translations) still carry client/case context. Reschedule updates linked reminders so orphan dates are less likely.

10
Findability & Accountability

Search, filters, and audit trails

Finding records quickly and seeing who changed what were treated as core features, not late add-ons.

  • Global search across clients, cases, documents, calendar entries, and translator records — ranked by relevance, with the module label attached to each hit.
  • Contextual filters per module — tables use filter sets built around how that practice works, rather than one generic search box for everything.
  • Saved views for recurring queries — open MPU files, this-week court dates, undelivered translations — so common filters do not have to be rebuilt each morning.
  • Module-scoped audit trails: actions are logged inside the module they belong to, so changes on a specific MPU case can be reviewed without wading through unrelated events.
  • Append-only audit log — entries are not edited in place; each change records user, IP, and what changed.
11
Internal communication

AZ-Chat — real-time staff messaging

AZ-Chat is the internal messaging channel for the four users. It runs on Socket.io inside the authenticated app and is kept strictly separate from client dossier files and from the AI assist path.

Socket.io real-time delivery

Messages push over Socket.io so staff do not need to refresh to see new replies during the workday.

Unread state

Unread counts are tracked per conversation so open threads stay visible in the sidebar without scanning every channel.

Image sharing

Staff can share images in chat for quick operational context (screenshots, photos). Uploads stay on the chat path — not written into client document vaults.

Isolation from client files

Chat payloads do not include dossier documents or ledger data. Client files remain behind the document proxy and module APIs.

12
Finance

GoBD invoicing, a dynamic tax engine, and one ledger per dossier

Billing is integrated into the case workflow. Invoices, tax modes, payments, and dossier balances share one financial path — with GoBD-oriented rules in both the UI and the API. The same platform also includes a dossier AI assistant with human-in-the-loop write-back. Cashbook-style POS (Z-Bon) is intentionally out of scope for this phase.

GoBD-oriented invoicing & immutability

Once issued, invoices are locked. BEZAHLT and STORNIERT records are immutable; Rechnungsnummer and invoice dates cannot change after release. A partial-payment floor guard blocks any total that would fall below paidAmount — frontend and backend — to reduce the risk of collected amounts and document totals drifting apart.

Master–slave dynamic tax engine

Custom tax logic for Brutto, Netto, and Steuerfrei (0%). A global tax mode drives position rates while still allowing row-level overrides — for example 0% on pass-through court fees (Durchlaufende Posten). Exemption-reason fields (Befreiungsgrund) appear only when the UI state needs them.

Dynamic PDFs & conditional legal footnotes

Invoice PDFs stream from the API with safe filenames. Mandated tax footnotes — §19 UStG, §4 UStG, §13b reverse charge — render only when the tax rate is exactly 0%. Misleading “0,00 € tax” lines are suppressed so the document stays legally clean.

Unified dossier cashbook

Payments are not kept in a separate cashbook. Bar, EC-Karte, and Überweisung payments post against an invoice and recalculate Vertragssumme, Bezahlt bis jetzt, and Restbetrag. Each financial event is also written to the case Verlauf so money and timeline stay aligned.

Dossier financial rollups

Dossier-level rollups of outstanding balances and recent payments — the same ledger figures used on each Akte. Executive Umsatz KPIs for the whole firm live on the role-gated dashboard, not as a second finance database.

AI-assisted dossier intelligence

Context-aware assistant (DossierAiAssistant) inside MPU, Court, and Translation dossiers (Gemini Flash Lite). Staff can ask about the open dossier, request document summaries, and review suggested fields — with human-in-the-loop write-back only.

Document vault

Drag-and-drop uploads with auto-compression and authenticated previews, so files stay in the same platform as the case and the invoice.

1 One financial path per dossier: locked invoices, conditional tax footnotes, and payments that update the balance.

13
Governance

Admin & settings — users, audit, letterhead, legal sync

Administrative controls sit in a dedicated sidebar area: user accounts, cross-domain audit logs, company letterhead for PDFs, and legal-text sync with the public marketing site.

User management

Admins manage accounts and roles for the small internal team (ADMIN / AGENT) without a separate identity tool.

Granular audit logs

Audit entries remain domain-scoped (module + action + user + IP) and can be reviewed from admin without mixing unrelated event streams.

Company profile & letterhead

Company profile fields and letterhead assets feed invoice and document PDFs so letterhead stays consistent across issued files.

Legal text sync (az-zangana.de)

Impressum and Datenschutz texts can sync automatically with the public marketing site az-zangana.de, reducing drift between CRM footers/PDFs and the public legal pages.

14
Technical implementation

Selected technical details

Alongside the practice modules: data modeling, document handling, DSGVO-oriented file access, and a server-side AI assist path with human-in-the-loop write-back.

Linked follow-up cases (Folgeakte)

Implemented a self-referential relation (parentCaseId via Prisma) for linked follow-up dossiers. Repeat clients are grouped in the UI with a +N pill to reduce duplicate rows.

Paginated document loading

Used server-side pagination and bounded eager loading for 20,000+ files (~19 GB legacy data), keeping list views responsive during migration and daily use.

Document access via proxy (DSGVO-oriented)

Sensitive documents are served through authenticated proxy middleware so direct Linux file paths are not exposed in public URLs.

Server-side AI assist pipeline

Document uploads use a hybrid parse path (pdf-parse, mammoth, xlsx) with Gemini Vision fallback for scans. AI calls run behind JWT auth with aiWalletLimiter (~15 req/min per user). Suggestions are shown to staff first; only approved values are written back.

15
Security & Data Protection

Layered protection for sensitive client and document data

The CRM handles sensitive client data, court documents, and MPU files. Security was built into the architecture — with role-based access control, protected document access, server-side validation, and controlled interfaces — rather than added as an afterthought.

Authentication & role-based access

Access and refresh tokens authenticate sessions; the refresh token is stored in a secure cookie. Roles (ADMIN, AGENT) are checked on the server. Permissions are not only hidden in the UI — they are enforced on API routes.

Protected document access

Documents are not served from public upload directories. Access goes through authenticated server endpoints. Direct server paths are not exposed to the browser; path traversal and unauthorized file access are blocked. This covers the 20,000+ migrated documents as well as new uploads.

Rate limiting & API protection

Separate rate limits protect critical paths: loginRateLimiter reduces brute-force risk on login, invoicePdfLimiter caps expensive PDF generation, and aiWalletLimiter keeps AI usage within cost and resource bounds (~15 requests/min per authenticated user).

Input validation & application security

Prisma uses parameterized queries, which helps reduce SQL injection risk. Zod validates inputs and configuration. Helmet and CSP-oriented security headers strengthen the web application surface.

Audit trails & traceability

Critical actions — such as payments, record changes, and security-relevant events — are logged with user, timestamp, and context. These trails support internal review and operational accountability.

16
Reliability

Automated backups to reduce manual maintenance

Client data is critical. Backups run automatically; the admin can also export on demand — with status visible in the UI so the four users do not need server access to check.

Automated daily PostgreSQL snapshot

A scheduled job runs each night at 03:00, creates a PostgreSQL snapshot via pg_dump, and shows "last successful backup" in the UI — without requiring a manual server login.

Manual download, on demand

Administrators can download a current database export from the UI at any time. Useful before sensitive changes or for end-of-period archives.

Dual-layer HiDrive backups

Dual-layer Strato HiDrive sync: Aktuell holds a daily mirror of the live system; Archiv keeps older and deleted files. Archive persistence uses an atomic system_archiv path so recovery remains consistent if something is removed by mistake.

Restore drills before trusting a backup

Restore drills are scripted and run automatically. A backup is only treated as reliable after it has been rebuilt successfully into a clean environment and verified end-to-end.

21 Since handover, the four internal users (3 employees + 1 manager) work in one system instead of switching between spreadsheets and the legacy tool.

Have a role in mind?

Open to Full-Stack Web Development, IT-System Engineering, and freelance roles in Cologne / NRW or remote.