Files
eminuxandCursor 36b3ffe507
CI / scan_ruby (push) Failing after 13m27s
CI / scan_js (push) Successful in 11m45s
CI / lint (push) Failing after 12m4s
Aggiunge IMAP bounce e flag email non valide nel CRM.
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>
2026-09-08 19:46:04 +02:00

243 lines
7.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 |
Lagente agisce come lutente 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 sullhost.
1. Avvia il CRM (`docker compose up`)
2. Crea un token in **Token API**
3. Esporta il token e lancia lagente 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.