Aller au contenu

App Family

Statut

En production sur family.2h15.fr — LXC 112


Vue d'ensemble

Application web PWA partagée entre Val et Milie. Installable sur iOS et Android sans passer par les stores. Accessible publiquement, sans authentification.

Propriété Valeur
URL https://family.2h15.fr
LXC 112 — IP 192.168.1.65
Stack PWA React/Vite + FastAPI + PostgreSQL + Nginx
Accès Public, sans auth
Favicon Maison violette + cœur rose

Architecture

Internet → NPM (LXC 101) → Nginx (LXC 112, port 80)
                                ├── /          → dist/ (React build)
                                └── /api/      → FastAPI (port 8000)
                                                    └── PostgreSQL (local)

Fichiers principaux

Chemin Rôle
/opt/family/backend/ Code FastAPI
/opt/family/backend/.env Variables d'environnement (DB, ntfy token)
/opt/family/frontend/ Code React/Vite
/opt/family/frontend/dist/ Build servi par Nginx
/opt/family/tokens/ Tokens OAuth Google (val.json, milie.json)
/opt/family/google_client_secret.json Credentials OAuth app Google Cloud
/opt/family/calendar_ids.json Mapping clé → ID calendrier Google

Interface

Ordre des onglets

🏠 Aujourd'hui · 📅 Calendrier · ✅ Todos · 🛒 Courses · 🍽️ Repas · 💑 Date Night · 🔧 Maison · 📝 Mémos

Thème sombre / clair

Le bouton 🌙/☀️ en haut à droite du header bascule entre thème clair et sombre. Le choix est persisté en localStorage. Le thème sombre est appliqué globalement via la classe html.dark, avec des overrides FullCalendar inclus.


Page d'accueil — Récap du jour

Affiché à l'ouverture de l'app :

  • Priorité haute — carte rouge listant les todos high non cochés (masquée si vide)
  • Événements du jour — tous calendriers confondus, avec l'heure et le badge Val/Milie si assigné
  • Todos du jour — items dont l'échéance est aujourd'hui, cochables directement depuis cette page

Onglet Calendrier

Affichage

  • Vue Planning 7 jours par défaut (7 jours glissants à partir d'aujourd'hui)
  • Toolbar : ← titre → en header pour naviguer, boutons Aujourd'hui · Mois · Semaine · Planning en footer
  • Format de date en vue Planning : "mercredi 13 mai 2026"

Couleurs des calendriers

Calendrier Couleur
Val (personnel) Bleu foncé #1e3a8a
Milie (personnel) Orange #f97316
The Floating Valley Cyan #06b6d4
Beat Cheese Jaune #eab308
Anniversaires Rouge #dc2626 (titres commençant par 🎂 ou contenant "anniv")

Créer un événement

  • Cliquer sur + Ajouter ou directement sur une date dans le calendrier
  • Champs : titre, début, fin, assigné à (Val / Milie / Les deux)
  • Toute la journée : case à cocher — bascule en sélecteur de date simple, champ Fin masqué, propagé à Google Calendar en format date-only
  • Types d'événement : cases à cocher — génèrent automatiquement des todos et des rappels ntfy
  • Champ Notes : stocké en description, synchronisé avec Google Calendar dans les deux sens

Modifier / supprimer un événement

  • Cliquer sur un événement → formulaire d'édition
  • Bouton 🗑 pour supprimer
  • Toute modification/suppression est propagée immédiatement sur Google Calendar

Événements récurrents

Les occurrences affichent un badge 🔁 Événement récurrent. Un dialog propose trois portées avant toute modification ou suppression :

Portée Effet
Cet événement uniquement Modifie/supprime cette occurrence seulement
Cet événement et les suivants Modifie/supprime cette occurrence et toutes les suivantes
Toute la série Modifie/supprime toutes les occurrences

Recherche d'événements

Barre de recherche dans l'onglet Calendrier : param search sur GET /api/events/, résultats triés par proximité à aujourd'hui, dropdown avec debounce 300ms, clic → modal d'édition.

Synchronisation Google Calendar

La sync est bidirectionnelle :

  • Google → App : import automatique toutes les 5 minutes (cron LXC 112)
  • App → Google : toute création, modification ou suppression depuis l'app est propagée immédiatement
  • Fenêtre de sync : 30 jours passés + 180 jours à venir

4 calendriers synchronisés :

Clé Calendrier Compte OAuth
val_primary valentinlucchini@gmail.com val
val_floating_valley floatingvalley.band@gmail.com val
val_beat_cheese beatcheese.band@gmail.com val
milie_primary amelie.leotard@gmail.com milie

Onglet Todos

Deux listes distinctes sur la même page :

Sans date

Items flottants sans échéance — triés par priorité (haute → normale → basse).

Avec date

Items datés triés par échéance. Inclut les todos générés automatiquement par les types d'événements.

Comportements

  • Assignable à : Val / Milie / Personne
  • Priorité : 🔴 Haute / 🟡 Normale / 🟢 Basse
  • Items cochés : restent visibles en bas de liste, séparés par un trait en pointillés
  • Modifier un item : cliquer sur son libellé → modal pré-remplie (titre, date, priorité, assigné)

