# Mostry — backend AI (Symfony)

Base del backend riscritta dalle "logiche" del vecchio Mostry, ma multi-provider e sicura.

## Concetto chiave: multi-provider + managed/BYOK
Ogni **Bot** sceglie un `provider` (Anthropic / Google / OpenAI) e un `model`.
La chiave API può essere:
- **managed** (`useManagedKey = true`): usa la chiave centrale di Mostry per quel provider
  (da `.env.local`). Il cliente non configura nulla → esperienza "automatica".
- **BYOK** (`useManagedKey = false`): il cliente usa la propria chiave, **cifrata nel DB**
  con libsodium (`SecretCipher`). Mai in chiaro.

La chiave del provider resta **sempre lato server**: il browser non la vede mai.

## Pezzi principali (`src/`)
| File | Ruolo |
|---|---|
| `Enum/LlmProvider.php` | I provider supportati (enum) |
| `Service/Llm/LlmProviderInterface.php` | Contratto comune a tutti i provider |
| `Service/Llm/AnthropicProvider · GoogleProvider · OpenAiProvider` | Implementazioni per ogni API |
| `Service/Llm/ProviderRegistry.php` | Raccoglie i provider + chiavi/modelli managed |
| `Service/Llm/LlmRequest.php` | DTO richiesta, indipendente dal provider |
| `Service/SecretCipher.php` | Cifratura/decifratura chiavi BYOK (sodium) |
| `Service/SubscriptionService.php` | Stato abbonamento + feature sbloccate (per `tier`) |
| `Service/ChatService.php` | Orchestratore: abbonamento → limite → prompt → provider |
| `Controller/Api/ChatController.php` | `POST /api/chat/{token}` (chiamato dal widget, con CORS) |
| `Entity/{User,Plan,Bot,UsageCounter}.php` | Modello dati Doctrine |

### Aggiungere un nuovo provider = 1 classe
Crea una classe che implementa `LlmProviderInterface` con un nuovo case nell'enum.
Viene raccolta in automatico dal registry (tag `app.llm_provider`). Zero modifiche al resto.

## Flusso di una richiesta
`POST /api/chat/{token}` con body `{"history":[{"role":"user","content":"..."}]}`
→ trova il Bot dal token → verifica l'abbonamento del proprietario → applica il limite
mensile (`UsageCounter`) → costruisce il system prompt (guardrailing / knowledge base)
→ risolve le credenziali (managed o BYOK) → chiama il provider → risponde `{"reply":"..."}`.

## Setup locale
```
# DB SQLite di sviluppo (già configurato in .env → var/data_dev.db)
php bin/console doctrine:schema:create
php bin/console mostry:seed          # crea piano + utente demo + bot, stampa il token
```
Avvia: doppio clic su `Desktop\Avvia Mostry Symfony.bat`.
Testa: `POST http://127.0.0.1:8000/api/chat/{token}`.

## Attivare l'AI vera
In `.env.local` decommenta e incolla la tua chiave, es.:
```
ANTHROPIC_API_KEY='sk-ant-...'
```
Senza chiave, l'endpoint risponde con un errore pulito "provider non disponibile"
(comportamento verificato).

## Produzione (FTP/MySQL)
In `.env.local` sul server imposta `DATABASE_URL` MySQL (vedi `.env`), poi
`php bin/console doctrine:schema:create` (o le migrazioni) sul DB dell'hosting.
`.env.local` e `var/` NON vanno su git (già in `.gitignore`).

## Ancora da fare (prossimi step)
- Autenticazione dashboard (Security già installato) + area cliente.
- CRUD Bot no-code (form di configurazione) + generazione snippet iframe/embed.
- Widget chat (frontend) che consuma `/api/chat/{token}`.
- Stripe (abbonamenti + webhook) e fatture.
- WhatsApp (webhook Meta Cloud API).
- Opzionale: RAG con embeddings al posto della knowledge base testuale.
