---
description: Phase 4 - Functional specifications FRD (ULTRATHINK)
agent: ba-specify
model: sonnet
---

# Phase 4: Spécifications Fonctionnelles - FRD

> **Modèle:** Sonnet (spécifications détaillées)
> **Coût estimé:** ~$0.18
> **Input:** 2-business-requirements.md
> **Output:** 3-functional-specification.md (FRD)

---

## OBJECTIF

```
╔══════════════════════════════════════════════════════════════════════════════╗
║  TRANSFORMER LE BRD EN SPÉCIFICATIONS IMPLÉMENTABLES                         ║
╠══════════════════════════════════════════════════════════════════════════════╣
║                                                                              ║
║  Le FRD définit COMMENT le système doit se comporter:                        ║
║                                                                              ║
║  • Cas d'utilisation détaillés (UC-XXX)                                      ║
║  • Exigences fonctionnelles (FR-XXX)                                         ║
║  • Wireframes d'interface                                                    ║
║  • Permissions granulaires                                                   ║
║  • Scénarios Gherkin pour tests                                              ║
║                                                                              ║
║  RÈGLE: Assez détaillé pour qu'un développeur puisse implémenter             ║
║         sans poser de questions.                                             ║
║                                                                              ║
╚══════════════════════════════════════════════════════════════════════════════╝
```

---

## STEP 1: Charger le BRD

```bash
FEATURE_ID=$1
FEATURE_DIR=$(find .business-analyse -type d -name "${FEATURE_ID}*" | head -1)
BRD_FILE="$FEATURE_DIR/2-business-requirements.md"

if [ ! -f "$BRD_FILE" ]; then
  echo "❌ ERREUR: 2-business-requirements.md non trouvé"
  echo "   Lancez d'abord: /business-analyse:3-analyse $FEATURE_ID"
  exit 1
fi

# Extraire application et module
APPLICATION=$(echo $FEATURE_DIR | grep -oP 'business/\K[^/]+')
MODULE=$(echo $FEATURE_DIR | grep -oP 'modules/\K[^/]+')
PERMISSION_BASE="business.$APPLICATION.$MODULE"
```

---

## STEP 2: Scanner les patterns UI existants

```bash
# Scanner les pages existantes pour cohérence UI
EXISTING_PAGES=$(find web/smartstack-web/src/pages -name "*.tsx" | head -20)

# Extraire les patterns de composants utilisés
COMPONENT_PATTERNS=$(grep -h "import.*from.*components" $EXISTING_PAGES 2>/dev/null | sort -u)

echo "Patterns UI existants identifiés"
```

---

## STEP 3: Génération du FRD

```bash
FRD_FILE="$FEATURE_DIR/3-functional-specification.md"
```

### Template 3-functional-specification.md

