feat(oki): intro publique, chimen, PWA offline, contribuer, kréyòl, ton OKI
- Landing : intro « Pourquoi ce site ? » (Chat Control expliqué au grand public) + sommaire-chimen en 3 arcs (Fondations 🟢 / Reprendre le contrôle 🟡 / Autodéfense avancée 🔴) avec compte d'outils par catégorie - PWA : service worker offline-first (précache coquille, network-first avec repli cache pour les fiches consultées), badge hors-ligne discret - Page /contribuer (3 voies + forge labola) + template d'issue Forgejo .gitea/ISSUE_TEMPLATE/nouvo-zouti.yaml ; liens GitHub → labola.o-k-i.net - Fiches jumelles créoles : chargeur content/outils/gcf/, affichage selon la langue avec bandeaux « an chantyé » / « póko tradui », 6 pilotes (signal, protonmail, brave, bitwarden, ublock, quad9) — À FAIRE RELIRE par un locuteur natif - Ton OKI : les 6 mêmes fiches réécrites (tutoiement, registre militant-chaleureux) ; le script de migration n'écrase plus les fiches retravaillées (--force pour tout régénérer) - UI : View Transitions (respect reduced-motion), aide clavier « ? » (dialog natif, raccourcis / h a), progression locale « jès fèt » (localStorage uniquement, compteur visible après le premier geste) - docs/DEPLOYMENT.md : guide VPS (Caddy, nginx, YunoHost, Docker, rsync) - Audits : axe-core 0 violation (5 pages), Lighthouse 99-98/100/100/100 ; corrections contraste monogrammes + ordre des titres - Budgets : JS 46 Ko gzip, CSS 3,5 Ko, 59 pages prérendues Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
+18
-4
@@ -46,6 +46,17 @@ le contrat de validation (ADR-001).
|
||||
- Exemples et localisation ancrés territoire — jamais de Lorem ipsum
|
||||
hexagonal (doctrine §4.2).
|
||||
|
||||
### Fiches de référence pour le ton
|
||||
|
||||
Six fiches sont réécrites au registre OKI et servent de modèle : `signal`,
|
||||
`protonmail`, `brave`, `bitwarden`, `ublock`, `quad9`. Avant d'écrire ou de
|
||||
réviser une fiche, relis-en deux. Ce qui change par rapport au ton d'origine :
|
||||
tutoiement systématique, le geste avant la technique (« dix secondes, effet
|
||||
immédiat »), l'enjeu politique dit sans détour (« ta correspondance — pas une
|
||||
matière première publicitaire »), et un ancrage collectif (« commence par ton
|
||||
groupe de famille »). Le script de migration ne régénère jamais une fiche
|
||||
existante (`--force` pour tout écraser) : les réécritures sont protégées.
|
||||
|
||||
## Créole guadeloupéen (gcf)
|
||||
|
||||
- Les **micro-textes de l'interface** (boutons, filtres, états vides, marqueur
|
||||
@@ -55,10 +66,13 @@ le contrat de validation (ADR-001).
|
||||
- ⚠️ **Relecture par un locuteur natif requise** : les chaînes gcf actuelles
|
||||
sont un premier jet à valider avant mise en production. La graphie de
|
||||
référence à trancher (GEREC-F ou autre) doit être notée ici une fois choisie.
|
||||
- La traduction intégrale des fiches est un chantier éditorial séparé :
|
||||
le format prévu est un fichier jumeau `content/outils/gcf/<slug>.md` avec
|
||||
`lang: "gcf"` (le chargeur l'ignorera tant que la locale de contenu n'est
|
||||
pas activée).
|
||||
- Chaque fiche peut avoir sa **jumelle créole** : `content/outils/gcf/<slug>.md`
|
||||
(frontmatter minimal : `name`, `slug`, `lang: "gcf"` ; mêmes sections
|
||||
`## what/why/who/install`). Elle s'affiche automatiquement quand la personne
|
||||
choisit Kréyòl, avec un bandeau « tradiksyon an chantyé » ; sans jumelle,
|
||||
la version française s'affiche avec un bandeau « póko tradui ». Six jumelles
|
||||
pilotes existent (mêmes slugs que les fiches de référence ci-dessus) —
|
||||
**premier jet non relu**, à valider avant d'en faire des modèles.
|
||||
- Termes fixés : « zouti » (outil), « Ou pa manké ayen » (fin de liste),
|
||||
« Chwazi zouti ou » (héros), niveaux « Débitan / Entèmédia / Avansé ».
|
||||
|
||||
|
||||
@@ -0,0 +1,140 @@
|
||||
# Déployer lage-chat-control sur un VPS
|
||||
|
||||
Le site est **100 % statique** (ADR-001) : le déploiement consiste à poser le
|
||||
contenu du dossier `frontend/build/` derrière un serveur web. Pas de base de
|
||||
données, pas de service Node à maintenir, pas de tâche cron. Un miroir du site
|
||||
= une copie du dossier.
|
||||
|
||||
## 0. Prérequis
|
||||
|
||||
- Un VPS (1 vCPU / 512 Mo suffisent très largement) sous Debian/Ubuntu
|
||||
- Un nom de domaine pointant sur le VPS (enregistrement A/AAAA)
|
||||
- En local : Node ≥ 22.12 et pnpm (le build se fait **sur ta machine**,
|
||||
le VPS n'a besoin ni de Node ni de pnpm)
|
||||
|
||||
## 1. Construire le site
|
||||
|
||||
```sh
|
||||
git clone https://labola.o-k-i.net/cyber-mawonaj/lage-chat-control.git
|
||||
cd lage-chat-control/frontend
|
||||
pnpm install
|
||||
pnpm build # produit frontend/build/ (~60 pages statiques)
|
||||
```
|
||||
|
||||
## 2. Option A — Caddy (recommandé : TLS automatique)
|
||||
|
||||
```sh
|
||||
# sur le VPS
|
||||
sudo apt install caddy
|
||||
sudo mkdir -p /srv/lage-chat-control
|
||||
```
|
||||
|
||||
`/etc/caddy/Caddyfile` :
|
||||
|
||||
```caddy
|
||||
exemple.o-k-i.net {
|
||||
root * /srv/lage-chat-control
|
||||
file_server
|
||||
encode zstd gzip
|
||||
|
||||
# SvelteKit adapter-static : pages pré-générées + fallback
|
||||
try_files {path} {path}.html {path}/index.html /404.html
|
||||
|
||||
header {
|
||||
# le service worker doit pouvoir se mettre à jour
|
||||
Cache-Control "no-cache" /service-worker.js
|
||||
# assets immuables (noms hachés)
|
||||
Cache-Control "public, max-age=31536000, immutable" /_app/immutable/*
|
||||
# en-têtes de sécurité
|
||||
Strict-Transport-Security "max-age=31536000; includeSubDomains"
|
||||
X-Content-Type-Options "nosniff"
|
||||
Referrer-Policy "no-referrer"
|
||||
Permissions-Policy "camera=(), microphone=(), geolocation=()"
|
||||
# CSP stricte : le site n'a aucune dépendance externe
|
||||
Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Le TLS (Let's Encrypt) est automatique, rien d'autre à faire.
|
||||
|
||||
## 3. Option B — nginx
|
||||
|
||||
```sh
|
||||
sudo apt install nginx certbot python3-certbot-nginx
|
||||
```
|
||||
|
||||
`/etc/nginx/sites-available/lage-chat-control` :
|
||||
|
||||
```nginx
|
||||
server {
|
||||
server_name exemple.o-k-i.net;
|
||||
root /srv/lage-chat-control;
|
||||
index index.html;
|
||||
|
||||
# pages pré-générées : /outils → outils.html, fallback 404
|
||||
location / {
|
||||
try_files $uri $uri.html $uri/index.html /404.html;
|
||||
}
|
||||
|
||||
location /_app/immutable/ {
|
||||
add_header Cache-Control "public, max-age=31536000, immutable";
|
||||
}
|
||||
|
||||
location = /service-worker.js {
|
||||
add_header Cache-Control "no-cache";
|
||||
}
|
||||
|
||||
add_header X-Content-Type-Options "nosniff" always;
|
||||
add_header Referrer-Policy "no-referrer" always;
|
||||
add_header Permissions-Policy "camera=(), microphone=(), geolocation=()" always;
|
||||
add_header Content-Security-Policy "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; font-src 'self'; connect-src 'self'; frame-ancestors 'none'; base-uri 'self'" always;
|
||||
|
||||
gzip on;
|
||||
gzip_types text/html text/css application/javascript application/json image/svg+xml;
|
||||
}
|
||||
```
|
||||
|
||||
```sh
|
||||
sudo ln -s /etc/nginx/sites-available/lage-chat-control /etc/nginx/sites-enabled/
|
||||
sudo nginx -t && sudo systemctl reload nginx
|
||||
sudo certbot --nginx -d exemple.o-k-i.net # TLS
|
||||
```
|
||||
|
||||
## 4. Publier (et republier)
|
||||
|
||||
```sh
|
||||
# depuis ta machine, après chaque `pnpm build`
|
||||
rsync -avz --delete frontend/build/ vps:/srv/lage-chat-control/
|
||||
```
|
||||
|
||||
C'est l'intégralité du « pipeline de déploiement ». Pour automatiser :
|
||||
un runner Forgejo Actions sur labola peut exécuter build + rsync à chaque
|
||||
push sur `main` (à ajouter quand le besoin se présente, pas avant).
|
||||
|
||||
## 5. Option C — YunoHost
|
||||
|
||||
Le site s'installe avec l'app **`my_webapp`** (site statique) :
|
||||
|
||||
1. Installe `my_webapp` depuis le catalogue, choisis le domaine/chemin.
|
||||
2. Copie le contenu de `frontend/build/` dans le dossier `www/` de l'app
|
||||
(SFTP ou rsync avec l'utilisateur dédié créé par l'app).
|
||||
3. Dans la config nginx avancée de l'app, ajoute le bloc `try_files` ci-dessus.
|
||||
|
||||
YunoHost gère TLS, HSTS et le renouvellement des certificats.
|
||||
|
||||
## 6. Option D — Docker
|
||||
|
||||
Le `Dockerfile` et `docker/nginx.conf` du dépôt (hérités du site Astro)
|
||||
servent déjà un site statique durci ; adapter le chemin de copie vers
|
||||
`frontend/build/` si tu veux cette voie. Utile pour l'infra OKI si tout
|
||||
le reste tourne déjà en conteneurs — sinon les options A/B sont plus simples.
|
||||
|
||||
## 7. Vérifier après mise en ligne
|
||||
|
||||
- [ ] `curl -sI https://exemple.o-k-i.net | grep -i content-security` → CSP présente
|
||||
- [ ] La page `/outils` répond (et `/outils?cat=messagerie` filtre)
|
||||
- [ ] DevTools > Application > Service worker : enregistré ; passer hors-ligne
|
||||
et recharger une fiche déjà visitée → elle s'affiche
|
||||
- [ ] observatory.mozilla.org : note A/A+ attendue avec les en-têtes ci-dessus
|
||||
- [ ] Aucune requête sortante vers un domaine tiers (onglet Réseau)
|
||||
Reference in New Issue
Block a user