Skip to content

Commit f35794b

Browse files
Florian Flahautclaude
andcommitted
Add server backend: SQLite DB, household auth, notifications, PWA
- SQLite persistence via built-in node:sqlite (no native deps); garden and plots moved from localStorage to a server-backed REST API with optimistic client hooks - Household-password auth: DB-backed cookie sessions, login/logout server actions, route gating via Next 16 proxy.ts - Pluggable notifier (Discord webhook, Home Assistant, Web Push/VAPID) with a cron-triggered monthly digest at /api/notify/run - Installable PWA: manifest, service worker (push + offline), icons, per-device push opt-in - GitHub Actions CI (lint, typecheck, build); .env.example and README deployment/notification docs Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
1 parent f286a09 commit f35794b

34 files changed

Lines changed: 1547 additions & 107 deletions

.env.example

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# ── Mon Potager — variables d'environnement ──────────────────────────────
2+
# Copier en `.env` (dev) ou `.env.production` (serveur) et renseigner.
3+
4+
# ── Authentification (mot de passe foyer) ────────────────────────────────
5+
# Si vide/non défini : l'auth est désactivée (accès libre sur le LAN).
6+
HOUSEHOLD_PASSWORD=change-moi
7+
8+
# ── Base de données ──────────────────────────────────────────────────────
9+
# Chemin du fichier SQLite (défaut : ./data/potager.db)
10+
# DATABASE_PATH=/var/lib/potager/potager.db
11+
12+
# ── Notifications : déclencheur cron ─────────────────────────────────────
13+
# Secret exigé pour appeler POST /api/notify/run
14+
CRON_SECRET=un-secret-long-et-aleatoire
15+
# Décalage de zone pour le digest (-1 = sud, 0 = tempéré, 1 = nord)
16+
NOTIFY_ZONE_OFFSET=0
17+
18+
# ── Notifications : Discord ──────────────────────────────────────────────
19+
# DISCORD_WEBHOOK_URL=https://discord.com/api/webhooks/xxxx/yyyy
20+
21+
# ── Notifications : Home Assistant ───────────────────────────────────────
22+
# Option A — webhook HA (le plus simple) :
23+
# HA_WEBHOOK_URL=https://ha.mondomaine.fr/api/webhook/potager
24+
# Option B — API REST + service notify + long-lived token :
25+
# HA_BASE_URL=https://ha.mondomaine.fr
26+
# HA_TOKEN=eyJ...long-lived-token...
27+
# HA_NOTIFY_SERVICE=mobile_app_mon_telephone
28+
29+
# ── Notifications : Web Push (PWA) ───────────────────────────────────────
30+
# Générer les clés : npx web-push generate-vapid-keys
31+
# NEXT_PUBLIC_VAPID_PUBLIC_KEY=BMxxxx...
32+
# VAPID_PRIVATE_KEY=xxxx...
33+
# VAPID_SUBJECT=mailto:vous@example.com

.github/workflows/ci.yml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [master, main]
6+
pull_request:
7+
8+
jobs:
9+
build:
10+
runs-on: ubuntu-latest
11+
steps:
12+
- uses: actions/checkout@v4
13+
14+
- name: Setup Node.js
15+
uses: actions/setup-node@v4
16+
with:
17+
node-version: 24
18+
cache: npm
19+
20+
- name: Install dependencies
21+
run: npm ci
22+
23+
- name: Generate route types
24+
run: npx next typegen
25+
26+
- name: Lint
27+
run: npm run lint
28+
29+
- name: Typecheck
30+
run: npx tsc --noEmit
31+
32+
- name: Build
33+
run: npm run build
34+
env:
35+
NEXT_TELEMETRY_DISABLED: "1"

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,10 @@ yarn-error.log*
3232

3333
# env files (can opt-in for committing if needed)
3434
.env*
35+
!.env.example
36+
37+
# base de données locale (SQLite)
38+
/data
3539

3640
# vercel
3741
.vercel

README.md

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,16 +18,36 @@ rien au jardinage.
1818
détection des voisinages déconseillés (compagnonnage).
1919
- **Zone climatique** — tout le calendrier se décale selon la région
2020
(Nord / France tempérée / Sud).
21+
- **Accès protégé** — mot de passe unique du foyer (session par cookie).
22+
- **Notifications** — rappels des tâches du mois envoyés sur **Discord**,
23+
**Home Assistant** et/ou **Web Push** (PWA), déclenchés par un cron.
24+
- **PWA installable** — installable sur mobile/desktop, fonctionnement
25+
hors-ligne basique via service worker.
2126

22-
Les données personnelles (jardin, plan) sont stockées dans le `localStorage`
23-
du navigateur : **aucune base de données ni backend** n'est nécessaire.
27+
Les données du foyer (jardin, plan) sont enregistrées côté serveur dans une
28+
base **SQLite** (`node:sqlite`, sans dépendance native).
2429

2530
## Stack technique
2631

