# 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`. 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.