---
description: Phase 7 - Generate HTML documentation (React components) integrated in module
agent: ba-doc-html
model: sonnet
---

# Phase 7: Documentation HTML (React) - Intégrée au Module

> **Modèle:** Sonnet (génération React + i18n avec Context7)
> **Coût estimé:** ~$0.20
> **Output:** Composant React dans le module business: `pages/business/{app}/{module}/DocumentationPage.tsx`

---

## OBJECTIF

```
+==============================================================================+
|  DOCUMENTATION FRD INTÉGRÉE AU MODULE BUSINESS                               |
+==============================================================================+
|                                                                              |
|  La documentation est un ONGLET/TAB dans chaque module business:             |
|                                                                              |
|  /business/{application}/{module}                                            |
|  ├── (index)           → Page principale du module                           |
|  ├── /list             → Liste des entités                                   |
|  ├── /create           → Création                                            |
|  ├── /:id              → Détail                                              |
|  └── /documentation    → 📄 Documentation FRD (CETTE PAGE)                   |
|                                                                              |
|  AVANTAGE: L'utilisateur accède à la doc depuis le module qu'il utilise      |
|                                                                              |
+==============================================================================+
```

---

## CONTEXT7 - UTILISATION OBLIGATOIRE

```
+==============================================================================+
|  GÉNÉRATION REACT AVEC CONTEXT7                                              |
+==============================================================================+
|                                                                              |
|  Pour CHAQUE composant React généré, utiliser:                               |
|                                                                              |
|  "use context7 with /facebook/react and /i18next/react-i18next               |
|   to generate {component} following SmartStack documentation patterns"       |
|                                                                              |
|  Libraries à référencer:                                                     |
|  • /facebook/react - React 19 patterns, hooks                                |
|  • /i18next/react-i18next - useTranslation, Trans                            |
|  • /remix-run/react-router - Link, useParams, useNavigate                    |
|  • /lucide-icons/lucide-react - Icons cohérents                              |
|                                                                              |
+==============================================================================+
```

---

## STEP 1: Charger les documents

```bash
FEATURE_ID=$1
FEATURE_DIR=$(find .business-analyse -type d -name "${FEATURE_ID}*" | head -1)
FRD_FILE="$FEATURE_DIR/3-functional-specification.md"
HANDOFF_FILE="$FEATURE_DIR/4-development-handoff.md"

# Extraire les informations
APPLICATION=$(echo $FEATURE_DIR | grep -oP 'business/\K[^/]+')
MODULE=$(echo $FEATURE_DIR | grep -oP 'modules/\K[^/]+')
FEATURE_NAME=$(echo $FEATURE_DIR | grep -oP 'FEAT-\d+-\K.*')

# Paths de sortie - DANS LE MODULE BUSINESS (pas dans /docs)
WEB_DIR="web/smartstack-web/src"
MODULE_DIR="$WEB_DIR/pages/business/$APPLICATION/$MODULE"
I18N_DIR="$WEB_DIR/i18n/locales"
```

---

## STEP 2: Analyser le FRD pour extraction

```bash
# Extraire les données structurées du FRD
echo "Extraction des données du FRD..."

# Cas d'utilisation
USE_CASES=$(grep -oP 'UC-\d+.*' "$FRD_FILE" | head -10)

# Règles métier liées
BUSINESS_RULES=$(grep -oP 'BR-\d+' "$FRD_FILE" | sort -u)

# Permissions
PERMISSIONS=$(grep -oP 'business\.[a-z.]+' "$FRD_FILE" | sort -u)

# Endpoints API
ENDPOINTS=$(grep -oP '/api/business/[a-z/{}]+' "$FRD_FILE" | sort -u)
```

---

## STEP 3: Créer la structure de dossiers

```bash
# Le dossier du module doit déjà exister (créé par /implement)
# On ajoute juste la page Documentation

if [ ! -d "$MODULE_DIR" ]; then
  echo "⚠️ Module $APPLICATION/$MODULE non implémenté"
  echo "   Exécutez d'abord: /implement $FEATURE_ID"
  exit 1
fi

# Vérifier si DocumentationPage existe déjà
if [ -f "$MODULE_DIR/DocumentationPage.tsx" ]; then
  echo "📄 DocumentationPage existe - mise à jour"
else
  echo "📄 Création de DocumentationPage"
fi
```

---

## STEP 4: Générer DocumentationPage.tsx

**Utiliser Context7 pour génération:**

```
use context7 with /facebook/react and /i18next/react-i18next
to generate a documentation page component for the {MODULE} module
following SmartStack patterns with:
- Back link to module main page
- Table of contents (sticky sidebar)
- Overview section
- Use cases section with actors
- Business rules section
- Permissions matrix
- API endpoints table
- Version and last update info
```