27-
- [Next.js](https://nextjs.org/) 16 (App Router) + React 19
28-
- TypeScript
29-
- Tailwind CSS v4
30-
- Node.js 24
32+
- [Next.js](https://nextjs.org/) 16 (App Router, « Proxy ») + React 19
33+
- TypeScript · Tailwind CSS v4 · Node.js 24
34+
- Persistance : **SQLite** via le module intégré `node:sqlite`
35+
- Notifications Web Push : `web-push` (VAPID)
36+
37+
## Configuration (variables d'environnement)
38+
39+
Copier [`.env.example`](.env.example) en `.env` (dev) ou `.env.production`
40+
(serveur) et renseigner au minimum `HOUSEHOLD_PASSWORD`. Principales clés :
41+
42+
| Variable | Rôle |
43+
| --- | --- |
44+
| `HOUSEHOLD_PASSWORD` | Mot de passe du foyer. **Vide ⇒ auth désactivée** (accès libre LAN). |
45+
| `DATABASE_PATH` | Chemin du fichier SQLite (défaut `./data/potager.db`). |
46+
| `CRON_SECRET` | Secret exigé pour déclencher `/api/notify/run`. |
47+
| `NOTIFY_ZONE_OFFSET` | Décalage de zone du digest (-1 sud, 0 tempéré, 1 nord). |
48+
| `DISCORD_WEBHOOK_URL` | Webhook Discord (optionnel). |
49+
| `HA_WEBHOOK_URL` *ou* `HA_BASE_URL`+`HA_TOKEN`+`HA_NOTIFY_SERVICE` | Home Assistant (optionnel). |
50+
| `NEXT_PUBLIC_VAPID_PUBLIC_KEY` / `VAPID_PRIVATE_KEY` / `VAPID_SUBJECT` | Web Push (optionnel). Générer : `npx web-push generate-vapid-keys`. |
3151

3252
## Développement local
3353

@@ -48,9 +68,10 @@ npm run lint
4868

4969
## Déploiement — Proxmox / conteneur LXC
5070

51-
> Procédure de référence. L'app est un serveur Next.js sans base de données ;
52-
> il suffit d'un conteneur Linux avec Node.js 24, du build, et d'un service
53-
> qui maintient le process en vie derrière un reverse proxy.
71+
> Procédure de référence. L'app est un serveur Next.js avec une base SQLite
72+
> locale (fichier) : il suffit d'un conteneur Linux avec Node.js 24, du build,
73+
> d'un fichier `.env.production`, et d'un service qui maintient le process en
74+
> vie derrière un reverse proxy.
5475
5576
### 1. Créer le conteneur LXC (sur l'hôte Proxmox)
5677

@@ -81,13 +102,23 @@ su - potager
81102
git clone https://github.com/Flalal/potager.git
82103
cd potager
83104
npm ci
105+
106+
# Configurer l'environnement (au minimum le mot de passe du foyer)
107+
cp .env.example .env.production
108+
nano .env.production # HOUSEHOLD_PASSWORD, CRON_SECRET, notifs…
109+
84110
npm run build
85111
```
86112

87113
> Le dépôt est **privé** : pour `git clone`, utiliser un Personal Access Token
88114
> (`https://<TOKEN>@github.com/Flalal/potager.git`) ou une clé de déploiement
89115
> SSH ajoutée au dépôt.
90116
117+
> La base SQLite est créée automatiquement au premier lancement sous
118+
> `./data/potager.db`. Pour la placer sur un volume persistant, définir
119+
> `DATABASE_PATH=/var/lib/potager/potager.db` (créer le dossier, propriétaire
120+
> `potager`).
121+
91122
### 4. Lancer en service (systemd)
92123

93124
Créer `/etc/systemd/system/potager.service` (en root) :
@@ -103,6 +134,9 @@ User=potager
103134
WorkingDirectory=/home/potager/potager
104135
Environment=NODE_ENV=production
105136
Environment=PORT=3000
137+
# node:sqlite est « expérimental » et émet un warning au démarrage : on le tait
138+
Environment=NODE_OPTIONS=--no-warnings
139+
EnvironmentFile=/home/potager/potager/.env.production
106140
ExecStart=/usr/bin/npm run start
107141
Restart=on-failure
108142

@@ -132,7 +166,21 @@ potager.mondomaine.fr {
132166

133167
Caddy gère automatiquement le certificat TLS Let's Encrypt.
134168

135-
### 6. Mises à jour
169+
### 6. Notifications (cron)
170+
171+
Les rappels du mois sont envoyés quand on appelle `/api/notify/run` (protégé
172+
par `CRON_SECRET`). Planifier un appel, par ex. tous les lundis à 8 h, via la
173+
crontab du conteneur (`crontab -e`) :
174+
175+
```cron
176+
0 8 * * 1 curl -fsS -X POST "https://potager.mondomaine.fr/api/notify/run?secret=VOTRE_CRON_SECRET" >/dev/null
177+
```
178+
179+
Les canaux actifs dépendent des variables définies (`DISCORD_WEBHOOK_URL`,
180+
`HA_*`, clés `VAPID`). Pour le **Web Push**, chaque appareil doit d'abord
181+
cliquer « 🔔 Activer les rappels » dans *Mon jardin*.
182+
183+
### 7. Mises à jour
136184

137185
```bash
138186
su - potager

0 commit comments

Comments
 (0)