# Architecture & visual model

Visual reference for how this repository works. All diagrams render on GitHub.

## 1. Source-of-truth split & end-to-end flow

Requirements live upstream, executable automation lives downstream, and this repo owns the testcase oracle in the middle.

```mermaid
flowchart TB
  subgraph SRC["Requirement — source of truth"]
    TSD["TSD / PRD / Jira"]
  end

  subgraph REPO["staffinc-testcase (this repo) — testcase source of truth"]
    direction TB
    AGENT["AI agent import<br/>reads TSD, maps scenarios"]
    TC["testcases/*.md<br/>draft → active"]
    PRE["preconditions/*.md<br/>composable data + state"]
    FLOW["flows/*.yaml<br/>journeys"]
    SUITE["suites/*.yaml<br/>run selection"]
    IDX["indexes/*.json<br/>generated"]
  end

  subgraph AUTO["staffinc-platform — automation source of truth"]
    SPEC["executable specs<br/>Playwright / Appium / API"]
  end

  TSD --> AGENT --> TC
  TC -->|preconditionRefs| PRE
  FLOW -->|step IDs| TC
  SUITE -->|testcase IDs| TC
  TC -->|generated into| IDX
  TC -. automationRef .-> SPEC
  IDX --> PLAN["agentic planner"]
  PLAN -. selects & runs .-> SPEC

  classDef gen fill:#eef,stroke:#88a;
  class IDX gen;
```

## 2. Artifact relationships (the ID is the glue)

Every artifact points at a permanent testcase **ID**. Preconditions, flows, suites, and indexes reference IDs from the outside, so they never modify testcase files.

```mermaid
flowchart LR
  TSD["TSD PK144<br/>section C1 · scenario C1.6"]
  TC(["testcase<br/>OV-C1-POS-009"])
  PRE["precondition<br/>fragments"]
  FLOW["flow<br/>journey"]
  SUITE["suite<br/>run set"]
  IDX["indexes<br/>(generated)"]
  SPEC["staffinc-platform<br/>spec"]

  TC -->|sourceRefs| TSD
  TC -->|preconditionRefs| PRE
  FLOW -->|steps| TC
  SUITE -->|testcases| TC
  TC -->|build-index| IDX
  TC -->|automationRef| SPEC
```

## 3. Precondition composition (data seed → state → navigation)

A precondition can build on a more foundational one. The data world (channel, form, visitation) must exist before any login/navigation/state. The validator resolves every ref and rejects cycles.

```mermaid
flowchart TB
  CH["PRE-OV-channel-exists<br/>channel + visitation policy"]
  FM["PRE-OV-form-template-assigned<br/>form template + option sets"]
  VIS["PRE-OV-visitation-assigned<br/>PJP / Non-PJP visitation"]
  SEED["PRE-OV-visitation-data-seeded<br/>foundational data bundle"]

  LOGIN["PRE-OV-logged-in-online"]
  DC["PRE-OV-download-center-open"]
  ML["PRE-OV-mode-luring-active"]
  GK["PRE-OV-gagal-kirim-has-items"]

  CH --> FM --> VIS --> SEED
  SEED --> LOGIN
  SEED --> DC
  SEED --> ML
  SEED --> GK

  TCX(["testcase<br/>e.g. OV-C1-POS-009"]) -->|preconditionRefs| DC
```

## 4. Agentic import (TSD → testcases)

How the AI agent turns a TSD into reviewable testcases — the path used for PK144.

```mermaid
flowchart LR
  PDF["TSD PDF"] -->|pdftotext| TXT["importer/examples/*.txt<br/>snapshot (committed)"]
  TXT --> AG["AI agent<br/>parse sections + scenarios"]
  AG --> SPLIT["split multi-branch<br/>POS / NEG / EDGE"]
  SPLIT --> WRITE["write testcases (draft)<br/>+ preconditions + flows"]
  WRITE --> GAP["capture gaps<br/>Testing Concerns / TBD"]
  GAP --> VAL["validate + index"]
  VAL --> PR["PR review"]
  PR --> MERGE["merge to main"]
```

## 5. Testcase lifecycle

`status` (draft/active/deprecated) plus `lifecycleStatus` track maturity. IDs are permanent; replaced behavior is deprecated, never renamed.

```mermaid
stateDiagram-v2
  [*] --> draft: AI import
  draft --> active: QA review passes
  active --> needs_update: behavior changed
  needs_update --> active: content updated
  active --> blocked: dependency blocks
  blocked --> active: unblocked
  active --> deprecated: behavior replaced (supersededBy)
  deprecated --> [*]: removed from active suites & flows
```

## 6. Testcase → automation contract

The testcase is the contract the automation must satisfy. This is where the precondition layers pay off — they define the automation's data setup.

```mermaid
flowchart LR
  subgraph TCC["testcase (oracle, this repo)"]
    P["preconditionRefs<br/>(data seed + state)"]
    S["Steps"]
    E["Expected Result"]
    EV["Evidence Required"]
  end
  subgraph SP["automation spec (staffinc-platform)"]
    F["fixtures / setup<br/>seed channel, form, visitation"]
    A["actions"]
    AS["assertions"]
    AR["captured artifacts"]
  end
  P --> F
  S --> A
  E --> AS
  EV --> AR
```

## 7. Agentic execution pipeline

Once testcases exist, the planner selects and runs automation. Dry-run is the default; only `mapped_existing` runs as completed automation.

```mermaid
flowchart LR
  RR["run-request.json"] --> PLAN["agentic-plan"] --> TP["test-plan.json"]
  TP --> MAP["agentic-map<br/>reuse-first"] --> MC["map-candidates"]
  MC --> EXP["agentic-explore"] --> DR["agentic-draft-automation<br/>(gaps only)"]
  DR --> RUN["agentic-run<br/>dry-run default"] --> ER["execution-result"]
  ER --> JU["agentic-judge"] --> JR["judge-result"]
  JR --> TRI["agentic-triage"] --> OUT["triage-result.md"]
```

## 8. PR validation gates

`npm run testcase:validate` (run in CI) blocks a merge when any of these fail.

```mermaid
flowchart TB
  START["PR opened"] --> C1{"IDs unique<br/>& well-formed?"}
  C1 -->|no| FAIL["❌ fail"]
  C1 -->|yes| C2{"required metadata<br/>& enums valid?"}
  C2 -->|no| FAIL
  C2 -->|yes| C3{"sourceRefs &<br/>automationRef valid?"}
  C3 -->|no| FAIL
  C3 -->|yes| C4{"preconditionRefs<br/>resolve, no cycle?"}
  C4 -->|no| FAIL
  C4 -->|yes| C5{"flows/suites ref<br/>active testcases?"}
  C5 -->|no| FAIL
  C5 -->|yes| C6{"indexes<br/>not stale?"}
  C6 -->|no| FAIL
  C6 -->|yes| PASS["✅ pass — mergeable"]
```
