# TypeScript Schema - Feature JSON Types

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

---

## Type Definitions

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

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

/**
 * Application-level index.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 {
  inScope: 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[];
  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 index.json, scope: "module")
// ===================================================================

/**
 * Module-level index.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 {
  inScope: 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[];
  sections: Section[];
  dashboards: Dashboard[];
  extensions?: Record<string, unknown>;
}

// --- Sections & Resources (Levels 4-5) ---

export interface Section {
  code: string;
  labels: Record<'fr' | 'en' | 'it' | 'de', string>;
  route: string;
  icon: string;
  permission: string;
  wireframe: string;
  useCases: string[];
  businessRules: string[];
  resources: Resource[];
}

export interface Resource {
  code: string;
  type: ResourceType;
  entity: string;
  parentEntity?: string;
  permission: string;
  columns?: string[];
  fields?: FormField[];
  actions?: string[];
  filters?: string[];
  kpis?: string[];
  chartType?: ChartType;
  dataSource?: string;
}

export type ResourceType = 'SmartTable' | 'SmartForm' | 'DetailCard' | 'KpiPanel' | 'KpiCard'
  | 'Timeline' | 'EntitySelect' | 'Chart' | 'Map' | 'FileUpload' | 'StatusBadge'
  | 'ActionMenu' | 'FilterBar' | 'Tabs';

export type ChartType = 'bar' | 'line' | 'pie' | 'area' | 'donut' | 'stacked-bar';

export interface FormField {
  name: string;
  component: FormComponent;
  source?: string;
  required?: boolean;
  validation?: string;
}

export type FormComponent = 'Input' | 'TextArea' | 'Select' | 'MultiSelect' | 'DatePicker'
  | 'DateRangePicker' | 'NumberInput' | 'Toggle' | 'EntitySelect' | 'FileUpload'
  | 'RichText' | 'ColorPicker';

export interface Dashboard {
  code: string;
  title: string;
  description: string;
  linkedUCs: string[];
  refreshMode: 'static' | 'polling' | 'signalr';
  defaultPeriod: 'day' | 'week' | 'month' | 'quarter' | 'year';
  kpis: DashboardKpi[];
  filters: DashboardFilter[];
  permissionsRequired: string[];
}

export interface DashboardKpi {
  code: string;
  label: string;
  metric: string;
  format: 'number' | 'currency' | 'percent' | 'duration';
  visualization: 'kpi-card' | 'bar' | 'line' | 'pie' | 'area' | 'donut' | 'stacked-bar';
  dataSource: string;
  dimensions?: string[];
}

export interface DashboardFilter {
  field: string;
  type: 'dateRange' | 'select' | 'multiselect' | 'search';
  label: string;
}

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;                // Module-level: {app}.{module}.{action} or section-level: {app}.{module}.{section}.{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;          // {app}.{module}.{action}
  description: string;
}

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

export interface NavigationHierarchy {
  entries: NavigationEntry[];
}

export interface NavigationEntry {
  level: 'application' | 'module' | 'section' | 'resource';
  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 index.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-cadrage, step-03-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 index.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/${app}/${module}/business-analyse/v${version}/index.json`
  );
  return response.json();
}

/**
 * Load application-level (master) index.json
 */
export async function loadApplicationFeature(
  app: string,
  version: string
): Promise<ApplicationFeatureJson> {
  const response = await fetch(
    `/docs/${app}/business-analyse/v${version}/index.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/${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/${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,
  Section,
  Resource,
  ResourceType,
  FormField,
  FormComponent,
  Dashboard,
  DashboardKpi,
  DashboardFilter,
  ChartType
} from './docs';
```
