---
name: step-01b-applications
description: Application decomposition - identify and define multiple applications within a project
model: opus
next_step: steps/step-02-decomposition.md
---

> **Context files:** `_shared.md`

# Step 1b: Application Decomposition

## MANDATORY EXECUTION RULES

- ALWAYS use ULTRATHINK mode
- This step is ONLY loaded when `workflow.mode === "project"` (multi-application mode)
- ALL communication in `{language}`
- This step takes the candidate applications identified during cadrage and formalizes them

## YOUR TASK

For each candidate application identified during step-01 cadrage, define its identity, context, roles, and scope. Establish inter-application dependencies and create per-application feature.json files.

---

### 1. Load Project Context

```
projectFeature = ba-reader.findProjectFeature()
candidateApps = projectFeature.cadrage.coverageMatrix grouped by domain
globalRoles = projectFeature.cadrage.globalRoles (if defined)
globalScope = projectFeature.cadrage.globalScope
```

### 2. Application Identity (per candidate)

For EACH candidate application from the cadrage analysis:

#### 2a. Confirm Application Name and Context

Display proposed application:
```
{language == "fr"
  ? "### Application : {suggestedName}\n\n**Contexte de navigation :** {suggestedContext}\n**Description :** {description based on coverage matrix items}"
  : "### Application: {suggestedName}\n\n**Navigation context:** {suggestedContext}\n**Description:** {description based on coverage matrix items}"}
```

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Cette application et son contexte vous conviennent-ils ?' : 'Does this application and its context suit you?'}"
header: "{appName}"
options:
  - label: "{language == 'fr' ? 'Oui, parfait' : 'Yes, perfect'}"
    description: "{language == 'fr' ? 'Nom et contexte corrects' : 'Name and context are correct'}"
  - label: "{language == 'fr' ? 'Modifier' : 'Modify'}"
    description: "{language == 'fr' ? 'Changer le nom, le contexte ou la description' : 'Change name, context, or description'}"
```

#### 2b. Table Prefix (per application)

Each application MUST have its own unique table prefix.

1. Derive suggested prefix from application name (2-5 lowercase letters + `_`)
2. Validate:
   - Format: `^[a-z]{2,5}_$`
   - No collision with platform prefixes: `auth_`, `nav_`, `usr_`, `ai_`, `cfg_`, `wkf_`, `support_`, `entra_`, `ref_`, `loc_`, `lic_`, `tenant_`
   - No collision with other applications in this project
3. Ask via AskUserQuestion for confirmation

#### 2c. Application-Specific Roles

Based on global roles from cadrage + application-specific needs:

```
{language == "fr"
  ? "### Rôles pour {appName}\n\nVoici les rôles hérités des rôles globaux, adaptés à cette application :"
  : "### Roles for {appName}\n\nHere are the roles inherited from global roles, adapted for this application:"}

| Role | Level | Permission Pattern |
|------|-------|--------------------|
{for each role: name | admin/manager/contributor/viewer | context.app.* pattern}
```

Ask via AskUserQuestion if additional roles are needed for this specific application.

#### 2d. Application Scope

Extract the subset of global scope that applies to this application:

```
applicationScope = {
  mustHave: globalScope.mustHave.filter(item => belongsToApp(item, appCode)),
  shouldHave: globalScope.shouldHave.filter(item => belongsToApp(item, appCode)),
  couldHave: globalScope.couldHave.filter(item => belongsToApp(item, appCode))
}
```

Display and confirm with user.

### 3. Inter-Application Dependency Analysis

After all applications are defined:

1. **Identify dependencies:** For each pair of applications:
   - Shared entities (e.g., Employee defined in HR, referenced by Self-Service)
   - Event flows (e.g., HR publishes "EmployeeCreated", Self-Service subscribes)
   - Authentication delegation (e.g., Self-Service uses HR's employee data for auth)
   - Data dependencies (e.g., Self-Service reads HR data)

2. **Build dependency graph:**
```
applicationDependencyGraph = {
  edges: [
    { from: "EmployeeSelfService", to: "HumanResources", type: "data-dependency", description: "Reads employee data" }
  ],
  topologicalOrder: ["HumanResources", "EmployeeSelfService"],
  layers: [
    { layer: 0, applications: ["HumanResources"] },
    { layer: 1, applications: ["EmployeeSelfService"] }
  ]
}
```

3. **Cycle detection:** If circular dependencies detected → BLOCKING ERROR
   - Display the cycle
   - Ask user to resolve (merge applications or remove dependency)

### 4. Client Checkpoint (BLOCKING)

Display the full application structure:

```
{language == "fr"
  ? "### Structure du projet\n\nVoici les applications identifiées :"
  : "### Project Structure\n\nHere are the identified applications:"}

