diff --git a/README.md b/README.md new file mode 100644 index 0000000..3734513 --- /dev/null +++ b/README.md @@ -0,0 +1,110 @@ +# Lassistanoque + +Assistant IA auto-hébergé : backend Go (API + SPA embarquée), base SQLite, connecteurs LLM multiples (via [any-llm](https://github.com/mozilla-ai/any-llm-go)), authentification par mot de passe ou OpenID Connect. + +## Prérequis + +- Go >= 1.26 +- Node.js + npm (build du frontend) +- (optionnel) un serveur OpenID Connect, ex. [Keycloak](https://www.keycloak.org/) + +## Installation + +```bash +# 1. frontend : build la SPA et l'écrit dans backend/internal/http/web +cd backend/web +npm install +npm run build + +# 2. backend +cd .. +go build -o lassistanoque . +``` + +Le `Makefile` du backend enchaîne les deux et produit les binaires multi-plateformes dans `build/` : + +```bash +make build # linux/amd64, linux/arm64, windows, darwin... +``` + +## Configuration + +La configuration se fait par variables d'environnement, chargeables depuis un fichier `.env` placé dans le répertoire de lancement (backend) : + +| Variable | Défaut | Description | +|----------------------------|--------------------|----------------------------------------------------| +| `LASSISTANOQUE_DB_TYPE` | `turso` | Type de base (seul `turso`/SQLite est implémenté) | +| `LASSISTANOQUE_DB_URL` | `lassistanoque.db` | Chemin du fichier SQLite | +| `LASSISTANOQUE_HTTP_PORT` | `3000` | Port du serveur HTTP | +| `LASSISTANOQUE_JWT_SECRET` | *(obligatoire)* | Secret de signature des tokens, ex. `openssl rand -base64 32` | +| `LASSISTANOQUE_STORAGE_TYPE`| `database` | Stockage des fichiers (seul `database` est implémenté) | +| `LASSISTANOQUE_SERVER_ID` | `default` | Identifiant du serveur | + +Exemple `backend/.env` : + +```env +LASSISTANOQUE_JWT_SECRET= +LASSISTANOQUE_HTTP_PORT=3000 +``` + +## Lancement + +```bash +./lassistanoque serve +``` + +- Les migrations de la base sont appliquées automatiquement au démarrage (ou manuellement avec `./lassistanoque migrate`). +- L'application est servie sur `http://localhost:3000` (SPA + API `/api`). +- Créez le premier compte depuis la page d'inscription (`/register`), puis configurez un fournisseur LLM et sa clé d'API dans les réglages de l'espace (`settings/models`). + +## Authentification OpenID Connect + +Les fournisseurs OIDC sont enregistrés dans la table `oidc` : + +```sql +insert into oidc (id, label, domain, client_id, client_secret, wellknown_url, _date_created, _version) +values ( + 'keycloak', -- identifiant du fournisseur + 'Keycloak', -- libellé affiché sur la page de connexion + 'sso.example.com', -- domaine du fournisseur + 'lassistanoque', -- client_id + '', + 'https:///realms//.well-known/openid-configuration', + datetime('now'), + 'v1' +); +``` + +Côté fournisseur (Keycloak) : + +- client de type *confidential*, *Standard Flow* (authorization code) activé ; +- *Valid Redirect URIs* : `http://localhost:3000/api/auth/oidc/callback` (l'URL de callback est reconstruite depuis le `Host` de la requête ; derrière un reverse proxy, transmettre `X-Forwarded-Proto` et `X-Forwarded-Host`). + +Flux : les fournisseurs configurés apparaissent comme boutons sur la page de connexion → redirection vers le fournisseur → au retour, le backend valide le `state` signé, échange le code, vérifie le token ID (signature JWKS, émetteur, audience) puis délivre les tokens applicatifs. À la première connexion, l'utilisateur est créé automatiquement avec son espace personnel. + +## Développement + +```bash +# backend (API sur :3000) +cd backend +go run . serve + +# frontend en mode dev (Vite sur :5173, API proxyfiée vers :3000) +cd web +npm run dev +``` + +Structure : + +``` +backend/ +├── cmd/ # CLI (serve, migrate, version) et assemblage IoC +├── internal/ +│ ├── adapter/ # implémentations : db (turso/SQLite), auth (password, oidc), llm, tools, security (JWT) +│ ├── domain/ # entités et interfaces des repositories +│ ├── http/ # serveur HTTP, routes, SPA embarquée +│ └── service/ # logique métier (auth, chat, agents, tasks...) +└── web/ # frontend SvelteKit +``` + +Tests : `go test ./backend/...`