Import initial de Vivier depuis l'hebergement OVH

This commit is contained in:
Yann PILLA committed 2026-10-16 21:52:44 +02:00
commit 839e5e57c5
126 files changed
+22447

No files matched your search

+332
View File
@@ -0,0 +1,332 @@
# Vivier
Outil de suivi des CV d'IT Club. PHP 8.3, MySQL ou MariaDB, sans framework ni dépendance à installer.
## Contenu
| Dossier | Rôle |
|---|---|
| `public/` | Racine web : `index.php`, styles, scripts |
| `src/` | Code PHP : socle, import, accès aux données |
| `vues/` | Écrans |
| `config/` | Configuration (`config.php` à créer) |
| `stockage/` | CV et documents, hors de la racine web |
| `sql/schema.sql` | Création de la base |
| `claude/` | Schéma JSON, exemple et consignes du projet Claude |
| `lang/` | Traductions : interface en anglais, libellés des CV en anglais et en allemand |
| `cron/` | Script de la sauvegarde hebdomadaire, lancé par la tâche planifiée de l'hébergement |
| `aide/` | Guides d'utilisation et d'administration, en français et en anglais, affichés dans Vivier |
| `tests/` | Tests sans base de données |
## Installation sur l'hébergement OVH
1. Dans l'espace client, onglet Bases de données : créer une base MySQL. Noter l'hôte, le nom, l'utilisateur et le mot de passe.
2. Ouvrir phpMyAdmin, onglet Importer : charger `sql/schema.sql`.
3. Envoyer tout le dossier `vivier/` par FTP, à côté de `www/` (par exemple `/vivier`).
4. Onglet Multisite : ajouter le sous-domaine choisi, par exemple `vivier.itclub.lu`, avec pour dossier racine `vivier/public`. Cocher SSL.
5. Copier `config/config.exemple.php` en `config/config.php` et renseigner la base.
6. Ouvrir l'adresse du site en `https://`. La page de premier lancement crée votre compte, gestionnaire des comptes, puis fait activer la double authentification. Le dossier `config/` doit être accessible en écriture : Vivier y crée `cle-secrets.php`. Sinon, renseigner `cle_secrets` dans `config/config.php`.
7. Programmer la sauvegarde hebdomadaire : voir la section Sauvegarde.
Le dossier racine doit être `vivier/public`. Les autres dossiers restent ainsi inaccessibles par URL. Des fichiers `.htaccess` les bloquent aussi en seconde protection.
## Mise à jour d'une installation existante
1. Dans phpMyAdmin, exécuter dans l'ordre les fichiers `sql/migration-*.sql` qui n'ont pas encore été passés.
2. Remplacer par FTP les dossiers `public/`, `src/`, `vues/`, `lang/`, `aide/`, `cron/`, `sql/`, `claude/` et `tests/`. Garder `config/config.php` et `stockage/`.
3. Reporter dans `config/config.php` les nouvelles clés de `config/config.exemple.php` (`societe`, `claude`, `sauvegarde`, `comptes`, `adresse`, `cle_secrets`, `securite`).
4. Dans Vivier : Comptes, puis « Réindexer tous les profils » et « Traduire tous les profils ».
5. Dans le projet Claude d'analyse : remplacer les consignes, le schéma et l'exemple par ceux du dossier `claude/`.
Après la migration 1.2, les anciennes adresses email servent d'identifiants. Le gestionnaire les raccourcit dans Comptes.
La migration 1.4 réunit « Premier entretien validé » et « Second entretien validé » en « Entretiens en cours ». Les profils concernés changent de colonne. Le journal garde les anciens libellés. Faire une sauvegarde de la base dans phpMyAdmin (onglet Exporter) avant de passer une migration.
La migration 1.5 ajoute la corbeille des profils et les demandes de compte. Elle crée le compte gestionnaire `ypilla`, ou met à jour son mot de passe et son rôle s'il existe. Le fichier contient l'empreinte du mot de passe, pas le mot de passe. Les autres comptes gardent leur rôle. La clé `comptes` de la configuration est facultative : sans elle, l'email de demande part à l'adresse d'expédition.
La version 1.6 réorganise la fiche d'un profil : un bandeau (statut, disponibilité, TJM, choses à faire) et quatre onglets, Profil, Suivi, Missions et Dossier. Pas de migration de base. Remplacer `public/`, `src/`, `vues/`, `lang/` et `aide/`. Les adresses des styles et du script changent (`?v=1.6`) : les navigateurs chargent la nouvelle version sans vider leur cache.
La version 1.7 corrige le survol du nom « Vivier » dans l'en-tête et affine l'usage : noms de famille en capitales, formulaire de la fiche en trois blocs, filtres appliqués dès qu'on les change, filtres repliés sur téléphone, une seule pastille sur Gestion. Passer `sql/migration-1.6-vers-1.7.sql` (noms existants en capitales), puis remplacer `public/`, `src/`, `vues/`, `lang/`, `aide/` et `sql/`. « Non retenu » passe en dernière colonne du Kanban, après « Embauché ».
La version 1.8 renforce la sécurité des accès, affiche les profils dans la langue de l'interface et ajoute la nationalité, le permis de travail et le CV Europass.
- Sécurité : double authentification obligatoire (application TOTP, dix codes de secours), accès sur lien d'invitation à la place de la demande publique, blocages progressifs par identifiant et par adresse, HTTPS obligatoire avec HSTS, sessions de 12 heures au plus, journal des connexions de 12 mois, alerte email quand un gestionnaire se connecte depuis un réseau nouveau, mots de passe contrôlés contre les fuites connues et hachés en Argon2id, export CSV, journal et conservation réservés au gestionnaire, mot de passe redemandé pour les actions sensibles, journal des erreurs. Nouveau guide « Sécurité », lisible depuis la page de connexion.
- Traduction : chaque profil s'affiche traduit dans la langue de l'interface, en arrière-plan. La recherche trouve les textes d'origine et traduits.
- Disponibilité : liste fixe (Immédiate, Sous 1, 2 ou 3 mois, Date précise, À préciser), avec une note libre.
- Nationalité (codes ISO, plusieurs possibles), filtre UE ou hors UE, permis de travail en texte libre avec date d'expiration et relance 2 mois avant. Sur aucun CV.
- CV Europass nominatif ou anonymisé, en Word et en PDF, en trois langues. Nouveaux champs : projet, mission et charge des expériences, dates et lieu des formations, grille européenne des langues, bénévolat, permis de conduire.
- Format d'échange avec Claude en version 1.2 : remplacer les consignes, le schéma et l'exemple du projet Claude d'analyse.
- Corrections d'affichage : chiffres du tableau de bord alignés, page Mon compte.
Passer `sql/migration-1.7-vers-1.8.sql`, puis remplacer `public/`, `src/`, `vues/`, `lang/`, `aide/`, `cron/`, `sql/` et `claude/`. Les disponibilités déjà saisies sont classées, leur texte d'origine reste en note. À la connexion suivante, chaque compte active la double authentification : prévenir les utilisateurs qu'il leur faut leur téléphone. Garder `config/cle-secrets.php` avec `config/config.php` dans les sauvegardes.
## Utilisation
1. Menu Importer. Deux voies :
- Analyse automatique : charger le CV. Vivier l'envoie à l'API Claude, qui renvoie le profil et le rapport.
- Fichiers déjà analysés : charger le JSON, le CV d'origine et le rapport produits dans un projet Claude.
2. Relire l'écran de contrôle, puis enregistrer. Le profil arrive dans la colonne Reçu.
3. Dans le Kanban, glisser les cartes d'une colonne à l'autre. Le passage en Non retenu demande un motif. Sur écran tactile, maintenir l'appui pour saisir une carte.
4. Sur une fiche : télécharger le CV d'origine, exporter le CV IT Club, commenter, changer le statut, noter les entretiens et les relances.
## États et archivage
Six états : Reçu, En cours, Entretiens en cours, Validé, Embauché, puis Non retenu en dernière colonne.
- En cours : le profil est à l'étude, avant tout entretien.
- Entretiens en cours : un seul état, quel que soit le nombre d'entretiens. Chaque entretien se note sur la fiche.
- Archiver (carte Gestion de la fiche) : le profil sort du Kanban, du tableau de bord, du suivi et de la recherche courante. Ses données, ses documents et son échéance de conservation restent. Il se retrouve dans Profils, filtre Archivés, et se désarchive d'un bouton.
- Un profil archivé garde son statut. Ce statut ne change pas tant que le profil est archivé.
## Suivi des candidats
Entretiens, sur la fiche :
- Date, heure facultative, type (téléphone, visioconférence, sur place, technique, client), personne qui mène l'entretien, besoin client concerné.
- Après l'entretien : avis (favorable, réservé, défavorable) et compte rendu.
- Au premier entretien d'un profil Reçu ou En cours, une case cochée fait passer le profil en « Entretiens en cours ».
- Le prochain entretien s'affiche sur la carte du Kanban.
Relances, sur la fiche : une chose à faire et une date. Une relance arrivée à échéance s'affiche sur la carte du Kanban et dans la pastille du menu Suivi.
Menu Suivi : les relances à faire, les entretiens des 30 prochains jours, les entretiens passés sans avis.
## Besoins clients et rapprochement
Menu Besoins. Un besoin décrit une mission : client, intitulé, technologies, séniorité minimale, langues, lieu, télétravail, début, budget journalier.
- La fiche d'un besoin ouvert liste les profils du vivier qui y répondent, les mieux notés d'abord. « Proposer » ajoute un profil au besoin.
- Un profil proposé suit quatre états : à présenter, présenté au client, retenu par le client, écarté. Une note libre l'accompagne.
- Un profil se propose aussi depuis sa fiche, carte Besoins clients.
- Statut du besoin : ouvert, pourvu, fermé. Seul un besoin ouvert affiche le rapprochement.
Note de rapprochement sur 100, calculée par `noter_rapprochement()` dans `src/besoins.php` :
| Critère | Points | Règle |
|---|---|---|
| Technologies | 55 | Part des technologies demandées présentes sur la fiche. Une technologie présente vaut 60 % de sa part, 100 % à partir de 5 ans de pratique. |
| Intitulé | 15 | Part des mots de l'intitulé présents sur la fiche. |
| Séniorité | 10 | 10 si le niveau demandé est atteint, 4 un niveau en dessous, 0 sinon. |
| Langues | 10 | Part des langues demandées présentes sur la fiche. |
| Disponibilité | 5 | 5 si le profil est disponible avant le début, 0 après. |
| Tarif | 5 | 5 si le TJM souhaité tient dans le budget, 2 jusqu'à 10 % au-dessus, 0 au-delà. |
Un critère absent du besoin donne tous ses points. Une donnée absente de la fiche (date de disponibilité, TJM) donne la moitié. Les profils archivés ou non retenus sont exclus. Un profil sans aucune technologie demandée ni aucun mot de l'intitulé n'est pas listé.
## Données commerciales
Sur la fiche, bouton Modifier : date de disponibilité, TJM souhaité, salaire annuel brut souhaité, mobilité, télétravail. Ces données servent au rapprochement et à l'export CSV. Elles ne figurent sur aucun CV exporté.
## Données personnelles
Carte Données personnelles de la fiche :
- Accord du candidat : la date à laquelle il a accepté la conservation de son CV, et la façon dont il l'a dit. L'accord se modifie et se retire. La page Conservation l'affiche.
- Exporter les données du candidat : un zip avec `donnees.json` (fiche, commentaires, entretiens, relances, historique), les documents et la photo. À remettre à un candidat qui demande l'accès à ses données.
## Import en lot
Menu Importer, bouton « Importer plusieurs CV ». 20 CV au plus dans le lot.
- CV à analyser : sélectionner plusieurs fichiers. Vivier les envoie à l'API Claude un par un, une requête par CV. La page doit rester ouverte pendant les analyses. Si elle est fermée, les analyses reprennent à sa réouverture.
- Profils déjà analysés : sélectionner ensemble les JSON, les CV et les rapports. Chaque JSON est associé au CV que nomme son champ `source.fichier_origine`. Un rapport `.md` ou `.txt` est associé au profil dont son nom reprend le nom du JSON ou le nom du candidat.
- Chaque ligne du lot s'ouvre en relecture. « Enregistrer les profils prêts » enregistre d'un coup ceux qui ne ressemblent à aucun profil existant.
- Un CV laissé dans le lot est retiré après 7 jours, avec ses fichiers temporaires.
## Doublons
À l'import, Vivier compare le profil aux fiches existantes, archivées comprises.
- Même adresse email : l'enregistrement est refusé. La fiche existante se met à jour par sa carte Gestion.
- Même téléphone (indicatif, espaces et ponctuation ignorés) ou même prénom et même nom (casse, accents et ordre ignorés) : avertissement. Une case à cocher confirme qu'il s'agit d'une autre personne.
## Analyse automatique
À activer dans `config/config.php`, clé `claude` : renseigner `cle_api`. Sans clé, seul l'import par fichiers est proposé.
- La clé se crée dans la console Anthropic. L'usage de l'API est facturé à part d'un abonnement Claude.
- Formats lus : PDF (envoyé tel quel), DOCX, ODT, MD, TXT (texte extrait par Vivier). Un DOC ou un RTF doit être converti en PDF.
- Les consignes envoyées sont celles du dossier `claude/`. Les modifier change les deux voies d'analyse.
- Le CV est transmis à Anthropic pour l'analyse. Le mentionner dans l'information donnée aux candidats.
- Délai maximal : 240 secondes, réglable. Si l'hébergement coupe avant, passer par les fichiers déjà analysés.
## Liste, export et tableau de bord
- Profils : la liste complète, filtrable. « Exporter en CSV » télécharge les profils affichés (séparateur point-virgule, lisible par Excel).
- Tableau de bord : profils par statut, temps moyen passé à chaque étape, séniorité, technologies les plus présentes.
## Recherche
Le champ de l'en-tête et le menu Profils interrogent toutes les fiches.
- Tous les mots saisis doivent figurer sur la fiche. Le score classe les résultats.
- Accents, majuscules et pluriels sont ignorés. Un mot de trois lettres ou plus trouve aussi les mots qui commencent par lui.
- « senior » filtre sur Confirmé et Expert. « junior », « confirmé », « expert » filtrent de même.
- Une expression entre guillemets est cherchée telle quelle : `"gestion documentaire"`.
- Les symboles des technologies sont gardés : C#, C++, .NET, Node.js, CI/CD.
- Filtres : statut, séniorité, langue, profils archivés (masqués, inclus, seulement).
Poids d'un mot selon sa place : nom 8, titre et métier 6, spécialité et technologie 5 (jusqu'à 10 selon les années de pratique), secteur et mot-clé 4, poste et langue 3, synthèse, employeur et formation 2, description 1. Un mot exact compte double par rapport à un début de mot.
Les mots-clés et les métadonnées viennent du JSON (format 1.1) : `mots_cles`, et `metadonnees` avec les métiers, spécialités, secteurs, niveau d'études et encadrement. Un recruteur peut en ajouter ou en retirer sur la fiche. Les ajouts manuels survivent à une mise à jour de l'analyse.
Les synonymes se règlent dans la table `synonymes_recherche` (phpMyAdmin) : `seniorite` transforme un mot en filtre, `texte` ajoute une variante. Réindexer n'est pas nécessaire après un changement de synonyme.
## Gestion des profils
- Modifier : identité, coordonnées, titre, disponibilité, synthèse. Chaque champ modifié est tracé avec l'ancienne et la nouvelle valeur.
- Mettre à jour depuis une nouvelle analyse : remplace expériences, technologies, langues et mots-clés. Garde le statut, les commentaires, les documents et l'historique.
- Supprimer : réservé au gestionnaire des comptes. Le profil part à la corbeille et disparaît de toute l'application. Le gestionnaire le restaure ou l'efface depuis Gestion, Corbeille.
- Effacement : 30 jours après la suppression (`CORBEILLE_JOURS`), par la tâche planifiée, à la connexion d'un gestionnaire ou à l'ouverture de la corbeille. Partent la fiche, les documents, la photo, les commentaires, les entretiens, les relances, les mots-clés et l'historique. Le journal garde une ligne avec la référence du profil, sans nom.
- Conservation : liste les profils échus ou à 60 jours de l'échéance, à prolonger ou à supprimer.
- Rapport : un rapport .md ou .txt se lit dans Vivier par le lien Lire.
## Photos des candidats
La photo sert à reconnaître un candidat dans Vivier : fiche, cartes du Kanban, résultats de recherche.
- À l'import, Vivier cherche la photo dans le CV (Word, OpenDocument, PDF) et la montre sur l'écran de relecture. Une case permet de ne pas la garder.
- Sur la fiche, la carte Photo permet d'en charger une, de la remplacer ou de la retirer.
- La photo est réenregistrée en JPEG de 480 px au plus, dans `stockage/photos/`. Elle part avec le profil à la suppression.
- Elle ne figure jamais sur les CV exportés et n'est jamais décrite ni analysée par Claude.
- Vivier choisit l'image du CV qui ressemble à un portrait : format vertical ou carré, sans grande plage unie. Un logo est écarté. Un portrait détouré sur un large fond blanc peut l'être aussi : il se charge alors à la main.
- La recherche de photo demande l'extension GD de PHP. Sans elle, seul le chargement manuel est refusé et l'import continue.
## Langues
Interface : français et anglais. Chaque compte garde sa langue. Le choix se fait dans le menu du compte, en haut à droite, ou sur la page de connexion.
Profils : chaque profil s'affiche dans la langue de l'interface. La traduction se fait à l'import, en arrière-plan (table `traductions_a_faire`, traitée une à une par le script des pages ouvertes), et de nouveau après chaque modification. Commentaires, comptes rendus, besoins et permis de travail ne sont pas traduits.
CV générés : français, anglais, allemand, au choix dans l'aperçu du CV.
- Les intitulés du CV suivent la langue choisie.
- Le contenu (titre, synthèse, postes, descriptions, diplômes) reste dans la langue du CV d'origine tant qu'il n'est pas traduit. L'aperçu le signale.
- Traduire le contenu : bouton « Traduire le contenu » si l'analyse automatique est configurée, sinon « Traduire par fichier » (télécharger le fichier, le déposer dans le projet Claude d'analyse, recharger le fichier traduit).
- La traduction est gardée. Si la fiche change ensuite, elle est signalée périmée et le contenu d'origine revient.
- Les noms de technologies, d'entreprises et de clients ne sont pas traduits.
Ajouter une langue d'interface : copier `lang/en.php` en `lang/xx.php`, traduire les valeurs, puis ajouter la langue à `LANGUES_INTERFACE` dans `src/i18n.php`. Une clé non traduite s'affiche en français. Pour une langue de CV, quelques dizaines de libellés suffisent (voir `lang/de.php`) et la langue s'ajoute à `LANGUES_CV`.
Le journal enregistre les actions en français et les affiche dans la langue de l'interface. Les données des profils (commentaires, synthèse, mots-clés) restent telles qu'elles ont été saisies.
## Sauvegarde
Menu Gestion, Sauvegarde, réservé au gestionnaire des comptes.
Chaque semaine, la tâche planifiée de l'hébergement lance `cron/sauvegarde.php`. Le script exporte toute la base dans un fichier SQL, le compresse en zip, garde une copie dans `stockage/sauvegardes/` et l'envoie par email.
Programmer la tâche chez OVH :
1. Espace client, hébergement, onglet « Plus », « Planificateur de tâches », « Ajouter une planification ».
2. Commande : `vivier/cron/sauvegarde.php`. Langage : PHP 8.3.
3. Fréquence : jour de la semaine dimanche, heure 6. OVH ne règle pas les minutes : la tâche part entre 6 h 00 et 6 h 59.
4. Adresse du rapport : facultative. OVH y envoie ce que le script affiche.
Réglages, dans `config/config.php`, clé `sauvegarde` :
- `destinataires` : les adresses qui reçoivent le fichier.
- `expediteur` : l'adresse d'expédition. Le domaine de cette adresse doit autoriser le serveur d'OVH dans son enregistrement SPF, sinon l'email risque le dossier des indésirables.
- `semaines_conservees` : 0 garde toutes les copies sur le serveur, un nombre supprime les copies plus anciennes.
- `taille_max_email` : au-delà, l'export est refait sans l'index de recherche. S'il reste trop lourd, l'email part sans pièce jointe et le fichier se télécharge dans Vivier.
Avant de compter sur la sauvegarde : page Sauvegarde, « Envoyer un email d'essai », puis « Sauvegarder maintenant » avec l'envoi coché. Vérifier les deux boîtes, courriers indésirables compris.
Le fichier n'est pas chiffré. Il contient les données des candidats, les empreintes des mots de passe et les clés de double authentification chiffrées. Sa protection est celle des boîtes qui le reçoivent. Les copies gardent les profils supprimés depuis : supprimer les anciens emails de sauvegarde pour respecter la durée de conservation.
En cas d'échec, un email d'alerte part aux mêmes adresses. Le tableau de bord du gestionnaire alerte aussi quand aucune sauvegarde n'a réussi depuis plus de 8 jours : ce second signal couvre le cas où la tâche ne démarre plus ou l'email ne part plus.
Fichiers : les CV, rapports, pièces jointes et photos sont trop lourds pour un email. Le bouton « Télécharger l'archive des fichiers » en fait un zip, avec un `index.csv` qui relie chaque fichier à son profil. Le télécharger le même jour que la sauvegarde de la base.
Restaurer :
1. phpMyAdmin, base de Vivier, onglet Importer : charger le fichier `.sql` extrait du zip. Il remplace toutes les tables.
2. Par FTP, copier les dossiers `docs/` et `photos/` de l'archive des fichiers dans `stockage/`.
3. Si le fichier SQL annonce en tête que l'index de recherche n'est pas inclus : Vivier, Comptes, « Réindexer tous les profils ».
4. Garder `config/cle-secrets.php` (ou la clé `cle_secrets`) : sans lui, chacun se connecte avec un code de secours et réactive sa double authentification.
5. Se connecter. Les comptes, les mots de passe et la double authentification sont ceux du jour de la sauvegarde.
## Aide intégrée
Le point d'interrogation de l'en-tête ouvre l'aide.
- Guide d'utilisation et guide Sécurité : pour tous les comptes. Guide d'administration : pour le gestionnaire des comptes.
- Chaque guide existe en français et en anglais. Il s'ouvre dans la langue de l'interface, et les boutons FR et EN changent la langue du guide seul.
- « Imprimer ou enregistrer en PDF » sort le guide affiché.
- Les textes sont les fichiers Markdown du dossier `aide/` : `guide`, `securite` et `administration`, en `.fr.md` et `.en.md`. Modifier un fichier modifie l'aide, sans autre réglage.
- Le guide Sécurité se lit aussi sans être connecté, depuis la page de connexion.
- Mise en forme lue : titres (`#` pour un chapitre, `##` pour une section), listes, tableaux, gras, code. Garder les mêmes chapitres dans les deux langues.
## Sécurité
Le détail est dans l'aide : guide « Sécurité » pour tous, chapitre Sécurité du guide d'administration. Réglages dans `src/bootstrap.php` et `src/securite.php`.
- Double authentification obligatoire : codes à 6 chiffres (RFC 6238), dix codes de secours hachés, clé chiffrée en AES-256-GCM avec une clé gardée hors de la base (`config/cle-secrets.php` ou `cle_secrets`).
- Accès sur lien d'invitation, valable 48 heures et une seule fois. La création directe par le gestionnaire reste possible, avec un mot de passe provisoire à changer.
- Blocage après 5 échecs sur un identifiant depuis une adresse : 15, puis 30 et 60 minutes. Blocage d'une adresse après 20 échecs en une heure. Déblocage manuel dans Comptes.
- HTTPS obligatoire : redirection et en-tête HSTS d'un an (`.htaccess` et PHP).
- Session fermée après 2 heures sans activité, 12 heures au plus. Changer de mot de passe ferme les autres sessions. Bouton « Déconnecter mes autres sessions ».
- Mots de passe de 12 caractères au moins, refusés s'ils figurent dans une fuite connue (Pwned Passwords, seuls 5 caractères de l'empreinte partent), hachés en Argon2id.
- Journal des connexions de 12 mois. Email d'alerte quand un gestionnaire se connecte depuis un réseau jamais vu.
- Export CSV, journal, conservation, corbeille, suppression : gestionnaire seulement. Mot de passe redemandé pour confier la gestion, changer le mot de passe d'un autre, remettre à zéro une double authentification, télécharger l'archive des fichiers.
- Journal des erreurs imprévues avec une référence, sans donnée de candidat.
- Site exclu des moteurs de recherche : en-tête `X-Robots-Tag` (PHP et `.htaccess`) et balise `robots`. Pas de `robots.txt`.
## Interface
- Mise en page adaptée du téléphone au grand écran. Le menu se replie sous 1180 px, le Kanban défile colonne par colonne sous 900 px.
- En-tête sur une ligne, fixe en haut de page : cinq rubriques, le sous-menu Gestion réservé au gestionnaire (Conservation, Journal, Connexions, Comptes, Corbeille, Sauvegarde, Erreurs), la recherche, le bouton Importer et le menu du compte (mon compte, langue, déconnexion).
- Fiche profil : un sommaire reste collé sous l'en-tête et mène à chaque section. L'historique montre les 10 dernières actions, le reste se déplie.
- Les pages s'enchaînent en fondu sur les navigateurs qui gèrent les transitions entre pages. Les animations sont coupées si le système demande de réduire les mouvements.
- Polices Bodoni Moda et Instrument Sans, hébergées dans `public/assets/polices/` (licence SIL Open Font License). Aucun appel à un service externe.
## CV au format IT Club
Sur une fiche, les boutons CV IT Club et CV anonymisé ouvrent l'aperçu A4. Deux exports partent de cet aperçu.
- Télécharger en Word : fichier .docx modifiable, généré par `src/ExportWord.php`.
- Enregistrer en PDF : impression du navigateur. Choisir « Enregistrer au format PDF » et décocher « En-têtes et pieds de page ».
Les deux exports lisent le même contenu, préparé par `donnees_cv()` dans `src/depot.php`.
- Aucune coordonnée personnelle. Le contact passe par IT Club.
- La version anonymisée remplace le nom par une référence (ITC-0001) et masque la localisation.
- Les noms d'employeurs et de clients restent visibles dans les deux versions.
- Les mentions de la société se règlent dans `config/config.php`, clé `societe`.
- Chaque export est tracé dans l'historique du profil.
## CV Europass
Sur une fiche, CV Europass, nominatif ou anonymisé. Mise en page du CV Europass d'IT Club : bandeau bleu, logo Europass officiel en version négative, rubriques européennes. Aperçu HTML enregistrable en PDF (`vues/europass.php`, `public/assets/europass.css`, police Open Sans sous licence SIL OFL) et export Word (`src/ExportEuropass.php`). Contenu préparé par `donnees_europass()` dans `src/europass.php`.
- Ni date de naissance, ni nationalité, ni permis de travail.
- Coordonnées affichées par défaut sur la version nominative, retirables. Photo sur demande.
- Version anonymisée : référence à la place du nom, ni photo ni coordonnées.
- Grille européenne des langues quand le CV la donne, sinon une ligne par langue.
## Comptes
- Un seul niveau d'accès aux profils : chaque compte lit et modifie tous les profils.
- Connexion par identifiant, mot de passe et code de double authentification, sans adresse email.
- Le premier compte créé est gestionnaire : il invite, crée et modifie les comptes, désactive un compte, remet à zéro une double authentification, lève un blocage. Il peut confier ce rôle à un autre compte.
- Chacun gère son mot de passe, ses codes de secours, son application et ses sessions dans Mon compte.
- Les demandes de compte faites avant la 1.8 restent visibles dans Comptes, à accepter ou refuser.
Pour rétablir un accès en lecture seule plus tard : la fonction `peut_ecrire()` de `src/bootstrap.php` est le seul point à modifier.
## Règles de calcul
- Séniorité recalculée à l'import à partir des dates. Stages exclus, périodes qui se chevauchent fusionnées.
- Un poste terminé compte son dernier mois. Un poste en cours compte jusqu'au dernier mois complet.
- Une date sans mois vaut janvier.
- Junior sous 4 ans, intermédiaire de 4 à moins de 8, confirmé de 8 à moins de 12, expert à partir de 12.
## Tests
php tests/test_import.php
php tests/test_recherche.php
php tests/test_photo.php
php tests/test_securite.php
php tests/test_i18n.php
php tests/test_suivi.php
php tests/test_aide.php