Onglet Courses

  • Organisée par rayons/catégories, dans l'ordre défini dans l'admin
  • Cocher un article le barre (reste visible jusqu'à clôture)
  • Modifier un article : cliquer sur son libellé → modal pré-remplie (nom, quantité, rayon)
  • Clôturer la liste → archive dans l'historique, repart à zéro

Onglet Repas

Liste d'idées de repas.

  • Cochables : cochés en gras en haut, non cochés en bas (chaque groupe trié alphabétiquement)
  • Modifier : cliquer sur le nom → édition inline

Onglet Date Night

Liste d'activités à faire ensemble (Val + Milie).

Fonctionnalités

  • Ajouter une activité : nom + notes
  • Roulette : animation de sélection aléatoire, 1 respin possible ; l'activité ignorée reste dans le pool
  • Planifier : date picker → crée un événement "Date Night 🌙" de 21h à 23h avec l'activité en description ; l'activité est marquée done à la création de l'événement (récupérable manuellement)
  • Activités done filtrées de la roulette

Notification

Chaque dimanche à 21h, ntfy topic family — rappel de planifier une soirée ensemble.


Onglet Maison

Projets maison avec checklist d'étapes.

Champs d'un projet

Champ Description
Nom Titre du projet
Pièce Texte libre avec autocomplete sur les pièces existantes
Priorité Haute / Normale / Basse
Budget Montant estimé
Notes Description libre
URL Lien vers un produit, un tuto, etc.

Étapes

Chaque projet peut avoir une checklist d'étapes, avec : - Assignee par étape (Val / Milie / Les deux) - Le statut du projet est auto-dérivé des étapes (À faire / En cours / Terminé) - Pour les projets sans étapes : bouton pour marquer manuellement comme terminé, bouton pour remettre en cours

Organisation

  • Tri par priorité dans chaque groupe + ordre manuel ↑↓ (boutons en colonne à gauche, occupent toute la hauteur)
  • Filtre par pièce
  • Budget total affiché en haut
  • Projets terminés séparés en bas avec opacité réduite (séparateur "Terminés (X)"), boutons ↑↓ masqués

Onglet Mémos

Canal de communication entre Val/Milie et Claude. Accessible depuis le téléphone pour capturer des idées et retours en cours d'utilisation.

Types de mémos

Type Usage
Backlog Family Fonctionnalité ou bug à traiter dans l'app Family
Backlog Global Chantier homelab ou idée infrastructure
Note Mémo libre sans catégorie

Pour Claude

pct exec 112 -- curl -s http://127.0.0.1:8000/api/memos/ | python3 -m json.tool

Administration

Accessible via le bouton ⚙️ en haut à droite.

Onglet Types d'événements

Chaque type définit : nom, délai de rappel, modèle de todo ({event} et {date}), couleur, assigné auto.

Types configurés :

Type Rappel Todo généré
Faire garder Daphné 2 semaines avant "Trouver quelqu'un pour garder Daphné pour {event} le {date}"
Faire des courses 3 jours avant "Faire des courses pour {event} le {date}"
Emmener des jeux 1h avant "Emmener des jeux pour {event} le {date}"

Onglet Rayons

Gestion des catégories de la liste de courses avec ordre d'affichage.

Onglet OAuth

Statut des comptes Google Calendar. Lien Connecter si le token est absent ou expiré.


Notifications (ntfy)

Topic Contenu Déclencheur
family Récap des événements du jour + todos haute priorité non cochés Cron 7h00 quotidien
family Rappel d'un événement J-X à l'heure exacte selon le type
family Rappel Date Night Dimanche 21h
anniversaires Anniversaires du jour + à venir 7j Cron 7h05 quotidien (4 calendriers Google)

Topic family — abonnement Milie

Milie a accès en lecture aux topics anniversaires et family sur ntfy.2h15.fr.

Timezone CronTrigger

Le LXC 112 est en UTC. Le timezone="Europe/Paris" doit être passé directement aux CronTrigger dans scheduler/jobs.py.


Gestion des tokens OAuth

Si un token expire :

  1. Aller dans l'admin → onglet OAuth
  2. Cliquer Connecter pour le compte concerné
  3. Se connecter avec le bon compte Google et autoriser

Les tokens sont dans /opt/family/tokens/val.json et /opt/family/tokens/milie.json.


Checklist déploiement

  • [x] Créer LXC 112
  • [x] Installer dépendances (Node.js 20, Python 3.11, PostgreSQL 15, Nginx)
  • [x] Développer le backend FastAPI + PostgreSQL
  • [x] Développer le frontend PWA React/Vite
  • [x] Configurer OAuth2 Google Calendar (Val + Milie)
  • [x] Configurer entrée NPM → family.2h15.fr (SSL Let's Encrypt)
  • [x] Ajouter au dashboard de supervision
  • [x] Créer monitor Uptime Kuma
  • [x] Configurer topic ntfy family + accès Milie

Backlog

En attente

Rien en attente actuellement.

Terminé

Sujet Date Détail
Marquer terminé sans étapes 2026-07-26 Colonne manually_done, bouton ✓/↩, statut auto-dérivé conservé pour projets avec étapes
Projets terminés en bas 2026-07-26 Séparateur "Terminés (X)", opacité réduite, boutons ↑↓ masqués
Onglet Maison 2026-06-30 Projets + étapes, priorité, budget, pièce autocomplete, assignee par étape
Onglet Date Night 2026-06-30 Roulette, planification événement, notif dimanche 21h
Événements all-day 2026-05-29 Checkbox "Toute la journée", input date simple, propagé à Google Calendar
Sync Google Calendar automatique 2026-05-12 Cron toutes les 5 min sur LXC 112
Propagation App → Google Calendar 2026-05-13 Créations, modifications et suppressions propagées immédiatement
Gestion événements récurrents 2026-05-13 Dialog de portée (this / following / all)
Vue Calendrier par défaut en Planning 2026-05-13 Vue custom list7Days (7 jours glissants)
Thème sombre / clair 2026-05-13 Bouton 🌙/☀️ dans le header, classe html.dark
Todos cochés 2026-05-13 Actifs en haut, cochés en bas avec séparateur en pointillés
Canal de communication phone → Claude 2026-05-13 Onglet Mémos (📝)