---
name: step-02-structure
description: Identify and challenge hierarchy - App > Module > Section > Resource
model: opus
next_step: steps/step-03-specify.md
---

# Step 02 — Structure (Identify & Challenge)

## Objective

Identify the complete hierarchy **Application > Module > Section > Resource** from the cadrage data, then CHALLENGE each element to ensure nothing is missing or superfluous.

## Context Recovery

Re-read session variables from `.business-analyse/config.json`:
```javascript
const config = readJSON('.business-analyse/config.json').currentFeature;
const { id: feature_id, docsDir: docs_dir, projectSlug, application: application_name,
        applicationCode, workflowMode: workflow_mode, language } = config;

// Path helpers (ba-006)
function toKebabCase(code) {
  return code.replace(/([a-z0-9])([A-Z])/g, '$1-$2').replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2').toLowerCase();
}
function resolveAppDir(appCode) { return `${docs_dir}/${toKebabCase(appCode)}`; }
function resolveModuleDir(appCode, moduleCode) { return `${docs_dir}/${toKebabCase(appCode)}/${toKebabCase(moduleCode)}`; }
```

## Prerequisites

- Step 01 (cadrage) completed
- `cadrage.json` available with context, stakeholders, scope, risks

## Input

Load via ba-reader:
- `cadrage.json` — framing data from step 01

## Process

### 1. Application Detection

Analyze the cadrage scope to determine if this is single-app or multi-app:

**Single-app indicators:**
- All scope items relate to one domain
- Single set of stakeholders
- No mention of separate systems

**Multi-app indicators:**
- Scope items spanning distinct domains (e.g., HR + CRM + Accounting)
- Different stakeholder groups per domain
- Mentions of separate applications or systems

If multi-app:
```
For each application:
  - Code (PascalCase)
  - Name (display name)
  - Route (URL prefix)
  - Icon (optional)
  - Description
```

If single-app: derive application from project context.

### 2. Module Identification

For each application, identify functional modules:

```
For each module:
  - Code (PascalCase)
  - Name (display name)
  - ApplicationCode (parent app)
  - Description
  - FeatureType (data-centric | workflow | reporting | integration | full-module)
  - Entities (preliminary list)
  - Audience ("internal" | "external" | "shared") — if portalMode = "dual"
    → Derived from coverageMatrix: if ALL items of the module are internal → "internal",
      if ALL external → "external", else → "shared"
```

### 3. Section & Resource Anticipation

For each module, anticipate the navigation structure:

```
For each section:
  - code (kebab-case, e.g., "list", "detail", "dashboard")
  - label (display name)
  - sectionType: primary | functional | view | embedded
  - permissionMode: crud | custom | read-only | inherit
  - resources: [
      { code, type (SmartTable|SmartForm|SmartCard|SmartKanban|SmartDashboard|SmartFilter), label }
    ]
```

**Section classification rules:**

| sectionType | permissionMode | When to use | Parent | Examples |
|---|---|---|---|---|
| `primary` | `crud` | Main entry point of the module, visible in menu | none | list |
| `functional` | `crud` or `custom` | Independent functional section with own access control | none | approve, import, planning |
| `view` | `inherit` | Sub-page reached from a primary/functional section (e.g., click a row) | `parentSectionCode` | detail, edit |
| `embedded` | `read-only` | Widget or tab embedded in another section | `parentSectionCode` | dashboard (when embedded in module) |

**Parent-child rule:** `view` and `embedded` sections MUST specify `parentSectionCode` — the code of the section they are reached from. A detail page is NOT a sibling of list; it is a **child** of list (user clicks a row in the list to reach the detail).

Common patterns:
- **Data-centric**: list (`primary`/`crud`) → detail (`view`/`inherit`, parent: list)
- **Workflow**: list (`primary`/`crud`) → detail (`view`/`inherit`, parent: list) + approve (`functional`/`custom`)
- **Reporting**: dashboard (`primary`/`read-only`) → detail (`view`/`inherit`, parent: dashboard)
- **Full module**: list (`primary`/`crud`) → detail (`view`/`inherit`, parent: list) + dashboard (`embedded`/`read-only`, parent: list)

