Enable Evolu-based invoicing (companies, contacts, documents, expenses in the browser) on satflux.io production. Pair this guide with DEPLOYMENT.md and BUSINESS_INVOICING.md.
| Layer | Flag | Effect |
|---|---|---|
| Frontend (build-time) | VITE_INVOICING_LOCAL_FIRST=true |
SPA reads/writes invoicing via Evolu SQLite + E2EE relay; server invoicing CRUD APIs are bypassed for core data |
| Backend (runtime) | INVOICING_LOCAL_FIRST=true |
Company::usesServerInvoicing() returns false globally; WooCommerce inbox routing uses local-first paths |
Both flags should be on together in production. Mismatch causes confusing behaviour (e.g. WooCommerce hooks still writing server rows while the UI shows Evolu).
Optional:
VITE_EVOLU_RELAY_URL- WebSocket URL for Evolu sync/backup (defaultwss://free.evoluhq.com; seeresources/js/evolu/config.ts). Set at build time withnpm run build/./deploy.sh. Use a self-hosted relay in production if you do not want to depend onfree.evoluhq.com. Empty string disables relay sync (local-only SQLite).SEED_FIRST_REGISTRATION=true- recommended with local-first (unified 24-word recovery phrase)- Per-company override:
app_settings.local_firston acompaniesrow forces that company off server invoicing even when the global flag is false (legacy escape hatch)
The frontend flag is global (baked into the Vite bundle). There is no per-user runtime toggle.
Users who already have companies and documents only in PostgreSQL will see an empty Invoicing module after rollout until they:
- use Import from server on
/invoicing(one-time PG → Evolu import in the browser), or - restore the same Satflux recovery phrase on a device that already had Evolu data, or
- create new local companies from scratch.
Server rows are not deleted by the import. After verifying local data, users can remove legacy companies under Profile → Server companies.
| Endpoint | Purpose |
|---|---|
GET /api/invoicing/migration/status |
Counts of server-side companies/contacts/documents/expenses and expense attachments |
GET /api/invoicing/migration/export |
Full InvoicingDataSnapshot JSON for browser restoreInvoicingSnapshot (throttled 5/hour; attachments and branding off by default) |
GET /api/invoicing/migration/export-attachments |
Phase 2: expenseAttachment rows with contentBase64 when readable (max ~384 KB each; throttled 3/hour) |
CLI for support: php artisan invoicing:export-for-evolu {email} writes JSON to storage/app/private/.
- Guest - no Business Invoicing (BTCPay demo only).
- Free (verified email) - can buy Pro.
- Pro - unlocks Invoicing UI and ephemeral server bridges (PDF render, ISDOC extract, e-faktura, BTCPay checkout, bulk PDF import).
Local-first data stays in the browser; PRO unlocks the module and bridges.
- Sync uses WebSocket to the Evolu relay (default
wss://free.evoluhq.com). - Users must keep the same 24-word recovery phrase on every device.
- See BUSINESS_INVOICING.md - Multi-device sync.
These need PRO and hit Laravel briefly; data is not stored server-side long-term:
- PDF generation and e-mail send for invoices
- ISDOC field extraction from expense PDFs
- Bulk PDF expense import
- Excel export of expense list and attachment ZIP
- SK e-faktura inbound (when
EFAKTURA_ENABLED=true) - BTCPay checkout for invoice payment links
In .env.standalone (or your deploy ENV_FILE):
VITE_INVOICING_LOCAL_FIRST=true
INVOICING_LOCAL_FIRST=true
# Recommended with local-first onboarding
SEED_FIRST_REGISTRATION=true
# Optional: self-hosted relay instead of free.evoluhq.com
# VITE_EVOLU_RELAY_URL=wss://relay.yourdomain.exampleDo not commit production .env files. Back up the file before editing.
VITE_* variables are compiled into JS at npm run build time. Changing them requires a rebuild, not only php artisan optimize:clear.
./deploy.shdeploy.sh passes the deploy env file into the build step so VITE_INVOICING_LOCAL_FIRST from .env.standalone is baked into the bundle even if a stale .env exists on disk.
After any .env change (including INVOICING_LOCAL_FIRST):
docker compose -f docker-compose.standalone.yml --env-file .env.standalone exec php php artisan optimize:clear- Build flag - in browser devtools, open a built JS chunk or check Invoicing index for the local-first notice banner (
invoicing.local_first_notice). - Guest - sign in as guest: Invoicing nav item should be absent or gated (no Pro).
- Pro user - open Invoicing: companies load from Evolu; create company works after relay sync settles.
- Recovery phrase - sign out, restore with phrase on a second browser profile: companies appear after sync (wait up to ~45 s).
- WooCommerce (if used) - create document with
INVOICING_LOCAL_FIRST=trueroutes to inbox integration, not legacyBusinessDocumentrows. - Relay - browser Network tab: WebSocket to
wss://free.evoluhq.com(or yourVITE_EVOLU_RELAY_URL) connects without errors.
No extra nginx rules are required for the Evolu relay (browser connects outbound to wss://free.evoluhq.com). If you add a strict Content-Security-Policy, allow connect-src to your relay host.
Satflux Reverb (wss://your-domain/...) is separate from Evolu relay.
- Set
VITE_INVOICING_LOCAL_FIRST=falseandINVOICING_LOCAL_FIRST=falsein.env.standalone. - Run
./deploy.sh(rebuild frontend). - Run
php artisan optimize:clearin the PHP container.
Server PostgreSQL invoicing data from before rollout is unchanged (not deleted). Users who created data only in Evolu during local-first mode will not see it in server mode until you export/restore via recovery phrase again.
| Symptom | Likely cause | Fix |
|---|---|---|
| Invoicing still uses server API | Old JS bundle | Redeploy with VITE_INVOICING_LOCAL_FIRST=true and hard-refresh browser |
| Empty company list after login | Relay sync not finished or wrong phrase | Wait on index; confirm same recovery phrase; see multi-device runbook |
| Duplicate companies | Created company before sync completed | Delete duplicate in Company settings - Danger zone |
| WooCommerce creates server documents | INVOICING_LOCAL_FIRST false on server |
Set server flag + optimize:clear |
| Flags mismatch warning during deploy | Only one of the paired flags set | Align both flags in env file |
- BUSINESS_INVOICING.md - module overview, plan access, multi-device sync
- BUSINESS_EXPENSES.md - expenses and attachments
- DEPLOYMENT.md - Docker standalone stack