Wiki
Architettura di QuoteNode
Panoramica tecnica dell'architettura del sistema QuoteNode: backend, frontend, database e modello di deployment.
Architettura di QuoteNode
QuoteNode e un’applicazione single-tenant progettata per deployment self-hosted. Ogni istanza e isolata e contiene il proprio database, file storage e processi applicativi.
Panoramica di sistema
Browser client
│
▼
Caddy (Reverse Proxy, HTTPS)
│
├── /api/* → Backend Spring Boot (Java 25)
├── /offer/* → Backend Spring Boot (pagine pubbliche offerta)
└── /* → Frontend Vue 3 (Vite, SPA)
│
▼
PostgreSQL 16
Backend
Il backend e un’applicazione Java 25 costruita con Spring Boot 4. Gestisce:
- REST API - tutta la logica di business esposta tramite endpoint versionati
- Authentication - sessioni con cookie cifrati e 2FA basata su TOTP
- Authorization - controllo accessi per ruolo con verifiche per endpoint
- Database access - Spring Data JPA con migrazioni Flyway
- PDF generation - template Thymeleaf renderizzati in HTML e convertiti in PDF da Gotenberg
- Email - integrazione SMTP asincrona con retry e logging
- Public offer pages - HTML server-rendered per link offerta rivolti al cliente
- Audit logging - tracciamento append-only delle mutazioni
- Scheduling - job in background per scadenza offerte, anonimizzazione IP e digest notifiche
Decisioni chiave di design:
- No multi-tenancy - l’applicazione serve una sola organizzazione. Questo elimina la complessita di isolamento tenant e semplifica il ragionamento sulla sicurezza.
- Flyway migrations - i cambi schema sono solo additivi. Le colonne non vengono eliminate; vengono rinominate con prefisso
deprecated_. - Immutable snapshots - i dati offerta vengono catturati come snapshot JSON al momento dell’invio. I PDF sono sempre renderizzati dagli snapshot, mai da dati live.
- Deterministic pricing - tutti i calcoli seguono un ordine definito con arrotondamento configurabile. I risultati vengono memorizzati per audit.
Frontend
Il frontend e una single-page application Vue 3 costruita con Vite:
- UI framework - libreria componenti PrimeVue 4
- Styling - Tailwind CSS 4
- State - store Pinia 3
- Routing - Vue Router 5 con route guard per ruolo
- i18n - vue-i18n con supporto attivo per inglese, polacco, tedesco, francese, spagnolo, italiano e portoghese
- API client - client HTTP tipizzato che chiama la REST API backend
Il frontend viene servito come asset statico da Caddy e comunica con il backend esclusivamente tramite API REST.
Database
PostgreSQL 16 e l’unico database supportato:
- Schema management - migrazioni Flyway eseguite all’avvio del backend
- Key entities - customers, contacts, offers, offer items, products, pricing rules, users, audit logs e notifications
- Denormalization - i totali offerta vengono salvati in una tabella dedicata per query veloci
- Views - una vista pipeline con lateral join sugli ultimi tassi FX
Generazione PDF
La generazione PDF usa una pipeline a due stadi:
- Thymeleaf renderizza lo snapshot offerta in un documento HTML con CSS inline
- Gotenberg, container basato su Chromium, converte quell’HTML in un PDF pronto per la stampa
Sono supportate due modalita:
- Synchronous - per offerte con meno di 50 righe, il PDF viene generato inline
- Asynchronous - per offerte grandi, un job in background genera il PDF e notifica l’utente quando e pronto
Deployment
QuoteNode viene distribuito con Docker Compose:
- Backend container - Java 25 su Eclipse Temurin
- Frontend container - Node 24 + Vite in sviluppo o build statica in produzione
- Database container - PostgreSQL 16
- Reverse proxy - Caddy 2 con HTTPS automatico
- PDF engine - Gotenberg
- Mail testing - Mailpit, solo in sviluppo
L’intero stack gira come un singolo progetto Docker Compose senza dipendenze esterne obbligatorie. Puo funzionare anche in ambienti air-gapped.
Licenze
Le licenze sono file firmati Ed25519 verificati offline. Il sistema controlla:
- edizione, come Free, Pro, Business o Enterprise
- numero massimo utenti
- data di scadenza
- feature flag, come white-label o template avanzati
Non viene contattato alcun license server esterno. Una licenza scaduta non disabilita funzioni; l’unico effetto e un badge Powered by QuoteNode sulle superfici rivolte al cliente e un promemoria di rinnovo in interfaccia.