# TypeScript Schema - Feature JSON Types

> **Usage:** TypeScript interfaces aligned with feature-schema.json and application-schema.json
> **Loaded in:** step-05-handoff.md (for web app rendering)
> **Source (module):** `docs/business/{app}/{module}/business-analyse/v{X.Y}/feature.json`
> **Source (application):** `docs/business/{app}/business-analyse/v{X.Y}/feature.json`

---

## Type Definitions

```typescript
// web/smartstack-web/src/types/business-analyse.ts

// ===================================================================
// APPLICATION-LEVEL TYPES (master feature.json, scope: "application")
// ===================================================================

/**
 * Application-level Feature JSON structure
 * Matches schemas/application-schema.json
 * Master document for multi-module BA
 */
export interface ApplicationFeatureJson {
  id: string;               // FEAT-XXX
  version: string;
  status: ApplicationStatus;
  scope: 'application';
  metadata: ApplicationMetadata;
  cadrage: ApplicationCadrage;
  modules: ApplicationModule[];
  dependencyGraph: DependencyGraph;
  consolidation: ApplicationConsolidation;
  suggestions: FeatureSuggestion[];
  changelog: ChangelogEntry[];
}

export type ApplicationStatus = 'draft' | 'framed' | 'decomposed' | 'specified' | 'consolidated' | 'handed-off';

export interface ApplicationMetadata {
  application: string;
  language: string;
  featureDescription: string;
  scope: 'application';
  createdAt: string;
  updatedAt: string;
  workflow: WorkflowState;
}

export interface WorkflowState {
  mode: 'application' | 'module';
  moduleOrder: string[];
  currentModuleIndex: number;
  completedModules: string[];
  currentModule: string | null;
}

export interface ApplicationCadrage {
  problem: string;
  asIs: string;
  toBe: string;
  trigger: string;
  stakeholders: Stakeholder[];
  globalScope: GlobalScope;
  applicationRoles: ApplicationRole[];
  risks: Risk[];
  acceptanceCriteria: AcceptanceCriterion[];
  codebaseContext?: Record<string, unknown>;
}

export interface GlobalScope {
  mustHave: string[];
  shouldHave: string[];
  couldHave: string[];
  outOfScope: string[];
}

export interface ApplicationRole {
  name: string;
  level: 'admin' | 'manager' | 'contributor' | 'viewer';
  description: string;
  defaultPermissions: string[];
  moduleRestrictions?: string[];
}

export interface ApplicationModule {
  code: string;
  description: string;
  featureType: string;
  entities: string[];
  priority: 'must' | 'should' | 'could';
  estimatedComplexity: 'simple' | 'medium' | 'complex';
  status: 'pending' | 'in-progress' | 'specified' | 'validated';
  featureJsonPath?: string;
  sortOrder: number;
  dependencies: string[];
  dependents: string[];
}

export interface DependencyGraph {
  edges: DependencyEdge[];
  topologicalOrder: string[];
  layers: DependencyLayer[];
}

export interface DependencyEdge {
  from: string;
  to: string;
  type: 'FK' | 'Event' | 'Shared-entity' | 'Lookup';
  description: string;
}

export interface DependencyLayer {
  layer: number;
  modules: string[];
}

export interface ApplicationConsolidation {
  crossModuleInteractions: CrossModuleInteractions;
  permissionCoherence: PermissionCoherence;
  e2eFlows: E2EFlow[];
  globalRiskAssessment: Record<string, unknown>;
}

export interface CrossModuleInteractions {
  fkReferences: FKReference[];
  sharedEntities: SharedEntity[];
  events: ModuleEvent[];
  sharedReferenceData: SharedReferenceData[];
}

export interface FKReference {
  sourceModule: string;
  sourceEntity: string;
  sourceField: string;
  targetModule: string;
  targetEntity: string;
  targetField: string;
  required: boolean;
}

export interface SharedEntity {
  entity: string;
  definedIn: string;
  referencedBy: string[];
  referenceType: string;
}

export interface ModuleEvent {
  producer: string;
  event: string;
  consumers: string[];
  description: string;
}

export interface SharedReferenceData {
  table: string;
  usedBy: string[];
  owner: string;
}

export interface PermissionCoherence {
  roleConsistency: boolean;
  pathFormatValid: boolean;
  hierarchyRespected: boolean;
  conflictsResolved: number;
}

export interface E2EFlow {
  name: string;
  steps: E2EFlowStep[];
  actors: string[];
  data: string;
}

export interface E2EFlowStep {
  module: string;
  action: string;
  permission: string;
}

// ===================================================================
// MODULE-LEVEL TYPES (per-module feature.json, scope: "module")
// ===================================================================

/**
 * Module-level Feature JSON structure
 * Matches schemas/feature-schema.json
 * Progressively enriched by each BA step
 */
export interface FeatureJson {
  id: string;               // FEAT-XXX
  version: string;          // 1.0, 1.1, etc.
  status: FeatureStatus;
  scope?: 'module';
  metadata: FeatureMetadata;
  applicationContext?: ApplicationContext;
  discovery: FeatureDiscovery;
  analysis: FeatureAnalysis;
  specification: FeatureSpecification;
  validation: FeatureValidation;
  handoff: FeatureHandoff;
  suggestions: FeatureSuggestion[];
  changelog: ChangelogEntry[];
}

export type FeatureStatus = 'draft' | 'framed' | 'analysed' | 'decomposed' | 'specified' | 'consolidated' | 'approved' | 'handed-off';

export interface FeatureMetadata {
  application: string;
  module: string;
  language: string;
  featureType: 'new' | 'refactoring' | 'micro';
  scope?: 'application' | 'module';
  applicationRef?: string | null;
  moduleIndex?: number | null;
  createdAt: string;
  updatedAt: string;
  previousVersion: string | null;
}

export interface ApplicationContext {
  applicationRoles: ApplicationRole[];
  permissionBase: string;
  relatedModules: string[];
}

// --- Discovery ---

export interface FeatureDiscovery {
  problem: string;
  asIs: string;
  toBe: string;
  trigger: string;
  stakeholders: Stakeholder[];
  scope: FeatureScope;
  risks: Risk[];
  acceptanceCriteria: AcceptanceCriterion[];
}

export interface Stakeholder {
  role: string;
  description: string;
  tasks: string[];
  frequency: 'daily' | 'weekly' | 'monthly' | 'rarely';
}

export interface FeatureScope {
  mustHave: string[];
  shouldHave: string[];
  couldHave: string[];
  outOfScope: string[];
  mainFlow: string[];
  alternativeFlows: AlternativeFlow[];
}

export interface AlternativeFlow {
  condition: string;
  steps: string[];
}

export interface Risk {
  id: string;
  description: string;
  severity: 'high' | 'medium' | 'low';
  mitigation: string;
}

export interface AcceptanceCriterion {
  id: string;
  description: string;
  testable: boolean;
}

// --- Analysis ---

export interface FeatureAnalysis {
  objectives: BusinessObjective[];
  businessRules: BusinessRule[];
  entities: Entity[];
  processFlow: string;
  integrations: Integration[];
}

export interface BusinessObjective {
  id: string;
  description: string;
  measurable: boolean;
}

export interface BusinessRule {
  id: string;            // BR-XXX
  rule: string;
  category: 'Validation' | 'Calculation' | 'Workflow' | 'Security' | 'Data';
  priority: 'Must' | 'Should' | 'Could';
  condition: string;
  action: string;
  examples: BusinessRuleExample[];
  linkedRules: string[];  // Cross-reference other BR-IDs
}

export interface BusinessRuleExample {
  input: string;
  expected: string;
}

export interface Entity {
  name: string;           // PascalCase
  description: string;
  attributes: EntityAttribute[];
  relationships: EntityRelationship[];
}

export interface EntityAttribute {
  name: string;
  type: string;
  required: boolean;
  rules: string;
}

export interface EntityRelationship {
  target: string;
  type: '1:1' | '1:N' | 'N:1' | 'N:M';
  description: string;
}

export interface Integration {
  system: string;
  direction: 'inbound' | 'outbound' | 'bidirectional';
  protocol: string;
  description: string;
}

// --- Specification ---

export interface FeatureSpecification {
  actors: Actor[];
  useCases: UseCase[];
  functionalRequirements: FunctionalRequirement[];
  permissionMatrix: PermissionMatrix;
  navigation: NavigationHierarchy;
  gherkinScenarios: GherkinScenario[];
  apiEndpoints: ApiEndpoint[];
  validations: ValidationRule[];
  wireframes: Wireframe[];
  messages: BusinessMessage[];
  lifeCycles: EntityLifeCycle[];
  seedDataCore: SeedDataCore;
  i18nKeys: I18nKey[];
}

export interface ValidationRule {
  field: string;
  rules: string;
  errorMessage: string;
}

export interface Wireframe {
  screen: string;
  section?: string;              // Section code (list, detail, create, etc.)
  description: string;
  mockupFormat?: 'ascii' | 'svg';  // Format of the mockup
  mockup?: string;                 // ASCII art or inline SVG content
  elements: string[];
  actions: string[];
  permissionsRequired: string[];
}

export interface BusinessMessage {
  code: string;                // SCREAMING_SNAKE_CASE
  type: 'success' | 'error' | 'warning' | 'info';
  title: string;
  message: string;             // User-facing with {placeholders}
  i18nKey: string;             // Dot-separated key
}

export interface EntityLifeCycle {
  entity: string;              // PascalCase entity name
  states: LifeCycleState[];
}

export interface LifeCycleState {
  id: string;                  // State code (Draft, Active, etc.)
  displayName: string;
  description?: string;
  allowedTransitions: string[];
  isTerminal: boolean;
}

export interface SeedDataCore {
  navigationModules: SeedDataNavModule[];
  navigationTranslations: SeedDataNavTranslation[];
  permissions: SeedDataPermission[];
  rolePermissions: SeedDataRolePermission[];
  permissionConstants: SeedDataPermissionConstant[];
}

export interface SeedDataNavModule {
  code: string;
  label: string;
  icon: string;
  route: string;
  parentCode: string | null;
  sort: number;
}

export interface SeedDataNavTranslation {
  moduleCode: string;
  language: 'fr' | 'en' | 'it' | 'de';
  label: string;
}

export interface SeedDataPermission {
  path: string;                // Full path: business.{app}.{module}.{resource}.{action}
  action: string;
  description?: string;
}

export interface SeedDataRolePermission {
  role: string;
  permissionPath: string;      // Must match permissions[].path
}

export interface SeedDataPermissionConstant {
  constantName: string;        // PascalCase (e.g., VehiclesRead)
  path: string;                // Matching permission path
}

export interface Actor {
  name: string;
  description: string;
  permissionBase: string;
}

export interface UseCase {
  id: string;            // UC-XXX
  name: string;
  actor: string;
  permission: string;
  preconditions: string[];
  postconditions: string[];
  mainScenario: string[];
  alternativeScenarios: { condition: string; steps: string[] }[];
  errorScenarios: { error: string; message: string; action: string }[];
  linkedRules: string[];  // BR-IDs
}

export interface FunctionalRequirement {
  id: string;            // FR-XXX
  statement: string;
  priority: 'Must' | 'Should' | 'Could';
  acceptanceCriteria: string[];
  linkedUseCases: string[];  // UC-IDs
  linkedRules: string[];     // BR-IDs
}

export interface PermissionMatrix {
  roles: string[];
  permissions: PermissionEntry[];
  roleAssignments: RoleAssignment[];
}

export interface PermissionEntry {
  path: string;          // business.{app}.{module}.{action}
  description: string;
}

export interface RoleAssignment {
  role: string;
  permissions: string[];  // Permission paths
}

export interface NavigationHierarchy {
  entries: NavigationEntry[];
}

export interface NavigationEntry {
  level: 'context' | 'application' | 'module' | 'section';
  code: string;
  labels: Record<string, string>;  // {fr, en, it, de}
  route: string;
  icon: string;
  isNew: boolean;
}

export interface GherkinScenario {
  feature: string;
  name: string;
  tags: string[];
  steps: string;
}

export interface ApiEndpoint {
  path: string;
  method: 'GET' | 'POST' | 'PUT' | 'DELETE';
  permission: string;
  requestBody: string | null;
  responseType: string;
}

export interface I18nKey {
  key: string;
  fr: string;
  en: string;
  it: string;
  de: string;
}

// --- Validation ---

export interface FeatureValidation {
  validatedAt: string | null;
  completenessChecks: CompletenessCheck[];
  consistencyChecks: ConsistencyCheck[];
  conventionChecks: ConventionCheck[];
  riskAssessments: RiskAssessment[];
  warnings: string[];
  decision: ValidationDecision;
}

export interface CompletenessCheck {
  section: string;
  count: number;
  minimum: number;
  status: 'PASS' | 'FAIL' | 'WARNING';
}

export interface ConsistencyCheck {
  check: string;
  passed: number;
  warnings: number;
  errors: number;
  status: 'PASS' | 'FAIL' | 'WARNING';
}

export interface ConventionCheck {
  check: string;
  status: 'PASS' | 'FAIL' | 'WARNING';
  details: string;
}

export interface RiskAssessment {
  risk: string;
  value: number;
  threshold: number;
  status: 'ACCEPTABLE' | 'WARNING' | 'CRITICAL' | 'MONITORED';
}

export interface ValidationDecision {
  approved: boolean;
  reason: string;
  approvalMode: 'standard' | 'micro' | 'delta' | 'force';
  approvedBy: string;
  approvedAt: string;
}

// --- Handoff ---

export interface FeatureHandoff {
  complexity: 'simple' | 'medium' | 'complex';
  complexityDetails?: {
    entities: number;
    useCases: number;
    businessRules: number;
    calculated: string;
  };
  filesToCreate: FilesToCreate;
  brToCodeMapping: BrToCodeMapping[];
  apiEndpointSummary: ApiEndpointSummaryEntry[];
  ralphPrd: object | null;     // .ralph/prd.json content
}

export interface FilesToCreate {
  domain: FileSpec[];
  application: FileSpec[];
  infrastructure: FileSpec[];
  api: FileSpec[];
  frontend: FileSpec[];
  seedData: FileSpec[];
  tests: FileSpec[];
}

export interface FileSpec {
  path: string;
  type: string;                // Entity, Service, DTO, HasData, Constants, ApiController, Page, Component, etc.
  linkedFRs?: string[];        // FR-XXX references
  linkedUCs?: string[];        // UC-XXX references
  category?: 'core' | 'business';  // For seedData files
  source?: string;             // Derivation source in feature.json
  description?: string;
}

export interface BrToCodeMapping {
  ruleId: string;              // BR-XXX from analysis.businessRules
  title: string;
  implementationPoints: ImplementationPoint[];
}

export interface ImplementationPoint {
  layer: string;               // Domain, Application, Infrastructure, API, Frontend
  component: string;           // File name
  method: string;              // Method or attribute
  implementation: string;      // How the rule is enforced
}

export interface ApiEndpointSummaryEntry {
  operation: string;
  method: 'GET' | 'POST' | 'PUT' | 'DELETE' | 'PATCH';
  route: string;               // MUST match specification.apiEndpoints[].path
  linkedUC: string;
  permissions: string;
}

// --- Suggestions & Changelog ---

export interface FeatureSuggestion {
  type: 'module' | 'section' | 'integration' | 'enhancement';
  code: string;
  title: string;
  reason: string;
  accepted: boolean | null;
}

export interface ChangelogEntry {
  step?: string;               // step-01-analyse, step-02-specify, etc.
  version?: string;
  timestamp: string;
  author?: string;
  changes: string[];
  warnings?: string[];
  decision?: string;
}
```

