---
name: step-01-analyze
description: Explore existing code to understand what exists — do NOT plan yet
model: opus
prev_step: steps/step-00-init.md
next_step: steps/step-02-plan.md
---

# Step 1: Analyze

**Goal:** Understand what EXISTS in the codebase. Pure exploration, NO planning.

## LOAD CONDITIONALLY

- **ALWAYS** read `references/smartstack-api.md` — BaseEntity API, entity/config/controller patterns
- If NOT `{economy_mode}`: read `references/agent-teams-protocol.md`

---

## 0. Fresh Project Detection (Early Exit)

```
IF .smartstack/init-state.json exists:
  Read it → check if project was recently initialized
  Glob("src/**/Entities/**/*.cs") → count entity files

  IF entity count == 0 AND no PRD AND no feature.json:
    → SKIP full code exploration (sections 2-3)
    → Declare: "Fresh project — all elements need to be CREATED"
    → Jump directly to section 4 (Gap Analysis) with all items marked "create"
```

This saves ~2 minutes of Glob searches on an empty project.

---

## 0b. Delegate Mode Fast Path (if delegate_mode)

> **When called via `/ralph-loop -d`, PRD tasks provide pre-computed scope. Reduce exploration to verification only.**

```
IF delegate_mode:
  Read PRD from {delegate_prd_path} (already loaded in step-00)

  1. Extract entity list from domain tasks:
     entities[] = prd.tasks.filter(category == 'domain').map(entity name from description)

  2. Extract FK relationships from frontend tasks with _frontendMeta:
     fkFields[] = _frontendMeta.fkFields[] (e.g., ["DepartmentId→Department", "CompanyId→Company"])

  3. Determine tenant modes per entity:
     IF feature.json exists at {feature_path}:
       Read entity definitions → extract tenantMode per entity
     ELSE:
       Default all entities to tenantMode: "strict"

  4. Read feature.json for wireframes/componentMapping if {feature_path} exists:
     → enriches frontend generation in step-03

  5. Perform LIGHTWEIGHT code exploration (verification only):
     - Glob("**/Domain/Entities/**/{module_code}/**/*.cs") → what already exists?
     - Glob("**/Infrastructure/Persistence/Seeding/Data/**/*SeedData*.cs") → existing seed data?
     - Glob("src/pages/**/{module_code}/**/*.tsx") → existing pages?
     → Only to determine create vs modify vs skip (NOT deep analysis)

  6. Gap Analysis: Mark all PRD tasks as "create" unless existing code found

  SKIP: Full Agent Teams exploration (section 2), challenge question follow-up
  Jump to section 5 (Gap Analysis summary) → section 7 (Analysis Summary)
```

---

## 1. Context Sources

Read available context (in order of priority):

| Source | Action |
|--------|--------|
| PRD (`{prd_path}`) | Extract: filesToCreate, brToCodeMapping, permissionMatrix, acceptance criteria |
| Feature.json (`{feature_path}`) | Extract: module structure, business rules, entity definitions, permissions |
| Task description only | Rely on task description and code exploration |

---

## 2. Code Exploration

### If economy_mode: Direct Tools

```
Backend:
- Glob("**/Domain/Entities/**/{module_code}/**/*.cs")
- Glob("**/Infrastructure/Persistence/Configurations/**/{module_code}/**/*.cs")
- Glob("**/Application/Services/**/{module_code}/**/*.cs")
- Glob("**/Api/Controllers/**/*{module_code}*Controller.cs")
- Glob("**/Infrastructure/Persistence/Seeding/Data/{module_code}/**/*.cs")

Frontend:
- Glob("src/pages/**/{module_code}/**/*.tsx")
- Glob("src/components/**/{module_code}/**/*.tsx")

MCP:
- mcp__smartstack__api_docs → existing API surface
- mcp__smartstack__analyze_extension_points → React extension points
```

### If NOT economy_mode: Agent Teams

> **Protocol:** See `references/agent-teams-protocol.md`

```
TeamCreate("apex-analyze", description: "Scan SmartStack project for existing code")

Spawn 3 teammates (subagent_type: "Explore", model: "sonnet"):

1. scan-backend:
   "Scan backend for module {module_code}: entities, EF configs, services,
    DTOs, validators, controllers in Domain/ + Infrastructure/ + Application/ + Api/"

2. scan-frontend:
   "Scan frontend for module {module_code}: pages, components, hooks,
    i18n files, route definitions in src/pages/ + src/components/ + src/locales/"

3. scan-context:
   "Read context artifacts for module {module_code}: .ralph/prd-{module_code}.json,
    docs/business/**/feature.json → extract sections, entities, rules, permissions, ACs"

Wait for all 3 → aggregate results → shutdown → TeamDelete("apex-analyze")
```

---

## 3. Seed Data Inventory

```
Glob("**/Seeding/Data/{module_code}/*SeedData.cs")
Glob("**/Seeding/*SeedDataProvider.cs")
```

