Schema Database Completo¶
PostgreSQL
italiasushi_db— 28 tabelle, server 209.38.215.154
SITO .154
Diagramma Relazioni¶
erDiagram
CONTACTS ||--o{ LEADS : ha
CONTACTS ||--o{ QUOTES : riceve
CONTACTS ||--o{ APPOINTMENTS : prenota
CONTACTS ||--o{ TICKETS : apre
CONTACTS ||--o{ OTP_CODES : richiede
CONTACTS ||--o{ WA_MESSAGES : scambia
PRODUCTS ||--o{ LEADS : genera
PRODUCTS ||--o{ QUOTE_ITEMS : incluso_in
QUOTES ||--o{ QUOTE_ITEMS : contiene
QUOTES ||--o{ COMMISSIONS : genera
QUOTES ||--o{ SUPPLIER_REQUESTS : richiede
SUPPLIERS ||--o{ SUPPLIER_REQUESTS : riceve
USERS ||--o{ NOTIFICATIONS : riceve
Tabelle Principali¶
contacts¶
Rubrica clienti e contatti interni — usata per Dynamic Identity Mapping
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| name | VARCHAR | Nome completo |
| display_name | VARCHAR | Nome visualizzato dal bot (priorita 1) |
| VARCHAR | ||
| phone | VARCHAR | Formato originale |
| phone_normalized | VARCHAR | Solo cifre (393337708642) |
| company | VARCHAR | |
| role | VARCHAR | |
| source | VARCHAR | internal, web, whatsapp |
| is_internal | BOOLEAN | true = staff, false = cliente |
| whatsapp_pushname | VARCHAR | Nome da WhatsApp (priorita 2) |
| status | VARCHAR | active, inactive |
| created_at, updated_at | TIMESTAMP |
products¶
Catalogo 70 prodotti sushi robot — sincronizzato col bot ogni ora
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| product_id | VARCHAR | ID esterno |
| product_name | TEXT | Nome prodotto |
| product_name_en | TEXT | Nome inglese |
| sku | VARCHAR | Codice articolo |
| brand | VARCHAR | 18 brand (Autec, Suzumo, ecc.) |
| category | VARCHAR | |
| subcategory | VARCHAR | |
| description | TEXT | |
| image_url | TEXT | |
| source_url | TEXT | |
| tags | ARRAY | |
| specs | JSONB | Specifiche tecniche |
| status | VARCHAR | active, draft, archived |
| added_by | VARCHAR | |
| created_at, updated_at | TIMESTAMP |
quotes¶
Preventivi generati dal CRM
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| quote_number | VARCHAR | Numero progressivo |
| agent_id | INTEGER FK | users.id |
| contact_id | INTEGER FK | contacts.id |
| status | VARCHAR | draft, sent, accepted, rejected |
| subtotal | NUMERIC | |
| discount_percent | NUMERIC | |
| discount_amount | NUMERIC | |
| total | NUMERIC | |
| notes | TEXT | Visibili al cliente |
| internal_notes | TEXT | Solo admin |
| valid_until | DATE | |
| hash | UUID | Link pubblico preventivo |
| accepted_at | TIMESTAMP | |
| created_at, updated_at | TIMESTAMP |
quote_items¶
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| quote_id | INTEGER FK | quotes.id |
| product_id | INTEGER FK | products.id |
| product_name | TEXT | Snapshot nome |
| quantity | INTEGER | |
| unit_price | NUMERIC | Prezzo vendita |
| supplier_price | NUMERIC | Prezzo fornitore |
| margin | NUMERIC | Margine calcolato |
| notes | TEXT |
leads¶
Pipeline vendita
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| contact_id | INTEGER FK | contacts.id |
| product_id | INTEGER FK | products.id |
| type | VARCHAR | inbound, outbound |
| message | TEXT | Richiesta originale |
| budget | VARCHAR | |
| status | VARCHAR | new, contacted, qualified, won, lost |
| priority | VARCHAR | low, medium, high |
| assigned_to | VARCHAR | |
| follow_up_date | DATE | |
| created_at, updated_at | TIMESTAMP |
tickets¶
Richieste di supporto
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| phone | VARCHAR | |
| issue | TEXT | Descrizione problema |
| status | VARCHAR | open, in_progress, resolved |
| created_at | TIMESTAMP |
appointments¶
Appuntamenti e demo
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| contact_id | INTEGER FK | |
| phone | VARCHAR | |
| contact_name | VARCHAR | |
| date | DATE | |
| time | VARCHAR | |
| type | VARCHAR | demo, meeting, call |
| notes | TEXT | |
| status | VARCHAR | confirmed, cancelled, completed |
| created_at | TIMESTAMP |
knowledge¶
Base di conoscenza per il bot AI
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| rule | TEXT | Regola/informazione |
| source | VARCHAR | manual, training, auto |
| category | VARCHAR | faq, product, policy |
| active | BOOLEAN | |
| created_at | TIMESTAMP |
otp_codes¶
Codici OTP per login Area Clienti
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| phone_normalized | VARCHAR | Numero cliente |
| code | VARCHAR(6) | Codice 6 cifre |
| expires_at | TIMESTAMP | Scadenza (5 min) |
| used | BOOLEAN | Gia utilizzato |
| created_at | TIMESTAMP |
wa_messages¶
Messaggi WhatsApp sincronizzati dal bot
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| session_id, contact_id | Link a contatto | |
| role | VARCHAR | user, assistant |
| message | TEXT | Corpo messaggio |
| metadata | JSONB | Dati extra |
| created_at | TIMESTAMP |
system_stats¶
Contatori giornalieri (persistenti, non RAM)
| Colonna | Tipo | Note |
|---|---|---|
| id | SERIAL PK | |
| stat_date | DATE UNIQUE | Un record per giorno |
| messages_in | INTEGER | Messaggi ricevuti |
| messages_out | INTEGER | Messaggi inviati |
| messages_total | INTEGER | Totale |
| contacts_new | INTEGER | Nuovi contatti |
| contacts_active | INTEGER | Contatti attivi |
| ai_requests | INTEGER | Richieste AI |
| errors | INTEGER | Errori |
| created_at, updated_at | TIMESTAMP |
Tabelle Secondarie¶
| Tabella | Funzione |
|---|---|
commissions |
Commissioni agenti su preventivi |
suppliers |
Anagrafica fornitori |
supplier_requests |
Richieste prezzo a fornitori |
emails |
Storico email inviate |
email_templates |
Template email (preventivi, follow-up) |
notifications |
Notifiche push/email admin |
events |
Tracking eventi sito web |
page_views |
Analytics pagine sito |
monitored_urls |
SEO: URL monitorati per meta/h1 |
chat_history |
Storico chat sessioni |
scrape_log |
Log scraping prodotti brand |
scraper_logs |
Log dettagliato scraper |
product_videos |
Video prodotti |
product_video_relation |
Relazione prodotto-video |
video_queue |
Coda elaborazione video |
todos |
Task interni admin |
users |
Utenti admin panel (JWT auth) |
REGOLA D'ORO SQL
VIETATO usare template literals nei placeholder:
// SBAGLIATO
pool.query(`SELECT * FROM contacts WHERE id = ${id}`)
// GIUSTO
pool.query('SELECT * FROM contacts WHERE id = $' + '1', [id])