```markdown
# FRD - {FEATURE_ID} {Feature Name}

> **Module:** business/{application}/{module}
> **Version:** 1.0
> **Basé sur:** 2-business-requirements.md v1.0
> **Permission base:** business.{application}.{module}.*
> **Standard:** IEEE 830

---

## 1. Vue d'ensemble

### 1.1 Objectif fonctionnel

{Description de ce que le système doit faire, du point de vue utilisateur}

### 1.2 Acteurs

| Acteur | Description | Permissions requises |
|--------|-------------|---------------------|
| Admin | Administrateur avec tous les droits | `{module}.*` |
| Manager | Gestionnaire du module | `{module}.read`, `{module}.create`, `{module}.update` |
| User | Utilisateur standard | `{module}.read` |
| ReadOnly | Consultation seule | `{module}.read` |

### 1.3 Préconditions globales

- Utilisateur authentifié
- Permission `business.{application}.{module}.read` au minimum
- Module activé dans la configuration tenant

---

## 2. Cas d'utilisation

### UC-001: {Nom du cas d'utilisation principal}

| Attribut | Valeur |
|----------|--------|
| **ID** | UC-001 |
| **Nom** | {Nom descriptif} |
| **Acteur principal** | {Rôle} |
| **Préconditions** | {conditions requises avant exécution} |
| **Postconditions** | {état du système après exécution} |
| **Permission** | `business.{app}.{module}.{action}` |
| **Fréquence** | {Daily/Weekly/Monthly} |
| **Criticité** | {High/Medium/Low} |

**Scénario principal:**

| # | Acteur | Système |
|---|--------|---------|
| 1 | {L'utilisateur fait...} | |
| 2 | | {Le système répond...} |
| 3 | {L'utilisateur fait...} | |
| 4 | | {Le système répond...} |
| 5 | | {Le système confirme avec message} |

**Scénarios alternatifs:**

| # | Condition | Étapes alternatives |
|---|-----------|---------------------|
| 3a | {Si condition X} | 3a.1 {action}, 3a.2 {action} |
| 4a | {Si condition Y} | 4a.1 {action} |

**Scénarios d'erreur:**

| # | Erreur | Message | Action système |
|---|--------|---------|----------------|
| E1 | {description erreur} | `{module}.errors.{code}` | {comportement} |
| E2 | Validation échouée | `{module}.errors.validation` | Afficher erreurs |
| E3 | Permission refusée | `common.errors.forbidden` | Rediriger login |

---

## 3. Exigences fonctionnelles

| ID | Exigence | UC lié | BR lié | Priorité |
|----|----------|--------|--------|----------|
| FR-001 | Le système DOIT {action} | UC-001 | BR-001 | Must |
| FR-002 | Le système DOIT {action} | UC-001 | BR-002 | Must |
| FR-003 | Le système DEVRAIT {action} | UC-002 | - | Should |

### 3.1 Détail FR-001: {Nom}

**Énoncé:**
Le système DOIT {description précise de l'exigence fonctionnelle}

**Critères d'acceptation:**
- [ ] {Critère mesurable et vérifiable 1}
- [ ] {Critère mesurable et vérifiable 2}
- [ ] {Critère mesurable et vérifiable 3}

**Règles associées:** BR-001, BR-002

**Scénario de test:**
```gherkin
Scenario: FR-001 - {description}
  Given {contexte initial}
  When {action utilisateur}
  Then {résultat attendu}
  And {vérification supplémentaire}