---

## Data Loading

```typescript
// web/smartstack-web/src/services/businessAnalyse.ts

import type { FeatureJson, ApplicationFeatureJson } from '../types/business-analyse';

/**
 * Load module-level feature.json from docs path
 * The web app reads the JSON directly - no transformation needed
 */
export async function loadFeature(
  app: string,
  module: string,
  version: string
): Promise<FeatureJson> {
  const response = await fetch(
    `/docs/business/${app}/${module}/business-analyse/v${version}/feature.json`
  );
  return response.json();
}

/**
 * Load application-level (master) feature.json
 */
export async function loadApplicationFeature(
  app: string,
  version: string
): Promise<ApplicationFeatureJson> {
  const response = await fetch(
    `/docs/business/${app}/business-analyse/v${version}/feature.json`
  );
  return response.json();
}

/**
 * List available versions for a module
 */
export async function listVersions(
  app: string,
  module: string
): Promise<string[]> {
  const response = await fetch(
    `/api/docs/business/${app}/${module}/business-analyse/versions`
  );
  return response.json();
}

/**
 * List available versions for an application (master)
 */
export async function listApplicationVersions(
  app: string
): Promise<string[]> {
  const response = await fetch(
    `/api/docs/business/${app}/business-analyse/versions`
  );
  return response.json();
}
```

---

## Index Export

```typescript
// web/smartstack-web/src/types/index.ts

export type {
  // Application-level types
  ApplicationFeatureJson,
  ApplicationStatus,
  ApplicationMetadata,
  WorkflowState,
  ApplicationCadrage,
  GlobalScope,
  ApplicationRole,
  ApplicationModule,
  DependencyGraph,
  DependencyEdge,
  DependencyLayer,
  ApplicationConsolidation,
  CrossModuleInteractions,
  E2EFlow,
  PermissionCoherence,

  // Module-level types
  FeatureJson,
  FeatureStatus,
  FeatureMetadata,
  ApplicationContext,
  FeatureDiscovery,
  FeatureAnalysis,
  FeatureSpecification,
  FeatureValidation,
  FeatureHandoff,
  BusinessRule,
  UseCase,
  FunctionalRequirement,
  Entity,
  PermissionMatrix,
  Wireframe,
  BusinessMessage,
  EntityLifeCycle,
  SeedDataCore,
  FilesToCreate,
  FileSpec,
  BrToCodeMapping,
  ValidationDecision,
  FeatureSuggestion,
  ChangelogEntry
} from './business-analyse';
```