### Template de sortie: DocumentationPage.tsx

```tsx
// web/smartstack-web/src/pages/business/{app}/{module}/DocumentationPage.tsx
// GÉNÉRÉ AVEC CONTEXT7: /facebook/react, /i18next/react-i18next

import { Link, useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';
import {
  FileText,
  Users,
  Shield,
  CheckCircle,
  ArrowLeft,
  List,
  Code,
  BookOpen,
  Hash
} from 'lucide-react';

// Données extraites du FRD
const frdData = {
  featureId: '{FEATURE_ID}',
  version: '1.0',
  lastUpdated: '{DATE}',

  overview: {
    description: '{FROM FRD SECTION 1}',
    objectives: [
      '{OBJECTIVE 1}',
      '{OBJECTIVE 2}'
    ]
  },

  useCases: [
    {
      id: 'UC-001',
      title: '{Title}',
      actor: '{Actor}',
      description: '{Description}',
      preconditions: ['{PRE}'],
      postconditions: ['{POST}'],
      steps: ['{STEP 1}', '{STEP 2}']
    }
  ],

  businessRules: [
    {
      id: 'BR-001',
      title: '{Title}',
      category: '{Category}',
      description: '{Description}',
      priority: 'Must'
    }
  ],

  permissions: [
    {
      key: 'business.{app}.{module}.read',
      description: '{Description}',
      roles: ['Admin', 'Manager']
    }
  ],

  endpoints: [
    {
      method: 'GET',
      path: '/api/business/{app}/{module}',
      description: '{Description}',
      permission: 'business.{app}.{module}.read'
    }
  ]
};

export function DocumentationPage() {
  const { t } = useTranslation('{app}-{module}');

  return (
    <div className="flex gap-8">
      {/* Sidebar - Table of Contents */}
      <aside className="hidden lg:block w-64 shrink-0">
        <nav className="sticky top-24 space-y-2">
          <h3 className="font-semibold text-sm text-[var(--text-secondary)] uppercase tracking-wide mb-4">
            {t('documentation.toc')}
          </h3>
          <a href="#overview" className="block py-1 text-sm hover:text-[var(--color-primary-600)]">
            {t('documentation.sections.overview')}
          </a>
          <a href="#use-cases" className="block py-1 text-sm hover:text-[var(--color-primary-600)]">
            {t('documentation.sections.useCases')}
          </a>
          <a href="#business-rules" className="block py-1 text-sm hover:text-[var(--color-primary-600)]">
            {t('documentation.sections.businessRules')}
          </a>
          <a href="#permissions" className="block py-1 text-sm hover:text-[var(--color-primary-600)]">
            {t('documentation.sections.permissions')}
          </a>
          <a href="#api" className="block py-1 text-sm hover:text-[var(--color-primary-600)]">
            {t('documentation.sections.api')}
          </a>
        </nav>
      </aside>

      {/* Main Content */}
      <main className="flex-1 max-w-4xl">
        {/* Back Link */}
        <Link
          to="/business/{app}/{module}"
          className="inline-flex items-center gap-2 text-sm text-[var(--text-secondary)] hover:text-[var(--color-primary-600)] mb-6"
        >
          <ArrowLeft className="w-4 h-4" />
          {t('documentation.backToModule')}
        </Link>

        {/* Header */}
        <header className="mb-8">
          <div className="flex items-center gap-3 mb-2">
            <BookOpen className="w-8 h-8 text-[var(--color-primary-600)]" />
            <h1 className="text-3xl font-bold">{t('documentation.title')}</h1>
          </div>
          <p className="text-[var(--text-secondary)]">
            {t('documentation.subtitle')}
          </p>
          <div className="flex gap-4 mt-4 text-sm text-[var(--text-tertiary)]">
            <span>Version {frdData.version}</span>
            <span>•</span>
            <span>{t('documentation.lastUpdated')}: {frdData.lastUpdated}</span>
          </div>
        </header>

        {/* Overview Section */}
        <section id="overview" className="mb-12">
          <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
            <Hash className="w-5 h-5 text-[var(--color-primary-600)]" />
            {t('documentation.sections.overview')}
          </h2>
          <div className="card p-6">
            <p className="mb-4">{frdData.overview.description}</p>
            <h4 className="font-medium mb-2">{t('documentation.objectives')}</h4>
            <ul className="list-disc list-inside space-y-1 text-[var(--text-secondary)]">
              {frdData.overview.objectives.map((obj, i) => (
                <li key={i}>{obj}</li>
              ))}
            </ul>
          </div>
        </section>

        {/* Use Cases Section */}
        <section id="use-cases" className="mb-12">
          <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
            <Users className="w-5 h-5 text-[var(--color-primary-600)]" />
            {t('documentation.sections.useCases')}
          </h2>
          <div className="space-y-4">
            {frdData.useCases.map((uc) => (
              <div key={uc.id} className="card p-6">
                <div className="flex items-center gap-2 mb-2">
                  <span className="px-2 py-1 text-xs font-mono bg-[var(--color-primary-100)] text-[var(--color-primary-700)] rounded">
                    {uc.id}
                  </span>
                  <h3 className="font-semibold">{uc.title}</h3>
                </div>
                <p className="text-[var(--text-secondary)] mb-4">{uc.description}</p>
                <div className="grid grid-cols-2 gap-4 text-sm">
                  <div>
                    <span className="font-medium">{t('documentation.labels.actor')}:</span>
                    <span className="ml-2">{uc.actor}</span>
                  </div>
                </div>
              </div>
            ))}
          </div>
        </section>

        {/* Business Rules Section */}
        <section id="business-rules" className="mb-12">
          <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
            <CheckCircle className="w-5 h-5 text-[var(--color-primary-600)]" />
            {t('documentation.sections.businessRules')}
          </h2>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-[var(--border-color)]">
                  <th className="text-left py-3 px-4">ID</th>
                  <th className="text-left py-3 px-4">{t('documentation.labels.rule')}</th>
                  <th className="text-left py-3 px-4">{t('documentation.labels.category')}</th>
                  <th className="text-left py-3 px-4">{t('documentation.labels.priority')}</th>
                </tr>
              </thead>
              <tbody>
                {frdData.businessRules.map((br) => (
                  <tr key={br.id} className="border-b border-[var(--border-color)]">
                    <td className="py-3 px-4 font-mono text-xs">{br.id}</td>
                    <td className="py-3 px-4">{br.title}</td>
                    <td className="py-3 px-4">{br.category}</td>
                    <td className="py-3 px-4">
                      <span className={`px-2 py-1 rounded text-xs ${
                        br.priority === 'Must' ? 'bg-red-100 text-red-700' :
                        br.priority === 'Should' ? 'bg-yellow-100 text-yellow-700' :
                        'bg-gray-100 text-gray-700'
                      }`}>
                        {br.priority}
                      </span>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </section>

        {/* Permissions Section */}
        <section id="permissions" className="mb-12">
          <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
            <Shield className="w-5 h-5 text-[var(--color-primary-600)]" />
            {t('documentation.sections.permissions')}
          </h2>
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b border-[var(--border-color)]">
                  <th className="text-left py-3 px-4">{t('documentation.labels.permission')}</th>
                  <th className="text-left py-3 px-4">Description</th>
                  <th className="text-left py-3 px-4">Roles</th>
                </tr>
              </thead>
              <tbody>
                {frdData.permissions.map((perm) => (
                  <tr key={perm.key} className="border-b border-[var(--border-color)]">
                    <td className="py-3 px-4 font-mono text-xs">{perm.key}</td>
                    <td className="py-3 px-4">{perm.description}</td>
                    <td className="py-3 px-4">
                      <div className="flex gap-1">
                        {perm.roles.map((role) => (
                          <span key={role} className="px-2 py-1 bg-[var(--bg-secondary)] rounded text-xs">
                            {role}
                          </span>
                        ))}
                      </div>
                    </td>
                  </tr>
                ))}
              </tbody>
            </table>
          </div>
        </section>

        {/* API Endpoints Section */}
        <section id="api" className="mb-12">
          <h2 className="text-xl font-semibold mb-4 flex items-center gap-2">
            <Code className="w-5 h-5 text-[var(--color-primary-600)]" />
            {t('documentation.sections.api')}
          </h2>
          <div className="space-y-3">
            {frdData.endpoints.map((ep, i) => (
              <div key={i} className="card p-4">
                <div className="flex items-center gap-3">
                  <span className={`px-2 py-1 text-xs font-bold rounded ${
                    ep.method === 'GET' ? 'bg-green-100 text-green-700' :
                    ep.method === 'POST' ? 'bg-blue-100 text-blue-700' :
                    ep.method === 'PUT' ? 'bg-yellow-100 text-yellow-700' :
                    ep.method === 'DELETE' ? 'bg-red-100 text-red-700' :
                    'bg-gray-100 text-gray-700'
                  }`}>
                    {ep.method}
                  </span>
                  <code className="text-sm">{ep.path}</code>
                </div>
                <p className="text-sm text-[var(--text-secondary)] mt-2">{ep.description}</p>
                <p className="text-xs text-[var(--text-tertiary)] mt-1">
                  {t('documentation.labels.permission')}: <code>{ep.permission}</code>
                </p>
              </div>
            ))}
          </div>
        </section>
      </main>
    </div>
  );
}
```

