Projects
PEX — Invoicing & Time-Tracking SaaS
2025 – today
Invoicing SaaS, built solo: e-invoicing (XRechnung, ZUGFeRD), DATEV export, dunning, customer portal and iOS app. Laravel 13 + Nuxt, version 1.0 live since 2026.
- Laravel 13
- Nuxt
- Stripe Connect
- XRechnung / ZUGFeRD
- DATEV
- Capacitor iOS
- Pest
- Playwright
The product
PEX is invoicing and time-tracking software for freelancers, agencies and small businesses in the German-speaking market. The idea: everything that happens between “project started” and “money in the bank” in one tool — including the parts German businesses tend to forget until their tax advisor asks.
I built PEX as a solo developer: product concept, data model, API, web app, iOS app, marketing site, and operations. Version 1.0 shipped to production on 26 September 2026. The product website with features and pricing: pex-inventory.com.
What PEX does
Offer to invoice. Offers, invoices, credit notes, recurring invoices, plus progress and final invoices for longer projects. Invoices can be split, and number formats are configurable per client. Copy is edited with a rich-text editor (TipTap) — identical on the web and on the iPhone.
Projects, time, expenses. Time tracking per project, expenses, CSV bulk import with live progress, and a rearrangeable dashboard with an activity feed.
E-invoicing — both directions. PEX generates outgoing invoices as XRechnung 3.0 (UBL) or ZUGFeRD 2.x / Factur-X hybrid PDF/A-3 files. Before an invoice is finalised, the official KoSIT validator checks it — so errors surface before sending, not at the recipient. Incoming e-invoices are parsed, validated, archived tamper-proof, and land in a quarantine view when something is wrong instead of disappearing.
Tax logic that actually comes up. Small-business exemption (§ 19 UStG), reverse charge (§ 13b UStG), VAT ID verification via VIES, EU B2B invoices with the recapitulative statement, and OSS.
Dunning. Multi-level payment reminders with configurable fees and statutory late-payment interest (§ 288 BGB) — set per reminder level.
Payments and banking. Clients pay by card or SEPA direct debit via Stripe Connect — right in the customer portal or through a signed payment link with a QR code. Bank statements (CAMT.053, MT940) are imported and matched to open invoices automatically.
Tax-advisor access and DATEV. Tax advisors get their own role with read-only access to every client they look after, and export bookkeeping data in DATEV format (EXTF, SKR03/SKR04, debtor accounts) — with a preview before export.
Customer portal. A separate area where clients see their invoices, credit notes and payments, receive notifications, and pay outstanding amounts directly — in the issuing company’s branding.
Integrations. Outgoing webhooks and an n8n integration, so PEX fits into existing workflows instead of replacing them.
GoBD: auditability built in
Invoicing software in Germany must be able to prove nothing was changed after the fact (GoBD). PEX solves this in the architecture, not by convention:
- Finalisation — issued invoices are locked; corrections happen only through cancellation invoices.
- Hash-chained audit journal — every change references the previous one cryptographically; a verification command checks the whole chain.
- WORM archive — the final PDF is stored immutably with its SHA-256 checksum.
- Gap-free numbering — invoice numbers are assigned under a lock, never duplicated and never skipped.
Architecture
Visitor ──▶ Marketing site pex-inventory.com (Astro, Vercel)
│ sign-up
Team ──▶ Web app (Nuxt, Vercel) ──┐
Tax advisor ──▶ Advisor workspace ───────┤
Client ──▶ Customer portal ─────────┼──▶ API (Laravel 13, Forge) ──▶ MySQL · Redis
iOS ──▶ Capacitor app ───────────┘ │
┌──────────────────────┼──────────────────────┐
Horizon queues Stripe Connect S3 (WORM archive)
(e-invoicing, KoSIT, (subscriptions, card,
DATEV, imports) SEPA, webhooks)
- Separate auth domains — team users via Laravel Sanctum with per-token-type lifetimes, portal customers via a dedicated guard. Internal data and client access are separated in the infrastructure, not in
ifstatements. - Roles — admin, user and tax advisor; the advisor switches between clients without ever gaining write access.
- E-invoicing as its own package — XRechnung/ZUGFeRD generation, parsing and validation live in a separate Composer package with its own test suite and its own queue, so long validations never slow down the rest of the app.
- Real time — progress of imports and background jobs is streamed to the frontend over WebSockets.
- One codebase, two platforms — the Nuxt app ships as an iOS app via Capacitor.
- Operations — API on Laravel Forge with separate staging and production environments, frontend on Vercel, monitoring through Sentry, Pulse and Horizon.
How PEX gets built
PEX is also my lab for how a one-person team can ship at the pace of a small team. Development is ticket-driven in YouTrack; AI agents take on clearly scoped roles — product owner, development, QA and design — and I make the calls at fixed review gates: design, backlog approval, code review, release.
Every change takes the same path:
- Pull request with tests, checked in CI on a dedicated self-hosted runner (parallel Pest, MySQL and KoSIT contract suites, code style, dependency audit, type check).
- Staging — deployed automatically, then re-verified by QA against the running environment.
- Release — only after a full regression run on staging: tagged release, promotion to production, a check that production serves the expected commit, changelog and release notes.
By the numbers
| Metric | As of October 2026 |
|---|---|
| Backend tests (Pest) | 2,000+ |
| Frontend unit tests (Vitest) | 2,200+ |
| End-to-end tests (Playwright) | 80+ |
| API endpoints | ~330 |
| Merged pull requests | 650+ |
| CI/CD workflows | 9 |
Outcome
A production SaaS product with marketing site, web app, iOS app, customer portal and tax-advisor access — all from one pair of hands, including the German must-haves: e-invoicing, GoBD and DATEV. Exactly the project scope I deliver for clients: from an empty repository to a paying user.