How radekhulan/myinvoice works
1. System shape
MyInvoice.cz is a self-hosted accounting/invoicing system with two main runtime parts: a PHP 8.5 backend API and a Vue 3 frontend SPA. The backend owns all business logic, persistence, file processing, background jobs, and integrations; the frontend is mostly a client for the REST API.
2. Request entry and web tier
HTTP traffic enters through api/public/index.php, which boots the app and routes requests via Slim 4. The frontend is served separately from web/ as a compiled Vite application. The repo also supports Apache/nginx deployment and Dockerized runtime variants.
3. Backend layering
The backend is organized into clear layers: Action classes implement endpoints, Middleware enforces request policies, Service classes contain domain logic, and Repository classes access MariaDB. This is the main boundary to show in a diagram: controllers/actions on top, services in the middle, repositories and infrastructure at the bottom.
4. Core domain subsystems
The domain is not generic CRUD; it is centered on accounting workflows:
- issued invoices and attachments
- purchase invoices
- clients, projects, suppliers
- bank statements and payment matching
- documents and folders
- recurring invoices, approval flows, work reports
- CRM/dashboard summaries
- tax/reporting outputs
- admin/maintenance tools
5. Persistence and multi-supplier model
Data lives in MariaDB 10.6+ via migrations under db/migrations. The app is explicitly multi-supplier: one installation can manage multiple companies, with supplier-scoped data such as invoices, clients, numbering, branding, bank accounts, and AI credentials. Repository classes map directly to these tables and isolate most data access from business logic.
6. File and document pipeline
A major subsystem is file handling under api/src/Service/Document and api/src/Action/Document. Uploaded PDFs, images, XML, ZIPs, and office files are stored in the app’s data volume, extracted, thumbnailed, indexed for fulltext search, and optionally linked back to invoices, clients, or projects. This subsystem is separate from pure database records and has its own storage/backup logic.
7. Automation and background processing
Operational work is done by CLI scripts in api/bin/ and wrappers in cmd/. These cover cron jobs such as reminders, backups, bank scans, recurring invoice generation, inbox scanning for purchase invoices, and version checks. There is also an admin UI for monitoring cron health, so background processing is a first-class subsystem, not an implementation detail.
8. Import and external data ingestion
Incoming data comes from several sources:
- ARES/VIES for company and VAT lookup
- Bank email notices and bank statement files for payment matching
- PDF/ISDOC/Pohoda XML for purchase invoice import
- optional Anthropic AI extraction for scanned PDFs
- Fakturoid/iDoklad synchronization
These flows typically enter through dedicated actions, pass through parsing/enrichment services, and end in repositories plus file storage.
9. Outbound generation and compliance outputs
The system generates multiple output formats: PDF invoices, QR payments, email messages, ISDOC, Pohoda XML, EPO XML for tax filings, and CSV/ZIP exports. Rendering is handled in service classes and Twig templates, while schema validation against XSDs is part of the reporting/export pipeline.
10. Security and access boundaries
Access control is enforced in middleware and services: session auth, API tokens, CSRF, RBAC, TOTP 2FA, IP allowlists, rate limiting, and first-run lockout. Sensitive secrets like AI keys and TOTP secrets are encrypted, and audit/activity logging records mutations. Public approval/work-report pages are separate tokenized flows with CAPTCHA.
11. Frontend structure
The Vue app mirrors the backend domains with API modules and page groups for invoices, purchase invoices, documents, reports, admin, bank, CRM, logbook, tax, and settings. Shared UI components include charts, forms, modals, layout shells, and a global supplier switcher, which reflects the backend’s supplier-scoped model.
12. Runtime packaging and storage
The repo supports both Docker and native deployment. In Docker, the app runs with a single stateful /data volume in newer layouts, plus MariaDB and optional Redis. Redis is used for brute-force protection and cache when available, otherwise MariaDB fallbacks are used. Generated manuals, PDFs, and app state are part of the deployment lifecycle.
13. Validation and confidence boundaries
The tests reinforce the architectural seams: there are unit and integration tests for parsers, export schemas, signing, security, and repository behavior, plus architecture tests that guard important domain constraints. That suggests the system is designed around stable service boundaries and data-shape validation, especially for financial outputs.
14. Suggested diagram framing
A clear architecture diagram would show:
- Browser/User → Vue SPA
- Vue SPA → PHP Slim API
- API → Services → Repositories → MariaDB
- API/CLI services → file storage / PDFs / imports / exports
- API/CLI services ↔ external systems (ARES, VIES, SMTP, Anthropic, bank sources, Fakturoid/iDoklad)
- cron/CLI workers running alongside the API and updating the same DB/storage.
Main entry points: Service Services · main.ts Frontend SPA · bin CLI Workers · api API Modules
Components 16
Vue SPA
Client-side application and UI modules.
- Users · People using the invoicing system.
- Frontend SPA · Vue 3 single-page app served from web/.
web/src/main.ts - Domain Pages · Page groups for invoices, documents, reports, admin, bank, CRM, and settings.
web/src/pages - API Modules · Frontend API clients that mirror backend domains.
web/src/api
PHP API
Slim-based backend with layered domain services.
- API Entry · Public entrypoint and Slim bootstrap for HTTP requests.
api/public/index.php - Routes · Request routing and endpoint wiring.
api/src/Routes.php - Middleware · Auth, CSRF, supplier scope, rate limiting, TOTP, and allowlists.
api/src/Middleware - Actions · Endpoint handlers for invoices, imports, reports, bank, documents, admin, and public flows.
api/src/Action - Services · Core accounting, import/export, document, mail, signing, tax, and background services.
api/src/Service - Repositories · Persistence layer mapping domain entities to MariaDB tables.
api/src/Repository - Infra Layer · Config, database, cache, and HTTP utility infrastructure.
api/src/Infrastructure
Ops & Runtime
CLI workers, packaging, and deployment support.
- CLI Workers · Background jobs and operational scripts run via api/bin and cmd wrappers.
api/bin - Deployment · Docker, native startup, web server config, and runtime packaging.
docker-compose.yml
Data & Integrations
Persistent storage, file pipeline, and external systems.
- MariaDB · Primary durable data store for suppliers, invoices, documents, reports, and jobs.
db/migrations - File Storage · Document, PDF, backup, and attachment storage on the app volume.
api/src/Service/Document - External Systems · Ares/VIES, SMTP, Anthropic, bank sources, and Fakturoid/iDoklad.
Connections 20
- Users → Frontend SPA: uses · Users interact with the SPA in the browser.
- Frontend SPA → API Modules: calls · UI pages use generated/handwritten API clients.
- API Modules → API Entry: HTTP · Frontend clients call the backend REST API.
- API Entry → Routes: boots · Slim boots and dispatches through the route table.
- Routes → Middleware: guards · Requests pass through auth and policy middleware.
- Middleware → Actions: permits · Authorized requests reach endpoint handlers.
- Actions → Services: orchestrates · Actions delegate business logic to domain services.
- Services → Repositories: reads/writes · Services use repositories for persistence.
- Repositories → MariaDB: sql · Repositories map domain state to MariaDB.
- Services → File Storage: stores files · Document, PDF, import, and backup flows use file storage.
- Services → External Systems: integrates · Services call registries, mail, AI, banks, and accounting sync systems.
- CLI Workers → Services: runs jobs · CLI scripts invoke the same domain services as HTTP flows.
- CLI Workers → Repositories: updates · Background processing mutates shared database state.
- CLI Workers → File Storage: backs up · Cron jobs and import workers manage file artifacts and backups.
- Deployment → API Entry: hosts · Container/native deployment starts the PHP API.
- Deployment → Frontend SPA: serves · Compiled frontend assets are served separately.
- MariaDB → Infra Layer: configured by · Infrastructure layer manages connection and runtime configuration.
- Infra Layer → Services: supports · Config, cache, and DB utilities underpin service execution.
- Domain Pages → API Modules: binds to · Pages are organized around domain-specific API clients.
- Frontend SPA → Domain Pages: renders · SPA routes render the application screens.