diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index c621e45..350e5e1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,7 +11,7 @@ Parenthèse est maintenu par une seule personne. Les retours sont les bienvenus, ## Lancer le projet en local -Tout est dans la section « Développer » du [README](README.md). +Tout est dans la section « Développer » du [README](README.fr.md). ## Tests diff --git a/README.fr.md b/README.fr.md new file mode 100644 index 0000000..9212f85 --- /dev/null +++ b/README.fr.md @@ -0,0 +1,156 @@ +# Parenthèse + +[![CI](https://github.com/IliesAllali/parenthese/actions/workflows/ci.yml/badge.svg)](https://github.com/IliesAllali/parenthese/actions/workflows/ci.yml) + +Un arbre de famille qu'on explore comme une carte, avec les photos, les vidéos et les voix de chacun. Il se partage par un lien et un mot de passe : les proches le parcourent sans compte et ajoutent ce qu'ils savent. + +Site et démo : [parenthese.io](https://parenthese.io) · [English version](README.md) + +## Ce que fait l'application + +- Un arbre par famille : personnes, unions, liens parent-enfant, mise en page automatique. +- Des médias sur chaque personne : photos, vidéos (fichier ou lien YouTube), enregistrements audio pour garder une voix, documents, traces GPS. +- Des annotations libres sur l'arbre : dessins, stickers, textes, photos posées où l'on veut. +- Un partage par lien : chaque arbre a une adresse `/arbre/` protégée par un mot de passe de partage, qui permet de regarder et de proposer des ajouts. +- Une consultation sans compte : un proche qui reçoit le lien et le mot de passe ouvre l'arbre directement. +- Des contributions validées : le propriétaire choisit si les modifications des contributeurs s'appliquent tout de suite ou passent par une file de relecture, où il approuve ou rejette chaque changement. +- Import et export GEDCOM pour venir d'un autre logiciel ou en repartir (l'export contient les personnes et leurs liens, pas les fichiers médias). + +## La promesse + +- Gratuit, et le restera. +- Vos données restent les vôtres : pas de publicité, pas de revente. Ce que l'application enregistre et pourquoi est détaillé sur la page [Données et vie privée](https://parenthese.io/donnees-et-vie-privee/). +- Auto-hébergeable : le code est ouvert, une famille peut faire tourner sa propre instance sur son serveur ou son NAS sans dépendre de personne. + +## Auto-héberger + +Prérequis : Docker avec le plugin Compose (`docker compose version` doit répondre). + +```bash +git clone https://github.com/IliesAllali/parenthese.git +cd parenthese +cp .env.example .env +``` + +Ouvrez `.env` et remplissez les deux valeurs vides : + +- `POSTGRES_PASSWORD` : un mot de passe pour la base (lettres et chiffres). +- `JWT_SECRET` : une clé longue et aléatoire. Pour la générer : `openssl rand -base64 48` ou `node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"`. + +Puis : + +```bash +docker compose up -d +``` + +Le premier démarrage construit les images, applique les migrations de la base, puis sert l'application sur [http://localhost](http://localhost). Créez votre compte depuis l'écran d'accueil : le premier compte est un compte comme les autres, il n'y a pas d'administrateur global. + +Trois conteneurs tournent : `db` (PostgreSQL 16), `api` (l'API Node) et `web` (nginx qui sert le front et relaie l'API). Seul `web` est exposé, sur le port choisi par `WEB_PORT` (80 par défaut). Si ce port est déjà pris, changez `WEB_PORT` dans `.env` et adaptez `CORS_ORIGIN` en conséquence. + +Pour ouvrir l'instance à la famille depuis Internet, placez un reverse proxy HTTPS devant le port `web` (Caddy, Traefik, nginx) et mettez l'adresse publique dans `CORS_ORIGIN`, par exemple `https://arbre.votre-domaine.fr`. + +Une instance auto-hébergée n'envoie aucune mesure d'audience : le suivi d'usage de parenthese.io ne s'active que si une clé PostHog est fournie au build, ce que cette configuration ne fait pas. + +Commandes utiles : + +```bash +docker compose logs -f api # journal de l'API +docker compose ps # état des conteneurs +docker compose down # arrêt, les données sont conservées +``` + +Pour vérifier qu'une installation fonctionne de bout en bout, lancez `bash tools/docker-smoke.sh http://localhost` (avec le port si `WEB_PORT` n'est pas 80). Le script a besoin de `curl` et `jq`. Il passe par le port web comme un navigateur : page d'accueil, santé de l'API, création d'un compte, connexion, création puis suppression d'un arbre de test. Le compte de test (`smoke-...@example.com`) reste en base. + +### Où sont les données + +Deux volumes Docker, conservés entre les redémarrages et les mises à jour : + +- `parenthese_db-data` : la base PostgreSQL (personnes, liens, comptes, contributions). +- `parenthese_media` : les fichiers envoyés (photos, vidéos, audio, documents). + +### Sauvegardes + +Avec Docker, une sauvegarde tient en deux commandes, à lancer depuis le dossier du dépôt : + +```bash +docker compose exec -T db pg_dump -U parenthese -Fc parenthese > parenthese-db-$(date +%F).dump +docker run --rm -v parenthese_media:/data -v "$PWD":/backup alpine tar -czf /backup/parenthese-media-$(date +%F).tar.gz -C /data . +``` + +Adaptez `-U parenthese` et le nom de base si vous avez changé `POSTGRES_USER` ou `POSTGRES_DB`. Pour restaurer la base : `docker compose exec -T db pg_restore -U parenthese -d parenthese --clean < parenthese-db-AAAA-MM-JJ.dump`, puis décompressez l'archive des médias dans le volume avec la même commande `docker run`, `tar -xzf` à la place de `-czf`. + +Le script `deploy/backup.sh` fait la même chose (dump PostgreSQL, archive des médias, sommes de contrôle, rotation, envoi S3 optionnel) pour une installation sans Docker : il lit `backend/.env` et a besoin de `pg_dump` sur la machine. Ses réglages passent par les variables `BACKUP_ROOT`, `BACKUP_RETENTION_DAYS` et `BACKUP_S3_BUCKET`. + +### Mettre à jour + +```bash +git pull && docker compose up -d --build +``` + +Les migrations de base de données s'appliquent toutes seules au démarrage de l'API. Faites une sauvegarde avant, par habitude. + +## Développer + +Le dépôt contient trois projets Node : `backend/` (Fastify, Prisma, PostgreSQL, TypeScript), `frontend/` (React, Vite) et `landing/` (le site vitrine, inutile pour faire tourner l'application). Les images Docker utilisent Node 24. + +### Backend + +```bash +npm --prefix backend install +npm --prefix backend run db:bootstrap +npm --prefix backend run dev +``` + +`db:bootstrap` démarre un PostgreSQL portable sous Windows (base `genealogy`, utilisateur `postgres`, port 5432) : les binaires doivent avoir été extraits dans `backend/.local/postgresql_full/pgsql`, le script ne les télécharge pas. Sur un autre système, n'importe quel PostgreSQL local convient : renseignez `DATABASE_URL` dans `backend/.env` (modèle dans `backend/.env.example`) et créez le schéma avec `npm --prefix backend run prisma:migrate`. + +Sur n'importe quel système avec Docker, une base jetable remplace `db:bootstrap` : + +```bash +docker run -d --name parenthese-dev-db -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=genealogy postgres:16 +npm --prefix backend run prisma:deploy +npm --prefix backend run dev +``` + +Avant `prisma:deploy`, `backend/.env` doit exister (copie de `backend/.env.example`) avec `DATABASE_URL="postgresql://postgres:postgres@localhost:5432/genealogy"`, qui correspond à ces identifiants. `docker stop parenthese-dev-db` arrête la base, `docker start parenthese-dev-db` la relance avec ses données. + +L'API écoute sur [http://localhost:4000](http://localhost:4000) et répond `{ "ok": true }` sur `/health`. + +### Frontend + +Créez `frontend/.env.development.local` : + +``` +VITE_API_BASE_URL= +VITE_DEV_PROXY_TARGET=http://127.0.0.1:4000 +VITE_DEV_PROXY_STRIP_API=1 +``` + +Puis : + +```bash +npm --prefix frontend install +npm --prefix frontend run dev +``` + +Le serveur Vite relaie `/api`, `/trees`, `/auth` et `/health` vers l'API locale en retirant le préfixe `/api`, comme le fait nginx en production. Sans ce fichier, le front appelle `http://localhost:4000` en direct et les liens partagés `/api/arbre/...` répondent 404. + +### Tests + +```bash +npm --prefix frontend test +npm --prefix backend test +``` + +## Contribuer + +Issues et petites pull requests ciblées sont les bienvenues : la marche à suivre, les tests à faire passer et les conventions sont dans [CONTRIBUTING.md](CONTRIBUTING.md). Pour une faille de sécurité, pas d'issue publique : voir [SECURITY.md](SECURITY.md). + +## Licence + +Le code est publié sous [PolyForm Noncommercial 1.0.0](LICENSE). En clair : + +- Vous pouvez lire le code, le modifier et l'auto-héberger pour un usage non commercial, pour votre famille ou une association par exemple. +- Vous ne pouvez pas monter un service payant à partir de ce code. +- Le nom et le logo Parenthèse restent la propriété d'Ilies Allali. + +Le texte de la licence fait foi. diff --git a/README.md b/README.md index 23045d0..d51a376 100644 --- a/README.md +++ b/README.md @@ -2,29 +2,35 @@ [![CI](https://github.com/IliesAllali/parenthese/actions/workflows/ci.yml/badge.svg)](https://github.com/IliesAllali/parenthese/actions/workflows/ci.yml) -Une galaxie familiale plutôt qu'un arbre à cases. Chaque personne est un point, les unions et les filiations les relient, et l'on navigue dedans comme dans une carte. +A family tree you explore like a map, with the photos, videos and voices of each person. Share it with one link and a password: relatives look around without an account and add what they know. -Site et démo : [parenthese.io](https://parenthese.io) +Website: [parenthese.io/en](https://parenthese.io/en/) · Demo, no account needed: [app.parenthese.io](https://app.parenthese.io/?lang=en) · [Version française](README.fr.md) -## Ce que fait l'application +![The demo tree, with Jean Dupont's profile open and his photos](docs/demo-tree.png) -- Une galaxie par famille : personnes, unions, liens parent-enfant, mise en page automatique. -- Des médias sur chaque personne : photos, vidéos (fichier ou lien YouTube), enregistrements audio pour garder une voix, documents, traces GPS. -- Des annotations libres sur la galaxie : dessins, stickers, textes, photos posées où l'on veut. -- Un partage par lien : chaque galaxie a une adresse `/arbre/` protégée par un mot de passe visiteur et un mot de passe contributeur. -- Une consultation sans compte : un proche qui reçoit le lien et le mot de passe ouvre la galaxie directement. -- Des contributions validées : le propriétaire choisit si les modifications des contributeurs s'appliquent tout de suite ou passent par une file de relecture, où il approuve ou rejette chaque changement. -- Import et export GEDCOM pour venir d'un autre logiciel ou en repartir (l'export contient les personnes et leurs liens, pas les fichiers médias). +- **License:** source-available under [PolyForm Noncommercial 1.0.0](LICENSE). Free to read, modify and self-host for non-commercial use. Not an OSI open source license, see [License](#license). +- **How it was made:** designed and directed by Ilies Allali. Most of the code was written with Claude Code (Anthropic), then reviewed and tested before being published. -## La promesse +## What it does -- Gratuit, et le restera. -- Vos données restent les vôtres : pas de publicité, pas de revente. Ce que l'application enregistre et pourquoi est détaillé sur la page [Données et vie privée](https://parenthese.io/donnees-et-vie-privee/). -- Auto-hébergeable : le code est ouvert, une famille peut faire tourner sa propre instance sur son serveur ou son NAS sans dépendre de personne. +- One tree per family: people, couples, parent-child links, laid out automatically. +- Memories on each person: photos, videos (a file or a YouTube link), audio recordings to keep a voice, documents, GPS tracks. +- Free annotations on the tree: drawings, stickers, text, photos placed anywhere. +- Sharing by link: each tree has an address `/arbre/` protected by a sharing password. With it, relatives can look around and suggest additions. +- No account needed to visit: someone who receives the link and the password opens the tree directly. +- Reviewed contributions: the owner chooses whether the family's changes apply right away or go through a review queue, where each change is approved or declined. +- GEDCOM import and export, to come from another program or leave for one (the export holds the people and their links, not the media files). +- English and French interface. It follows the browser's language, with a switch in the app, and `?lang=en` or `?lang=fr` in the address forces one. -## Auto-héberger +## The promise -Prérequis : Docker avec le plugin Compose (`docker compose version` doit répondre). +- Free, and it will stay free. +- Your data stays yours: no ads, nothing sold. What the app records and why is on the [Data and privacy](https://parenthese.io/en/privacy/) page. +- Self-hostable: the code is public, and a family can run its own instance on a server or a NAS without depending on anyone. + +## Self-hosting + +Requirement: Docker with the Compose plugin (`docker compose version` must answer). ```bash git clone https://github.com/IliesAllali/parenthese.git @@ -32,66 +38,66 @@ cd parenthese cp .env.example .env ``` -Ouvrez `.env` et remplissez les deux valeurs vides : +Open `.env` and fill in the two empty values: -- `POSTGRES_PASSWORD` : un mot de passe pour la base (lettres et chiffres). -- `JWT_SECRET` : une clé longue et aléatoire. Pour la générer : `openssl rand -base64 48` ou `node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"`. +- `POSTGRES_PASSWORD`: a password for the database (letters and digits only). +- `JWT_SECRET`: a long random key. To generate one: `openssl rand -base64 48` or `node -e "console.log(require('crypto').randomBytes(48).toString('base64'))"`. -Puis : +Then: ```bash docker compose up -d ``` -Le premier démarrage construit les images, applique les migrations de la base, puis sert l'application sur [http://localhost](http://localhost). Créez votre compte depuis l'écran d'accueil : le premier compte est un compte comme les autres, il n'y a pas d'administrateur global. +The first start builds the images, applies the database migrations, then serves the app on [http://localhost](http://localhost). Create your account from the home screen. The first account is an account like any other, there is no global administrator. -Trois conteneurs tournent : `db` (PostgreSQL 16), `api` (l'API Node) et `web` (nginx qui sert le front et relaie l'API). Seul `web` est exposé, sur le port choisi par `WEB_PORT` (80 par défaut). Si ce port est déjà pris, changez `WEB_PORT` dans `.env` et adaptez `CORS_ORIGIN` en conséquence. +Three containers run: `db` (PostgreSQL 16), `api` (the Node API) and `web` (nginx, which serves the front end and proxies the API). Only `web` is exposed, on the port set by `WEB_PORT` (80 by default). If that port is taken, change `WEB_PORT` in `.env` and update `CORS_ORIGIN` to match. -Pour ouvrir l'instance à la famille depuis Internet, placez un reverse proxy HTTPS devant le port `web` (Caddy, Traefik, nginx) et mettez l'adresse publique dans `CORS_ORIGIN`, par exemple `https://arbre.votre-domaine.fr`. +To open the instance to your family over the Internet, put an HTTPS reverse proxy in front of the `web` port (Caddy, Traefik, nginx) and set the public address in `CORS_ORIGIN`, for example `https://tree.your-domain.com`. -Une instance auto-hébergée n'envoie aucune mesure d'audience : le suivi d'usage de parenthese.io ne s'active que si une clé PostHog est fournie au build, ce que cette configuration ne fait pas. +A self-hosted instance sends no analytics. Usage tracking on parenthese.io only turns on when a PostHog key is provided at build time, which this setup does not do. -Commandes utiles : +Useful commands: ```bash -docker compose logs -f api # journal de l'API -docker compose ps # état des conteneurs -docker compose down # arrêt, les données sont conservées +docker compose logs -f api # API log +docker compose ps # container status +docker compose down # stop, data is kept ``` -Pour vérifier qu'une installation fonctionne de bout en bout, lancez `bash tools/docker-smoke.sh http://localhost` (avec le port si `WEB_PORT` n'est pas 80). Le script a besoin de `curl` et `jq`. Il passe par le port web comme un navigateur : page d'accueil, santé de l'API, création d'un compte, connexion, création puis suppression d'une galaxie de test. Le compte de test (`smoke-...@example.com`) reste en base. +To check that an installation works end to end, run `bash tools/docker-smoke.sh http://localhost` (add the port if `WEB_PORT` is not 80). The script needs `curl` and `jq`. It goes through the web port like a browser: home page, API health, account creation, sign-in, creating then deleting a test tree. The test account (`smoke-...@example.com`) stays in the database. -### Où sont les données +### Where the data lives -Deux volumes Docker, conservés entre les redémarrages et les mises à jour : +Two Docker volumes, kept across restarts and updates: -- `parenthese_db-data` : la base PostgreSQL (personnes, liens, comptes, contributions). -- `parenthese_media` : les fichiers envoyés (photos, vidéos, audio, documents). +- `parenthese_db-data`: the PostgreSQL database (people, links, accounts, contributions). +- `parenthese_media`: the uploaded files (photos, videos, audio, documents). -### Sauvegardes +### Backups -Avec Docker, une sauvegarde tient en deux commandes, à lancer depuis le dossier du dépôt : +With Docker, a backup takes two commands, run from the repository folder: ```bash docker compose exec -T db pg_dump -U parenthese -Fc parenthese > parenthese-db-$(date +%F).dump docker run --rm -v parenthese_media:/data -v "$PWD":/backup alpine tar -czf /backup/parenthese-media-$(date +%F).tar.gz -C /data . ``` -Adaptez `-U parenthese` et le nom de base si vous avez changé `POSTGRES_USER` ou `POSTGRES_DB`. Pour restaurer la base : `docker compose exec -T db pg_restore -U parenthese -d parenthese --clean < parenthese-db-AAAA-MM-JJ.dump`, puis décompressez l'archive des médias dans le volume avec la même commande `docker run`, `tar -xzf` à la place de `-czf`. +Adjust `-U parenthese` and the database name if you changed `POSTGRES_USER` or `POSTGRES_DB`. To restore the database, run `docker compose exec -T db pg_restore -U parenthese -d parenthese --clean < parenthese-db-YYYY-MM-DD.dump`, then extract the media archive into the volume with the same `docker run` command, using `tar -xzf` instead of `-czf`. -Le script `deploy/backup.sh` fait la même chose (dump PostgreSQL, archive des médias, sommes de contrôle, rotation, envoi S3 optionnel) pour une installation sans Docker : il lit `backend/.env` et a besoin de `pg_dump` sur la machine. Ses réglages passent par les variables `BACKUP_ROOT`, `BACKUP_RETENTION_DAYS` et `BACKUP_S3_BUCKET`. +The `deploy/backup.sh` script does the same (PostgreSQL dump, media archive, checksums, rotation, optional S3 upload) for an installation without Docker. It reads `backend/.env` and needs `pg_dump` on the machine. It is configured through the `BACKUP_ROOT`, `BACKUP_RETENTION_DAYS` and `BACKUP_S3_BUCKET` variables. -### Mettre à jour +### Updating ```bash git pull && docker compose up -d --build ``` -Les migrations de base de données s'appliquent toutes seules au démarrage de l'API. Faites une sauvegarde avant, par habitude. +Database migrations apply on their own when the API starts. Make a backup first, as a habit. -## Développer +## Development -Le dépôt contient trois projets Node : `backend/` (Fastify, Prisma, PostgreSQL, TypeScript), `frontend/` (React, Vite) et `landing/` (le site vitrine, inutile pour faire tourner l'application). Les images Docker utilisent Node 24. +The repository holds three Node projects: `backend/` (Fastify, Prisma, PostgreSQL, TypeScript), `frontend/` (React, Vite) and `landing/` (the marketing site, not needed to run the app). The Docker images use Node 24. ### Backend @@ -101,9 +107,9 @@ npm --prefix backend run db:bootstrap npm --prefix backend run dev ``` -`db:bootstrap` démarre un PostgreSQL portable sous Windows (base `genealogy`, utilisateur `postgres`, port 5432) : les binaires doivent avoir été extraits dans `backend/.local/postgresql_full/pgsql`, le script ne les télécharge pas. Sur un autre système, n'importe quel PostgreSQL local convient : renseignez `DATABASE_URL` dans `backend/.env` (modèle dans `backend/.env.example`) et créez le schéma avec `npm --prefix backend run prisma:migrate`. +`db:bootstrap` starts a portable PostgreSQL on Windows (database `genealogy`, user `postgres`, port 5432). The binaries must already be extracted in `backend/.local/postgresql_full/pgsql`, the script does not download them. On other systems any local PostgreSQL works: set `DATABASE_URL` in `backend/.env` (template in `backend/.env.example`) and create the schema with `npm --prefix backend run prisma:migrate`. -Sur n'importe quel système avec Docker, une base jetable remplace `db:bootstrap` : +On any system with Docker, a throwaway database replaces `db:bootstrap`: ```bash docker run -d --name parenthese-dev-db -p 5432:5432 -e POSTGRES_USER=postgres -e POSTGRES_PASSWORD=postgres -e POSTGRES_DB=genealogy postgres:16 @@ -111,13 +117,13 @@ npm --prefix backend run prisma:deploy npm --prefix backend run dev ``` -Avant `prisma:deploy`, `backend/.env` doit exister (copie de `backend/.env.example`) avec `DATABASE_URL="postgresql://postgres:postgres@localhost:5432/genealogy"`, qui correspond à ces identifiants. `docker stop parenthese-dev-db` arrête la base, `docker start parenthese-dev-db` la relance avec ses données. +Before `prisma:deploy`, `backend/.env` must exist (a copy of `backend/.env.example`) with `DATABASE_URL="postgresql://postgres:postgres@localhost:5432/genealogy"`, matching those credentials. `docker stop parenthese-dev-db` stops the database, `docker start parenthese-dev-db` restarts it with its data. -L'API écoute sur [http://localhost:4000](http://localhost:4000) et répond `{ "ok": true }` sur `/health`. +The API listens on [http://localhost:4000](http://localhost:4000) and answers `{ "ok": true }` on `/health`. ### Frontend -Créez `frontend/.env.development.local` : +Create `frontend/.env.development.local`: ``` VITE_API_BASE_URL= @@ -125,14 +131,18 @@ VITE_DEV_PROXY_TARGET=http://127.0.0.1:4000 VITE_DEV_PROXY_STRIP_API=1 ``` -Puis : +Then: ```bash npm --prefix frontend install npm --prefix frontend run dev ``` -Le serveur Vite relaie `/api`, `/trees`, `/auth` et `/health` vers l'API locale en retirant le préfixe `/api`, comme le fait nginx en production. Sans ce fichier, le front appelle `http://localhost:4000` en direct et les liens partagés `/api/arbre/...` répondent 404. +The Vite server proxies `/api`, `/trees`, `/auth` and `/health` to the local API and strips the `/api` prefix, as nginx does in production. Without this file, the front end calls `http://localhost:4000` directly and shared links under `/api/arbre/...` return 404. + +### Translations + +Interface text goes through `t()` from `frontend/src/i18n/index.js`. The French text is the key, and the English lives in `frontend/src/i18n/en/*.js`. A missing English entry falls back to French, and a test fails if any text passed to `t()` has no English entry. ### Tests @@ -141,16 +151,16 @@ npm --prefix frontend test npm --prefix backend test ``` -## Contribuer +## Contributing -Issues et petites pull requests ciblées sont les bienvenues : la marche à suivre, les tests à faire passer et les conventions sont dans [CONTRIBUTING.md](CONTRIBUTING.md). Pour une faille de sécurité, pas d'issue publique : voir [SECURITY.md](SECURITY.md). +Issues and small, focused pull requests are welcome. The steps, the tests to pass and the conventions are in [CONTRIBUTING.md](CONTRIBUTING.md) (in French). For a security issue, no public issue please, see [SECURITY.md](SECURITY.md). -## Licence +## License -Le code est publié sous [PolyForm Noncommercial 1.0.0](LICENSE). En clair : +The code is published under [PolyForm Noncommercial 1.0.0](LICENSE). In plain words: -- Vous pouvez lire le code, le modifier et l'auto-héberger pour un usage non commercial, pour votre famille ou une association par exemple. -- Vous ne pouvez pas monter un service payant à partir de ce code. -- Le nom et le logo Parenthèse restent la propriété d'Ilies Allali. +- You can read the code, change it and self-host it for non-commercial use, for your family or a nonprofit for example. +- You cannot build a paid service from this code. +- The Parenthèse name and logo remain the property of Ilies Allali. -Le texte de la licence fait foi. +The license text is what counts. diff --git a/deploy/HOSTINGER_GITHUB_SETUP.md b/deploy/HOSTINGER_GITHUB_SETUP.md index bd8c73b..9b28b2f 100644 --- a/deploy/HOSTINGER_GITHUB_SETUP.md +++ b/deploy/HOSTINGER_GITHUB_SETUP.md @@ -1,6 +1,6 @@ # Déploiement de parenthese.io -Ce document concerne l'instance hébergée par Ilies Allali. Pour installer Parenthèse chez vous, suivez plutôt la section « Auto-héberger » du README (Docker). +Ce document concerne l'instance hébergée par Ilies Allali. Pour installer Parenthèse chez vous, suivez plutôt la section « Auto-héberger » du [README](../README.fr.md) (Docker). ## Principe diff --git a/docs/demo-tree.png b/docs/demo-tree.png new file mode 100644 index 0000000..65b50af Binary files /dev/null and b/docs/demo-tree.png differ