@atlashub/smartstack-cli 4.29.0 → 4.30.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.documentation/business-analyse.html +217 -0
- package/package.json +1 -1
- package/templates/skills/ba-generate-html/html/ba-interactive.html +207 -199
- package/templates/skills/ba-generate-html/html/src/partials/cadrage-context.html +9 -9
- package/templates/skills/ba-generate-html/html/src/partials/cadrage-scope.html +15 -15
- package/templates/skills/ba-generate-html/html/src/partials/cadrage-stakeholders.html +7 -7
- package/templates/skills/ba-generate-html/html/src/partials/cadrage-success.html +13 -13
- package/templates/skills/ba-generate-html/html/src/partials/consol-datamodel.html +4 -4
- package/templates/skills/ba-generate-html/html/src/partials/consol-flows.html +5 -5
- package/templates/skills/ba-generate-html/html/src/partials/consol-interactions.html +2 -2
- package/templates/skills/ba-generate-html/html/src/partials/consol-permissions.html +4 -4
- package/templates/skills/ba-generate-html/html/src/partials/decomp-dependencies.html +11 -11
- package/templates/skills/ba-generate-html/html/src/partials/decomp-modules.html +9 -9
- package/templates/skills/ba-generate-html/html/src/partials/handoff-summary.html +5 -5
- package/templates/skills/ba-generate-html/html/src/scripts/01-data-init.js +10 -2
- package/templates/skills/ba-generate-html/html/src/scripts/02-navigation.js +10 -10
- package/templates/skills/ba-generate-html/html/src/scripts/03-render-cadrage.js +1 -1
- package/templates/skills/ba-generate-html/html/src/scripts/04-render-modules.js +4 -4
- package/templates/skills/ba-generate-html/html/src/scripts/05-render-specs.js +57 -57
- package/templates/skills/ba-generate-html/html/src/scripts/06-render-consolidation.js +4 -4
- package/templates/skills/ba-generate-html/html/src/scripts/06-render-mockups.js +5 -5
- package/templates/skills/ba-generate-html/html/src/scripts/07-render-handoff.js +8 -8
- package/templates/skills/ba-generate-html/html/src/scripts/08-editing.js +3 -3
- package/templates/skills/ba-generate-html/html/src/scripts/09-export.js +2 -2
- package/templates/skills/ba-generate-html/html/src/scripts/10-comments.js +2 -2
- package/templates/skills/ba-generate-html/html/src/scripts/11-review-panel.js +8 -8
- package/templates/skills/ba-generate-html/html/src/styles/03-navigation.css +1 -1
- package/templates/skills/ba-generate-html/html/src/template.html +92 -92
- package/templates/skills/ba-generate-html/steps/step-02-build-data.md +5 -1
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
6
|
-
<title>{{APPLICATION_NAME}} - Analyse
|
|
6
|
+
<title>{{APPLICATION_NAME}} - Analyse métier</title>
|
|
7
7
|
<style>
|
|
8
8
|
/* --- 01-variables.css --- */
|
|
9
9
|
/* ============================================
|
|
@@ -171,7 +171,7 @@ body {
|
|
|
171
171
|
text-overflow: ellipsis;
|
|
172
172
|
}
|
|
173
173
|
|
|
174
|
-
/* Nav groups (top-level: Cadrage, Modules, Consolidation,
|
|
174
|
+
/* Nav groups (top-level: Cadrage, Modules, Consolidation, Synthèse) */
|
|
175
175
|
.nav-group { padding: 0.4rem 0; }
|
|
176
176
|
.nav-group + .nav-group { border-top: 1px solid var(--border); }
|
|
177
177
|
|
|
@@ -1772,15 +1772,15 @@ body {
|
|
|
1772
1772
|
============================================ -->
|
|
1773
1773
|
<header class="header">
|
|
1774
1774
|
<div class="header-logo">BA</div>
|
|
1775
|
-
<span class="header-title">Analyse
|
|
1775
|
+
<span class="header-title">Analyse métier</span>
|
|
1776
1776
|
<div class="header-sep"></div>
|
|
1777
1777
|
<span class="header-app-name" id="appName">{{APPLICATION_NAME}}</span>
|
|
1778
1778
|
<div class="header-spacer"></div>
|
|
1779
1779
|
<div class="header-actions">
|
|
1780
|
-
<button class="btn btn-sm" onclick="resetToEmbedded()" title="
|
|
1780
|
+
<button class="btn btn-sm" onclick="resetToEmbedded()" title="Réinitialiser depuis les données d'origine (supprime les modifications locales)">Reset</button>
|
|
1781
1781
|
<button class="btn btn-sm" onclick="saveToLocalStorage()" title="Sauvegarder les modifications dans le navigateur">Sauvegarder</button>
|
|
1782
|
-
<button class="btn btn-sm btn-review" onclick="saveReviewJSON()" title="Sauvegarder les corrections pour
|
|
1783
|
-
<button class="btn btn-sm btn-primary" onclick="exportJSON()" title="Exporter les
|
|
1782
|
+
<button class="btn btn-sm btn-review" onclick="saveReviewJSON()" title="Sauvegarder les corrections pour créer une nouvelle version">Sauvegarder corrections</button>
|
|
1783
|
+
<button class="btn btn-sm btn-primary" onclick="exportJSON()" title="Exporter les données au format JSON pour l'extraction">Exporter JSON</button>
|
|
1784
1784
|
<button class="btn btn-sm review-toggle-btn" id="reviewToggleBtn" onclick="toggleReviewPanel()" title="Ouvrir/fermer le panneau de review">
|
|
1785
1785
|
Review
|
|
1786
1786
|
<span class="review-badge hidden" id="reviewBadge">0</span>
|
|
@@ -1790,7 +1790,7 @@ body {
|
|
|
1790
1790
|
|
|
1791
1791
|
<div class="body" id="appBody">
|
|
1792
1792
|
<!-- ============================================
|
|
1793
|
-
SIDEBAR - Navigation
|
|
1793
|
+
SIDEBAR - Navigation hiérarchique
|
|
1794
1794
|
============================================ -->
|
|
1795
1795
|
<aside class="sidebar">
|
|
1796
1796
|
<!-- Application Name -->
|
|
@@ -1811,15 +1811,15 @@ body {
|
|
|
1811
1811
|
<!-- SECTION: Contexte (merged: problem + current + vision) -->
|
|
1812
1812
|
<div class="section" id="cadrage-context">
|
|
1813
1813
|
<h2 class="section-title">Contexte du projet</h2>
|
|
1814
|
-
<p class="section-subtitle">Vue
|
|
1814
|
+
<p class="section-subtitle">Vue synthétique du besoin : problème, situation actuelle et objectif visé.</p>
|
|
1815
1815
|
|
|
1816
1816
|
<div style="display:grid;grid-template-columns:repeat(3,1fr);gap:1rem;margin-bottom:1.5rem;">
|
|
1817
1817
|
<div class="card" style="border-left:3px solid #f87171;">
|
|
1818
|
-
<div class="card-label" style="color:#f87171;">
|
|
1819
|
-
<div class="editable" contenteditable="true" data-field="context.problem" data-placeholder="Quel
|
|
1818
|
+
<div class="card-label" style="color:#f87171;">Problème identifié</div>
|
|
1819
|
+
<div class="editable" contenteditable="true" data-field="context.problem" data-placeholder="Quel problème ce projet doit-il résoudre ?"></div>
|
|
1820
1820
|
<div style="margin-top:0.75rem;font-size:0.8rem;color:var(--text-muted);">
|
|
1821
|
-
<strong>
|
|
1822
|
-
<div class="editable" contenteditable="true" data-field="context.trigger" data-placeholder="
|
|
1821
|
+
<strong>Déclencheur :</strong>
|
|
1822
|
+
<div class="editable" contenteditable="true" data-field="context.trigger" data-placeholder="Événement déclencheur" style="display:inline;"></div>
|
|
1823
1823
|
</div>
|
|
1824
1824
|
</div>
|
|
1825
1825
|
|
|
@@ -1834,10 +1834,10 @@ body {
|
|
|
1834
1834
|
|
|
1835
1835
|
<div class="card" style="border-left:3px solid #4ade80;">
|
|
1836
1836
|
<div class="card-label" style="color:#4ade80;">Objectif</div>
|
|
1837
|
-
<div class="editable" contenteditable="true" data-field="context.desiredSituation" data-placeholder="Que doit permettre le
|
|
1837
|
+
<div class="editable" contenteditable="true" data-field="context.desiredSituation" data-placeholder="Que doit permettre le système cible ?"></div>
|
|
1838
1838
|
<div style="margin-top:0.75rem;font-size:0.8rem;color:var(--text-muted);">
|
|
1839
|
-
<strong>
|
|
1840
|
-
<div class="editable" contenteditable="true" data-field="context.acceptanceCriteria" data-placeholder="
|
|
1839
|
+
<strong>Critères :</strong>
|
|
1840
|
+
<div class="editable" contenteditable="true" data-field="context.acceptanceCriteria" data-placeholder="Critères de succès" style="display:inline;"></div>
|
|
1841
1841
|
</div>
|
|
1842
1842
|
</div>
|
|
1843
1843
|
</div>
|
|
@@ -1846,7 +1846,7 @@ body {
|
|
|
1846
1846
|
<!-- SECTION: Parties prenantes -->
|
|
1847
1847
|
<div class="section" id="cadrage-stakeholders" style="display:none;">
|
|
1848
1848
|
<h2 class="section-title">Parties prenantes</h2>
|
|
1849
|
-
<p class="section-subtitle">Toutes les personnes
|
|
1849
|
+
<p class="section-subtitle">Toutes les personnes concernées par ce projet et leurs besoins.</p>
|
|
1850
1850
|
|
|
1851
1851
|
<div class="stakeholder-grid" id="stakeholderGrid">
|
|
1852
1852
|
<!-- Populated dynamically -->
|
|
@@ -1865,12 +1865,12 @@ body {
|
|
|
1865
1865
|
<input type="text" class="form-input" id="sh-function" placeholder="Ce qu'il fait dans l'organisation">
|
|
1866
1866
|
</div>
|
|
1867
1867
|
<div class="form-group">
|
|
1868
|
-
<label class="form-label">
|
|
1869
|
-
<textarea class="form-textarea" id="sh-tasks" placeholder="
|
|
1868
|
+
<label class="form-label">Tâches principales (une par ligne)</label>
|
|
1869
|
+
<textarea class="form-textarea" id="sh-tasks" placeholder="Tâche 1 Tâche 2 Tâche 3"></textarea>
|
|
1870
1870
|
</div>
|
|
1871
1871
|
<div class="form-row">
|
|
1872
1872
|
<div class="form-group">
|
|
1873
|
-
<label class="form-label">
|
|
1873
|
+
<label class="form-label">Fréquence d'utilisation</label>
|
|
1874
1874
|
<select class="form-select" id="sh-frequency">
|
|
1875
1875
|
<option value="daily">Quotidienne</option>
|
|
1876
1876
|
<option value="weekly">Hebdomadaire</option>
|
|
@@ -1879,9 +1879,9 @@ body {
|
|
|
1879
1879
|
</select>
|
|
1880
1880
|
</div>
|
|
1881
1881
|
<div class="form-group">
|
|
1882
|
-
<label class="form-label">Niveau d'
|
|
1882
|
+
<label class="form-label">Niveau d'accès</label>
|
|
1883
1883
|
<select class="form-select" id="sh-access">
|
|
1884
|
-
<option value="admin">Administration
|
|
1884
|
+
<option value="admin">Administration complète</option>
|
|
1885
1885
|
<option value="manager">Supervision et validation</option>
|
|
1886
1886
|
<option value="contributor">Saisie et modification</option>
|
|
1887
1887
|
<option value="viewer">Consultation seule</option>
|
|
@@ -1890,7 +1890,7 @@ body {
|
|
|
1890
1890
|
</div>
|
|
1891
1891
|
<div class="form-group">
|
|
1892
1892
|
<label class="form-label">Frustrations actuelles</label>
|
|
1893
|
-
<textarea class="form-textarea" id="sh-frustrations" placeholder="Quelles sont les 2-3 plus grandes frustrations de ce profil avec la
|
|
1893
|
+
<textarea class="form-textarea" id="sh-frustrations" placeholder="Quelles sont les 2-3 plus grandes frustrations de ce profil avec la façon de travailler actuelle ?"></textarea>
|
|
1894
1894
|
</div>
|
|
1895
1895
|
<div class="form-actions">
|
|
1896
1896
|
<button class="btn" onclick="toggleForm('addStakeholderForm')">Annuler</button>
|
|
@@ -1899,87 +1899,87 @@ body {
|
|
|
1899
1899
|
</div>
|
|
1900
1900
|
</div>
|
|
1901
1901
|
|
|
1902
|
-
<!-- SECTION:
|
|
1902
|
+
<!-- SECTION: Périmètre fonctionnel -->
|
|
1903
1903
|
<div class="section" id="cadrage-scope" style="display:none;">
|
|
1904
|
-
<h2 class="section-title">
|
|
1905
|
-
<p class="section-subtitle">Ce que le
|
|
1904
|
+
<h2 class="section-title">Périmètre fonctionnel</h2>
|
|
1905
|
+
<p class="section-subtitle">Ce que le système doit faire et ne pas faire, par ordre de priorité.</p>
|
|
1906
1906
|
|
|
1907
1907
|
<h3 style="color: var(--text-bright); font-size: 1rem; margin-bottom: 0.75rem;">
|
|
1908
|
-
<span style="color: #f87171;">■</span>
|
|
1908
|
+
<span style="color: #f87171;">■</span> Fonctionnalités indispensables
|
|
1909
1909
|
</h3>
|
|
1910
1910
|
<div id="scopeVital" class="uc-list"></div>
|
|
1911
|
-
<button class="add-btn" onclick="toggleForm('addScopeForm-vital')">+ Ajouter une
|
|
1911
|
+
<button class="add-btn" onclick="toggleForm('addScopeForm-vital')">+ Ajouter une fonctionnalité indispensable</button>
|
|
1912
1912
|
<div class="inline-form" id="addScopeForm-vital">
|
|
1913
|
-
<div class="form-group"><label class="form-label">Nom de la
|
|
1913
|
+
<div class="form-group"><label class="form-label">Nom de la fonctionnalité</label><input type="text" class="form-input" id="scope-name-vital" placeholder="Ex: Gestion des commandes"></div>
|
|
1914
1914
|
<div class="form-group"><label class="form-label">Description (optionnel)</label><input type="text" class="form-input" id="scope-desc-vital" placeholder="Courte description"></div>
|
|
1915
1915
|
<div class="form-actions"><button class="btn" onclick="toggleForm('addScopeForm-vital')">Annuler</button><button class="btn btn-primary" onclick="addScopeItem('vital')">Ajouter</button></div>
|
|
1916
1916
|
</div>
|
|
1917
1917
|
|
|
1918
1918
|
<h3 style="color: var(--text-bright); font-size: 1rem; margin: 1.5rem 0 0.75rem;">
|
|
1919
|
-
<span style="color: #facc15;">■</span>
|
|
1919
|
+
<span style="color: #facc15;">■</span> Fonctionnalités importantes
|
|
1920
1920
|
</h3>
|
|
1921
1921
|
<div id="scopeImportant" class="uc-list"></div>
|
|
1922
|
-
<button class="add-btn" onclick="toggleForm('addScopeForm-important')">+ Ajouter une
|
|
1922
|
+
<button class="add-btn" onclick="toggleForm('addScopeForm-important')">+ Ajouter une fonctionnalité importante</button>
|
|
1923
1923
|
<div class="inline-form" id="addScopeForm-important">
|
|
1924
|
-
<div class="form-group"><label class="form-label">Nom de la
|
|
1924
|
+
<div class="form-group"><label class="form-label">Nom de la fonctionnalité</label><input type="text" class="form-input" id="scope-name-important" placeholder="Ex: Export PDF"></div>
|
|
1925
1925
|
<div class="form-group"><label class="form-label">Description (optionnel)</label><input type="text" class="form-input" id="scope-desc-important" placeholder="Courte description"></div>
|
|
1926
1926
|
<div class="form-actions"><button class="btn" onclick="toggleForm('addScopeForm-important')">Annuler</button><button class="btn btn-primary" onclick="addScopeItem('important')">Ajouter</button></div>
|
|
1927
1927
|
</div>
|
|
1928
1928
|
|
|
1929
1929
|
<h3 style="color: var(--text-bright); font-size: 1rem; margin: 1.5rem 0 0.75rem;">
|
|
1930
|
-
<span style="color: #4ade80;">■</span>
|
|
1930
|
+
<span style="color: #4ade80;">■</span> Fonctionnalités optionnelles
|
|
1931
1931
|
</h3>
|
|
1932
1932
|
<div id="scopeOptional" class="uc-list"></div>
|
|
1933
|
-
<button class="add-btn" onclick="toggleForm('addScopeForm-optional')">+ Ajouter une
|
|
1933
|
+
<button class="add-btn" onclick="toggleForm('addScopeForm-optional')">+ Ajouter une fonctionnalité optionnelle</button>
|
|
1934
1934
|
<div class="inline-form" id="addScopeForm-optional">
|
|
1935
|
-
<div class="form-group"><label class="form-label">Nom de la
|
|
1935
|
+
<div class="form-group"><label class="form-label">Nom de la fonctionnalité</label><input type="text" class="form-input" id="scope-name-optional" placeholder="Ex: Calendrier partagé"></div>
|
|
1936
1936
|
<div class="form-group"><label class="form-label">Description (optionnel)</label><input type="text" class="form-input" id="scope-desc-optional" placeholder="Courte description"></div>
|
|
1937
1937
|
<div class="form-actions"><button class="btn" onclick="toggleForm('addScopeForm-optional')">Annuler</button><button class="btn btn-primary" onclick="addScopeItem('optional')">Ajouter</button></div>
|
|
1938
1938
|
</div>
|
|
1939
1939
|
|
|
1940
1940
|
<h3 style="color: var(--text-bright); font-size: 1rem; margin: 1.5rem 0 0.75rem;">
|
|
1941
|
-
<span style="color: #94a3b8;">■</span> Hors
|
|
1941
|
+
<span style="color: #94a3b8;">■</span> Hors périmètre
|
|
1942
1942
|
</h3>
|
|
1943
1943
|
<div id="scopeExcluded" class="uc-list"></div>
|
|
1944
1944
|
<button class="add-btn" onclick="toggleForm('addScopeForm-excluded')">+ Ajouter une exclusion</button>
|
|
1945
1945
|
<div class="inline-form" id="addScopeForm-excluded">
|
|
1946
|
-
<div class="form-group"><label class="form-label"
|
|
1947
|
-
<div class="form-group"><label class="form-label">Raison (optionnel)</label><input type="text" class="form-input" id="scope-desc-excluded" placeholder="Pourquoi hors
|
|
1946
|
+
<div class="form-group"><label class="form-label">Élément hors périmètre</label><input type="text" class="form-input" id="scope-name-excluded" placeholder="Ex: Gestion de la paie"></div>
|
|
1947
|
+
<div class="form-group"><label class="form-label">Raison (optionnel)</label><input type="text" class="form-input" id="scope-desc-excluded" placeholder="Pourquoi hors périmètre"></div>
|
|
1948
1948
|
<div class="form-actions"><button class="btn" onclick="toggleForm('addScopeForm-excluded')">Annuler</button><button class="btn btn-primary" onclick="addScopeItem('excluded')">Ajouter</button></div>
|
|
1949
1949
|
</div>
|
|
1950
1950
|
</div>
|
|
1951
1951
|
|
|
1952
|
-
<!-- SECTION:
|
|
1952
|
+
<!-- SECTION: Critères de réussite -->
|
|
1953
1953
|
<div class="section" id="cadrage-success" style="display:none;">
|
|
1954
|
-
<h2 class="section-title">
|
|
1955
|
-
<p class="section-subtitle">Comment mesurer objectivement que le projet est un
|
|
1954
|
+
<h2 class="section-title">Critères de réussite</h2>
|
|
1955
|
+
<p class="section-subtitle">Comment mesurer objectivement que le projet est un succès.</p>
|
|
1956
1956
|
|
|
1957
1957
|
<div class="card">
|
|
1958
|
-
<div class="card-label">
|
|
1959
|
-
<div class="editable" contenteditable="true" data-field="success.definition" data-placeholder="Comment saurez-vous que le projet est un
|
|
1958
|
+
<div class="card-label">Définition du succès</div>
|
|
1959
|
+
<div class="editable" contenteditable="true" data-field="success.definition" data-placeholder="Comment saurez-vous que le projet est un succès ? Quel changement concret observerez-vous ?"></div>
|
|
1960
1960
|
</div>
|
|
1961
1961
|
|
|
1962
1962
|
<div class="card" data-vibe-hide>
|
|
1963
1963
|
<div class="card-label">Objectifs mesurables</div>
|
|
1964
|
-
<div class="editable" contenteditable="true" data-field="success.metrics" data-placeholder="Quels chiffres
|
|
1964
|
+
<div class="editable" contenteditable="true" data-field="success.metrics" data-placeholder="Quels chiffres présenteriez-vous à votre direction pour prouver le succès ? (temps, erreurs, satisfaction...)"></div>
|
|
1965
1965
|
</div>
|
|
1966
1966
|
|
|
1967
1967
|
<div class="card" data-vibe-hide>
|
|
1968
|
-
<div class="card-label">
|
|
1969
|
-
<div class="editable" contenteditable="true" data-field="success.timeline" data-placeholder="Au bout de combien de temps pourrez-vous juger si
|
|
1968
|
+
<div class="card-label">Délai d'évaluation</div>
|
|
1969
|
+
<div class="editable" contenteditable="true" data-field="success.timeline" data-placeholder="Au bout de combien de temps pourrez-vous juger si ça fonctionne ? 1 semaine ? 1 mois ? 3 mois ?"></div>
|
|
1970
1970
|
</div>
|
|
1971
1971
|
|
|
1972
1972
|
<div class="card" data-vibe-hide>
|
|
1973
1973
|
<div class="card-label">Conditions minimales de mise en service</div>
|
|
1974
|
-
<div class="editable" contenteditable="true" data-field="success.minimumConditions" data-placeholder="Quelles conditions minimales pour mettre le
|
|
1974
|
+
<div class="editable" contenteditable="true" data-field="success.minimumConditions" data-placeholder="Quelles conditions minimales pour mettre le système en service ? (fonctionnalités présentes, données migrées, formation faite...)"></div>
|
|
1975
1975
|
</div>
|
|
1976
1976
|
|
|
1977
|
-
<h3 style="color: var(--text-bright); font-size: 1rem; margin: 2rem 0 0.75rem;">
|
|
1978
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">
|
|
1977
|
+
<h3 style="color: var(--text-bright); font-size: 1rem; margin: 2rem 0 0.75rem;">Critères d'acceptation</h3>
|
|
1978
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Critères concrets et mesurables pour valider le succès du projet.</p>
|
|
1979
1979
|
<div id="criteriaList" class="uc-list"></div>
|
|
1980
|
-
<button class="add-btn" onclick="toggleForm('addCriterionForm')">+ Ajouter un
|
|
1980
|
+
<button class="add-btn" onclick="toggleForm('addCriterionForm')">+ Ajouter un critère d'acceptation</button>
|
|
1981
1981
|
<div class="inline-form" id="addCriterionForm">
|
|
1982
|
-
<div class="form-group"><label class="form-label">
|
|
1982
|
+
<div class="form-group"><label class="form-label">Critère (mesurable)</label><input type="text" class="form-input" id="criterion-text" placeholder="Ex: 80% des employés saisissent leurs heures chaque semaine"></div>
|
|
1983
1983
|
<div class="form-actions"><button class="btn" onclick="toggleForm('addCriterionForm')">Annuler</button><button class="btn btn-primary" onclick="addCriterion()">Ajouter</button></div>
|
|
1984
1984
|
</div>
|
|
1985
1985
|
</div>
|
|
@@ -1991,7 +1991,7 @@ body {
|
|
|
1991
1991
|
<!-- SECTION: Domaines fonctionnels -->
|
|
1992
1992
|
<div class="section" id="decomp-modules" style="display:none;">
|
|
1993
1993
|
<h2 class="section-title">Domaines fonctionnels</h2>
|
|
1994
|
-
<p class="section-subtitle">Identifiez les grands domaines de votre application. Chaque domaine regroupe des
|
|
1994
|
+
<p class="section-subtitle">Identifiez les grands domaines de votre application. Chaque domaine regroupe des fonctionnalités cohérentes et indépendantes.</p>
|
|
1995
1995
|
|
|
1996
1996
|
<div class="module-grid" id="moduleGrid">
|
|
1997
1997
|
<!-- Populated dynamically -->
|
|
@@ -2007,21 +2007,21 @@ body {
|
|
|
2007
2007
|
</div>
|
|
2008
2008
|
<div class="form-group">
|
|
2009
2009
|
<label class="form-label">Description en une ou deux phrases</label>
|
|
2010
|
-
<textarea class="form-textarea" id="mod-desc" placeholder="
|
|
2010
|
+
<textarea class="form-textarea" id="mod-desc" placeholder="À quoi sert ce domaine ? Quel problème résout-il ?"></textarea>
|
|
2011
2011
|
</div>
|
|
2012
2012
|
<div class="form-row">
|
|
2013
2013
|
<div class="form-group">
|
|
2014
2014
|
<label class="form-label">Type de domaine</label>
|
|
2015
2015
|
<select class="form-select" id="mod-type">
|
|
2016
|
-
<option value="data-centric">Gestion de
|
|
2017
|
-
<option value="workflow">Processus
|
|
2016
|
+
<option value="data-centric">Gestion de données (listes, fiches, formulaires)</option>
|
|
2017
|
+
<option value="workflow">Processus métier (étapes, validations, approbations)</option>
|
|
2018
2018
|
<option value="reporting">Tableaux de bord et rapports</option>
|
|
2019
|
-
<option value="integration">
|
|
2020
|
-
<option value="full-module">Domaine complet (
|
|
2019
|
+
<option value="integration">Intégration avec des systèmes externes</option>
|
|
2020
|
+
<option value="full-module">Domaine complet (données + processus + rapports)</option>
|
|
2021
2021
|
</select>
|
|
2022
2022
|
</div>
|
|
2023
2023
|
<div class="form-group">
|
|
2024
|
-
<label class="form-label">
|
|
2024
|
+
<label class="form-label">Priorité</label>
|
|
2025
2025
|
<select class="form-select" id="mod-priority">
|
|
2026
2026
|
<option value="must">Indispensable</option>
|
|
2027
2027
|
<option value="should">Important</option>
|
|
@@ -2030,7 +2030,7 @@ body {
|
|
|
2030
2030
|
</div>
|
|
2031
2031
|
</div>
|
|
2032
2032
|
<div class="form-group">
|
|
2033
|
-
<label class="form-label">Principales
|
|
2033
|
+
<label class="form-label">Principales données gérées (une par ligne)</label>
|
|
2034
2034
|
<textarea class="form-textarea" id="mod-entities" placeholder="Commande Ligne de commande Facture"></textarea>
|
|
2035
2035
|
</div>
|
|
2036
2036
|
<div class="form-actions">
|
|
@@ -2040,41 +2040,41 @@ body {
|
|
|
2040
2040
|
</div>
|
|
2041
2041
|
</div>
|
|
2042
2042
|
|
|
2043
|
-
<!-- SECTION:
|
|
2043
|
+
<!-- SECTION: Dépendances -->
|
|
2044
2044
|
<div class="section" id="decomp-dependencies" style="display:none;">
|
|
2045
|
-
<h2 class="section-title">
|
|
2046
|
-
<p class="section-subtitle">Indiquez quels domaines
|
|
2045
|
+
<h2 class="section-title">Dépendances entre domaines</h2>
|
|
2046
|
+
<p class="section-subtitle">Indiquez quels domaines dépendent d'autres domaines. Par exemple, les Commandes dépendent des Clients et des Produits.</p>
|
|
2047
2047
|
|
|
2048
2048
|
<div id="depGraphContainer">
|
|
2049
2049
|
<div class="dep-graph" id="depGraph">
|
|
2050
|
-
<p style="color:var(--text-muted);text-align:center;padding:2rem;">Ajoutez des domaines fonctionnels pour visualiser les
|
|
2050
|
+
<p style="color:var(--text-muted);text-align:center;padding:2rem;">Ajoutez des domaines fonctionnels pour visualiser les dépendances.</p>
|
|
2051
2051
|
</div>
|
|
2052
2052
|
</div>
|
|
2053
2053
|
|
|
2054
2054
|
<div style="margin-top:1.5rem;">
|
|
2055
|
-
<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:0.75rem;">Ajouter une
|
|
2055
|
+
<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:0.75rem;">Ajouter une dépendance</h3>
|
|
2056
2056
|
<div class="form-row">
|
|
2057
2057
|
<div class="form-group">
|
|
2058
2058
|
<label class="form-label">Ce domaine...</label>
|
|
2059
2059
|
<select class="form-select" id="dep-from"></select>
|
|
2060
2060
|
</div>
|
|
2061
2061
|
<div class="form-group">
|
|
2062
|
-
<label class="form-label">...
|
|
2062
|
+
<label class="form-label">...dépend de</label>
|
|
2063
2063
|
<select class="form-select" id="dep-to"></select>
|
|
2064
2064
|
</div>
|
|
2065
2065
|
</div>
|
|
2066
2066
|
<div class="form-group">
|
|
2067
|
-
<label class="form-label">Nature de la
|
|
2068
|
-
<input type="text" class="form-input" id="dep-desc" placeholder="Exemple : La commande
|
|
2067
|
+
<label class="form-label">Nature de la dépendance</label>
|
|
2068
|
+
<input type="text" class="form-input" id="dep-desc" placeholder="Exemple : La commande référence un client existant">
|
|
2069
2069
|
</div>
|
|
2070
|
-
<button class="btn btn-primary" onclick="addDependency()" style="margin-top:0.5rem;">Ajouter cette
|
|
2070
|
+
<button class="btn btn-primary" onclick="addDependency()" style="margin-top:0.5rem;">Ajouter cette dépendance</button>
|
|
2071
2071
|
</div>
|
|
2072
2072
|
|
|
2073
2073
|
<div id="depList" style="margin-top:1.5rem;"></div>
|
|
2074
2074
|
|
|
2075
2075
|
<div style="margin-top:2rem;">
|
|
2076
|
-
<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:0.75rem;">Ordre de traitement
|
|
2077
|
-
<p class="section-subtitle">Les domaines sont
|
|
2076
|
+
<h3 style="color:var(--text-bright);font-size:1rem;margin-bottom:0.75rem;">Ordre de traitement proposé</h3>
|
|
2077
|
+
<p class="section-subtitle">Les domaines sont traités dans l'ordre de leurs dépendances : les fondations d'abord, puis les domaines qui en dépendent.</p>
|
|
2078
2078
|
<div id="processingOrder" class="process-flow"></div>
|
|
2079
2079
|
</div>
|
|
2080
2080
|
</div>
|
|
@@ -2092,37 +2092,37 @@ body {
|
|
|
2092
2092
|
PHASE 4 : CONSOLIDATION
|
|
2093
2093
|
================================================================ -->
|
|
2094
2094
|
|
|
2095
|
-
<!-- SECTION:
|
|
2095
|
+
<!-- SECTION: Modèle de données -->
|
|
2096
2096
|
<div class="section" id="consol-datamodel" style="display:none;">
|
|
2097
|
-
<h2 class="section-title">
|
|
2098
|
-
<p class="section-subtitle">Vue d'ensemble de toutes les
|
|
2097
|
+
<h2 class="section-title">Modèle de données</h2>
|
|
2098
|
+
<p class="section-subtitle">Vue d'ensemble de toutes les entités métier, leurs attributs et leurs relations entre domaines.</p>
|
|
2099
2099
|
<div id="dataModelContainer">
|
|
2100
|
-
<p style="color:var(--text-muted);text-align:center;padding:2rem;">Le
|
|
2100
|
+
<p style="color:var(--text-muted);text-align:center;padding:2rem;">Le modèle de données sera généré à partir des spécifications de chaque domaine.</p>
|
|
2101
2101
|
</div>
|
|
2102
2102
|
</div>
|
|
2103
2103
|
|
|
2104
2104
|
<!-- SECTION: Interactions cross-module -->
|
|
2105
2105
|
<div class="section" id="consol-interactions" style="display:none;">
|
|
2106
2106
|
<h2 class="section-title">Interactions entre domaines</h2>
|
|
2107
|
-
<p class="section-subtitle">Vue d'ensemble de la
|
|
2107
|
+
<p class="section-subtitle">Vue d'ensemble de la façon dont les domaines communiquent et partagent des données.</p>
|
|
2108
2108
|
<div id="consolInteractions">
|
|
2109
|
-
<p style="color:var(--text-muted);text-align:center;padding:2rem;">Les interactions seront
|
|
2109
|
+
<p style="color:var(--text-muted);text-align:center;padding:2rem;">Les interactions seront calculées automatiquement à partir des dépendances et des données partagées entre domaines.</p>
|
|
2110
2110
|
</div>
|
|
2111
2111
|
</div>
|
|
2112
2112
|
|
|
2113
|
-
<!-- SECTION:
|
|
2113
|
+
<!-- SECTION: Cohérence des accès -->
|
|
2114
2114
|
<div class="section" id="consol-permissions" style="display:none;">
|
|
2115
|
-
<h2 class="section-title">
|
|
2116
|
-
<p class="section-subtitle">
|
|
2115
|
+
<h2 class="section-title">Cohérence des droits d'accès</h2>
|
|
2116
|
+
<p class="section-subtitle">Vérification que les profils utilisateurs ont des droits cohérents dans tous les domaines.</p>
|
|
2117
2117
|
<div id="consolPermissions">
|
|
2118
|
-
<p style="color:var(--text-muted);text-align:center;padding:2rem;">La
|
|
2118
|
+
<p style="color:var(--text-muted);text-align:center;padding:2rem;">La cohérence sera vérifiée quand les permissions de chaque domaine seront définies.</p>
|
|
2119
2119
|
</div>
|
|
2120
2120
|
</div>
|
|
2121
2121
|
|
|
2122
2122
|
<!-- SECTION: Parcours bout en bout -->
|
|
2123
2123
|
<div class="section" id="consol-flows" style="display:none;">
|
|
2124
2124
|
<h2 class="section-title">Parcours bout en bout</h2>
|
|
2125
|
-
<p class="section-subtitle">Les processus
|
|
2125
|
+
<p class="section-subtitle">Les processus métier qui traversent plusieurs domaines, de bout en bout.</p>
|
|
2126
2126
|
|
|
2127
2127
|
<div id="e2eFlowsList"></div>
|
|
2128
2128
|
|
|
@@ -2131,16 +2131,16 @@ body {
|
|
|
2131
2131
|
<div class="inline-form" id="addFlowForm">
|
|
2132
2132
|
<div class="inline-form-title">Nouveau parcours bout en bout</div>
|
|
2133
2133
|
<div class="form-group">
|
|
2134
|
-
<label class="form-label">Nom du parcours (exemple : De la commande
|
|
2134
|
+
<label class="form-label">Nom du parcours (exemple : De la commande à la facture)</label>
|
|
2135
2135
|
<input type="text" class="form-input" id="flow-name" placeholder="Nom descriptif du parcours">
|
|
2136
2136
|
</div>
|
|
2137
2137
|
<div class="form-group">
|
|
2138
|
-
<label class="form-label"
|
|
2139
|
-
<textarea class="form-textarea" id="flow-steps" placeholder="Clients - Le client existe dans le
|
|
2138
|
+
<label class="form-label">Étapes du parcours (une par ligne : Domaine - Action)</label>
|
|
2139
|
+
<textarea class="form-textarea" id="flow-steps" placeholder="Clients - Le client existe dans le système Commandes - Créer la commande Commandes - Valider la commande Factures - Générer la facture"></textarea>
|
|
2140
2140
|
</div>
|
|
2141
2141
|
<div class="form-group">
|
|
2142
2142
|
<label class="form-label">Qui intervient dans ce parcours ?</label>
|
|
2143
|
-
<input type="text" class="form-input" id="flow-actors" placeholder="Exemple : Contributeur (
|
|
2143
|
+
<input type="text" class="form-input" id="flow-actors" placeholder="Exemple : Contributeur (création), Responsable (validation)">
|
|
2144
2144
|
</div>
|
|
2145
2145
|
<div class="form-actions">
|
|
2146
2146
|
<button class="btn" onclick="toggleForm('addFlowForm')">Annuler</button>
|
|
@@ -2154,8 +2154,8 @@ body {
|
|
|
2154
2154
|
================================================================ -->
|
|
2155
2155
|
|
|
2156
2156
|
<div class="section" id="handoff-summary" style="display:none;">
|
|
2157
|
-
<h2 class="section-title">
|
|
2158
|
-
<p class="section-subtitle">Vue d'ensemble de toute l'analyse
|
|
2157
|
+
<h2 class="section-title">Synthèse de l'analyse</h2>
|
|
2158
|
+
<p class="section-subtitle">Vue d'ensemble de toute l'analyse métier, prête pour le développement.</p>
|
|
2159
2159
|
|
|
2160
2160
|
<div class="stat-grid" id="handoffStats">
|
|
2161
2161
|
<!-- Populated dynamically -->
|
|
@@ -2172,9 +2172,9 @@ body {
|
|
|
2172
2172
|
</div>
|
|
2173
2173
|
|
|
2174
2174
|
<div style="margin-top:2rem;padding:1.5rem;background:var(--bg-card);border:1px solid var(--border);border-radius:10px;text-align:center;">
|
|
2175
|
-
<p style="color:var(--text-bright);font-size:1.1rem;font-weight:600;margin-bottom:0.5rem;">Analyse
|
|
2176
|
-
<p style="color:var(--text-muted);font-size:0.85rem;margin-bottom:1rem;">Exportez le fichier JSON pour lancer la
|
|
2177
|
-
<button class="btn btn-primary" onclick="exportJSON()" style="font-size:0.9rem;padding:0.6rem 1.5rem;">Exporter l'analyse
|
|
2175
|
+
<p style="color:var(--text-bright);font-size:1.1rem;font-weight:600;margin-bottom:0.5rem;">Analyse prête pour l'extraction</p>
|
|
2176
|
+
<p style="color:var(--text-muted);font-size:0.85rem;margin-bottom:1rem;">Exportez le fichier JSON pour lancer la génération automatique du système.</p>
|
|
2177
|
+
<button class="btn btn-primary" onclick="exportJSON()" style="font-size:0.9rem;padding:0.6rem 1.5rem;">Exporter l'analyse complète en JSON</button>
|
|
2178
2178
|
</div>
|
|
2179
2179
|
</div>
|
|
2180
2180
|
|
|
@@ -2190,8 +2190,8 @@ body {
|
|
|
2190
2190
|
</div>
|
|
2191
2191
|
<div class="review-filters">
|
|
2192
2192
|
<button class="review-filter-btn active" onclick="filterReviewComments('all')" data-filter="all">Tous</button>
|
|
2193
|
-
<button class="review-filter-btn" onclick="filterReviewComments('to-review')" data-filter="to-review"
|
|
2194
|
-
<button class="review-filter-btn" onclick="filterReviewComments('validated')" data-filter="validated">
|
|
2193
|
+
<button class="review-filter-btn" onclick="filterReviewComments('to-review')" data-filter="to-review">À revoir</button>
|
|
2194
|
+
<button class="review-filter-btn" onclick="filterReviewComments('validated')" data-filter="validated">Validés</button>
|
|
2195
2195
|
</div>
|
|
2196
2196
|
<div class="review-comments" id="reviewCommentsList">
|
|
2197
2197
|
<div class="review-empty">Aucun commentaire pour le moment.</div>
|
|
@@ -2203,11 +2203,11 @@ body {
|
|
|
2203
2203
|
</div>
|
|
2204
2204
|
<div class="review-stat">
|
|
2205
2205
|
<div class="review-stat-value" id="reviewStatToReview">0</div>
|
|
2206
|
-
<div class="review-stat-label"
|
|
2206
|
+
<div class="review-stat-label">À revoir</div>
|
|
2207
2207
|
</div>
|
|
2208
2208
|
<div class="review-stat">
|
|
2209
2209
|
<div class="review-stat-value" id="reviewStatValidated">0</div>
|
|
2210
|
-
<div class="review-stat-label">
|
|
2210
|
+
<div class="review-stat-label">Validés</div>
|
|
2211
2211
|
</div>
|
|
2212
2212
|
</div>
|
|
2213
2213
|
</aside>
|
|
@@ -2292,6 +2292,14 @@ data.moduleSpecs = data.moduleSpecs || {};
|
|
|
2292
2292
|
}
|
|
2293
2293
|
});
|
|
2294
2294
|
|
|
2295
|
+
// Defensive: normalize stakeholder tasks (string → array)
|
|
2296
|
+
(data.cadrage.stakeholders || []).forEach(function(s) {
|
|
2297
|
+
if (typeof s.tasks === 'string') {
|
|
2298
|
+
s.tasks = s.tasks.split(',').map(t => t.trim()).filter(Boolean);
|
|
2299
|
+
}
|
|
2300
|
+
s.tasks = s.tasks || [];
|
|
2301
|
+
});
|
|
2302
|
+
|
|
2295
2303
|
// Vibe coding mode: hide non-relevant sections
|
|
2296
2304
|
const isVibeCoding = data.metadata?.vibeCoding === true;
|
|
2297
2305
|
if (isVibeCoding) {
|
|
@@ -2344,7 +2352,7 @@ function formatAccess(a) {
|
|
|
2344
2352
|
}
|
|
2345
2353
|
|
|
2346
2354
|
function formatPriority(p) {
|
|
2347
|
-
return { vital: 'Indispensable', important: 'Important', optional: 'Optionnel', excluded: 'Hors
|
|
2355
|
+
return { vital: 'Indispensable', important: 'Important', optional: 'Optionnel', excluded: 'Hors périmètre' }[p] || p;
|
|
2348
2356
|
}
|
|
2349
2357
|
|
|
2350
2358
|
function formatLevel(l) {
|
|
@@ -2352,7 +2360,7 @@ function formatLevel(l) {
|
|
|
2352
2360
|
}
|
|
2353
2361
|
|
|
2354
2362
|
function formatModuleType(t) {
|
|
2355
|
-
return { 'data-centric': '
|
|
2363
|
+
return { 'data-centric': 'Données', 'workflow': 'Processus', 'reporting': 'Rapports', 'integration': 'Intégration', 'full-module': 'Complet' }[t] || t;
|
|
2356
2364
|
}
|
|
2357
2365
|
|
|
2358
2366
|
function formatModulePriority(p) {
|
|
@@ -2463,13 +2471,13 @@ function buildNavTree() {
|
|
|
2463
2471
|
});
|
|
2464
2472
|
html += renderNavGroup('modules-other', 'Autres modules (' + orphanModules.length + ')', orphanItems);
|
|
2465
2473
|
}
|
|
2466
|
-
html += renderNavItem('decomp-dependencies', '
|
|
2474
|
+
html += renderNavItem('decomp-dependencies', 'Dépendances', data.dependencies.length);
|
|
2467
2475
|
} else {
|
|
2468
2476
|
html += renderNavGroup('modules', 'Modules (' + data.modules.length + ')', buildModuleItems());
|
|
2469
2477
|
}
|
|
2470
2478
|
|
|
2471
2479
|
html += renderNavGroup('consolidation', 'Consolidation', buildConsolidationItems());
|
|
2472
|
-
html += renderNavGroup('synthese', '
|
|
2480
|
+
html += renderNavGroup('synthese', 'Synthèse', buildSyntheseItems());
|
|
2473
2481
|
|
|
2474
2482
|
nav.innerHTML = html;
|
|
2475
2483
|
restoreNavState();
|
|
@@ -2501,8 +2509,8 @@ function renderNavItem(sectionId, label, badge) {
|
|
|
2501
2509
|
function buildCadrageItems() {
|
|
2502
2510
|
return renderNavItem('cadrage-context', 'Contexte') +
|
|
2503
2511
|
renderNavItem('cadrage-stakeholders', 'Parties prenantes', data.cadrage.stakeholders.length) +
|
|
2504
|
-
renderNavItem('cadrage-scope', '
|
|
2505
|
-
renderNavItem('cadrage-success', '
|
|
2512
|
+
renderNavItem('cadrage-scope', 'Périmètre fonctionnel') +
|
|
2513
|
+
renderNavItem('cadrage-success', 'Critères de réussite');
|
|
2506
2514
|
}
|
|
2507
2515
|
|
|
2508
2516
|
function buildModuleItems() {
|
|
@@ -2512,7 +2520,7 @@ function buildModuleItems() {
|
|
|
2512
2520
|
});
|
|
2513
2521
|
// Global module views at bottom
|
|
2514
2522
|
html += renderNavItem('decomp-modules', 'Vue d\'ensemble', data.modules.length);
|
|
2515
|
-
html += renderNavItem('decomp-dependencies', '
|
|
2523
|
+
html += renderNavItem('decomp-dependencies', 'Dépendances', data.dependencies.length);
|
|
2516
2524
|
return html;
|
|
2517
2525
|
}
|
|
2518
2526
|
|
|
@@ -2520,9 +2528,9 @@ function buildConsolidationItems() {
|
|
|
2520
2528
|
var totalEntities = data.modules.reduce(function(sum, m) {
|
|
2521
2529
|
return sum + (data.moduleSpecs[m.code]?.entities || []).length;
|
|
2522
2530
|
}, 0);
|
|
2523
|
-
return renderNavItem('consol-datamodel', '
|
|
2531
|
+
return renderNavItem('consol-datamodel', 'Modèle de données', totalEntities) +
|
|
2524
2532
|
renderNavItem('consol-interactions', 'Interactions') +
|
|
2525
|
-
renderNavItem('consol-permissions', '
|
|
2533
|
+
renderNavItem('consol-permissions', 'Cohérence des accès') +
|
|
2526
2534
|
renderNavItem('consol-flows', 'Parcours bout en bout', data.consolidation.e2eFlows.length);
|
|
2527
2535
|
}
|
|
2528
2536
|
|
|
@@ -2553,9 +2561,9 @@ function renderModuleNavItem(mod) {
|
|
|
2553
2561
|
// Children: tabs
|
|
2554
2562
|
html += '<div class="nav-children"' + (collapsed ? ' style="display:none;"' : '') + '>';
|
|
2555
2563
|
html += renderModuleTabNavItem(code, 'uc', 'Cas d\'utilisation', ucCount);
|
|
2556
|
-
html += renderModuleTabNavItem(code, 'br', '
|
|
2557
|
-
html += renderModuleTabNavItem(code, 'ent', '
|
|
2558
|
-
html += renderModuleTabNavItem(code, 'perm', 'Droits d\'
|
|
2564
|
+
html += renderModuleTabNavItem(code, 'br', 'Règles métier', brCount);
|
|
2565
|
+
html += renderModuleTabNavItem(code, 'ent', 'Données', entCount);
|
|
2566
|
+
html += renderModuleTabNavItem(code, 'perm', 'Droits d\'accès');
|
|
2559
2567
|
html += renderModuleTabNavItem(code, 'mock', 'Maquettes');
|
|
2560
2568
|
html += renderModuleTabNavItem(code, 'struct', 'Structure', sections.length);
|
|
2561
2569
|
|
|
@@ -2691,7 +2699,7 @@ function renderStakeholders() {
|
|
|
2691
2699
|
</div>
|
|
2692
2700
|
<div class="stakeholder-function">${s.function || ''}</div>
|
|
2693
2701
|
<ul class="stakeholder-tasks">
|
|
2694
|
-
${(s.tasks
|
|
2702
|
+
${(Array.isArray(s.tasks) ? s.tasks : typeof s.tasks === 'string' ? s.tasks.split(',').map(t => t.trim()).filter(Boolean) : []).map(t => '<li>' + t + '</li>').join('')}
|
|
2695
2703
|
</ul>
|
|
2696
2704
|
<div class="stakeholder-meta">
|
|
2697
2705
|
<span>${formatFrequency(s.frequency)}</span>
|
|
@@ -2869,11 +2877,11 @@ function renderModules() {
|
|
|
2869
2877
|
<div class="module-card-desc">${m.description || ''}</div>
|
|
2870
2878
|
<div class="module-card-meta">
|
|
2871
2879
|
<span class="priority priority-${m.priority === 'must' ? 'vital' : m.priority === 'should' ? 'important' : 'optional'}">${formatModulePriority(m.priority)}</span>
|
|
2872
|
-
<span>${(m.entities || []).length}
|
|
2880
|
+
<span>${(m.entities || []).length} données</span>
|
|
2873
2881
|
<span>${(data.moduleSpecs[m.code]?.useCases || []).length} cas d'utilisation</span>
|
|
2874
2882
|
</div>
|
|
2875
2883
|
</div>
|
|
2876
|
-
`).join('') || '<p style="color:var(--text-muted);text-align:center;padding:2rem;grid-column:1/-1;">Aucun domaine fonctionnel
|
|
2884
|
+
`).join('') || '<p style="color:var(--text-muted);text-align:center;padding:2rem;grid-column:1/-1;">Aucun domaine fonctionnel défini. Cliquez sur le bouton ci-dessous pour commencer.</p>';
|
|
2877
2885
|
}
|
|
2878
2886
|
|
|
2879
2887
|
function updateModulesNav() {
|
|
@@ -2946,7 +2954,7 @@ function renderDepGraph() {
|
|
|
2946
2954
|
|
|
2947
2955
|
const layers = computeTopologicalLayers();
|
|
2948
2956
|
if (!layers) {
|
|
2949
|
-
graph.innerHTML = '<p style="color:var(--error);text-align:center;padding:1rem;">
|
|
2957
|
+
graph.innerHTML = '<p style="color:var(--error);text-align:center;padding:1rem;">Dépendance circulaire détectée ! Corrigez les dépendances.</p>';
|
|
2950
2958
|
return;
|
|
2951
2959
|
}
|
|
2952
2960
|
|
|
@@ -3003,7 +3011,7 @@ function renderProcessingOrder() {
|
|
|
3003
3011
|
const m = data.modules.find(mod => mod.code === code);
|
|
3004
3012
|
return `
|
|
3005
3013
|
<div class="process-step">
|
|
3006
|
-
<div class="process-step-number"
|
|
3014
|
+
<div class="process-step-number">Étape ${i + 1}</div>
|
|
3007
3015
|
<div class="process-step-label">${m ? (m.name || m.code) : code}</div>
|
|
3008
3016
|
</div>
|
|
3009
3017
|
${i < order.length - 1 ? '<div class="process-arrow">→</div>' : ''}
|
|
@@ -3043,13 +3051,13 @@ function renderModuleSpecSection(mod) {
|
|
|
3043
3051
|
return `
|
|
3044
3052
|
<div class="section" id="module-spec-${code}" style="display:none;">
|
|
3045
3053
|
<h2 class="section-title">${mod.name}</h2>
|
|
3046
|
-
<p class="section-subtitle">${mod.description || '
|
|
3054
|
+
<p class="section-subtitle">${mod.description || 'Spécification détaillée de ce domaine fonctionnel.'}</p>
|
|
3047
3055
|
|
|
3048
3056
|
<div class="tab-bar">
|
|
3049
3057
|
<button class="tab-btn active" onclick="switchTab('${code}', 'uc')">Cas d'utilisation</button>
|
|
3050
|
-
<button class="tab-btn" onclick="switchTab('${code}', 'br')">
|
|
3051
|
-
<button class="tab-btn" onclick="switchTab('${code}', 'ent')">
|
|
3052
|
-
<button class="tab-btn" onclick="switchTab('${code}', 'perm')">Droits d'
|
|
3058
|
+
<button class="tab-btn" onclick="switchTab('${code}', 'br')">Règles métier</button>
|
|
3059
|
+
<button class="tab-btn" onclick="switchTab('${code}', 'ent')">Données</button>
|
|
3060
|
+
<button class="tab-btn" onclick="switchTab('${code}', 'perm')">Droits d'accès</button>
|
|
3053
3061
|
<button class="tab-btn" onclick="switchTab('${code}', 'mock')">Maquettes</button>
|
|
3054
3062
|
<button class="tab-btn" onclick="switchTab('${code}', 'notes')">Notes</button>
|
|
3055
3063
|
<button class="tab-btn" onclick="switchTab('${code}', 'struct')">Structure</button>
|
|
@@ -3057,7 +3065,7 @@ function renderModuleSpecSection(mod) {
|
|
|
3057
3065
|
|
|
3058
3066
|
<!-- TAB: Cas d'utilisation -->
|
|
3059
3067
|
<div class="tab-panel active" id="tab-${code}-uc">
|
|
3060
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">
|
|
3068
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Décrivez ce que chaque type d'utilisateur peut faire dans ce domaine. Un cas d'utilisation = une action concrète.</p>
|
|
3061
3069
|
<div id="ucList-${code}" class="uc-list">
|
|
3062
3070
|
${spec.useCases.map((uc, i) => renderUseCase(code, uc, i)).join('')}
|
|
3063
3071
|
</div>
|
|
@@ -3065,20 +3073,20 @@ function renderModuleSpecSection(mod) {
|
|
|
3065
3073
|
<div class="inline-form" id="addUcForm-${code}">
|
|
3066
3074
|
<div class="inline-form-title">Nouveau cas d'utilisation</div>
|
|
3067
3075
|
<div class="form-group">
|
|
3068
|
-
<label class="form-label">Que fait l'utilisateur ? (exemple :
|
|
3069
|
-
<input type="text" class="form-input" id="uc-name-${code}" placeholder="Action
|
|
3076
|
+
<label class="form-label">Que fait l'utilisateur ? (exemple : Créer une commande)</label>
|
|
3077
|
+
<input type="text" class="form-input" id="uc-name-${code}" placeholder="Action concrète de l'utilisateur">
|
|
3070
3078
|
</div>
|
|
3071
3079
|
<div class="form-group">
|
|
3072
|
-
<label class="form-label">Qui
|
|
3080
|
+
<label class="form-label">Qui réalise cette action ? (profil utilisateur)</label>
|
|
3073
3081
|
<input type="text" class="form-input" id="uc-actor-${code}" placeholder="Exemple : Responsable de production">
|
|
3074
3082
|
</div>
|
|
3075
3083
|
<div class="form-group">
|
|
3076
|
-
<label class="form-label">
|
|
3077
|
-
<textarea class="form-textarea" id="uc-steps-${code}" placeholder="1. L'utilisateur ouvre la page de
|
|
3084
|
+
<label class="form-label">Déroulement normal, étape par étape (une par ligne)</label>
|
|
3085
|
+
<textarea class="form-textarea" id="uc-steps-${code}" placeholder="1. L'utilisateur ouvre la page de création 2. Il remplit les champs obligatoires 3. Il valide le formulaire 4. Le système enregistre et confirme"></textarea>
|
|
3078
3086
|
</div>
|
|
3079
3087
|
<div class="form-group">
|
|
3080
3088
|
<label class="form-label">Que se passe-t-il si quelque chose ne va pas ? (optionnel)</label>
|
|
3081
|
-
<textarea class="form-textarea" id="uc-alt-${code}" placeholder="Exemple : Si les
|
|
3089
|
+
<textarea class="form-textarea" id="uc-alt-${code}" placeholder="Exemple : Si les données sont incorrectes, le système affiche un message d'erreur" style="min-height:50px;"></textarea>
|
|
3082
3090
|
</div>
|
|
3083
3091
|
<div class="form-actions">
|
|
3084
3092
|
<button class="btn" onclick="toggleForm('addUcForm-${code}')">Annuler</button>
|
|
@@ -3087,36 +3095,36 @@ function renderModuleSpecSection(mod) {
|
|
|
3087
3095
|
</div>
|
|
3088
3096
|
</div>
|
|
3089
3097
|
|
|
3090
|
-
<!-- TAB:
|
|
3098
|
+
<!-- TAB: Règles métier -->
|
|
3091
3099
|
<div class="tab-panel" id="tab-${code}-br">
|
|
3092
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Les
|
|
3100
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Les règles que le système doit respecter. Formulez-les sous forme de conditions : "Si... alors... sinon..."</p>
|
|
3093
3101
|
<div id="brList-${code}">
|
|
3094
3102
|
${spec.businessRules.map((br, i) => renderBusinessRule(code, br, i)).join('')}
|
|
3095
3103
|
</div>
|
|
3096
|
-
<button class="add-btn" onclick="toggleForm('addBrForm-${code}')">+ Ajouter une
|
|
3104
|
+
<button class="add-btn" onclick="toggleForm('addBrForm-${code}')">+ Ajouter une règle métier</button>
|
|
3097
3105
|
<div class="inline-form" id="addBrForm-${code}">
|
|
3098
|
-
<div class="inline-form-title">Nouvelle
|
|
3106
|
+
<div class="inline-form-title">Nouvelle règle métier</div>
|
|
3099
3107
|
<div class="form-group">
|
|
3100
|
-
<label class="form-label">Nom court de la
|
|
3101
|
-
<input type="text" class="form-input" id="br-name-${code}" placeholder="Exemple :
|
|
3108
|
+
<label class="form-label">Nom court de la règle</label>
|
|
3109
|
+
<input type="text" class="form-input" id="br-name-${code}" placeholder="Exemple : Vérification du budget disponible">
|
|
3102
3110
|
</div>
|
|
3103
3111
|
<div class="form-group">
|
|
3104
|
-
<label class="form-label">
|
|
3112
|
+
<label class="form-label">Catégorie</label>
|
|
3105
3113
|
<select class="form-select" id="br-cat-${code}">
|
|
3106
|
-
<option value="validation">
|
|
3107
|
-
<option value="calculation">Calcul (le
|
|
3114
|
+
<option value="validation">Vérification (le système vérifie que...)</option>
|
|
3115
|
+
<option value="calculation">Calcul (le système calcule...)</option>
|
|
3108
3116
|
<option value="workflow">Processus (quand X se produit, alors...)</option>
|
|
3109
|
-
<option value="security">
|
|
3110
|
-
<option value="data">
|
|
3117
|
+
<option value="security">Sécurité (seul... peut...)</option>
|
|
3118
|
+
<option value="data">Données (les données doivent...)</option>
|
|
3111
3119
|
</select>
|
|
3112
3120
|
</div>
|
|
3113
3121
|
<div class="form-group">
|
|
3114
|
-
<label class="form-label">Formulation de la
|
|
3115
|
-
<textarea class="form-textarea" id="br-statement-${code}" placeholder="Si le montant de la commande
|
|
3122
|
+
<label class="form-label">Formulation de la règle (Si... alors... sinon...)</label>
|
|
3123
|
+
<textarea class="form-textarea" id="br-statement-${code}" placeholder="Si le montant de la commande dépasse le budget du client, alors la commande est refusée et un message d'erreur s'affiche"></textarea>
|
|
3116
3124
|
</div>
|
|
3117
3125
|
<div class="form-group">
|
|
3118
3126
|
<label class="form-label">Exemple concret (optionnel)</label>
|
|
3119
|
-
<input type="text" class="form-input" id="br-example-${code}" placeholder="Exemple : Commande de 5000 CHF, budget de 2000 CHF ->
|
|
3127
|
+
<input type="text" class="form-input" id="br-example-${code}" placeholder="Exemple : Commande de 5000 CHF, budget de 2000 CHF -> refusée">
|
|
3120
3128
|
</div>
|
|
3121
3129
|
<div class="form-actions">
|
|
3122
3130
|
<button class="btn" onclick="toggleForm('addBrForm-${code}')">Annuler</button>
|
|
@@ -3125,34 +3133,34 @@ function renderModuleSpecSection(mod) {
|
|
|
3125
3133
|
</div>
|
|
3126
3134
|
</div>
|
|
3127
3135
|
|
|
3128
|
-
<!-- TAB:
|
|
3136
|
+
<!-- TAB: Données (Entités) -->
|
|
3129
3137
|
<div class="tab-panel" id="tab-${code}-ent">
|
|
3130
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Les types de
|
|
3138
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Les types de données que ce domaine gère. Décrivez les informations importantes à enregistrer pour chaque type.</p>
|
|
3131
3139
|
<div id="entList-${code}">
|
|
3132
3140
|
${spec.entities.length > 0
|
|
3133
3141
|
? spec.entities.map((ent, i) => renderEntity(code, ent, i)).join('')
|
|
3134
3142
|
: (mod.entities || []).length > 0
|
|
3135
|
-
? '<div class="card" style="color:var(--text-muted);padding:1.5rem;"><p style="margin-bottom:0.75rem;">Les
|
|
3143
|
+
? '<div class="card" style="color:var(--text-muted);padding:1.5rem;"><p style="margin-bottom:0.75rem;">Les schémas détaillés ne sont pas encore disponibles. Entités identifiées :</p><ul style="list-style:disc;padding-left:1.5rem;">' + mod.entities.map(e => '<li>' + e + '</li>').join('') + '</ul><p style="font-size:0.8rem;margin-top:0.75rem;font-style:italic;">Utilisez le bouton ci-dessous pour ajouter les schémas détaillés.</p></div>'
|
|
3136
3144
|
: ''
|
|
3137
3145
|
}
|
|
3138
3146
|
</div>
|
|
3139
|
-
<button class="add-btn" onclick="toggleForm('addEntForm-${code}')">+ Ajouter un type de
|
|
3147
|
+
<button class="add-btn" onclick="toggleForm('addEntForm-${code}')">+ Ajouter un type de données</button>
|
|
3140
3148
|
<div class="inline-form" id="addEntForm-${code}">
|
|
3141
|
-
<div class="inline-form-title">Nouveau type de
|
|
3149
|
+
<div class="inline-form-title">Nouveau type de données</div>
|
|
3142
3150
|
<div class="form-group">
|
|
3143
3151
|
<label class="form-label">Nom (exemple : Commande, Client, Facture)</label>
|
|
3144
|
-
<input type="text" class="form-input" id="ent-name-${code}" placeholder="Nom du type de
|
|
3152
|
+
<input type="text" class="form-input" id="ent-name-${code}" placeholder="Nom du type de données">
|
|
3145
3153
|
</div>
|
|
3146
3154
|
<div class="form-group">
|
|
3147
|
-
<label class="form-label">Description :
|
|
3148
|
-
<textarea class="form-textarea" id="ent-desc-${code}" placeholder="En une ou deux phrases,
|
|
3155
|
+
<label class="form-label">Description : à quoi sert cette donnée ?</label>
|
|
3156
|
+
<textarea class="form-textarea" id="ent-desc-${code}" placeholder="En une ou deux phrases, décrivez ce que représente cette donnée dans votre activité" style="min-height:50px;"></textarea>
|
|
3149
3157
|
</div>
|
|
3150
3158
|
<div class="form-group">
|
|
3151
|
-
<label class="form-label">Informations
|
|
3152
|
-
<textarea class="form-textarea" id="ent-attrs-${code}" placeholder="Numero - Identifiant unique de la commande Date - Date de
|
|
3159
|
+
<label class="form-label">Informations à enregistrer (une par ligne : Nom - Description)</label>
|
|
3160
|
+
<textarea class="form-textarea" id="ent-attrs-${code}" placeholder="Numero - Identifiant unique de la commande Date - Date de création de la commande Montant total - Somme des lignes Statut - Brouillon, Envoyée, Validée, Refusée"></textarea>
|
|
3153
3161
|
</div>
|
|
3154
3162
|
<div class="form-group">
|
|
3155
|
-
<label class="form-label">Relations avec d'autres
|
|
3163
|
+
<label class="form-label">Relations avec d'autres données (optionnel, une par ligne)</label>
|
|
3156
3164
|
<textarea class="form-textarea" id="ent-rels-${code}" placeholder="Client - Chaque commande appartient a un client Ligne de commande - Une commande contient plusieurs lignes" style="min-height:50px;"></textarea>
|
|
3157
3165
|
</div>
|
|
3158
3166
|
<div class="form-actions">
|
|
@@ -3162,20 +3170,20 @@ function renderModuleSpecSection(mod) {
|
|
|
3162
3170
|
</div>
|
|
3163
3171
|
</div>
|
|
3164
3172
|
|
|
3165
|
-
<!-- TAB: Droits d'
|
|
3173
|
+
<!-- TAB: Droits d'accès -->
|
|
3166
3174
|
<div class="tab-panel" id="tab-${code}-perm">
|
|
3167
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">
|
|
3175
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Définissez qui peut faire quoi dans ce domaine. Cochez les actions autorisées pour chaque profil.</p>
|
|
3168
3176
|
<div id="permGrid-${code}">
|
|
3169
3177
|
${renderPermissionGrid(code)}
|
|
3170
3178
|
</div>
|
|
3171
3179
|
<div style="display:flex;gap:0.75rem;margin-top:1rem;flex-wrap:wrap;">
|
|
3172
|
-
<button class="add-btn" onclick="toggleForm('addRoleForm-${code}')" style="flex:1;min-width:200px;">+ Ajouter un
|
|
3180
|
+
<button class="add-btn" onclick="toggleForm('addRoleForm-${code}')" style="flex:1;min-width:200px;">+ Ajouter un rôle</button>
|
|
3173
3181
|
<button class="add-btn" onclick="toggleForm('addActionForm-${code}')" style="flex:1;min-width:200px;">+ Ajouter une action</button>
|
|
3174
3182
|
</div>
|
|
3175
3183
|
<div class="inline-form" id="addRoleForm-${code}">
|
|
3176
|
-
<div class="inline-form-title">Nouveau
|
|
3184
|
+
<div class="inline-form-title">Nouveau rôle</div>
|
|
3177
3185
|
<div class="form-group">
|
|
3178
|
-
<label class="form-label">Nom du
|
|
3186
|
+
<label class="form-label">Nom du rôle</label>
|
|
3179
3187
|
<input type="text" class="form-input" id="role-name-${code}" placeholder="Exemple : Superviseur, Auditeur...">
|
|
3180
3188
|
</div>
|
|
3181
3189
|
<div class="form-actions">
|
|
@@ -3198,7 +3206,7 @@ function renderModuleSpecSection(mod) {
|
|
|
3198
3206
|
|
|
3199
3207
|
<!-- TAB: Maquettes -->
|
|
3200
3208
|
<div class="tab-panel" id="tab-${code}-mock">
|
|
3201
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Maquettes
|
|
3209
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Maquettes validées lors de l'analyse. Ces wireframes montrent la structure exacte des écrans de ce domaine.</p>
|
|
3202
3210
|
<div id="mockupContainer-${code}">
|
|
3203
3211
|
${renderModuleMockups(code)}
|
|
3204
3212
|
</div>
|
|
@@ -3206,15 +3214,15 @@ function renderModuleSpecSection(mod) {
|
|
|
3206
3214
|
|
|
3207
3215
|
<!-- TAB: Notes -->
|
|
3208
3216
|
<div class="tab-panel" id="tab-${code}-notes">
|
|
3209
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Notes libres, questions en suspens,
|
|
3217
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Notes libres, questions en suspens, éléments à clarifier pour ce domaine.</p>
|
|
3210
3218
|
<div class="card">
|
|
3211
|
-
<div class="editable" contenteditable="true" data-module-code="${code}" data-module-field="notes" data-placeholder="Notez ici tout ce qui concerne ce domaine : questions,
|
|
3219
|
+
<div class="editable" contenteditable="true" data-module-code="${code}" data-module-field="notes" data-placeholder="Notez ici tout ce qui concerne ce domaine : questions, précisions, contraintes particulières...">${spec.notes || ''}</div>
|
|
3212
3220
|
</div>
|
|
3213
3221
|
</div>
|
|
3214
3222
|
|
|
3215
3223
|
<!-- TAB: Structure (sections/resources) -->
|
|
3216
3224
|
<div class="tab-panel" id="tab-${code}-struct">
|
|
3217
|
-
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Organisation des
|
|
3225
|
+
<p style="font-size:0.85rem;color:var(--text-muted);margin-bottom:1rem;">Organisation des écrans et ressources de ce domaine. Structure hiérarchique : sections regroupant des ressources.</p>
|
|
3218
3226
|
<div id="structContainer-${code}">
|
|
3219
3227
|
${renderModuleStructure(code)}
|
|
3220
3228
|
</div>
|
|
@@ -3233,8 +3241,8 @@ function renderUseCase(code, uc, index) {
|
|
|
3233
3241
|
</div>
|
|
3234
3242
|
</div>
|
|
3235
3243
|
<div class="uc-actors"><div class="uc-actor">${uc.actor}</div></div>
|
|
3236
|
-
${uc.steps ? `<div class="uc-detail-label">
|
|
3237
|
-
${uc.alternative ? `<div class="uc-detail-label">En cas de
|
|
3244
|
+
${uc.steps ? `<div class="uc-detail-label">Déroulement</div><div class="uc-detail">${uc.steps.replace(/\n/g, '<br>')}</div>` : ''}
|
|
3245
|
+
${uc.alternative ? `<div class="uc-detail-label">En cas de problème</div><div class="uc-detail" style="color:var(--warning);">${uc.alternative}</div>` : ''}
|
|
3238
3246
|
<div style="padding:0.5rem 0.75rem;border-top:1px solid var(--border);background:var(--bg-input);border-radius:0 0 8px 8px;">
|
|
3239
3247
|
<label style="font-size:0.75rem;color:var(--text-muted);display:block;margin-bottom:0.25rem;">Commentaire / Feedback :</label>
|
|
3240
3248
|
<textarea class="form-textarea" placeholder="Ajouter un commentaire sur ce cas d'utilisation..."
|
|
@@ -3270,7 +3278,7 @@ function removeUseCase(code, index) {
|
|
|
3270
3278
|
|
|
3271
3279
|
function renderBusinessRule(code, br, index) {
|
|
3272
3280
|
const catColors = { validation: 'br-cat-validation', calculation: 'br-cat-calculation', workflow: 'br-cat-workflow', security: 'br-cat-security', data: 'br-cat-data' };
|
|
3273
|
-
const catLabels = { validation: '
|
|
3281
|
+
const catLabels = { validation: 'Vérification', calculation: 'Calcul', workflow: 'Processus', security: 'Sécurité', data: 'Données' };
|
|
3274
3282
|
return `
|
|
3275
3283
|
<div style="margin-bottom:0.5rem;">
|
|
3276
3284
|
<div class="br-item" style="margin-bottom:0;border-radius:8px 8px 0 0;">
|
|
@@ -3283,7 +3291,7 @@ function renderBusinessRule(code, br, index) {
|
|
|
3283
3291
|
<button class="btn btn-sm" onclick="removeBusinessRule('${code}',${index})" style="opacity:0.5;flex-shrink:0;">✕</button>
|
|
3284
3292
|
</div>
|
|
3285
3293
|
<div style="padding:0.4rem 0.75rem 0.6rem;background:var(--bg-input);border:1px solid var(--border);border-top:0;border-radius:0 0 8px 8px;">
|
|
3286
|
-
<textarea class="form-textarea" placeholder="Commentaire sur cette
|
|
3294
|
+
<textarea class="form-textarea" placeholder="Commentaire sur cette règle..."
|
|
3287
3295
|
onblur="updateSpecComment('${code}','br',${index},this.value)"
|
|
3288
3296
|
style="min-height:35px;font-size:0.8rem;resize:vertical;">${getSpecComment(code, 'br', index)}</textarea>
|
|
3289
3297
|
</div>
|
|
@@ -3338,7 +3346,7 @@ function renderEntity(code, ent, index) {
|
|
|
3338
3346
|
</div>` : ''}
|
|
3339
3347
|
<div style="padding:0.4rem 0.75rem 0.6rem;background:var(--bg-input);border-top:1px solid var(--border);border-radius:0 0 8px 8px;">
|
|
3340
3348
|
<label style="font-size:0.75rem;color:var(--text-muted);display:block;margin-bottom:0.25rem;">Commentaire :</label>
|
|
3341
|
-
<textarea class="form-textarea" placeholder="Commentaire sur cette
|
|
3349
|
+
<textarea class="form-textarea" placeholder="Commentaire sur cette entité..."
|
|
3342
3350
|
onblur="updateSpecComment('${code}','ent',${index},this.value)"
|
|
3343
3351
|
style="min-height:35px;font-size:0.8rem;resize:vertical;">${getSpecComment(code, 'ent', index)}</textarea>
|
|
3344
3352
|
</div>
|
|
@@ -3431,7 +3439,7 @@ function renderModuleMockups(code) {
|
|
|
3431
3439
|
return `
|
|
3432
3440
|
<div class="card" style="text-align:center;padding:2rem;color:var(--text-muted);">
|
|
3433
3441
|
<p>Aucune maquette disponible pour ce module.</p>
|
|
3434
|
-
<p style="font-size:0.85rem;margin-top:0.5rem;">Les maquettes seront
|
|
3442
|
+
<p style="font-size:0.85rem;margin-top:0.5rem;">Les maquettes seront générées lors de la spécification détaillée.</p>
|
|
3435
3443
|
</div>`;
|
|
3436
3444
|
}
|
|
3437
3445
|
|
|
@@ -3480,7 +3488,7 @@ function renderWireframeMockup(code, wf, i) {
|
|
|
3480
3488
|
<details class="wireframe-details">
|
|
3481
3489
|
<summary>Mapping composants SmartStack</summary>
|
|
3482
3490
|
<table class="mapping-table">
|
|
3483
|
-
<thead><tr><th
|
|
3491
|
+
<thead><tr><th>Élément maquette</th><th>Composant React</th></tr></thead>
|
|
3484
3492
|
<tbody>
|
|
3485
3493
|
${mappings.map(m =>
|
|
3486
3494
|
'<tr><td>' + (m.wireframeElement || '') + '</td><td><code>' + (m.reactComponent || '') + '</code></td></tr>'
|
|
@@ -3494,7 +3502,7 @@ function renderWireframeMockup(code, wf, i) {
|
|
|
3494
3502
|
<textarea class="form-textarea"
|
|
3495
3503
|
data-module="${code}"
|
|
3496
3504
|
data-screen="${wf.screen}"
|
|
3497
|
-
placeholder="Ajouter un commentaire sur cette maquette (ex:
|
|
3505
|
+
placeholder="Ajouter un commentaire sur cette maquette (ex: déplacer ce bouton, ajouter une colonne...)"
|
|
3498
3506
|
onblur="updateWireframeComment('${code}', '${wf.screen}', this.value)"
|
|
3499
3507
|
style="min-height:60px;font-size:0.85rem;resize:vertical;"
|
|
3500
3508
|
>${getWireframeComment(code, wf.screen)}</textarea>
|
|
@@ -3542,7 +3550,7 @@ function getPermRoles() {
|
|
|
3542
3550
|
}
|
|
3543
3551
|
|
|
3544
3552
|
function getPermActions() {
|
|
3545
|
-
const baseActions = ['Consulter', '
|
|
3553
|
+
const baseActions = ['Consulter', 'Créer', 'Modifier', 'Supprimer', 'Valider', 'Exporter'];
|
|
3546
3554
|
return [...baseActions, ...(data.customActions || [])];
|
|
3547
3555
|
}
|
|
3548
3556
|
|
|
@@ -3563,7 +3571,7 @@ function renderPermissionGrid(code) {
|
|
|
3563
3571
|
<tbody>
|
|
3564
3572
|
${roles.map((role, ri) => `
|
|
3565
3573
|
<tr>
|
|
3566
|
-
<td style="font-weight:500;color:var(--text-bright);">${role}${ri >= baseRolesCount ? ' <span onclick="removeCustomRole('+`'${code}','${role}'`+')" style="cursor:pointer;color:var(--danger);font-size:0.7rem;" title="Supprimer ce
|
|
3574
|
+
<td style="font-weight:500;color:var(--text-bright);">${role}${ri >= baseRolesCount ? ' <span onclick="removeCustomRole('+`'${code}','${role}'`+')" style="cursor:pointer;color:var(--danger);font-size:0.7rem;" title="Supprimer ce rôle">✕</span>' : ''}</td>
|
|
3567
3575
|
${actions.map(action => {
|
|
3568
3576
|
const key = role + '|' + action;
|
|
3569
3577
|
const wildcardKey = role + '|*';
|
|
@@ -3650,8 +3658,8 @@ function renderModuleStructure(code) {
|
|
|
3650
3658
|
|
|
3651
3659
|
if (sections.length === 0) {
|
|
3652
3660
|
return '<div class="card" style="text-align:center;padding:2rem;color:var(--text-muted);">' +
|
|
3653
|
-
'<p>Aucune section
|
|
3654
|
-
'<p style="font-size:0.85rem;margin-top:0.5rem;">Les sections et ressources seront
|
|
3661
|
+
'<p>Aucune section définie pour ce module.</p>' +
|
|
3662
|
+
'<p style="font-size:0.85rem;margin-top:0.5rem;">Les sections et ressources seront identifiées lors de l\'analyse approfondie.</p>' +
|
|
3655
3663
|
'</div>';
|
|
3656
3664
|
}
|
|
3657
3665
|
|
|
@@ -3725,7 +3733,7 @@ function renderDataModel() {
|
|
|
3725
3733
|
});
|
|
3726
3734
|
|
|
3727
3735
|
if (allEntities.length === 0) {
|
|
3728
|
-
container.innerHTML = '<p style="color:var(--text-muted);text-align:center;padding:2rem;">Aucune
|
|
3736
|
+
container.innerHTML = '<p style="color:var(--text-muted);text-align:center;padding:2rem;">Aucune entité définie. Spécifiez les données dans chaque domaine (Phase 3 > onglet Données).</p>';
|
|
3729
3737
|
return;
|
|
3730
3738
|
}
|
|
3731
3739
|
|
|
@@ -3741,7 +3749,7 @@ function renderDataModel() {
|
|
|
3741
3749
|
const relCount = allEntities.reduce((sum, e) => sum + (e.relationships || []).length, 0);
|
|
3742
3750
|
html += `
|
|
3743
3751
|
<div class="dm-summary">
|
|
3744
|
-
<div class="dm-summary-item"><span class="dm-summary-value">${allEntities.length}</span><span class="dm-summary-label">
|
|
3752
|
+
<div class="dm-summary-item"><span class="dm-summary-value">${allEntities.length}</span><span class="dm-summary-label">Entités</span></div>
|
|
3745
3753
|
<div class="dm-summary-item"><span class="dm-summary-value">${moduleCount}</span><span class="dm-summary-label">Domaines</span></div>
|
|
3746
3754
|
<div class="dm-summary-item"><span class="dm-summary-value">${relCount}</span><span class="dm-summary-label">Relations</span></div>
|
|
3747
3755
|
</div>`;
|
|
@@ -3755,7 +3763,7 @@ function renderDataModel() {
|
|
|
3755
3763
|
html += `<div class="dm-module-group">`;
|
|
3756
3764
|
html += `<div class="dm-module-header">
|
|
3757
3765
|
<span class="dm-module-name">${m.name || m.code}</span>
|
|
3758
|
-
<span class="dm-module-count">${entities.length}
|
|
3766
|
+
<span class="dm-module-count">${entities.length} entité${entities.length > 1 ? 's' : ''}</span>
|
|
3759
3767
|
</div>`;
|
|
3760
3768
|
|
|
3761
3769
|
html += `<div class="dm-entity-grid">`;
|
|
@@ -3804,7 +3812,7 @@ function renderConsolInteractions() {
|
|
|
3804
3812
|
<span style="font-weight:600;color:var(--text-bright);">${fromName}</span>
|
|
3805
3813
|
<span class="interaction-arrow">→</span>
|
|
3806
3814
|
<span style="font-weight:600;color:var(--text-bright);">${toName}</span>
|
|
3807
|
-
<span class="interaction-type">
|
|
3815
|
+
<span class="interaction-type">Dépendance</span>
|
|
3808
3816
|
<span style="flex:1;font-size:0.8rem;color:var(--text-muted);">${d.description || ''}</span>
|
|
3809
3817
|
</div>`;
|
|
3810
3818
|
}).join('');
|
|
@@ -3986,7 +3994,7 @@ function renderResourceMockup(code, sectionCode, res, index) {
|
|
|
3986
3994
|
/* ---------- SmartTable ---------- */
|
|
3987
3995
|
function renderSmartTableMockup(res) {
|
|
3988
3996
|
var columns = res.columns || [];
|
|
3989
|
-
if (columns.length === 0) return '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Table sans colonnes
|
|
3997
|
+
if (columns.length === 0) return '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Table sans colonnes définies</div>';
|
|
3990
3998
|
|
|
3991
3999
|
var html = '';
|
|
3992
4000
|
|
|
@@ -4043,7 +4051,7 @@ function renderSmartTableMockup(res) {
|
|
|
4043
4051
|
|
|
4044
4052
|
// Pagination
|
|
4045
4053
|
html += '<div style="display:flex;justify-content:space-between;align-items:center;padding:0.75rem 0;font-size:0.8rem;color:var(--text-muted);">';
|
|
4046
|
-
html += '<span>1-4 sur 24
|
|
4054
|
+
html += '<span>1-4 sur 24 résultats</span>';
|
|
4047
4055
|
html += '<div style="display:flex;gap:0.3rem;">';
|
|
4048
4056
|
html += '<span class="mock-btn" style="background:var(--primary);font-size:0.75rem;padding:0.2rem 0.5rem;">1</span>';
|
|
4049
4057
|
html += '<span class="mock-btn" style="background:var(--bg-hover);font-size:0.75rem;padding:0.2rem 0.5rem;">2</span>';
|
|
@@ -4059,7 +4067,7 @@ function renderSmartFormMockup(res) {
|
|
|
4059
4067
|
if (tabs.length === 0 && res.fields) {
|
|
4060
4068
|
tabs = [{ label: 'Informations', fields: res.fields }];
|
|
4061
4069
|
}
|
|
4062
|
-
if (tabs.length === 0) return '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Formulaire sans champs
|
|
4070
|
+
if (tabs.length === 0) return '<div style="padding:2rem;text-align:center;color:var(--text-muted);">Formulaire sans champs définis</div>';
|
|
4063
4071
|
|
|
4064
4072
|
var html = '';
|
|
4065
4073
|
|
|
@@ -4167,7 +4175,7 @@ function renderSmartCardMockup(res) {
|
|
|
4167
4175
|
|
|
4168
4176
|
/* ---------- SmartKanban ---------- */
|
|
4169
4177
|
function renderSmartKanbanMockup(res) {
|
|
4170
|
-
var options = res.options || res.columns || ['
|
|
4178
|
+
var options = res.options || res.columns || ['À faire', 'En cours', 'Terminé'];
|
|
4171
4179
|
var html = '<div class="mock-header"><span class="mock-title">' + (res.label || 'Kanban') + '</span></div>';
|
|
4172
4180
|
html += '<div style="display:flex;gap:1rem;overflow-x:auto;padding-bottom:0.5rem;">';
|
|
4173
4181
|
|
|
@@ -4179,7 +4187,7 @@ function renderSmartKanbanMockup(res) {
|
|
|
4179
4187
|
html += '</div>';
|
|
4180
4188
|
for (var j = 0; j < Math.max(1, 3 - ci); j++) {
|
|
4181
4189
|
html += '<div style="background:var(--bg-card);border:1px solid var(--border);border-radius:6px;padding:0.5rem;margin-bottom:0.5rem;font-size:0.8rem;">';
|
|
4182
|
-
html += '<div style="color:var(--text-bright);font-weight:500;"
|
|
4190
|
+
html += '<div style="color:var(--text-bright);font-weight:500;">Élément ' + (j + 1) + '</div>';
|
|
4183
4191
|
html += '<div style="color:var(--text-muted);font-size:0.7rem;margin-top:0.25rem;">Description...</div>';
|
|
4184
4192
|
html += '</div>';
|
|
4185
4193
|
}
|
|
@@ -4293,10 +4301,10 @@ function renderHandoffStats() {
|
|
|
4293
4301
|
container.innerHTML = `
|
|
4294
4302
|
<div class="stat-card"><div class="stat-value">${data.modules.length}</div><div class="stat-label">Domaines fonctionnels</div></div>
|
|
4295
4303
|
<div class="stat-card"><div class="stat-value">${totalUCs}</div><div class="stat-label">Cas d'utilisation</div></div>
|
|
4296
|
-
<div class="stat-card"><div class="stat-value">${totalBRs}</div><div class="stat-label">
|
|
4297
|
-
<div class="stat-card"><div class="stat-value">${totalEnts}</div><div class="stat-label">Types de
|
|
4304
|
+
<div class="stat-card"><div class="stat-value">${totalBRs}</div><div class="stat-label">Règles métier</div></div>
|
|
4305
|
+
<div class="stat-card"><div class="stat-value">${totalEnts}</div><div class="stat-label">Types de données</div></div>
|
|
4298
4306
|
<div class="stat-card"><div class="stat-value">${totalStakeholders}</div><div class="stat-label">Profils utilisateurs</div></div>
|
|
4299
|
-
<div class="stat-card"><div class="stat-value">${data.dependencies.length}</div><div class="stat-label">
|
|
4307
|
+
<div class="stat-card"><div class="stat-value">${data.dependencies.length}</div><div class="stat-label">Dépendances</div></div>
|
|
4300
4308
|
<div class="stat-card"><div class="stat-value">${data.consolidation.e2eFlows.length}</div><div class="stat-label">Parcours bout en bout</div></div>
|
|
4301
4309
|
`;
|
|
4302
4310
|
}
|
|
@@ -4322,8 +4330,8 @@ function renderHandoffModules() {
|
|
|
4322
4330
|
</div>
|
|
4323
4331
|
<div style="display:flex;gap:1rem;font-size:0.75rem;color:var(--text-muted);">
|
|
4324
4332
|
<span>${(spec.useCases || []).length} cas d'utilisation</span>
|
|
4325
|
-
<span>${(spec.businessRules || []).length}
|
|
4326
|
-
<span>${(spec.entities || []).length}
|
|
4333
|
+
<span>${(spec.businessRules || []).length} règles</span>
|
|
4334
|
+
<span>${(spec.entities || []).length} données</span>
|
|
4327
4335
|
</div>
|
|
4328
4336
|
<span class="priority priority-${m.priority === 'must' ? 'vital' : m.priority === 'should' ? 'important' : 'optional'}">${formatModulePriority(m.priority)}</span>
|
|
4329
4337
|
</div>
|
|
@@ -4340,18 +4348,18 @@ function renderCoverageMatrix() {
|
|
|
4340
4348
|
);
|
|
4341
4349
|
|
|
4342
4350
|
if (allScope.length === 0) {
|
|
4343
|
-
container.innerHTML = '<p style="color:var(--text-muted);font-style:italic;">Aucun
|
|
4351
|
+
container.innerHTML = '<p style="color:var(--text-muted);font-style:italic;">Aucun élément de périmètre défini dans le cadrage.</p>';
|
|
4344
4352
|
return;
|
|
4345
4353
|
}
|
|
4346
4354
|
|
|
4347
4355
|
container.innerHTML = `
|
|
4348
4356
|
<table class="mock-table" style="background:var(--bg-card);border-radius:8px;overflow:hidden;">
|
|
4349
|
-
<thead><tr><th>Besoin</th><th>
|
|
4357
|
+
<thead><tr><th>Besoin</th><th>Priorité</th><th>Domaine</th><th>Couvert</th></tr></thead>
|
|
4350
4358
|
<tbody>
|
|
4351
4359
|
${allScope.map(item => {
|
|
4352
4360
|
const moduleName = item.module
|
|
4353
4361
|
? (data.modules.find(m => m.code === item.module)?.name || item.module)
|
|
4354
|
-
: (data.modules.length > 0 ? data.modules.map(m => m.name).join(', ') : '
|
|
4362
|
+
: (data.modules.length > 0 ? data.modules.map(m => m.name).join(', ') : 'À définir');
|
|
4355
4363
|
return `
|
|
4356
4364
|
<tr>
|
|
4357
4365
|
<td>${item.name}</td>
|
|
@@ -4376,11 +4384,11 @@ function autoSave() {
|
|
|
4376
4384
|
|
|
4377
4385
|
function saveToLocalStorage() {
|
|
4378
4386
|
autoSave();
|
|
4379
|
-
showNotification('Modifications
|
|
4387
|
+
showNotification('Modifications sauvegardées');
|
|
4380
4388
|
}
|
|
4381
4389
|
|
|
4382
4390
|
function resetToEmbedded() {
|
|
4383
|
-
if (!confirm('
|
|
4391
|
+
if (!confirm('Réinitialiser toutes les données depuis la version d\'origine ? Vos modifications locales (commentaires, notes) seront perdues.')) return;
|
|
4384
4392
|
localStorage.removeItem(APP_KEY);
|
|
4385
4393
|
// Restore data from ORIGINAL_DATA
|
|
4386
4394
|
Object.keys(data).forEach(k => delete data[k]);
|
|
@@ -4398,7 +4406,7 @@ function resetToEmbedded() {
|
|
|
4398
4406
|
renderE2EFlows();
|
|
4399
4407
|
updateCounts();
|
|
4400
4408
|
renderReviewPanel();
|
|
4401
|
-
showNotification('
|
|
4409
|
+
showNotification('Données réinitialisées depuis la version d\'origine');
|
|
4402
4410
|
}
|
|
4403
4411
|
|
|
4404
4412
|
function loadFromLocalStorage() {
|
|
@@ -4565,7 +4573,7 @@ function exportJSON() {
|
|
|
4565
4573
|
a.download = (data.metadata.applicationId || 'analyse') + '-export.json';
|
|
4566
4574
|
a.click();
|
|
4567
4575
|
URL.revokeObjectURL(url);
|
|
4568
|
-
showNotification('Export JSON
|
|
4576
|
+
showNotification('Export JSON téléchargé');
|
|
4569
4577
|
}
|
|
4570
4578
|
|
|
4571
4579
|
/* ============================================
|
|
@@ -4668,7 +4676,7 @@ function saveReviewJSON() {
|
|
|
4668
4676
|
a.download = 'ba-review.json';
|
|
4669
4677
|
a.click();
|
|
4670
4678
|
URL.revokeObjectURL(url);
|
|
4671
|
-
showNotification('ba-review.json
|
|
4679
|
+
showNotification('ba-review.json téléchargé — sauvegardez-le à côté du HTML');
|
|
4672
4680
|
}
|
|
4673
4681
|
|
|
4674
4682
|
|
|
@@ -4796,11 +4804,11 @@ function renderCommentItems(sectionId, cardIndex) {
|
|
|
4796
4804
|
<span class="comment-author">${c.author || 'Utilisateur'}</span>
|
|
4797
4805
|
<span class="comment-date">${date}</span>
|
|
4798
4806
|
<span class="comment-category comment-category-${c.category}">${c.category}</span>
|
|
4799
|
-
<span class="comment-status comment-status-${c.status}">${c.status === 'validated' ? '
|
|
4807
|
+
<span class="comment-status comment-status-${c.status}">${c.status === 'validated' ? 'Validé' : 'À revoir'}</span>
|
|
4800
4808
|
</div>
|
|
4801
4809
|
<div class="comment-text">${c.content}</div>
|
|
4802
4810
|
<div class="comment-actions">
|
|
4803
|
-
<button class="comment-action-btn" onclick="toggleCommentStatus(${globalIndex})">${c.status === 'validated' ? 'Remettre
|
|
4811
|
+
<button class="comment-action-btn" onclick="toggleCommentStatus(${globalIndex})">${c.status === 'validated' ? 'Remettre à revoir' : 'Valider'}</button>
|
|
4804
4812
|
<button class="comment-action-btn" onclick="deleteComment(${globalIndex})" style="color:var(--error);">Supprimer</button>
|
|
4805
4813
|
</div>
|
|
4806
4814
|
</div>
|
|
@@ -4960,8 +4968,8 @@ function renderReviewPanel() {
|
|
|
4960
4968
|
<div class="review-comment-actions">
|
|
4961
4969
|
<button class="review-action-btn ${c.status === 'validated' ? 'reject' : 'validate'}"
|
|
4962
4970
|
onclick="event.stopPropagation();toggleCommentStatus(${globalIndex})"
|
|
4963
|
-
title="${c.status === 'validated' ? 'Remettre
|
|
4964
|
-
${c.status === 'validated' ? '
|
|
4971
|
+
title="${c.status === 'validated' ? 'Remettre à revoir' : 'Valider'}">
|
|
4972
|
+
${c.status === 'validated' ? 'À revoir' : 'Valider'}
|
|
4965
4973
|
</button>
|
|
4966
4974
|
<button class="review-action-btn delete"
|
|
4967
4975
|
onclick="event.stopPropagation();deleteComment(${globalIndex})"
|
|
@@ -4979,14 +4987,14 @@ function getSectionLabel(sectionId) {
|
|
|
4979
4987
|
const labels = {
|
|
4980
4988
|
'cadrage-context': 'Contexte',
|
|
4981
4989
|
'cadrage-stakeholders': 'Parties prenantes',
|
|
4982
|
-
'cadrage-scope': '
|
|
4983
|
-
'cadrage-success': '
|
|
4990
|
+
'cadrage-scope': 'Périmètre',
|
|
4991
|
+
'cadrage-success': 'Critères',
|
|
4984
4992
|
'decomp-modules': 'Domaines',
|
|
4985
|
-
'decomp-dependencies': '
|
|
4993
|
+
'decomp-dependencies': 'Dépendances',
|
|
4986
4994
|
'consol-interactions': 'Interactions',
|
|
4987
|
-
'consol-permissions': '
|
|
4995
|
+
'consol-permissions': 'Accès',
|
|
4988
4996
|
'consol-flows': 'Parcours',
|
|
4989
|
-
'handoff-summary': '
|
|
4997
|
+
'handoff-summary': 'Synthèse'
|
|
4990
4998
|
};
|
|
4991
4999
|
if (labels[sectionId]) return labels[sectionId];
|
|
4992
5000
|
if (sectionId.startsWith('module-spec-')) {
|
|
@@ -5004,7 +5012,7 @@ function getSectionLabel(sectionId) {
|
|
|
5004
5012
|
// Handle list-based sectionIds (ucList-*, brList-*, entList-*)
|
|
5005
5013
|
const listMatch = sectionId.match(/^(uc|br|ent)List-(.+)$/);
|
|
5006
5014
|
if (listMatch) {
|
|
5007
|
-
const tabLabels = { uc: 'Cas d\'utilisation', br: '
|
|
5015
|
+
const tabLabels = { uc: 'Cas d\'utilisation', br: 'Règles métier', ent: 'Données' };
|
|
5008
5016
|
const mod = data.modules.find(m => m.code === listMatch[2]);
|
|
5009
5017
|
const modName = mod ? mod.name : listMatch[2];
|
|
5010
5018
|
return modName + ' > ' + (tabLabels[listMatch[1]] || listMatch[1]);
|