# 01 — Analyse fonctionnelle ## 1. Contexte et objectif CV-Maker est une application web **sans backend** permettant à un utilisateur de créer son CV rapidement, en saisissant le contenu en **Markdown** dans des zones de saisie et en visualisant le résultat en **temps réel** sur une feuille au **format A4**. - **Utilisateur cible** : une personne unique, sur poste de travail (desktop). - **Aucune donnée n'est envoyée à un serveur** : tout est stocké dans le navigateur (localStorage). - **Notation (ECF CDA)** : le projet sert de support pédagogique et doit démontrer : maîtrise de Next.js/React, composants réutilisables, gestion d'état, persistance locale, sécurité de rendu, capacité de documentation. ## 2. Périmètre fonctionnel ### 2.1 Fonctions principales (issue du GOAL.md) | Réf. | Fonction | Description | | --- | --- | --- | | F1 | Éditeur temps réel | Saisie Markdown dans le panneau gauche → rendu HTML temps réel dans le panneau droit | | F2 | Preview A4 | Panneau droit matérialisé en feuille A4 (210 × 297 mm), impeccable à l'impression | | F3 | Persistance | Sauvegarde automatique dans localStorage à chaque frappe ; données restaurées au rechargement | | F4 | Impression PDF | Bouton d'impression → export PDF via la boîte de dialogue du navigateur | | F5 | Gestion des expériences | Ajout / modification / suppression d'expériences professionnelles | | F6 | Page documentation | Page d'aide expliquant l'utilisation et la syntaxe Markdown | | F7 | Page Mentions légales | Page d'information « mentions légales / vie privée » | | F8 | PWA | Application web installable hors-ligne (nice to have côté objectif, prévue au cahier des charges) | ### 2.2 Responsive / device - **Desktop first** : l'expérience est optimisée pour un écran large. - **Tablette et mobile : nice to have** ; minimum acceptable = interface utilisable sans casse majeure. Pas de refonte dédiée. ## 3. Maquette fonctionnelle de l'écran principal `/` ### 3.1 Agencement général ``` ┌──────────────────────────────────────────────────────────────┐ │ Barre d'application (logo, titre, boutons : imprimer, doc) │ ├───────────────────────────────┬──────────────────────────────┤ │ Panneau GAUCHE │ Panneau DROIT │ │ 1/3 de la largeur │ 2/3 de la largeur │ │ │ │ │ [Tabs 1 ▸ 2 ▸ 3 ▸ 4 ▸ 5 ▸ 6] │ ┌────────────────────────┐ │ │ │ │ Feuille A4 │ │ │ [MarkdownTextarea : │ │ ┌────────────────────┐ │ │ │ zone active] │ │ │ Header accroche │ │ │ │ │ │ └────────────────────┘ │ │ │ ── SÉPARATEUR ── │ │ ┌───────┬────────────┐ │ │ │ [Zone EXPÉRIENCES] │ │ │ 1/3 │ 2/3 │ │ │ │ [+ Ajouter] │ │ │ Etat │ Expériences│ │ │ │ • 1. Titre exp [Modif] [×] │ │ │ civil │ profession.│ │ │ │ • 2. Titre exp [Modif] [×] │ │ │ Forma-│ ... │ │ │ │ │ │ │ tions │ │ │ │ │ │ │ │ Compé- │ │ │ │ │ │ │ │ tences │ │ │ │ │ │ │ │ Soft │ │ │ │ │ │ │ │ skills│ │ │ │ │ │ │ │ Centr.│ │ │ │ │ │ │ │ intérêt│ │ │ │ │ │ │ └───────┴────────────┘ │ │ │ │ └────────────────────────┘ │ └───────────────────────────────┴──────────────────────────────┘ ``` ### 3.2 Panneau latéral gauche — saisie #### Structure - **Zones 1 à 6** gérées par un **système d'onglets (tabs)** numérotés de 1 à 6. Un seul onglet actif à la fois ; chaque onglet affiche une `textarea` Markdown dédiée. | N° onglet | Zone | Champ(s) du CV associé(s) | Préfixe de navigation | | --- | --- | --- | --- | | 1 | Message d'accroche | En-tête du CV (sous le nom/poste) | | | 2 | État civil + contacts | Nom, prénom, adresse, e-mail, téléphone, **site web**, **lien GitHub** | | | 3 | Formations | Liste des formations / diplômes | | | 4 | Compétences | Compétences techniques (langages, frameworks, outils) | | | 5 | Soft skills | Compétences comportementales | | | 6 | Centres d'intérêt | Loisirs, activités | | - **Zone « Expériences »** : fonctionne **hors du système d'onglets**. Elle est toujours visible sous la zone d'onglets. Elle sert à saisir **toutes les expériences professionnelles**, une par une. #### Interactions zone expériences 1. **Bouton `+`** : ajoute une nouvelle expérience. 2. Une **liste numérotée** s'affiche sous la zone de saisie : chaque entrée affiche le titre de l'expérience avec deux actions : - **`Modifier`** (bouton édition) : recharge le contenu de l'expérience dans la zone de saisie pour modification ; - **`×`** (bouton suppression) : supprime l'expérience (avec confirmation). 3. Toute nouvelle expérience s'ajoute **en bas** de la section « Expériences professionnelles » du CV : l'ordre d'affichage suit **l'ordre de saisie** (la 1ʳᵉ expérience ajoutée reste en haut, numérotée 1). 4. La liste est numérotée dans l'ordre d'affichage (1, 2, 3… correspondant à la position dans le CV). ### 3.3 Panneau latéral droit — preview A4 - Une seule feuille blanche au **format A4** (210 × 297 mm), avec une marge définie, représentant 1 page de CV. - **Header** (toute la largeur de la feuille) : rendu de l'**onglet 1 — message d'accroche**. - **Colonne gauche (1/3 de la largeur utile)** : rendus des sections correspondant aux **onglets 2 à 6** : - État civil (zone 2) : contacts, site web, GitHub ; - Formations (zone 3) ; - Compétences (zone 4) : compétences techniques ; - Soft skills (zone 5) ; - Centres d'intérêt (zone 6). - **Colonne droite (2/3 de la largeur utile)** : rendu des **expériences professionnelles**, sous le titre fixe **« Expériences professionnelles »**. - Le rendu est **temps réel** : toute frappe dans une zone de saisie met à jour la zone cible correspondante instantanément. ### 3.4 Barre d'application (en-tête de l'application) Éléments minimaux : - Nom applicatif « CV-Maker » / logo ; - Bouton **Imprimer / PDF** (déclenche `window.print()`) ; - Boutons **Importer JSON** puis **Exporter JSON** (partage de CV entre appareils) ; - Bouton **Réinitialiser** (après confirmation) ; - Lien vers la page **Documentation** ; - Pied de page : lien vers la page **Mentions légales** ; - Sauvegarde automatique silencieuse (aucun indicateur de statut — inutile vu l'enregistrement à chaque frappe). ## 4. Pages | Route | Rôle | | --- | --- | | `/` | Éditeur principal (2 colonnes) | | `/documentation` | Aide : prise en main + rappel syntaxe Markdown supportée | | `/mentions-legales` | Informations vie privée / traitement des données (localOnly) | ## 5. Contraintes transverses - **Desktop first** : design optimisé ≥ 1024 px ; grille responsive en repli simple (colonnes empilées) sous 768 px. - **No backend** : aucune API, aucun appel réseau. Les pages `/documentation` et `/mentions-legales` sont statiques. - **Rendu Markdown sécurisé** : HTML produit par `marked` puis **assaini par DOMPurify** avant injection. - **Performance de rendu** : rendu Markdown synchrone (contenus de taille « CV »), tolérable en temps réel. - **Persistance robuste** : écriture localStorage à chaque frappe de la zone active, lecture au chargement, gestion des erreurs (quota, navigateur bloqué, JSON corrompu). ## 6. Règles de gestion (résumé formalisé) | Règle | Description | | --- | --- | | RG1 | Toute modification d'un champ (textarea ou liste expériences) est persistée immédiatement dans localStorage. | | RG2 | Au chargement, si une sauvegarde existe, l'état de l'application est restauré (toutes les zones). | | RG3 | Si aucune sauvegarde ou sauvegarde corrompue/non compatible → données par défaut (zones vides), sauvegarde initiale créée. | | RG4 | Un seul onglet actif ; la navigation entre onglets ne modifie pas les contenus des autres onglets. | | RG5 | L'ajout d'une expérience place cette expérience en tête de la preview « Expériences professionnelles ». | | RG6 | Chaque expérience possède un identifiant unique stable (UUID) — jamais l'index de liste. | | RG7 | L'impression n'interrompt pas la persistance ; le rendu imprimé = rendu de la feuille A4 uniquement (les panneaux d'édition sont masqués en impression). | | RG8 | Le HTML saisi (via Markdown brut) est neutralisé s'il contient du JavaScript/sans sécurisation → DOMPurify obligatoire avant `dangerouslySetInnerHTML`. | ## 7. Hors périmètre (v1) - Multi-utilisateurs / comptes / cloud ; - Édition collaborative ; - Drag & drop de réorganisation des expériences (prévu comme évolution) ; - Export multi-formats autres que PDF (Docx, JSON…) ; - Tests automatisés (prévus en v2, cf. `07-plan-tests.md` pour la recette manuelle).