Permette di leggere i bounce dalla stessa MailIdentity SMTP, aggiornare le email in anagrafica e saltare gli indirizzi invalidi nei mailing. Co-authored-by: Cursor <cursoragent@cursor.com>
243 lines
7.5 KiB
Markdown
243 lines
7.5 KiB
Markdown
# eminuxCRM
|
||
|
||
CRM commerciale standalone focalizzato su una domanda:
|
||
|
||
> Cosa devo fare oggi per trasformare i miei prospect in clienti?
|
||
|
||
Applicazione Rails tradizionale (Hotwire / Turbo / Stimulus + Tailwind), pensata per poche persone, veloce da usare e semplice da mantenere. Completamente indipendente da MatchLiveTV.
|
||
|
||
## Architettura
|
||
|
||
- **Ruby on Rails 8** + **PostgreSQL 16**
|
||
- **Hotwire** (Turbo + Stimulus) — nessuna SPA
|
||
- **Tailwind CSS**
|
||
- Autenticazione locale con `has_secure_password` (bcrypt)
|
||
- Audit base `created_by` / `updated_by` sulle entità principali
|
||
- Timezone: `Europe/Rome` · UI: italiano
|
||
|
||
### Servizi Docker
|
||
|
||
| Servizio | Ruolo |
|
||
|----------|--------|
|
||
| `web` | Applicazione Rails (porta 3000) |
|
||
| `postgres` | Database PostgreSQL 16 |
|
||
|
||
## Requisiti
|
||
|
||
- Docker + Docker Compose
|
||
- (Opzionale) Ruby 3.3+ per sviluppo fuori da Docker
|
||
|
||
## Avvio rapido (Docker)
|
||
|
||
```bash
|
||
cp .env.example .env
|
||
# modifica SECRET_KEY_BASE e password DB se necessario
|
||
|
||
docker compose up -d --build
|
||
```
|
||
|
||
Al primo avvio vengono eseguiti automaticamente:
|
||
|
||
1. `bundle install` (in build)
|
||
2. `tailwindcss:build`
|
||
3. `db:prepare` (create + migrate)
|
||
4. `db:seed`
|
||
|
||
Apri: [http://localhost:3001](http://localhost:3001)
|
||
|
||
> Su questa macchina la porta 3000 è già usata da un altro stack: di default eminuxCRM usa **3001**.
|
||
> Puoi cambiarla con `APP_PORT` nel file `.env`.
|
||
|
||
|
||
### Progetti = istanze CRM separate
|
||
|
||
Ogni progetto ha un URL dedicato:
|
||
|
||
- Launcher: `/`
|
||
- MatchLiveTV: `/p/matchlivetv`
|
||
- RiskMeter: `/p/riskmeter`
|
||
- Cardoo: `/p/cardoo`
|
||
|
||
Dentro ogni istanza trovi dashboard, organizzazioni, pipeline, task, report e impostazioni **del solo quel progetto**.
|
||
|
||
- Gli **admin** vedono tutti i progetti
|
||
- Gli **utenti** solo i progetti abilitati
|
||
- In sidebar: “Tutti i progetti” + switch rapido tra istanze
|
||
|
||
## Credenziali development (solo seed)
|
||
|
||
| Email | Password | Ruolo | Progetti |
|
||
|-------|----------|-------|----------|
|
||
| `admin@simplecrm.local` | `password123` | Admin | Tutti |
|
||
| `marco@simplecrm.local` | `password123` | Utente | MatchLiveTV, RiskMeter |
|
||
| `lucia@simplecrm.local` | `password123` | Utente | MatchLiveTV, Cardoo |
|
||
|
||
## Configurazione `.env`
|
||
|
||
Copia `.env.example` → `.env`. Variabili principali:
|
||
|
||
- `POSTGRES_USER` / `POSTGRES_PASSWORD` / `POSTGRES_DB`
|
||
- `DATABASE_HOST` (in Docker: `postgres`)
|
||
- `SECRET_KEY_BASE`
|
||
- `MAILER_FROM`
|
||
- `APP_HOST` / `APP_PORT`
|
||
- `TZ=Europe/Rome`
|
||
|
||
**Non committare** `.env` con secret reali.
|
||
|
||
## Migration e seed
|
||
|
||
```bash
|
||
docker compose exec web bin/rails db:migrate
|
||
docker compose exec web bin/rails db:seed
|
||
```
|
||
|
||
Reset completo (distruttivo):
|
||
|
||
```bash
|
||
docker compose exec web bin/rails db:reset
|
||
```
|
||
|
||
## Test
|
||
|
||
```bash
|
||
docker compose exec web bin/rails db:test:prepare
|
||
docker compose exec web bin/rails test
|
||
```
|
||
|
||
## Backup / restore
|
||
|
||
```bash
|
||
bin/backup
|
||
# crea tmp/backups/simplecrm_YYYYMMDD_HHMMSS.sql.gz
|
||
|
||
bin/restore tmp/backups/simplecrm_YYYYMMDD_HHMMSS.sql.gz
|
||
```
|
||
|
||
Con Docker Compose attivo gli script usano `pg_dump` / `psql` sul container `postgres`.
|
||
|
||
## Import CSV
|
||
|
||
Pagina: **Impostazioni → Import CSV** oppure `/imports/new`.
|
||
|
||
Formato standard (file esempio: `examples/organizations_import_sample.csv`):
|
||
|
||
```csv
|
||
organization_name,organization_type,sport,country,region,province,city,website,organization_email,contact_first_name,contact_last_name,contact_role,contact_email,contact_phone,lead_source,notes
|
||
```
|
||
|
||
Duplicati evitati confrontando nome organizzazione, email e sito.
|
||
|
||
## Export CSV
|
||
|
||
Disponibile da liste Organizzazioni, Contatti e Opportunità (rispetta i filtri attivi dove applicabile).
|
||
|
||
## Struttura database (principale)
|
||
|
||
- `users` — autenticazione, ruolo admin/user
|
||
- `organizations` — prospect/clienti
|
||
- `contacts` — contatti per organizzazione
|
||
- `opportunities` — pipeline commerciale
|
||
- `activities` — timeline
|
||
- `tasks` — follow-up / next actions
|
||
- `sales_goals` — obiettivi dashboard
|
||
- `products` — catalogo prodotti (Light, Full, …)
|
||
|
||
Pipeline stages: Da contattare → Contattato → Ha risposto → Interessato → Demo/Trial → Primo utilizzo → Proposta → Cliente / Perso.
|
||
|
||
## Funzionalità principali
|
||
|
||
- Dashboard con obiettivo, KPI, funnel, “Cosa fare oggi”, indicatori di attenzione
|
||
- Pagina `/today` operativa
|
||
- Scheda Organization come centro operativo + quick actions
|
||
- Kanban pipeline con drag & drop (Stimulus) e cambio stage da menu
|
||
- Task con evidenziazione scaduti / oggi / futuri
|
||
- Report: funnel, lead source, won/lost, lost reasons, sales owner, revenue
|
||
- Import/export CSV
|
||
|
||
## Deploy (suggerimento semplice)
|
||
|
||
1. Copia il progetto su una VM
|
||
2. Configura `.env` di produzione (`RAILS_ENV=production`, `SECRET_KEY_BASE`, password DB forti)
|
||
3. `docker compose up -d --build` (oppure builda il target `production` del Dockerfile)
|
||
4. Metti un reverse proxy (Caddy/Nginx) con HTTPS davanti alla porta 3000
|
||
5. Esegui backup periodici con `bin/backup`
|
||
|
||
## API JSON per agenti
|
||
|
||
I client HTML restano su cookie di sessione. Gli agenti (Cursor, Claude Code, Codex) usano un token Bearer.
|
||
|
||
1. Nel CRM: **Token API** (menu utente, oppure Impostazioni piattaforma se sei admin)
|
||
2. Crea un token: il valore `crm_…` si vede **una sola volta**
|
||
3. Header: `Authorization: Bearer crm_…`
|
||
|
||
Endpoint v1 (tutti tranne `GET /api/v1/projects` richiedono `:project_code`):
|
||
|
||
| Metodo | Path | Ruolo |
|
||
|--------|------|--------|
|
||
| GET | `/api/v1/projects` | progetti accessibili |
|
||
| GET | `/api/v1/p/:project_code/today` | task scaduti / oggi / in arrivo + opportunità ferme |
|
||
| GET | `/api/v1/p/:project_code/search?q=` | org, contatti, opportunità |
|
||
| GET | `/api/v1/p/:project_code/organizations/:id` | scheda operativa |
|
||
| POST | `/api/v1/p/:project_code/tasks` | crea task |
|
||
| POST | `/api/v1/p/:project_code/tasks/:id/complete` | completa task |
|
||
| POST | `/api/v1/p/:project_code/activities` | annota timeline |
|
||
| PATCH | `/api/v1/p/:project_code/opportunities/:id/stage` | cambia stage pipeline |
|
||
|
||
L’agente agisce come l’utente del token (stessi progetti, stesso `created_by`). Fuori da questa v1: mailing, utenti, delete, import CSV.
|
||
|
||
Esempio:
|
||
|
||
```bash
|
||
curl -sS -H "Authorization: Bearer crm_…" \
|
||
http://localhost:3001/api/v1/p/matchlivetv/today
|
||
```
|
||
|
||
## MCP (Cursor CLI / Claude Code / Codex)
|
||
|
||
Gli agenti parlano con il CRM su **HTTP**: `http://localhost:3001/mcp` (stesso Bearer del token API). Non serve Ruby sull’host.
|
||
|
||
1. Avvia il CRM (`docker compose up`)
|
||
2. Crea un token in **Token API**
|
||
3. Esporta il token e lancia l’agente dalla root del repo:
|
||
|
||
```bash
|
||
export CRM_API_TOKEN='crm_…'
|
||
# Cursor CLI:
|
||
agent "Interagisci col CRM su MatchLiveTV: cosa c'è da fare oggi?"
|
||
# Claude Code:
|
||
claude "Interagisci col CRM su MatchLiveTV: cosa c'è da fare oggi?"
|
||
```
|
||
|
||
Config già nel repo (il token sta solo in env, non nei file):
|
||
|
||
- Cursor / Cursor CLI: [`.cursor/mcp.json`](.cursor/mcp.json)
|
||
- Claude Code: [`.mcp.json`](.mcp.json)
|
||
- Codex: copia [mcp/codex.config.toml.example](mcp/codex.config.toml.example) in `~/.codex/config.toml`
|
||
|
||
Istruzioni per gli agenti: [AGENTS.md](AGENTS.md).
|
||
|
||
Tool: `list_projects`, `today`, `search`, `get_organization`, `create_task`, `complete_task`, `create_activity`, `update_opportunity_stage`, `update_organization_email`, `check_mail_bounces`.
|
||
|
||
Stdio (`mcp/server.rb` / `bin/crm-mcp`) resta come alternativa se un client non parla HTTP.
|
||
|
||
Esempio in chat: *«Interagisci col CRM e fai alcune cose per me su MatchLiveTV.»*
|
||
|
||
## Sviluppo locale senza Docker (opzionale)
|
||
|
||
```bash
|
||
bundle install
|
||
bin/rails db:prepare db:seed
|
||
bin/dev # server + tailwind watch
|
||
```
|
||
|
||
## Volutamente fuori scope (fase successiva)
|
||
|
||
- Integrazioni Gmail/SMTP avanzate, sync email, calendario
|
||
- Stripe, webhook
|
||
- Dark mode, BI avanzata, microservizi
|
||
|
||
## Licenza
|
||
|
||
Uso interno / progetto privato.
|