ordinarthur-os/PLAN.md
ordinarthur bc0c15873f init
2026-04-15 16:41:19 +02:00

120 lines
7.3 KiB
Markdown
Raw 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.

# ordinarthur-os — Plan d'implémentation
> **Status** : planning terminé 2026-04-15. À implémenter via Claude Code (Sonnet).
## Vision produit
Un assistant personnel qui aide Arthur à s'organiser **sans le déresponsabiliser**.
- Dashboard clair de ce qu'il fait / veut faire
- Aucune action automatique invasive : l'IA propose, Arthur confirme d'un clic
- Pas de "weekly review" automatique, pas de nudges
- Une fonctionnalité signature : le **bouton "Parler"** — enregistrement vocal → transcription → création d'une todo / idée / étape projet / événement agenda, avec validation explicite avant écriture en base
## Principes directeurs
1. **Self-hosted, open-source**. Pas de Vercel, pas de Next.js. Tout tourne sur le k3s d'Arthur.
2. **Single-user**. Pas de multi-tenant, pas d'invitations, pas de partage. Bearer token unique pour protéger l'API.
3. **PWA installable iOS**. Vite + React, pas de SSR. Service worker + mutation queue pour l'offline.
4. **BFF unique**. La PWA ne parle qu'au NestJS. Le Nest parle à Supabase, Mistral, Groq, Google Calendar, Telegram.
5. **Design éditorial / Swiss-brutalist** — mirror du portfolio arthurbarre.fr (cream, ink, orange, borders, mono labels).
## Stack verrouillée
| Couche | Choix |
| --- | --- |
| Monorepo | pnpm workspaces + Turborepo |
| Frontend | Vite + React 18 + TanStack Router + TanStack Query + Tailwind + shadcn/ui |
| Backend | NestJS + `@supabase/supabase-js` (pas d'ORM) |
| DB | Postgres via Supabase self-hosted, schéma dédié `ordinarthur_os` |
| Auth | Bearer token statique (single-user), middleware Nest |
| IA LLM | Mistral `mistral-small-latest` (low-cost) via API |
| STT | Groq `whisper-large-v3-turbo` |
| Bot | Telegram Bot API (webhook) |
| Calendar | Google Calendar API (Apple souscrit au calendar Google via webcal) |
| Langue IA | FR only |
| Déploiement | Images Docker → Gitea Container Registry → pipeline Gitea Actions → k3s (Traefik + cert-manager supposés présents) |
| Backups | CronJob k8s `pg_dump --schema=ordinarthur_os` quotidien → stockage S3-compatible (à confirmer avec Arthur) |
## Roadmap — ordre d'implémentation
### Phase 0 — Scaffold (prio immédiate)
- Monorepo `pnpm-workspace.yaml`, `turbo.json`
- `apps/pwa` : Vite + React + Tailwind + shadcn + manifest PWA + service worker placeholder + routing TanStack
- `apps/api` : NestJS + module `health` + middleware bearer + client supabase initialisé
- `packages/shared` : types et zod schemas partagés
- `packages/db` : premier fichier de migration SQL créant le schéma `ordinarthur_os`
- `deploy/k8s` : manifests génériques (à adapter ensuite à la conf Gitea/Traefik d'Arthur)
- Design system : composants primitifs (`<Label>`, `<SectionHeader>`, `<GridFrame>`, `<DataChip>`, `<MetaRow>`) qui reproduisent le style arthurbarre.fr
- Routes `GET /health` et `POST /auth/verify`
### Phase 1 — Jobs (prio haute, remontée)
- Migration : tables `jobs`, `job_search_criteria`
- API : `POST /jobs/ingest` (bearer), `GET /jobs`, `PATCH /jobs/:id`, `GET/PUT /jobs/criteria`
- PWA : route `/jobs` avec filtres (toutes / remote / hybrid / marseille), rendu éditorial façon portfolio (lignes tableau, pas des cards violettes)
- PWA : route `/settings/jobs` pour éditer les critères (titres, localisations, stack[], remote_types[], salary_min, active)
- Dedup : clé unique `source_url`, update `last_seen_at` si déjà vu
- Rétention : jobs >30j auto-archivés (soft delete via `archived=true`)
- Le scheduled task Claude Code (hors repo) lit `/jobs/criteria?active=true` et push les résultats via `/jobs/ingest` quotidiennement à 7h
### Phase 2 — Todos riches
- Migration : table `todos` (voir ARCHITECTURE.md pour le schéma complet)
- API : CRUD + endpoints `/todos/:id/ai-enrich` (renvoie draft, ne sauve pas) et `/ai-enrich/apply` (après confirmation)
- PWA : route `/todos` avec inbox, filtres (status, priority, context, tags, project), édition inline
- Offline : mutation queue via Dexie, replay à la reconnexion, déduplication côté API via table `client_mutations`
### Phase 3 — Projets + Kanban
- Migrations : `projects`, `project_steps`, `project_ideas`
- API : CRUD projets, CRUD steps, reorder, CRUD ideas
- PWA : route `/projects`, détail projet avec kanban (colonnes backlog/todo/doing/review/done), zone idées
### Phase 4 — Agenda + Google Calendar sync
- Migration : `calendar_events`
- API : OAuth Google (scope calendar), CRUD events avec sync bi-directionnelle, endpoint `/agenda/ical/:secret.ics` pour souscription Apple
- PWA : route `/agenda` vue semaine + jour
### Phase 5 — IA : bouton texte + voice magic button
- Migration : `ai_actions` (log d'audit)
- API : `POST /ai/command` (texte → function calling Mistral → plan), `POST /ai/voice` (audio → Groq Whisper → texte → Mistral → plan), `POST /ai/command/confirm` (applique après clic user)
- Fonctions exposées au LLM : `create_todo`, `add_project_idea`, `add_project_step`, `create_calendar_event`, `toggle_daily_checkin`
- PWA : bouton "🎤 Parler" sur le dashboard, `Cmd-K` pour la barre de commande texte, modal de confirmation avant exécution
### Phase 6 — Telegram bot
- Webhook Nest `/telegram/webhook` signé (header `X-Telegram-Bot-Api-Secret-Token`)
- Commandes : `/today` (events + todos du jour), `/todo <texte>` (crée une todo), messages vocaux traités comme le voice magic button
- Rappel quotidien optionnel à une heure configurable (simple message, pas d'action auto)
### Phase 7 — Health tab
- Migration : `daily_checkins (day date PK, meds_taken boolean, note text?)`
- API : `GET /health/today`, `POST /health/today/toggle`
- PWA : slider/toggle simple "médocs pris aujourd'hui" + historique 30j minimaliste
### Phase 8 — Finance (reporté)
- Revolut perso n'a pas d'API → passer par GoCardless Bank Account Data (ex-Nordigen)
- À traiter uniquement quand les phases 07 sont stables
## Handoff Claude Code
Pour reprendre ce projet avec Claude Code (Sonnet) :
1. Lire `README.md`, `PLAN.md`, `ARCHITECTURE.md` dans cet ordre
2. Pointer `CLAUDE.md` du repo vers ces docs
3. Respecter les règles de collaboration d'Arthur :
- Pas de Next.js, pas de Vercel
- L'IA ne mute jamais la DB sans clic de confirmation
- Design = portfolio arthurbarre.fr (pas le violet/cyan du HTML jobs)
4. Avant de scaffolder, récupérer de l'utilisateur :
- Le dossier `/Users/arthurbarre/dev/perso/proxmox` (conf k3s) pour aligner les manifests
- Le skill `/deploy` ou `/create-deployment` qu'Arthur utilise pour ses autres déploiements Gitea
- Les secrets nécessaires : `MISTRAL_API_KEY`, `GROQ_API_KEY`, `TELEGRAM_BOT_TOKEN`, `GOOGLE_OAUTH_CLIENT_ID/SECRET`, `SUPABASE_URL`, `SUPABASE_SERVICE_ROLE_KEY`, `API_BEARER_TOKEN`
- Le choix du stockage backup S3-compatible (B2 / Scaleway / autre)
5. Attaquer par la Phase 0 (scaffold), puis Phase 1 (jobs) — c'est explicitement prioritaire dans la tête d'Arthur.
## Points ouverts à trancher avec Arthur
- Stockage backups (quel bucket S3-compatible ?)
- Gitea Container Registry vs GHCR (défaut proposé : Gitea CR, déjà présent dans sa stack)
- STT Groq → clé à créer côté Arthur
- Google OAuth → app Google Cloud à créer, redirect URI `https://api.os.arthurbarre.fr/agenda/google/oauth/callback`
- Bot Telegram → @BotFather → récupérer le token, configurer le webhook vers `https://api.os.arthurbarre.fr/telegram/webhook`