| # | Application | Contexte | Préfixe | Rôles | Dépendances |
|---|-------------|----------|---------|-------|-------------|
{for each app: index | name | context | prefix | role count | dependency list}

{language == "fr"
  ? "### Ordre de traitement\n\nLes applications seront traitées dans cet ordre (fondations d'abord) :"
  : "### Processing Order\n\nApplications will be processed in this order (foundations first):"}

{for each layer: "Layer {n}: {app1}, {app2}, ..."}
```

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Cette structure de projet vous convient-elle ?' : 'Does this project structure suit you?'}"
header: "Validation"
options:
  - label: "{language == 'fr' ? 'Oui, continuer' : 'Yes, continue'}"
    description: "{language == 'fr' ? 'Passer à la décomposition en modules' : 'Proceed to module decomposition'}"
  - label: "{language == 'fr' ? 'Modifier' : 'Modify'}"
    description: "{language == 'fr' ? 'Ajouter, supprimer ou modifier des applications' : 'Add, remove, or modify applications'}"
  - label: "{language == 'fr' ? 'Fusionner en une seule' : 'Merge into one'}"
    description: "{language == 'fr' ? 'Finalement, c'est une seule application avec plusieurs modules' : 'Actually, this is one application with multiple modules'}"
```

**IF "Merge into one":**
→ Convert back to single-application mode
→ Delete project-level feature.json
→ Create application-level feature.json with all scope items
→ Load `steps/step-02-decomposition.md` directly

### 5. Create Per-Application Feature.json Files

For EACH application in topological order:

```
ba-writer.createApplicationFeature({
  id: generate_feature_id(),
  version: "1.0",
  scope: "application",
  status: "draft",
  metadata: {
    application: {app.code},
    context: {app.context},
    language: {language},
    featureDescription: {app.description},
    workflowType: "new",
    analysisMode: "interactive",
    mcpAvailable: true,
    tablePrefix: {app.tablePrefix},
    projectRef: {project_id},
    workflow: {
      mode: "application",
      moduleOrder: [],
      currentModuleIndex: 0,
      completedModules: [],
      currentModule: null
    }
  }
})
```

Store the created feature.json path in the project feature.json `applications[].featureJsonPath`.

### 6. Write to Project Feature.json

```
ba-writer.enrichApplicationRegistry({
  projectId: {project_id},
  applications: [
    {
      code: {app1.code},
      name: {app1.name},
      context: {app1.context},
      tablePrefix: {app1.tablePrefix},
      icon: {app1.icon},
      description: {app1.description},
      applicationRoles: [{...}],
      scope: { mustHave: [...], shouldHave: [...], couldHave: [...] },
      modules: [],
      dependencies: [{...}],
      status: "pending",
      featureJsonPath: {app1.featureJsonPath},
      estimatedComplexity: {app1.estimatedComplexity}
    },
    // ... more applications
  ],
  applicationDependencyGraph: {
    edges: [...],
    topologicalOrder: [...],
    layers: [...]
  }
})

ba-writer.updateStatus({project_id}, "decomposed")
```

### 7. Display Summary

```
{language == "fr"
  ? "### Décomposition en applications terminée\n\n"
  : "### Application decomposition complete\n\n"}

| Application | Contexte | Préfixe | Feature ID |
|-------------|----------|---------|------------|
{for each app: name | context | prefix | FEAT-NNN}

{language == "fr"
  ? "→ Prochaine étape : décomposition en modules pour **{firstApp}** (application {1}/{total})"
  : "→ Next step: module decomposition for **{firstApp}** (application {1}/{total})"}
```

---

## NEXT STEP

Load: `./step-02-decomposition.md` (for the first application in topological order)
