# PRD JSON v2.0.0 - Référence Complète

## Vue d'ensemble

Le `prd.json` est généré **programmatiquement** par `ss derive-prd` à partir du `feature.json` (section handoff).

**Garanties** :
- ✅ Zéro hallucination LLM (extraction déterministe TypeScript)
- ✅ Traçabilité complète (`source.featureJson` path)
- ✅ Validation stricte (status + contenu obligatoire)
- ✅ Reproductibilité parfaite (même input = même output)

**Code source** :
- Types : [src/types/prd-json.d.ts](../src/types/prd-json.d.ts)
- Extraction : [src/utils/prd-extractor.ts](../src/utils/prd-extractor.ts)
- CLI : [src/commands/derive-prd.ts](../src/commands/derive-prd.ts)

---

## Commande CLI

```bash
# Module unique
ss derive-prd --feature docs/business/MyApp/Orders/business-analyse/v1.0/feature.json

# Application complète (tous les modules)
ss derive-prd --application docs/business/MyApp/business-analyse/v1.0/feature.json

# Mode strict (fail on warnings)
ss derive-prd --feature <path> --strict

# Output custom
ss derive-prd --feature <path> --output .ralph/custom-prd.json
```

**Output par défaut** : `.ralph/prd-{module}.json`

---

## Structure Complète

```typescript
{
  // VERSION
  version: "2.0.0",

  // SOURCE (traçabilité)
  source: {
    type: "ba-handoff-programmatic",
    featureJson: "docs/business/MyApp/Orders/business-analyse/v1.0/feature.json",
    extractedAt: "2024-01-15T10:30:00Z"
  },

  // PROJECT
  project: {
    application: "MyApp",
    module: "Orders",
    namespace: "MyCompany.MyApp"  // Optionnel, depuis .smartstack/config.json
  },

  // REQUIREMENTS
  requirements: {
    useCases: [{
      id: "UC-001",
      name: "Create Order",
      actor: "Sales Manager",
      permission: "business.myapp.orders.create",
      steps: ["Select products", "Validate cart", "Create order"],
      linkedRules: ["BR-VAL-001"]
    }],
    functionalRequirements: [{
      id: "FR-001",
      statement: "System must allow creating orders",
      priority: "high",
      linkedUCs: ["UC-001"]
    }]
  },

  // BUSINESS RULES
  businessRules: [{
    id: "BR-VAL-001",
    name: "Order total validation",
    category: "validation",
    statement: "Order total must equal sum of item prices",
    priority: "critical"
  }],

  // ARCHITECTURE
  architecture: {
    entities: [{
      name: "Order",
      type: "aggregate-root",
      attributes: [{
        name: "Reference",
        type: "string",
        required: true,
        unique: true
      }],
      relationships: [{
        target: "Customer",
        type: "many-to-one"
      }]
    }],
    apiEndpoints: [{
      method: "POST",
      route: "/api/business/myapp/orders",
      operation: "CreateOrder",
      permission: "business.myapp.orders.create",
      requestSchema: "CreateOrderDto",
      responseSchema: "OrderDto",
      errorCodes: ["400", "401", "403", "422"],
      linkedUC: "UC-001"
    }],
    permissionMatrix: {
      permissions: [{
        path: "business.myapp.orders.create",
        description: "Create new orders",
        scope: "tenant"
      }],
      roleAssignments: [{
        role: "MyApp Manager",
        level: "full",
        permissions: ["business.myapp.orders.*"]
      }]
    },
    sections: [{
      code: "orders-list",
      name: "Orders List",
      route: "/business/myapp/orders",
      permission: "business.myapp.orders.read",
      resources: [{
        code: "orders-grid",
        type: "DataGrid",
        entity: "Order",
        columns: ["reference", "customer", "total", "status"]
      }]
    }],
    lifeCycles: [{
      entity: "Order",
      field: "status",
      initialState: "draft",
      states: [
        { id: "draft", allowedTransitions: ["submitted"] },
        { id: "submitted", allowedTransitions: ["approved", "rejected"] }
      ]
    }]
  },

  // IMPLEMENTATION
  implementation: {
    strategy: "module-by-module",
    filesToCreate: {
      domain: [{
        path: "src/Domain/Business/MyApp/Orders/Order.cs",
        type: "Entity",
        linkedFRs: ["FR-001"],
        linkedUCs: ["UC-001"]
      }],
      application: [/* DTOs, Services, Validators */],
      infrastructure: [/* Repositories, DbContext */],
      api: [/* Controllers */],
      frontend: [{
        path: "src/pages/MyApp/OrdersPage.tsx",
        type: "Page",
        linkedUCs: ["UC-001"],
        linkedWireframes: ["orders-list"]
      }],
      seedData: [{
        path: "src/Infrastructure/Persistence/Seeding/Data/Orders/NavigationModuleSeedData.cs",
        type: "SeedData",
        category: "core"
      }],
      tests: [/* Unit, Integration, Security tests */]
    },
    brToCodeMapping: [{
      ruleId: "BR-VAL-001",
      targetFile: "src/Domain/Business/MyApp/Orders/Order.cs",
      targetMethod: "CalculateTotal()",
      implementationType: "domain-validation"
    }]
  },

  // SEED DATA
  seedData: {
    core: [
      { entity: "NavigationModule", count: 1 },
      { entity: "Permission", count: 8 }
    ],
    business: [
      { entity: "OrderStatus", samples: ["Draft", "Submitted"], count: 5 }
    ]
  }
}
```