```

---

## 4. Interface utilisateur

### 4.1 Navigation

**Chemin d'accès:** Business > {Application} > {Module}

**URL:** `/business/{application}/{module}`

### 4.2 Wireframe - Liste principale

```
┌─────────────────────────────────────────────────────────────────────────────┐
│  [Logo]    Business / {App} / {Module}                    [User ▼] [☰]     │
├─────────────────────────────────────────────────────────────────────────────┤
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ {Module Name}                                           [+ Nouveau] │   │
│  │ {Description courte du module}                                      │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ FILTRES                                                             │   │
│  │ [Statut ▼] [Date du ▼] [Date au ▼] [Recherche...    ] [Filtrer]    │   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
│  ┌─────────────────────────────────────────────────────────────────────┐   │
│  │ TABLEAU                                                             │   │
│  │ ┌────────┬────────────┬────────────┬──────────┬─────────────────┐  │   │
│  │ │ □      │ {Col 1}    │ {Col 2}    │ {Col 3}  │ Actions         │  │   │
│  │ ├────────┼────────────┼────────────┼──────────┼─────────────────┤  │   │
│  │ │ □      │ {data}     │ {data}     │ {badge}  │ [👁] [✏] [🗑]   │  │   │
│  │ │ □      │ {data}     │ {data}     │ {badge}  │ [👁] [✏] [🗑]   │  │   │
│  │ │ □      │ {data}     │ {data}     │ {badge}  │ [👁] [✏] [🗑]   │  │   │
│  │ └────────┴────────────┴────────────┴──────────┴─────────────────┘  │   │
│  │                                                                     │   │
│  │ Affichage 1-10 sur 125                    [< Précédent] [Suivant >]│   │
│  └─────────────────────────────────────────────────────────────────────┘   │
│                                                                             │
└─────────────────────────────────────────────────────────────────────────────┘
```

### 4.3 Description des éléments UI

| Élément | Type | Comportement | Permission | Clé i18n |
|---------|------|--------------|------------|----------|
| [+ Nouveau] | Button primary | Ouvre modal création | `.create` | `{module}.actions.create` |
| [👁] | Icon button | Ouvre page détail | `.read` | `common.actions.view` |
| [✏] | Icon button | Ouvre modal édition | `.update` | `common.actions.edit` |
| [🗑] | Icon button | Confirmation + suppression | `.delete` | `common.actions.delete` |
| Checkbox | Checkbox | Sélection multiple | `.read` | - |
| Filtres | Select/Input | Filtre la liste | `.read` | `{module}.filters.*` |

### 4.4 Wireframe - Modal création/édition

```
┌─────────────────────────────────────────────────────────────┐
│  {Créer | Modifier} {EntityName}                       [X]  │
├─────────────────────────────────────────────────────────────┤
│                                                             │
│  {Champ 1} *                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│  {Message d'aide}                                           │
│                                                             │
│  {Champ 2} *                                                │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                           [▼]       │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
│  {Champ 3}                                                  │
│  ┌─────────────────────────────────────────────────────┐   │
│  │                                                     │   │
│  │                                                     │   │
│  │                                                     │   │
│  └─────────────────────────────────────────────────────┘   │
│                                                             │
├─────────────────────────────────────────────────────────────┤
│                            [Annuler]  [Enregistrer]         │
└─────────────────────────────────────────────────────────────┘
```

### 4.5 Champs du formulaire

| Champ | Type | Obligatoire | Validation | Clé i18n |
|-------|------|-------------|------------|----------|
| {champ1} | Text input | Oui | Max 100 chars | `{module}.fields.{champ1}` |
| {champ2} | Select | Oui | Liste prédéfinie | `{module}.fields.{champ2}` |
| {champ3} | Textarea | Non | Max 500 chars | `{module}.fields.{champ3}` |

---

## 5. Validation et messages

### 5.1 Règles de validation

| Champ | Règle | Message erreur (clé i18n) |
|-------|-------|---------------------------|
| {champ} | Requis | `{module}.validation.{champ}Required` |
| {champ} | Format email | `{module}.validation.{champ}InvalidEmail` |
| {champ} | Min 3 caractères | `{module}.validation.{champ}MinLength` |

### 5.2 Messages système

| Code | Type | Clé i18n | Quand affiché |
|------|------|----------|---------------|
| MSG-001 | Success | `{module}.messages.created` | Après création |
| MSG-002 | Success | `{module}.messages.updated` | Après modification |
| MSG-003 | Success | `{module}.messages.deleted` | Après suppression |
| MSG-004 | Error | `{module}.errors.notFound` | Entité non trouvée |
| MSG-005 | Error | `{module}.errors.duplicate` | Doublon détecté |

---

## 6. Permissions détaillées

### 6.1 Permission paths

| Permission | Description |
|------------|-------------|
| `business.{app}.{module}.read` | Voir la liste et les détails |
| `business.{app}.{module}.create` | Créer une nouvelle entrée |
| `business.{app}.{module}.update` | Modifier une entrée existante |
| `business.{app}.{module}.delete` | Supprimer une entrée |

### 6.2 Matrice Rôle-Permission

| Permission | SuperAdmin | Admin | Manager | User | ReadOnly |
|------------|------------|-------|---------|------|----------|
| `.read` | ✅ | ✅ | ✅ | ✅ | ✅ |
| `.create` | ✅ | ✅ | ✅ | ❌ | ❌ |
| `.update` | ✅ | ✅ | ✅ | ❌ | ❌ |
| `.delete` | ✅ | ✅ | ❌ | ❌ | ❌ |

### 6.3 Mapping Endpoint-Permission

| Endpoint | Méthode | Permission requise | Response si refusé |
|----------|---------|-------------------|-------------------|
| `/api/business/{module}` | GET | `.read` | 403 Forbidden |
| `/api/business/{module}` | POST | `.create` | 403 Forbidden |
| `/api/business/{module}/{id}` | GET | `.read` | 403 Forbidden |
| `/api/business/{module}/{id}` | PUT | `.update` | 403 Forbidden |
| `/api/business/{module}/{id}` | DELETE | `.delete` | 403 Forbidden |

### 6.4 Visibilité UI par permission

| Élément | Permission requise | Si absent |
|---------|-------------------|-----------|
| Bouton [+ Nouveau] | `.create` | Caché |
| Bouton [✏] | `.update` | Caché |
| Bouton [🗑] | `.delete` | Caché |
| Lien vers détail | `.read` | Désactivé |

---

## 7. Scénarios Gherkin

```gherkin
Feature: {FEATURE_ID} - {Feature Name}

  Background:
    Given the system is running
    And the module "{module}" is enabled

  # ===== PERMISSIONS =====

  @permission @403
  Scenario: User without permission cannot access module
    Given I am logged in as "noperm@test.com" with role "NoPerm"
    When I send GET to "/api/business/{module}"
    Then the response status should be 403
    And the response should contain "Permission denied"

  @permission @403
  Scenario: ReadOnly user cannot create
    Given I am logged in as "readonly@test.com" with role "ReadOnly"
    And I have permission "business.{app}.{module}.read"
    When I send POST to "/api/business/{module}" with:
      | field1 | value1 |
    Then the response status should be 403

  # ===== CRUD OPERATIONS =====

  @happy-path @create
  Scenario: Admin creates new {entity}
    Given I am logged in as "admin@test.com" with role "Admin"
    And I have permission "business.{app}.{module}.create"
    When I send POST to "/api/business/{module}" with:
      | field1 | Test Value |
      | field2 | Option A   |
    Then the response status should be 201
    And the response should contain "id"
    And the response header "Location" should match "/api/business/{module}/[a-f0-9-]+"

  @happy-path @read
  Scenario: User views {entity} list
    Given I am logged in as "user@test.com" with role "User"
    And I have permission "business.{app}.{module}.read"
    And there are 5 {entities} in the database
    When I send GET to "/api/business/{module}"
    Then the response status should be 200
    And the response should contain "items"
    And the response should contain "totalCount"

  @happy-path @update
  Scenario: Manager updates {entity}
    Given I am logged in as "manager@test.com" with role "Manager"
    And I have permission "business.{app}.{module}.update"
    And there is a {entity} with id "test-id"
    When I send PUT to "/api/business/{module}/test-id" with:
      | field1 | Updated Value |
    Then the response status should be 200
    And the response field "field1" should be "Updated Value"

  @happy-path @delete
  Scenario: Admin deletes {entity}
    Given I am logged in as "admin@test.com" with role "Admin"
    And I have permission "business.{app}.{module}.delete"
    And there is a {entity} with id "test-id"
    When I send DELETE to "/api/business/{module}/test-id"
    Then the response status should be 204
    And the {entity} "test-id" should not exist

  # ===== VALIDATION =====

  @validation @400
  Scenario: Create fails with missing required field
    Given I am logged in as "admin@test.com" with role "Admin"
    And I have permission "business.{app}.{module}.create"
    When I send POST to "/api/business/{module}" with:
      | field2 | Option A |
    Then the response status should be 400
    And the response should contain "field1"
    And the response should contain "required"

  # ===== BUSINESS RULES =====

  @business-rule @BR-001
  Scenario: BR-001 - {Business rule description}
    Given I am logged in as "admin@test.com" with role "Admin"
    And {precondition for business rule}
    When {action that triggers business rule}
    Then {expected outcome per BR-001}
```

---

## 8. API Specification

### 8.1 GET /api/business/{module}

**Description:** Récupère la liste paginée des {entities}

**Query Parameters:**

| Param | Type | Requis | Default | Description |
|-------|------|--------|---------|-------------|
| page | int | Non | 1 | Numéro de page |
| pageSize | int | Non | 10 | Éléments par page (max 100) |
| sortBy | string | Non | createdAt | Champ de tri |
| sortOrder | string | Non | desc | asc ou desc |
| search | string | Non | - | Recherche textuelle |
| status | string | Non | - | Filtre par statut |

**Response 200:**
```json
{
  "items": [
    {
      "id": "guid",
      "field1": "value",
      "field2": "value",
      "status": "active",
      "createdAt": "2024-01-01T00:00:00Z",
      "updatedAt": "2024-01-01T00:00:00Z"
    }
  ],
  "totalCount": 125,
  "page": 1,
  "pageSize": 10,
  "totalPages": 13
}
```

### 8.2 POST /api/business/{module}

**Description:** Crée une nouvelle {entity}

**Request Body:**
```json
{
  "field1": "string (required, max 100)",
  "field2": "string (required, enum: [A, B, C])",
  "field3": "string (optional, max 500)"
}
```

**Response 201:**
```json
{
  "id": "guid",
  "field1": "value",
  "field2": "value",
  "field3": "value",
  "status": "active",
  "createdAt": "2024-01-01T00:00:00Z"
}
```

**Response Headers:**
- `Location: /api/business/{module}/{id}`

---

## 9. Intégrations SmartStack ⭐

> **Importé depuis 1-discovery.md Section 7**

### 9.1 Notifications

| Requis | Événements | Destinataires | Type notification |
|--------|------------|---------------|-------------------|
| {oui/non} | {entity.created, entity.updated, ...} | {créateur, assigné, rôle} | {info, warning, success} |

**Spécification:**
- NotificationType à créer: `{Entity}Created`, `{Entity}Updated`, etc.
- Service à modifier: `{Entity}Service.cs`
- Hook frontend: `use{Module}Notifications.ts`

### 9.2 Workflows & Emails

| Requis | Trigger | Steps | Templates email |
|--------|---------|-------|-----------------|
| {oui/non} | `{entity}.{event}` | {SendEmail, Wait, Condition} | {template-codes} |

**Spécification:**
- Trigger à créer: `{entity}.{event}`
- Workflow: `{workflow-code}`
- Variables: `entityId`, `entityName`, `userEmail`, etc.

### 9.3 Assistance IA

| Requis | Fonction | Entrée | Sortie | Schema |
|--------|----------|--------|--------|--------|
| {oui/non} | {génération/classification/suggestion} | {données contexte} | {format attendu} | {JSON schema si applicable} |

**Spécification:**
- Prompt à créer: `{prompt-code}`
- Blocks: {system, context, query}
- OutputSchema: {schema JSON si structuré}

### 9.4 Skills à utiliser

| Intégration | Skill | Quand |
|-------------|-------|-------|
| Notifications | `/notification add` | Après création des services backend |
| Workflows | `/workflow create` | Après définition des triggers |
| IA | `/ai-prompt create` | Lors de l'implémentation du service |

---

## 10. Prochaines étapes

- [ ] Valider ce FRD avec le sponsor
- [ ] Lancer validation: `/business-analyse:5-validate {FEATURE_ID}`

---

## Historique des versions

| Version | Date | Auteur | Modifications |
|---------|------|--------|---------------|
| 1.0 | {date} | BA (Sonnet) | Création initiale |
```

---

## STEP 4: Résumé

```
================================================================================
                    SPÉCIFICATIONS COMPLÈTES - {FEATURE_ID}
================================================================================

DOCUMENT GÉNÉRÉ:   {FEATURE_DIR}/3-functional-specification.md
MODÈLE UTILISÉ:    Sonnet
BASÉ SUR:          2-business-requirements.md v1.0

CONTENU:
  Cas d'utilisation:    {N} (UC-001 à UC-XXX)
  Exigences fonct.:     {N} (FR-001 à FR-XXX)
  Wireframes:           {N} écrans
  Permissions:          {N} définies
  Scénarios Gherkin:    {N} scénarios
  Intégrations:         {N} (Notifications/Workflows/IA)

================================================================================
PROCHAINE ÉTAPE
================================================================================

Lancez la validation utilisateur:

  /business-analyse:5-validate {FEATURE_ID}

⚠️  La validation est OBLIGATOIRE avant de générer le handoff!

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

Contact support: support@atlshub.ch
```