---

## STEP 5: Générer/Mettre à jour i18n

### Ajouter les clés dans le namespace du module

Fichier: `{lang}/{app}-{module}.json`

```json
{
  "documentation": {
    "title": "Documentation fonctionnelle",
    "subtitle": "Spécifications du module {Module}",
    "backToModule": "Retour au module",
    "lastUpdated": "Dernière mise à jour",
    "toc": "Table des matières",
    "objectives": "Objectifs",

    "sections": {
      "overview": "Vue d'ensemble",
      "useCases": "Cas d'utilisation",
      "businessRules": "Règles métier",
      "permissions": "Permissions",
      "api": "API Endpoints"
    },

    "labels": {
      "actor": "Acteur",
      "rule": "Règle",
      "category": "Catégorie",
      "priority": "Priorité",
      "permission": "Permission"
    }
  }
}
```

| Langue | Fichier |
|--------|---------|
| FR | `fr/{app}-{module}.json` |
| EN | `en/{app}-{module}.json` |
| IT | `it/{app}-{module}.json` |
| DE | `de/{app}-{module}.json` |

---

## STEP 6: Mettre à jour App.tsx

Ajouter la route dans le groupe du module business:

```tsx
{/* Business context routes */}
<Route path="/business" element={<BusinessLayout />}>
  {/* {Application} */}
  <Route path="{app}/{module}" element={<{Module}IndexPage />} />
  <Route path="{app}/{module}/list" element={<{Module}ListPage />} />
  <Route path="{app}/{module}/create" element={<{Module}CreatePage />} />
  <Route path="{app}/{module}/:id" element={<{Module}DetailPage />} />
  <Route path="{app}/{module}/documentation" element={<DocumentationPage />} />  {/* ← NOUVEAU */}
</Route>
```