---

## Mapping feature.json → prd.json

| Champ prd.json | Source feature.json | Transformation |
|----------------|---------------------|----------------|
| `requirements.useCases[]` | `specification.useCases[]` | Direct (id, name, actor, permission, steps, linkedRules) |
| `requirements.functionalRequirements[]` | `specification.functionalRequirements[]` | Direct (id, statement, priority, linkedUCs) |
| `businessRules[]` | `analysis.businessRules[]` | Direct (id, name, category, statement, priority) |
| `architecture.entities[]` | `analysis.entities[]` | Direct (name, type, attributes, relationships) |
| `architecture.apiEndpoints[]` | `specification.apiEndpoints[]` | Direct (method, route, operation, permission) |
| `architecture.permissionMatrix` | `specification.permissionMatrix` | Direct (permissions, roleAssignments) |
| `architecture.sections[]` | `specification.sections[]` | Direct (code, name, route, resources) |
| `architecture.lifeCycles[]` | `specification.lifeCycles[]` | Direct (entity, states, transitions) |
| `implementation.strategy` | `handoff.implementationStrategy` | Direct ("module-by-module", "layer-by-layer", "hybrid") |
| `implementation.filesToCreate` | `handoff.filesToCreate` | Direct (7 categories: domain, application, infrastructure, api, frontend, seedData, tests) |
| `implementation.brToCodeMapping[]` | `handoff.brToCodeMapping[]` | Direct (ruleId, targetFile, targetMethod) |
| `seedData.core` | `specification.seedDataCore` | Direct |
| `seedData.business` | `specification.seedDataBusiness` | Direct |

**Aucune transformation complexe** : Le prd.json est une copie structurée du feature.json.

---

## Validation (Pre-Extraction)

### Pré-requis MANDATORY

```typescript
// Code: src/utils/prd-extractor.ts:validateForPrdExtraction()

function validateForPrdExtraction(feature: ModuleFeatureJson): string[] {
  const errors: string[] = [];

  if (!feature.id) errors.push('Missing feature ID');
  if (!feature.metadata?.application) errors.push('Missing metadata.application');
  if (!feature.metadata?.module) errors.push('Missing metadata.module');

  if (feature.status !== 'handed-off' &&
      feature.status !== 'approved' &&
      feature.status !== 'consolidated') {
    errors.push(`Feature status is "${feature.status}" — expected "handed-off", "approved", or "consolidated"`);
  }

  if (!feature.specification?.useCases?.length) {
    errors.push('No use cases found in specification');
  }

  if (!feature.analysis?.businessRules?.length) {
    errors.push('No business rules found in analysis');
  }

  if (!feature.handoff?.filesToCreate) {
    errors.push('No filesToCreate found in handoff');
  }

  return errors;
}
```

### Mode Strict