### 4. Dependency Graph

Map dependencies between modules:
```
For each dependency:
  - from: module code
  - to: module code (depends on)
  - description: nature of dependency
```

### 5. CHALLENGE Phase

For EACH identified element, ask yourself:

**Applications:**
- Is this really a separate application or should it be a module?
- Are there shared users between applications?

**Modules:**
- Is this module too large? Should it be split?
- Is this module too small? Should it merge with another?
- Does every scope item have at least one module covering it?
- Are there scope items NOT covered by any module?

**Sections:**
- Does this module need a dashboard?
- Is the list/detail pattern sufficient or are there other views?
- Are there workflow steps that need dedicated sections?
- Does this section need its own access control? If not → `view` or `embedded`
- Is this a read-only view (dashboard, balances, statistics)? If yes → `permissionMode: read-only`
- Is this section reached by clicking a row in another section? If yes → always `view`

**Resources:**
- Is SmartTable the right component for this list?
- Does the form need tabs?
- Are there missing filter components?

**Split audience (if portalMode = "dual"):**
- Pour chaque module "shared" : le portail voit-il les MÊMES données ou un sous-ensemble filtré ?
- Y a-t-il des sections qui ne doivent apparaître QUE dans le portail ? (ex: "Mes demandes")
- Y a-t-il des sections qui ne doivent apparaître QUE en interne ? (ex: reporting admin)

### 6. Present to User

Display the complete hierarchy for validation:

**Tree nesting rules:**
- `view` sections are **indented under their parent** (the section they are reached from)
- `functional` and `primary` sections stay at module level
- `embedded` sections are indented under their parent section
- Tabs are indented under detail

```
[App: HumanResources]
  ├── [Module: Employees]
  │   ├── list (primary/crud) → employees-grid, employees-filters
  │   │   └── detail (view/inherit) → employee-form
  │   │       └── Tabs: Infos, Contrats
  ├── [Module: Absences]
  │   ├── list (primary/crud) → absences-grid, absences-filters
  │   │   └── detail (view/inherit) → absence-form
  │   └── calendar (functional) → absences-calendar
  └── [Module: Reports]
      └── dashboard (primary/read-only) → hr-dashboard

IF portalMode = "dual", annotate each module with its audience:

[App: ServiceManagement]
  ├── [Module: Projects] [partagé]
  ├── [Module: TimeTracking] [interne]
  └── [Module: ClientDashboard] [portail]
```

Ask: "Does this structure match your vision? Any missing modules, sections, or resources?"

## Output

Write via ba-writer:
1. **Application index** (`{docs_dir}/{appKebab}/index.json`) with modules list
2. **Module directories** created as `{docs_dir}/{appKebab}/{moduleKebab}/`
3. **Each module's anticipated sections** as `anticipatedSections` in module data

> **ba-006 path pattern:** `docs/{projectSlug}/v{X.Y}/{appKebab}/{moduleKebab}/`
> No `business-analyse/` intermediate directory.

### Data written

```json
{
  "applications": [
    { "code": "HumanResources", "name": "Ressources Humaines", "route": "/hr", "modules": ["Employees", "Absences"] }
  ],
  "modules": [
    {
      "code": "Employees",
      "applicationCode": "HumanResources",
      "name": "Employés",
      "featureType": "data-centric",
      "entities": ["Employee", "Contract"],
      "anticipatedSections": [
        { "code": "list", "label": "Liste", "sectionType": "primary", "permissionMode": "crud", "resources": [{ "code": "employees-grid", "type": "SmartTable" }] },
        { "code": "detail", "label": "Fiche", "sectionType": "view", "permissionMode": "inherit", "parentSectionCode": "list", "resources": [{ "code": "employee-form", "type": "SmartForm" }] }
      ]
    }
  ],
  "dependencies": [
    { "from": "Absences", "to": "Employees", "description": "Une absence référence un employé" }
  ]
}
```

## Status Update

After writing the structure, update the application status:
```javascript
ba-writer.updateStatus({feature_id}, "decomposed")
```

## Transition

→ Step 03 (specify) — Sequential module specification
