SPB Git forge

spb/spb-cloud

Public
10commits 1branches 0releases
3.2 MBsize
maindefault branch
1 h agolast push
JavaScript 56.7% TypeScript 42.6%
21.3 KB · 510 lines markdown
Rendered Raw Blame History
1<p align="center">2  <img src="https://img.shields.io/badge/SPB_Cloud-v3.1-6366f1?style=for-the-badge&logo=cloud&logoColor=white" alt="Version" />3</p>45<h1 align="center">SPB Private Cloud</h1>67<p align="center">8  <strong>Cloud personnel priv&eacute;, souverain, s&eacute;curis&eacute; et mobile-first.</strong><br/>9  Plus clean que Dropbox. Plus priv&eacute; que Google Drive. 100% local-first.10</p>1112<p align="center">13  <img src="https://img.shields.io/badge/Next.js-14-black?style=flat-square&logo=nextdotjs&logoColor=white" alt="Next.js" />14  <img src="https://img.shields.io/badge/TypeScript-5-3178C6?style=flat-square&logo=typescript&logoColor=white" alt="TypeScript" />15  <img src="https://img.shields.io/badge/Tailwind_CSS-3.4-06B6D4?style=flat-square&logo=tailwindcss&logoColor=white" alt="Tailwind" />16  <img src="https://img.shields.io/badge/Prisma-ORM-2D3748?style=flat-square&logo=prisma&logoColor=white" alt="Prisma" />17  <img src="https://img.shields.io/badge/SQLite-Database-003B57?style=flat-square&logo=sqlite&logoColor=white" alt="SQLite" />18  <img src="https://img.shields.io/badge/Claude_AI-Sonnet_4.5-D97706?style=flat-square&logo=anthropic&logoColor=white" alt="Claude AI" />19</p>2021<p align="center">22  <img src="https://img.shields.io/badge/License-Private-red?style=flat-square" alt="License" />23  <img src="https://img.shields.io/badge/Platform-macOS%20%7C%20Linux%20%7C%20VPS-lightgrey?style=flat-square" alt="Platform" />24  <img src="https://img.shields.io/badge/Mobile-Responsive-green?style=flat-square&logo=apple&logoColor=white" alt="Mobile" />25  <img src="https://img.shields.io/badge/Auth-2FA%20TOTP-purple?style=flat-square&logo=keycdn&logoColor=white" alt="2FA" />26  <img src="https://img.shields.io/badge/Encryption-AES--256--GCM-orange?style=flat-square&logo=letsencrypt&logoColor=white" alt="Encryption" />27  <img src="https://img.shields.io/badge/API-REST%20v1-blue?style=flat-square&logo=fastapi&logoColor=white" alt="API" />28</p>2930---3132## v3.1 — Connexion par code courriel, audit fonctionnel, réorganisation IA (2026-09-07)3334**Connexion par code courriel (Resend)** — méthode par défaut : saisir son adresse (`spbou4@protonmail.com`, `r-boucher@sympatico.ca`…), recevoir un code à 6 chiffres (10 min, 5 essais, renvoi 30 s), le saisir. Le code est stocké haché dans le cookie de session chiffré (aucune table). Routes `POST /api/auth/otp/request` et `/verify` ; envoi via `lib/mailer.ts` (Resend REST, `RESEND_API_KEY`, `MAIL_FROM`). ⚠ Sans domaine vérifié dans Resend, seul `onboarding@resend.dev` est autorisé et il ne livre qu'au propriétaire du compte : vérifier `spboucher.ai` dans Resend puis mettre `MAIL_FROM="SPB Cloud <no-reply@spboucher.ai>"` pour que Richard reçoive ses codes. Connexion par mot de passe conservée (administration).3536**Audit fonctionnel (11 correctifs)** — suppression de dossier = corbeille récursive (plus de fichiers orphelins ni de contenu effacé du disque), restauration fidèle (dossier d'origine recréé), purge réelle (contenu + versions + vignettes) et purge horaire des > 30 j (`server.ts`), **partage de dossier** (`POST /api/shares {folderId}`, page publique avec navigation, ZIP, mot de passe via cookie signé), sous-dossiers héritant de l'espace partagé, quotas cohérents (chunks, duplication, corbeille exclue), duplication conservant l'extension, validations 404/400, notifications d'upload, WebDAV DELETE → corbeille. Migration : `scripts/migrations/apply-2026-09-07-audit.ts` (idempotente) puis `npx prisma generate` **dans le dossier de l'app** (le client Prisma mémorise le dossier `prisma/` au moment de la génération).3738**Réorganisation IA des espaces partagés** (`scripts/organize/`) — `extract.ts` (Claude Opus 5 : vision pour les photos, PDF natif, texte/Office), `dupes.ts` (SHA-256), `plan.ts` (arborescence + noms par espace, albums photo par ordre de numérisation), `apply.ts --dry-run` puis `apply.ts` (sauvegarde `VACUUM INTO`, journal `data/applied.jsonl`), `verify.ts`, `rollback.ts`. Appliqué le 2026-09-07 : 9 espaces, 1 171 fichiers renommés/déplacés, 85 dossiers créés, 44 anciens supprimés, 78 doublons identiques isolés dans « 99 Doublons identiques ». `data/` est ignoré par git (métadonnées personnelles).3940## Nouveautés v3 « Aurora » (2026-09-07)4142Refonte complète du front-end, déployée sur `cloud.spboucher.ai` (M2U64, PM2 `cloud`).4344**Design system**45- Tokens sémantiques (`canvas`, `surface`, `elevated`, `line`), thème clair / sombre / système, **7 couleurs d'accent** au choix (Aurore, Océan, Glacier, Forêt, Corail, Ambre, Améthyste) appliquées à toute l'interface via `--accent-*`.46- Police **Geist** locale (plus d'appel à Google Fonts), verre dépoli, ombres douces, animations réductibles (préférence « Réduire les animations »).47- Densité des listes (confortable / compacte). Préférences dans `⌘,` — persistées en `localStorage` et appliquées avant le premier rendu (script inline dans `app/layout.tsx`, clés dans `lib/prefs.ts`).4849**Coquille**50- Barre latérale repliable en rail (`⌘B`), sections Dossiers / Espaces / Outils / Administration / Tags, jauge de stockage, menu utilisateur.51- Barre supérieure avec fil d'Ariane (cible de dépôt), bouton Envoyer, assistant IA, notifications, thème.52- **Palette de commandes `⌘K`** (ou `/`) : recherche de fichiers et dossiers en direct, navigation, actions (envoyer, nouveau dossier, thème, préférences, déconnexion), historique des commandes.53- Mobile : barre d'onglets iOS-like, tiroir glissable, PWA installable (`manifest.webmanifest`, icônes, `viewport-fit=cover`).5455**Explorateur**56- Liste avec en-tête collant et colonnes triables, grille avec vignettes et actions rapides, sélection par plage (⇧-clic), clic droit → menu contextuel, navigation clavier complète.57- **Glisser-déposer** : fichiers du bureau (overlay plein écran), déplacement interne vers dossiers, arbre latéral (auto-expansion) et fil d'Ariane ; déplacement multiple.58- Liens profonds `?file=`, `?upload=1`, `?new=1` (utilisés par la palette, la barre supérieure et l'accueil).59- Aperçu : plein écran réel, balayage tactile, panneau d'informations et versions refaits.6061**Accueil et administration**62- Bandeau vivant, anneau de stockage par catégorie, activité sur 14 jours, KPI, « Reprendre », favoris, fichiers volumineux.63- `GET /api/admin/stats` enrichi (rétro-compatible) : `byCategory`, `activityByDay`, `favoriteCount`, `trashCount`, `versionCount`, `largestFiles`.6465**Correctifs**66- Recherche `/api/files?search=` : `mode: "insensitive"` (non supporté par Prisma/SQLite) renvoyait 500.67- Limiteur de débit : 600 req/min/IP et exemption des aperçus/flux (une grille de 50 vignettes dépassait l'ancien plafond de 100).68- Vignettes de l'accueil pointaient vers une route `/raw` inexistante.69- Route `/admin/snapshots` manquante (404) ; `app/api/snapshots` n'était pas versionné (`.gitignore` trop large).70- `SNAPSHOT_DISABLED=1` désactive le snapshot quotidien (utile pour un serveur de staging).7172## Qu'est-ce que SPB Cloud ?7374SPB Private Cloud est un cloud personnel auto-h&eacute;berg&eacute; con&ccedil;u pour offrir un contr&ocirc;le total sur vos donn&eacute;es. Aucune d&eacute;pendance &agrave; Google, Dropbox ou iCloud. Vos fichiers restent chez vous, chiffr&eacute;s, accessibles depuis n'importe quel appareil.7576### Pourquoi SPB Cloud ?7778| | SPB Cloud | Google Drive | Dropbox |79|---|---|---|---|80| **Propri&eacute;t&eacute; des donn&eacute;es** | Vous | Google | Dropbox |81| **Chiffrement at-rest** | AES-256-GCM | Oui (leur cl&eacute;) | Oui (leur cl&eacute;) |82| **IA int&eacute;gr&eacute;e** | Claude Sonnet 4.5 | Gemini (limit&eacute;) | Non |83| **OCR intelligent** | Oui (Vision IA) | Basique | Non |84| **Co&ucirc;t mensuel** | 0$ (auto-h&eacute;berg&eacute;) | 2.99$/mois+ | 11.99$/mois+ |85| **Code source** | Acc&egrave;s complet | Ferm&eacute; | Ferm&eacute; |86| **Multi-utilisateur** | Oui (roles) | Oui | Oui |87| **2FA TOTP** | Oui | Oui | Oui |88| **API REST** | Oui | Oui | Oui |8990---9192## Fonctionnalit&eacute;s9394### Gestion de fichiers95- Upload multi-fichiers avec drag & drop96- Upload depuis cam&eacute;ra mobile97- Rename, delete, move, duplicate98- Organisation en dossiers imbriqu&eacute;s99- Breadcrumb navigation100- Vue grille et liste101- S&eacute;lection multiple + actions en lot102- T&eacute;l&eacute;chargement de dossiers en ZIP103- Progress bar d'upload104105### Preview de fichiers106- Images (JPG, PNG, GIF, WebP, SVG)107- Vid&eacute;os (MP4, WebM, MOV)108- Audio (MP3, WAV, OGG) avec waveform109- PDF avec navigation de pages110- Code source avec syntax highlighting (20+ langages)111- Markdown avec rendu112- CSV/JSON avec tableau interactif113- Archives ZIP (exploration du contenu)114115### Intelligence Artificielle (Claude Sonnet 4.5)116- **Recherche s&eacute;mantique** : trouvez des fichiers par description naturelle117- **Chat IA** : posez des questions sur vos fichiers118- **Auto-tagging** : classification automatique par contenu119- **OCR intelligent** : extraction de texte depuis images et PDFs120- **Description IA** : g&eacute;n&eacute;ration automatique de descriptions121122### S&eacute;curit&eacute;123- Hash bcrypt pour les mots de passe124- Authentification 2FA TOTP (Google Authenticator, Authy)125- Chiffrement AES-256-GCM at-rest126- Sessions HTTP-only cookies (iron-session)127- Rate limiting sur le login128- CSRF protection129- Validation des types de fichiers130131### Multi-utilisateur132- Syst&egrave;me de r&ocirc;les : Admin, User, Viewer133- Gestion CRUD des utilisateurs134- Permissions par r&ocirc;le135- Logs d'activit&eacute; par utilisateur136137### Partage s&eacute;curis&eacute;138- Liens de partage avec token unique139- Protection par mot de passe optionnel140- Date d'expiration configurable141- Mode t&eacute;l&eacute;chargement ou aper&ccedil;u seul142- D&eacute;sactivation instantan&eacute;e143- Gestion centralis&eacute;e des liens144145### Syst&egrave;me de backup146- Backup complet (DB + fichiers) en ZIP147- Backup incr&eacute;mental148- Historique des backups avec statut149- Suppression des anciens backups150151### Notifications152- Notifications en temps r&eacute;el (polling 30s)153- Badge avec compteur non-lus154- Types : upload, backup, IA, partage155- Marquer comme lu / tout lire156157### API REST publique158- Authentification par cl&eacute; API (Bearer token)159- G&eacute;n&eacute;ration et r&eacute;vocation de cl&eacute;s160- Permissions configurable (read, write, admin)161- Expiration optionnelle des cl&eacute;s162- Endpoint : `GET /api/v1/files`163164### Interface165- Design mobile-first (iPhone optimis&eacute;)166- Mode clair / sombre avec persistance167- Touch targets 44px minimum168- Bottom sheet modals sur mobile169- Safe area support (notch iPhone)170- Sidebar collapsible171- Animations Framer Motion172- Typographie Inter173174---175176## Stack technique177178<p align="center">179  <img src="https://img.shields.io/badge/Frontend-Next.js_14-000000?style=for-the-badge&logo=nextdotjs" alt="Next.js" />180  <img src="https://img.shields.io/badge/Language-TypeScript_5-3178C6?style=for-the-badge&logo=typescript" alt="TypeScript" />181  <img src="https://img.shields.io/badge/Styling-Tailwind_CSS-06B6D4?style=for-the-badge&logo=tailwindcss" alt="Tailwind" />182  <img src="https://img.shields.io/badge/Animation-Framer_Motion-FF0055?style=for-the-badge&logo=framer" alt="Framer" />183</p>184<p align="center">185  <img src="https://img.shields.io/badge/ORM-Prisma-2D3748?style=for-the-badge&logo=prisma" alt="Prisma" />186  <img src="https://img.shields.io/badge/Database-SQLite-003B57?style=for-the-badge&logo=sqlite" alt="SQLite" />187  <img src="https://img.shields.io/badge/Auth-iron--session-FF6600?style=for-the-badge" alt="iron-session" />188  <img src="https://img.shields.io/badge/AI-Anthropic_Claude-D97706?style=for-the-badge&logo=anthropic" alt="Claude" />189</p>190191---192193## Installation194195### Pr&eacute;requis196197- **Node.js** 18+198- **npm** 9+199- Cl&eacute; API Anthropic (pour les fonctionnalit&eacute;s IA)200201### Installation rapide202203```bash204# 1. Cloner le repo205git clone https://github.com/simonpierreboucher02/spb-private-cloud.git206cd spb-private-cloud207208# 2. Installer les d&eacute;pendances209npm install210211# 3. Configurer l'environnement212cp .env.example .env213# &Eacute;diter .env avec vos valeurs214215# 4. Initialiser la base de donn&eacute;es216npx prisma db push217npx tsx prisma/seed.ts218219# 5. Lancer l'application220npm run dev221```222223L'application sera accessible sur [http://localhost:3000](http://localhost:3000).224225### Configuration (.env)226227```env228DATABASE_URL="file:./dev.db"229SESSION_PASSWORD="votre-secret-session-min-32-caracteres"230ANTHROPIC_API_KEY="sk-ant-api03-..."231ENCRYPTION_KEY="votre-cle-encryption-32-caracteres"232BACKUP_DIR="./backups"233UPLOAD_DIR="./uploads"234MAX_FILE_SIZE="524288000"235```236237### Identifiants par d&eacute;faut238239| Champ | Valeur |240|---|---|241| **Email** | `admin@spbcloud.local` |242| **Mot de passe** | `admin123` |243| **R&ocirc;le** | Admin |244245> **Important** : Changez le mot de passe apr&egrave;s la premi&egrave;re connexion via Admin > Utilisateurs.246247---248249## Architecture250251```252spb-private-cloud/253├── app/254│   ├── admin/            # Pages administration255│   │   ├── activity/     # Historique d'activit&eacute;256│   │   ├── api-keys/     # Gestion cl&eacute;s API257│   │   ├── backup/       # Gestion backups258│   │   ├── settings/     # Param&egrave;tres (2FA)259│   │   ├── shares/       # Liens partag&eacute;s260│   │   └── users/        # Gestion utilisateurs261│   ├── api/262│   │   ├── ai/           # Endpoints IA (search, chat, tag, ocr, describe)263│   │   ├── auth/         # Login, logout, 2FA264│   │   ├── backup/       # CRUD backups265│   │   ├── files/        # CRUD fichiers + bulk + versions266│   │   ├── folders/      # CRUD dossiers + ZIP download267│   │   ├── keys/         # CRUD cl&eacute;s API268│   │   ├── notifications/# Notifications269│   │   ├── shares/       # Liens de partage270│   │   ├── tags/         # Tags271│   │   ├── users/        # Gestion utilisateurs272│   │   └── v1/           # API REST publique273│   ├── dashboard/        # File explorer274│   ├── login/            # Page de connexion275│   └── shared/           # Pages de partage public276├── components/277│   ├── admin/            # Composants admin278│   ├── ai/               # Panel IA279│   ├── files/            # FileCard, FileExplorer, BulkActions280│   ├── folders/          # FolderCard, CreateFolderModal281│   ├── layout/           # AppShell, Sidebar, MobileNav, Notifications282│   ├── preview/          # Preview engine + plugins (image, video, pdf...)283│   ├── tags/             # TagBadge, TagSelector284│   ├── theme/            # ThemeProvider, ThemeToggle285│   └── ui/               # Button, Modal, SearchBar286├── lib/287│   ├── ai.ts             # Int&eacute;gration Claude API288│   ├── auth.ts           # Authentification multi-user289│   ├── backup.ts         # Syst&egrave;me de backup290│   ├── encryption.ts     # Chiffrement AES-256-GCM291│   ├── notifications.ts  # Syst&egrave;me de notifications292│   ├── prisma.ts         # Client Prisma293│   ├── rate-limit.ts     # Rate limiting294│   ├── session.ts        # Configuration sessions295│   ├── storage.ts        # Gestion fichiers sur disque296│   └── utils.ts          # Utilitaires297├── prisma/298│   ├── schema.prisma     # Sch&eacute;ma de base de donn&eacute;es299│   └── seed.ts           # Seed admin user300├── types/301│   └── files.ts          # Types TypeScript302└── uploads/              # Stockage fichiers (git-ignored)303```304305---306307## Base de donn&eacute;es308309### Mod&egrave;les Prisma310311| Mod&egrave;le | Description |312|---|---|313| `User` | Utilisateurs avec r&ocirc;les et 2FA |314| `File` | Fichiers avec m&eacute;tadonn&eacute;es, IA, chiffrement |315| `Folder` | Dossiers imbriqu&eacute;s (arbre r&eacute;cursif) |316| `SharedLink` | Liens de partage s&eacute;curis&eacute;s |317| `Permission` | Permissions par dossier/utilisateur |318| `ActivityLog` | Journal d'activit&eacute; |319| `FileMetadata` | M&eacute;tadonn&eacute;es &eacute;tendues (favoris, annotations) |320| `Tag` / `FileTag` | Syst&egrave;me de tags |321| `FileVersion` | Versioning de fichiers |322| `Notification` | Notifications utilisateur |323| `ApiKey` | Cl&eacute;s API REST |324| `BackupLog` | Historique des backups |325326---327328## API REST329330### Authentification331332Toutes les requ&ecirc;tes &agrave; l'API publique n&eacute;cessitent un header `Authorization` :333334```bash335curl -H "Authorization: Bearer spb_votre_cle_api" \336     https://votre-domaine/api/v1/files337```338339### Endpoints340341| M&eacute;thode | Endpoint | Description |342|---|---|---|343| `GET` | `/api/v1/files` | Lister les fichiers |344| `GET` | `/api/v1/files?folderId=xxx` | Fichiers d'un dossier |345346### G&eacute;n&eacute;rer une cl&eacute; API3473481. Connectez-vous en tant qu'admin3492. Allez dans **Administration > Cl&eacute;s API**3503. Cliquez **Nouvelle cl&eacute;**3514. Copiez la cl&eacute; g&eacute;n&eacute;r&eacute;e (affich&eacute;e une seule fois)352353---354355## D&eacute;ploiement356357### Mac Studio / NAS (local)358359```bash360# Build de production361npm run build362363# Lancer en production364PORT=3001 npm start365```366367### VPS (avec Nginx)368369```nginx370server {371    listen 443 ssl;372    server_name cloud.votredomaine.com;373374    ssl_certificate /etc/letsencrypt/live/cloud.votredomaine.com/fullchain.pem;375    ssl_certificate_key /etc/letsencrypt/live/cloud.votredomaine.com/privkey.pem;376377    client_max_body_size 500M;378379    location / {380        proxy_pass http://127.0.0.1:3001;381        proxy_http_version 1.1;382        proxy_set_header Upgrade $http_upgrade;383        proxy_set_header Connection 'upgrade';384        proxy_set_header Host $host;385        proxy_set_header X-Real-IP $remote_addr;386        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;387        proxy_set_header X-Forwarded-Proto $scheme;388        proxy_cache_bypass $http_upgrade;389    }390}391```392393### Docker (optionnel)394395```dockerfile396FROM node:18-alpine397WORKDIR /app398COPY package*.json ./399RUN npm ci400COPY . .401RUN npx prisma generate402RUN npm run build403EXPOSE 3000404CMD ["npm", "start"]405```406407---408409## Roadmap410411### Fait412- [x] Upload multi-fichiers + drag & drop413- [x] Organisation en dossiers imbriqu&eacute;s414- [x] Preview 10+ formats (PDF, images, vid&eacute;o, audio, code, markdown...)415- [x] Partage s&eacute;curis&eacute; avec expiration et mot de passe416- [x] Mode clair / sombre417- [x] Multi-utilisateur avec r&ocirc;les418- [x] 2FA TOTP419- [x] Recherche IA (Claude Sonnet 4.5)420- [x] Chat IA int&eacute;gr&eacute;421- [x] Auto-tagging IA422- [x] OCR intelligent (images + PDF)423- [x] Chiffrement AES-256-GCM424- [x] Syst&egrave;me de backup425- [x] Notifications426- [x] API REST avec cl&eacute;s427- [x] Actions en lot (supprimer, d&eacute;placer, ZIP, chiffrer)428- [x] Interface mobile-first (iPhone optimis&eacute;)429430### &Agrave; venir431- [ ] Migration PostgreSQL432- [ ] HTTPS / SSL int&eacute;gr&eacute;433- [ ] Corbeille (soft delete)434- [ ] Thumbnails auto-g&eacute;n&eacute;r&eacute;s435- [ ] Video streaming HLS436- [ ] Infinite scroll437- [ ] Docker Compose438- [ ] WebDAV439- [ ] Sync multi-device440441---442443## S&eacute;curit&eacute;444445SPB Cloud est con&ccedil;u avec la s&eacute;curit&eacute; en priorit&eacute; :446447| Mesure | D&eacute;tail |448|---|---|449| **Mots de passe** | Hash bcrypt (12 rounds) |450| **2FA** | TOTP RFC 6238 (Google Authenticator) |451| **Sessions** | Cookies HTTP-only, SameSite, expiration 24h |452| **Chiffrement** | AES-256-GCM avec cl&eacute; d&eacute;riv&eacute;e (scrypt) |453| **Rate limiting** | 5 tentatives/min sur login |454| **API Keys** | SHA-256 hash, jamais stock&eacute;es en clair |455| **Upload** | Limite de taille configurable |456457---458459## Auteurs460461<table>462  <tr>463    <td align="center">464      <strong>Simon-Pierre Boucher</strong><br/>465      Cr&eacute;ateur & Propri&eacute;taire<br/>466      <a href="https://www.spboucher.ai">www.spboucher.ai</a><br/>467      <a href="mailto:spbou4@protonmail.com">spbou4@protonmail.com</a>468    </td>469    <td align="center">470      <strong>Claude Opus 4.6</strong><br/>471      Co-auteur & D&eacute;veloppeur IA<br/>472      <a href="https://anthropic.com">Anthropic</a><br/>473      Architecture, code, optimisation mobile474    </td>475  </tr>476</table>477478---479480## Statistiques du projet481482<p align="center">483  <img src="https://img.shields.io/badge/Fichiers-139-blue?style=for-the-badge" alt="Files" />484  <img src="https://img.shields.io/badge/Lignes_de_code-21%2C456-green?style=for-the-badge" alt="Lines" />485  <img src="https://img.shields.io/badge/API_Routes-32-orange?style=for-the-badge" alt="API Routes" />486  <img src="https://img.shields.io/badge/Composants-28-purple?style=for-the-badge" alt="Components" />487</p>488489<p align="center">490  <img src="https://img.shields.io/badge/Preview_Plugins-10-teal?style=flat-square" alt="Plugins" />491  <img src="https://img.shields.io/badge/Mod%C3%A8les_DB-12-red?style=flat-square" alt="DB Models" />492  <img src="https://img.shields.io/badge/Fonctions_IA-5-yellow?style=flat-square" alt="AI Functions" />493  <img src="https://img.shields.io/badge/D%C3%A9pendances-42-grey?style=flat-square" alt="Dependencies" />494</p>495496---497498## Contact499500- **Email** : [spbou4@protonmail.com](mailto:spbou4@protonmail.com)501- **Site web** : [www.spboucher.ai](https://www.spboucher.ai)502- **GitHub** : [github.com/simonpierreboucher02](https://github.com/simonpierreboucher02)503504---505506<p align="center">507  <sub>Built with passion by Simon-Pierre Boucher & Claude Opus 4.6</sub><br/>508  <sub>&copy; 2024-2026 SPB Private Cloud. Tous droits r&eacute;serv&eacute;s.</sub>509</p>510