En mode `--strict`, les warnings bloquent l'extraction :

```bash
ss derive-prd --feature <path> --strict
# Échoue si : warnings.length > 0
```

---

## Exemples Annotés

### Simple Module (CRUD basique)

**Contexte** : Module Orders avec 1 entity, 2 UCs, 3 BRs

**Commande** :
```bash
ss derive-prd --feature docs/business/MyApp/Orders/business-analyse/v1.0/feature.json
```

**Output** : `.ralph/prd-Orders.json` (voir [examples/prd-simple.json](examples/prd-simple.json))

**Métriques** :
- UCs: 2
- FRs: 3
- BRs: 3
- Endpoints: 5 (CRUD + List)
- Files to create: 15
- SeedData core: 5 (MANDATORY)

---

### Medium Module (Avec Lifecycle)

**Contexte** : Module Invoices avec 4 entities, 6 UCs, 12 BRs, lifecycle states

**Commande** :
```bash
ss derive-prd --feature docs/business/MyApp/Invoices/business-analyse/v1.0/feature.json
```

**Output** : `.ralph/prd-Invoices.json` (voir [examples/prd-medium.json](examples/prd-medium.json))

**Métriques** :
- UCs: 6
- FRs: 10
- BRs: 12
- Endpoints: 12
- Files to create: 35
- LifeCycles: 1 (Invoice.status: draft → submitted → paid)

---

### Complex Module (Cross-Dependencies)

**Contexte** : Module Orders dépendant de Customers + Products

**Commande** :
```bash
ss derive-prd --application docs/business/MyApp/business-analyse/v1.0/feature.json
# Génère prd-Orders.json + prd-Customers.json + prd-Products.json
```

**Output** : 3 fichiers prd.json (voir [examples/prd-complex/](examples/prd-complex/))

**Métriques** :
- Modules: 3
- Total UCs: 15
- Total BRs: 25
- Cross-module relationships: Order → Customer, Order → Product

---

## Consommation par Ralph Loop

Ralph Loop lit le prd.json pour :

1. **Générer les fichiers** (`implementation.filesToCreate`) :
   - Domain entities (BaseEntity + IAuditableEntity)
   - Application services (DTOs, Validators)
   - Infrastructure (Repositories, DbContext)
   - API controllers (RequirePermission)
   - Frontend pages (SmartTable, EntityForm)
   - SeedData (5 CORE + business)
   - Tests (Unit, Integration, Security)

2. **Implémenter les business rules** (`implementation.brToCodeMapping`) :
   - Injection dans les layers appropriées (Domain, Application, API)

3. **Créer les SeedData** (`seedData.core` + `seedData.business`) :
   - NavigationModule, Permissions, Roles (CORE)
   - Lookup tables, test fixtures (business)

4. **Valider la couverture** :
   - Tous les UCs ont des endpoints
   - Tous les BRs sont mappés au code
   - Toutes les permissions sont définies

---

## Dépannage

### Erreur : "Feature status is X — expected handed-off"

**Cause** : Le feature.json n'a pas été finalisé par step-05-handoff.md

**Solution** :
```bash
# Vérifier le status
jq '.status' docs/business/MyApp/Orders/business-analyse/v1.0/feature.json

# Doit retourner : "handed-off"
```

### Erreur : "No filesToCreate found in handoff"

**Cause** : La section handoff est vide (`handoff: {}`) ou manquante

**Solution** : Relancer step-05-handoff.md pour générer le handoff complet avec les 7 catégories de fichiers.

### Erreur : "No use cases found"

**Cause** : `specification.useCases[]` est vide ou manquant

**Solution** : Relancer step-03-specify.md pour spécifier les use cases.

### Avertissement : Module feature.json mais status = "approved"

**Cause** : Feature validée mais pas encore en mode handoff

**Solution** : Acceptable en mode non-strict. Pour strict, relancer step-05.

---

## Voir aussi

- [feature.json Schema](../templates/skills/business-analyse/schemas/feature-schema.json)
- [Step 05 Handoff](../templates/skills/business-analyse/steps/step-05-handoff.md)
- [Ralph Loop Documentation](../templates/skills/ralph-loop/SKILL.md)
