update guidelines
This commit is contained in:
parent
22e5ed1a15
commit
242abdba5d
@ -33,7 +33,12 @@ ordinarthur-os/
|
||||
│ │ │ └── icons/ # 192, 512, maskable, apple-touch
|
||||
│ │ └── src/
|
||||
│ │ ├── routes/ # / /jobs /todos /projects /agenda /health /settings/*
|
||||
│ │ ├── components/ # Composants métier
|
||||
│ │ ├── components/ # Composants métier, organisés par domaine
|
||||
│ │ │ ├── ai/ # MagicButton, VoiceConfirmModal
|
||||
│ │ │ ├── health/ # MedsSlider (UI pure), MedsSection (data + layout)
|
||||
│ │ │ ├── jobs/
|
||||
│ │ │ ├── todos/
|
||||
│ │ │ └── …
|
||||
│ │ ├── design/ # Tokens + primitives éditoriales
|
||||
│ │ ├── api/ # Client HTTP typé, zod parse
|
||||
│ │ ├── offline/ # sw.ts, dexie.ts, mutationQueue.ts
|
||||
@ -131,7 +136,51 @@ theme: {
|
||||
- Motion minimal (fade ≤ 200ms), pas d'animation flashy
|
||||
- `accent-pulse` : petit dot orange qui pulse doucement pour marquer "live/disponible" (voir header portfolio)
|
||||
|
||||
## 4. Schéma Postgres `ordinarthur_os`
|
||||
## 4. Conventions composants PWA
|
||||
|
||||
### Séparation UI / data
|
||||
|
||||
Chaque feature suit un découpage strict en deux niveaux :
|
||||
|
||||
| Niveau | Fichier | Responsabilité |
|
||||
| --- | --- | --- |
|
||||
| **UI pure** | `ComponentName.tsx` | Props uniquement, aucun `useQuery`/`useMutation`, pas d'import `api`. Testable en isolation. |
|
||||
| **Section data** | `ComponentNameSection.tsx` | Encapsule le `useQuery` + `useMutation` TanStack Query, compose le composant UI, gère l'état de chargement. |
|
||||
|
||||
La route (`routes/*.tsx`) ne fait jamais de fetching pour une feature tierce — elle importe la `Section` correspondante et la pose.
|
||||
|
||||
**Exemple : médocs**
|
||||
|
||||
```
|
||||
components/health/
|
||||
MedsSlider.tsx ← drag UI, props: medsTaken / onToggle / disabled
|
||||
MedsSection.tsx ← query GET /health-tab/today + mutation POST toggle
|
||||
```
|
||||
|
||||
```tsx
|
||||
// routes/index.tsx — la route ne sait rien de l'API health
|
||||
import { MedsSection } from "@/components/health/MedsSection";
|
||||
// …
|
||||
<MedsSection />
|
||||
```
|
||||
|
||||
### Organisation des dossiers `components/`
|
||||
|
||||
Un sous-dossier par domaine métier, aligné sur les modules NestJS :
|
||||
|
||||
```
|
||||
components/
|
||||
ai/ # MagicButton, VoiceConfirmModal
|
||||
health/ # MedsSlider, MedsSection
|
||||
jobs/
|
||||
todos/
|
||||
projects/
|
||||
agenda/
|
||||
```
|
||||
|
||||
Pas de dossier `common/` fourre-tout. Les primitives partagées (bordures, labels, empty states) vivent dans `design/`.
|
||||
|
||||
## 5. Schéma Postgres `ordinarthur_os`
|
||||
|
||||
Source de vérité : les définitions Drizzle dans [`packages/db/src/schema/`](./packages/db/src/schema/). Le SQL ci-dessous est l'équivalent dénormalisé, à titre de référence — les migrations réelles vivent dans `packages/db/migrations/`.
|
||||
|
||||
@ -296,7 +345,7 @@ create table client_mutations (
|
||||
|
||||
**Pas de RLS.** La base n'est jamais exposée : le seul client SQL est le backend NestJS (ClusterIP interne au k3s, credentials Postgres classiques). La PWA est derrière le bearer Nest.
|
||||
|
||||
## 5. API NestJS — routes
|
||||
## 6. API NestJS — routes
|
||||
|
||||
Middleware global : `BearerGuard` sauf `/health`, `/telegram/webhook` (signé autrement), `/agenda/ical/:secret.ics` (secret URL).
|
||||
|
||||
@ -376,7 +425,7 @@ type ProposedAction =
|
||||
|
||||
Flow garanti : l'API **ne jamais** exécute une action directement. Elle renvoie un `ProposedAction[]` à la PWA, qui affiche une modal de confirmation. Seul `/ai/command/confirm` écrit en DB.
|
||||
|
||||
## 6. PWA — routing & pages
|
||||
## 7. PWA — routing & pages
|
||||
|
||||
```
|
||||
/ Dashboard (events du jour, todos due today, médocs, bouton 🎤, Cmd-K)
|
||||
@ -399,7 +448,7 @@ Flow garanti : l'API **ne jamais** exécute une action directement. Elle renvoie
|
||||
- Au retour online : `POST /sync/replay` séquentiel, l'API déduplique via `client_mutations` (idempotence)
|
||||
- UI optimiste via `useMutation` TanStack Query (`onMutate` update cache, `onError` rollback)
|
||||
|
||||
## 7. Voice magic button
|
||||
## 8. Voice magic button
|
||||
|
||||
1. `MediaRecorder` dans le navigateur → blob WebM/Opus
|
||||
2. `POST /ai/voice` (multipart) vers NestJS
|
||||
@ -410,7 +459,7 @@ Flow garanti : l'API **ne jamais** exécute une action directement. Elle renvoie
|
||||
7. PWA affiche modal : "Tu veux faire : …" avec boutons **Confirmer** / **Annuler** / **Éditer**
|
||||
8. Sur Confirmer → `POST /ai/command/confirm` → Nest exécute + update `ai_actions.status='confirmed'`
|
||||
|
||||
## 8. Déploiement k3s
|
||||
## 9. Déploiement k3s
|
||||
|
||||
### Ingress
|
||||
|
||||
@ -512,7 +561,7 @@ jobs:
|
||||
kubectl set image deploy/pwa pwa=gitea.arthurbarre.fr/arthurbarre/ordinarthur-os-pwa:${{ github.sha }}
|
||||
```
|
||||
|
||||
## 9. Sécurité
|
||||
## 10. Sécurité
|
||||
|
||||
- TLS everywhere via cert-manager
|
||||
- Bearer token Nest : stocké seulement dans les secrets k8s, jamais dans le bundle PWA → la PWA demande le token à l'utilisateur (écran d'onboarding) et le stocke dans `localStorage` (accès par Arthur uniquement sur son device)
|
||||
@ -521,7 +570,7 @@ jobs:
|
||||
- Postgres : service ClusterIP interne au k3s, jamais exposé ; credentials via Secret k8s
|
||||
- Backups : quotidien, chiffrés au repos côté bucket, rétention 30 jours
|
||||
|
||||
## 10. Observabilité (phase ultérieure)
|
||||
## 11. Observabilité (phase ultérieure)
|
||||
|
||||
- Logs Nest en JSON → si Arthur a déjà Loki/Grafana, les envoyer là
|
||||
- Health probes Liveness / Readiness sur `/health`
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user