Identify: NavigationModuleSeedData, PermissionsSeedData, RolesSeedData, SeedConstants, IClientSeedDataProvider (+ DI registration).

---

## 4. FK Field Detection

For each entity found (or to be created), identify FK relationships:
- Properties ending in "Id" with matching navigation property
- Record: `{ entity, fkProperty, targetEntity, isRequired }`

**Why:** FK fields drive two critical requirements:
1. **Frontend:** Each FK field MUST use `<EntityLookup />` (NEVER `<input>`, NEVER `<select>` — even with API-loaded options)
2. **Backend:** Each target entity's GetAll MUST support `?search=` parameter + return `PaginatedResult<T>`

---

## 4a. Tenant Mode Decision

For each entity found (or to be created), determine the `tenantMode`:

- **`strict`** (default) — Data belongs to a specific tenant. Examples: Employee, Order, Invoice, CustomerInteraction
- **`optional`** — Data can be shared across tenants OR tenant-specific. Examples: Department, Currency, JobTitle, Language
- **`scoped`** — Data has explicit visibility scope controlled by workflow/feature rules. Examples: Settings, Workflow, EmailTemplate, ApprovalConfig
- **`none`** — Platform-wide data (never tenant-filtered). Examples: Navigation, Permission, User, SystemConfiguration

**Why:** Tenant mode drives EF query filters, seed data generation, and API access control. Must be decided before planning.

**Reference:** See `references/smartstack-api.md` for TenantId handling patterns and `smartstack-layers.md` for seed data strategies per tenant mode.

---

## 4b. Code Pattern Detection

For each entity found (or to be created), identify code generation needs:

```
IF feature.json exists AND entity has codePattern:
  → Use codePattern config from feature.json (strategy, prefix, digits, etc.)
  → Record in analysis: entity has auto-generated code

ELSE IF feature.json exists BUT entity has NO codePattern:
  → Record: entity needs codePattern decision in step-02
  → Apply heuristic default based on entity name:
    Invoice/Order/Receipt → timestamp-daily
    Ticket/Incident → timestamp-minute
    Contract/Policy → year-sequential
    Reference/Category → uuid-short
    Employee/Customer/Project → sequential

ELSE (no feature.json):
  → Propose codePattern during step-02 planning based on task description
```

**Why:** Code generation strategy drives CreateDto structure (Code field removed when auto-generated), service injection (ICodeGenerator<T>), and DI registration. Must be decided before planning.

**Reference:** See `references/code-generation.md` for strategy table, volume-to-digits calculation, and backend patterns.

---

## 5. Gap Analysis

Compare what EXISTS vs what the TASK REQUIRES:

```
For each element: EXISTS+COMPLETE → "skip" | EXISTS+INCOMPLETE → "modify" | MISSING → "create"
```

Cross-reference with step-00 challenge responses:
- Each entity: entity, EF config, service, controller, frontend pages → exists/missing
- Each section: NavigationSectionSeedData, frontend route → exists/missing
- If dependencies: verify FK target entities and their `?search=` support

---

## 6. Analysis Validation (User Checkpoint)

> **Objective:** Present findings and validate scope with the user BEFORE planning.

### 6a. Present Findings

```
ANALYSIS FINDINGS
═══════════════════════════════════════════════════════════════

Entities expected / found / to create: {summary}
Sections expected / found / to create: {summary}
FK Relationships: {fkFields summary}
Dependencies: {cross-module refs or "none"}
Complexity: {module_complexity}
```

### 6b. Validate with User (if NOT auto_mode)

```yaml
questions:
  - header: "Scope"
    question: "Based on the analysis above, is the scope accurate?"
    options:
      - label: "Scope is correct (Recommended)"
        description: "Proceed to planning with the identified elements"
      - label: "Add elements"
        description: "I need to add entities, properties, or sections"
      - label: "Reduce scope"
        description: "Remove some elements — smaller first iteration"
      - label: "Change approach"
        description: "The analysis reveals issues — let's adjust"
    multiSelect: false
```

If "Add elements": update `{entities}`, `{sections}`, `{key_properties}`, re-run gap analysis.
If "Reduce scope": update variables accordingly.
If "Change approach": discuss with user, potentially restart from step-00.

---

## 7. Analysis Summary

```
**APEX SmartStack - Analysis Complete**
Navigation: {context_code} → {app_name} → {module_code} → {sections[].code}
Entities: {entity_name → create | modify | skip}
Existing: entities, configs, services, controllers, pages, seed data, tests (with paths)
Required: create / modify / skip lists
Profile: complexity, dependencies, FK fields, workflow, notifications
ACs: AC1..ACn (inferred from PRD/feature/task/challenge)
```

---

## 8. Save Output (if save_mode)

Write to `{output_dir}/01-analyze.md` with analysis results.

---

## NEXT STEP

Load `steps/step-02-plan.md`
