# Multi-App Detection Algorithm

> **Purpose:** Detect and extract multiple applications from user prompts using a two-tier approach.
> Executed early in initialization to determine `workflow_mode` ("application" vs "project").

## Overview

When the user's prompt describes multiple applications or spans multiple business domains, we must recognize this immediately and set `workflow.mode = "project"` to avoid doing cadrage for a single app.

## Tier 1 — Explicit Patterns (ANY match = multi-app detected)

### French patterns:
- "une application X ... une application Y" (two occurrences of "une application")
- "application 1: X ... application 2: Y" (numbered applications)
- "première application ... deuxième application"
- "app 1: ... app 2: ..."

### English patterns:
- "an application (for) X ... an application (for) Y" (two occurrences)
- "application #1: ... application #2: ..." (numbered)
- "first app ... second app"

### Decision:

If ANY of these patterns is found in `{feature_description}`:
→ `isMultiApp = true`, `detectionTier = "explicit"`

## Tier 2 — Domain Diversity Analysis (when Tier 1 does not match)

### Definition

A "domain" is an autonomous business perimeter with its own entities and processes (e.g., HR, CRM, Finance, Projects, Sales, Inventory).

### Algorithm

ULTRATHINK: Analyze `{feature_description}` to extract distinct business domains.

1. List all business domains mentioned or implied in the description
2. Classify each domain:
   - **DISTINCT** — has its own entities, processes, and lifecycle (e.g., HR vs CRM)
   - **RELATED** — is a sub-domain of another (e.g., Payroll is a sub-domain of HR)
3. Count DISTINCT domains only

### Threshold

2+ DISTINCT domains → `isMultiApp = true`, `detectionTier = "domain-diversity"`

### False Positive Protection

- "RH complet avec employés, congés, paie, pointage" = 1 domain (HR) with 4 modules, NOT 4 domains
- "HR and Payroll management" = 1 domain (HR) with 2 modules — Payroll is RELATED to HR
- "gestion commerciale avec devis, commandes et facturation" = 1 domain (Sales) with 3 modules
- Only count as DISTINCT when domains have genuinely independent entity models and processes

## Extraction Algorithm (depends on detection tier)

### IF Tier 1 (explicit):

1. **Identify boundaries:** Split the prompt at each "une application" / "an application" occurrence. Each block = one candidate.
2. **Extract per candidate:** For each block, derive `name` (application name), `description` (summary of purpose), and `modules[]` (listed modules/features).
   - Example: `[{ name: "RH", description: "gestion des employés, congés, temps", modules: ["Employés", "Congés", "Temps"] }, ...]`
3. **Detect shared modules:** Collect all module names across all candidates. Any module appearing in more than one candidate is a shared module.
   - Example: `sharedModules = ["Temps"]` (appears in both RH and Projet)

### IF Tier 2 (domain-diversity):

1. Each DISTINCT domain = 1 candidate application:
   - `name` = short domain label (e.g., "RH", "CRM", "Finance")
   - `description` = user's expressed need for that domain
   - `modules[]` = sub-functionalities mentioned (can be empty → "(à définir au cadrage)")
2. Group RELATED sub-domains under their parent DISTINCT domain as modules
3. **Detect shared modules:** Same logic as Tier 1 — modules appearing in multiple candidates

## Confirmation Dialogue

Display detection result:

```
{detectionTier == "explicit"
  ? (language == "fr"
    ? "### Détection multi-application\n\nJ'ai détecté **{candidates.length} applications** dans votre description :"
    : "### Multi-application detection\n\nI detected **{candidates.length} applications** in your description:")
  : (language == "fr"
    ? "### Détection multi-application\n\nVotre description couvre **{candidates.length} domaines métier distincts**. Chaque domaine pourrait constituer une application séparée :"
    : "### Multi-application detection\n\nYour description covers **{candidates.length} distinct business domains**. Each domain could be a separate application:")}

| # | Application | Modules identifiés |
|---|-------------|-------------------|
{for each candidate: index | name | modules.join(", ") || "(à définir au cadrage)"}

{sharedModules.length > 0
  ? "⚠️ **Modules partagés détectés :** {sharedModules.join(', ')} — ces modules apparaissent dans plusieurs applications. Ils pourraient constituer une application transversale dédiée."
  : ""}
```

### AskUserQuestion Options

```
question: "{language == 'fr' ? 'Confirmez-vous cette structure multi-application ?' : 'Do you confirm this multi-application structure?'}"
header: "Architecture"
options:
  - label: "{language == 'fr' ? 'Oui, {candidates.length} applications' : 'Yes, {candidates.length} applications'}"
    description: "{language == 'fr' ? 'Créer un projet avec les applications identifiées' : 'Create a project with the identified applications'}"
  - label: "{language == 'fr' ? 'Extraire les modules partagés' : 'Extract shared modules'}" (only if sharedModules.length > 0)
    description: "{language == 'fr' ? 'Créer une application dédiée pour {sharedModules.join(', ')} ({candidates.length + 1} applications au total)' : 'Create a dedicated app for {sharedModules.join(', ')} ({candidates.length + 1} total)'}"
  - label: "{language == 'fr' ? 'Regrouper certains domaines' : 'Regroup some domains'}" (only if detectionTier == "domain-diversity")
    description: "{language == 'fr' ? 'Fusionner des domaines en moins d\\'applications' : 'Merge domains into fewer applications'}"
  - label: "{language == 'fr' ? 'Application unique' : 'Single application'}"
    description: "{language == 'fr' ? 'Tout regrouper en une seule application avec plusieurs modules' : 'Group everything into one application with multiple modules'}"
```

## Handling User Responses

### IF "Oui, N applications" or "Extraire les modules partagés":

```yaml
workflow_mode: "project"
project_name: derived from feature_description
candidate_applications: [{ name, description, modules, context }]
shared_modules_extracted: boolean  # true if user chose extraction
```

→ Skip step 4 (application name) — applications will be confirmed in step-01-cadrage
→ Continue to step 5 (language selection)

### IF "Regrouper certains domaines" (Tier 2 only):

Ask via AskUserQuestion:
```
question: "{language == 'fr' ? 'Comment souhaitez-vous regrouper ces domaines ? (ex: \"RH + Paie ensemble, CRM seul\")' : 'How would you like to regroup these domains? (e.g., \"HR + Payroll together, CRM alone\")'}"
header: "Regroupement"
```

Process user response:
1. Parse the grouping instructions (natural language)
2. Rebuild `candidate_applications` based on the specified groups
3. Re-display the confirmation dialogue with the updated candidates

### IF "Application unique":

```yaml
workflow_mode: "application"
```

→ Continue to step 4 normally

### IF no multi-app detected (neither Tier 1 nor Tier 2):

→ Continue to step 4 normally