---

## STEP 7: Ajouter le lien dans la navigation du module

Dans la page principale du module, ajouter un onglet/lien vers la documentation:

```tsx
// Dans {Module}IndexPage.tsx ou layout du module
<nav className="flex gap-4 border-b border-[var(--border-color)] mb-6">
  <NavLink to="/business/{app}/{module}" end>
    {t('tabs.overview')}
  </NavLink>
  <NavLink to="/business/{app}/{module}/list">
    {t('tabs.list')}
  </NavLink>
  <NavLink to="/business/{app}/{module}/documentation">
    <BookOpen className="w-4 h-4 mr-1" />
    {t('tabs.documentation')}
  </NavLink>
</nav>
```

---

## STEP 8: Validation

```bash
# Vérifier que les fichiers sont créés
echo "Vérification des fichiers générés..."

FILES_TO_CHECK=(
  "$MODULE_DIR/DocumentationPage.tsx"
  "$I18N_DIR/fr/{app}-{module}.json"
  "$I18N_DIR/en/{app}-{module}.json"
  "$I18N_DIR/it/{app}-{module}.json"
  "$I18N_DIR/de/{app}-{module}.json"
)

for file in "${FILES_TO_CHECK[@]}"; do
  if [ -f "$file" ]; then
    echo "  ✓ $file"
  else
    echo "  ✗ $file (MANQUANT)"
  fi
done

# Vérifier le build
echo ""
echo "Test build frontend..."
cd web/smartstack-web && npm run build --dry-run 2>/dev/null || echo "Build check skipped"
```

---

## STEP 9: Résumé

```
================================================================================
                    DOCUMENTATION HTML GÉNÉRÉE - {FEATURE_ID}
================================================================================

MODULE:            /business/{app}/{module}

FICHIERS CRÉÉS:

PAGE REACT:
  ✓ pages/business/{app}/{module}/DocumentationPage.tsx

I18N (4 langues):
  ✓ fr/{app}-{module}.json (clés documentation.*)
  ✓ en/{app}-{module}.json
  ✓ it/{app}-{module}.json
  ✓ de/{app}-{module}.json

ROUTE AJOUTÉE (App.tsx):
  /business/{app}/{module}/documentation

NAVIGATION:
  Onglet "Documentation" ajouté dans le module

================================================================================
ACCÈS
================================================================================

URL de la documentation:
  http://localhost:5173/business/{app}/{module}/documentation

Accès depuis le module:
  Onglet "Documentation" dans la barre de navigation du module

================================================================================
CONTEXT7 UTILISÉ
================================================================================

Libraries référencées:
  • /facebook/react
  • /i18next/react-i18next
  • /remix-run/react-router
  • /lucide-icons/lucide-react

================================================================================

Contact support: support@atlshub.ch
```

---

## Checklist génération

- [ ] DocumentationPage.tsx généré avec Context7
- [ ] Données FRD extraites et intégrées
- [ ] i18n ajouté pour 4 langues dans namespace module
- [ ] Route ajoutée dans App.tsx
- [ ] Onglet Documentation ajouté dans navigation module
- [ ] Build frontend vérifié
