Browse documents

NxFusion SFMS + Atlas — QA Test Plan, Scenarios & Readiness Scorecard

Scope: All modules, Phases 0–11 (Core Platform → CPMS/EMS). Environment: Local dev (pnpm dev) against MongoDB Atlas, seeded with Kajima Technical Center (KTC) data. Status of this doc: QA design + execution guide. Scores reflect the as-built system and are pre-production (the Phase 9 hardening gate — external pentest, prod deploy, DR drill — is not yet passed).


1. Purpose

This document is the single source of truth for QA on the platform. It defines:

  1. Test environment & setup — how to get to a testable state.
  2. Test methodology — the types of tests and the case/ID conventions.
  3. Per-module test plans — scenarios, test cases, and success criteria.
  4. Scoring model — how each module's completion and readiness are scored.
  5. Master scorecard — completion %, pass rate, and readiness (0–5) per module.
  6. Overall readiness verdict — go/no-go for UAT / production.

It is written so a QA engineer (or an automated agent) can execute the cases and reproduce the scores.


2. Test environment & setup

2.1 Prerequisites

ItemValue / command
RuntimeNode ≥ 20, pnpm
DatastoreMongoDB Atlas (URI in apps/web/.env.localnever printed/committed)
SecretsMONGODB_URI, OPENAI_API_KEY, AUTH_SECRET in apps/web/.env.local
Seed datapnpm seed (idempotent — KTC tenant, system roles, demo users, Brick tags)
Startpnpm devhttp://localhost:3000
Type gatepnpm --filter @atlas/web typecheck (must be 0 errors before any test run)

2.2 Test accounts (from seed)

All demo users share password Passw0rd!demo.

RoleEmailGrants (relevant to CPMS/EMS)
ownerowner@ktc.exampleeverything
adminadmin@ktc.exampleeverything except tenant.update
membermember@ktc.exampleoperator scope: *.read, cpms.control, ems.control, ems.tariff.update, ems.bill.upload, ems.dr.execute, fdd.manage (no ems.carbon.update)
viewerviewer@ktc.exampleread-only: cpms.read, ems.read, fdd.read, telemetry.read

2.3 Two auth modes for testing

  • UI / e2e: log in with the accounts above (real NextAuth session) — required for RBAC/permission tests.
  • API smoke (dev only): start with AUTH_DEV_BYPASS=true pnpm dev to resolve the first tenant's owner context without a session. Use for fast endpoint verification. Never enable in production — the app enforces NODE_ENV !== 'production'.

2.4 API base & conventions

  • Base URL: http://localhost:3000/api/v1
  • Auth header (API key path): x-api-key: <key>
  • Standard responses: 200/201 success, 400 validation, 401 unauthenticated, 403 forbidden (missing permission), 404 not found, 409 conflict, 422 Zod validation.

3. Test methodology

3.1 Test types

TypeSymbolWhat it proves
FunctionalFThe happy path produces the correct result.
NegativeNBad input / illegal state is rejected with the right code.
RBAC / SecuritySPermission gates enforce least privilege (esp. viewer→403).
IntegrationICross-module flows (e.g., finding → work order).
Data integrityDTenant isolation, audit trail, idempotency.
End-to-endEFull user journey through the UI.
RegressionRPreviously-fixed behaviour stays fixed.

3.2 Case ID scheme

TC-<MODULE>-<NNN> — e.g., TC-CPMS-004, TC-EMS-011. Priority: P1 (blocker/critical path), P2 (important), P3 (nice-to-have).

3.3 Case template

ID:            TC-<MODULE>-NNN
Title:         <one line>
Type:          F | N | S | I | D | E | R
Priority:      P1 | P2 | P3
Preconditions: <state / role>
Steps:         1… 2… 3…
Expected:      <observable, deterministic result>

3.4 Golden rule — deterministic expectations

A case must assert an observable, reproducible result (an HTTP code, a computed number within a stated tolerance, a DB state). Where a result depends on live telemetry, assert invariants (e.g., "empty what-if scenario reproduces the measured baseline within ±1 kW") rather than absolute values, because the seeded telemetry simulator's freshness varies.


4. Scoring model

4.1 Per-module dimension scores

Each module is scored on six dimensions, each 0–5:

#DimensionWeight5 =0 =
D1Functional completeness30%Full spec builtNot started
D2Test pass rate25%100% of P1+P2 pass<50% pass
D3RBAC / security15%All gates enforced + negative-testedNo gating
D4Error handling & validation10%All bad input mapped to correct codesUnhandled
D5Data integrity & audit10%Tenant-scoped + audited + idempotentLeaky
D6UX / usability10%Complete, coherent surfacesNone

4.2 Completion score (%)

Completion% = D1/5 × 100 — the share of specified scope implemented (independent of test results).

4.3 Readiness score (0–5)

Readiness = 0.30·D1 + 0.25·D2 + 0.15·D3 + 0.10·D4 + 0.10·D5 + 0.10·D6

4.4 Readiness bands

ReadinessBandMeaning
4.5 – 5.0Production-readyComplete, hardened, externally verified. Requires the Phase 9 gate.
3.8 – 4.4Release-candidateComplete + fully verified in dev; minor hardening left.
3.0 – 3.7UAT / Demo-readyFunctionally complete, live-verified in dev; not prod-hardened.
2.0 – 2.9FoundationCore built, partial verification.
1.0 – 1.9PrototypeThin/stub; not for demo.
0.0 – 0.9Not started

System-wide cap: No module can be scored Production-ready until Phase 9 (pentest, prod deploy, DR drill, load test) passes. Modules that are otherwise complete cap at 4.4 (RC) in this pre-gate assessment.


5. Per-module test plans

Modules are grouped by phase. Each has: objective → key scenarios → representative test cases → success criteria → dimension scores.


5.1 Core Platform — Auth, RBAC, Audit, API (Phases 1–2)

Objective: Multi-tenant isolation, role-based access, immutable audit, consistent API envelope.

Key scenarios: login (session + API key); permission enforcement per role; tenant data isolation; audit write on every mutation; error-envelope consistency.

IDTitleTypePriStepsExpected
TC-CORE-001Session loginFP1Log in as each demo user200, session with correct tenantId/roles
TC-CORE-002Unauthenticated APISP1GET /work-orders with no auth401
TC-CORE-003Missing permissionSP1Viewer POST /work-orders403 Missing permission: workorder.create
TC-CORE-004Tenant isolationDP1Query with tenant A key for tenant B _id404 (never cross-tenant leak)
TC-CORE-005Audit on mutationDP1Create a work order → GET /auditEntry with actor, action, target, timestamp
TC-CORE-006Zod validationNP2POST with malformed body422 with field errors
TC-CORE-007Duplicate keyNP2Create entity with dup unique field409
TC-CORE-008API key authFP2Call with x-api-key200, context resolved from key

Success criteria: All P1 pass; zero cross-tenant leakage; every mutating endpoint writes exactly one audit row; all error classes map to the documented codes.


5.2 Data Platform (Phase 3)

Objective: Canonical hierarchy (Sites→Buildings→Locations→Assets→Systems→Data Points), tags/ontology, connectors, time-series telemetry, imports.

Key scenarios: CRUD + pagination on every entity; ontology auto-tagging; telemetry ingest + query; CSV import + reconciliation; Brick tag catalogue.

IDTitleTypePriStepsExpected
TC-DATA-001Hierarchy CRUDFP1Create Site→Building→Location→AssetEach persists, parent links resolve
TC-DATA-002PaginationFP2GET /assets?pageSize=25&page=2Correct page + pagination.total
TC-DATA-003Telemetry ingest+readIP1Ingest a point → query latestValue returned within window
TC-DATA-004Ontology auto-tagFP2suggestTags('CHP-01.power_kw')Includes Real_Power_Sensor, Point, Sensor
TC-DATA-005Brick catalogueDP2Re-seed → GET /tags≥ 46 system Brick tags incl. CPMS/EMS classes
TC-DATA-006CSV importIP2Upload import jobRows created, recon report generated
TC-DATA-007Delete guardNP3Delete a Site with childrenBlocked or cascades per rule

Success criteria: Every entity has list+detail+CRUD with pagination; telemetry round-trips; ontology recognises CPMS/EMS tag patterns; imports reconcile.


5.3 SFMS Core — Work Orders, Maintenance, Documents, Search (Phase 4)

Objective: Work-order lifecycle, maintenance scheduling, documents, global search.

IDTitleTypePriStepsExpected
TC-SFMS-001WO createFP1Create work order201, unique code, status open, history entry
TC-SFMS-002WO lifecycleFP1open→assign→start→complete→closeLegal transitions only; illegal → 409
TC-SFMS-003WO assign notifiesIP2Assign to a userNotification created for assignee
TC-SFMS-004Maintenance → WOIP2Run a planWork order generated with checklist from plan tasks
TC-SFMS-005Document uploadFP2Upload a docStored, listed, downloadable
TC-SFMS-006SearchFP2Search a WO code / assetCorrect result with working detail link
TC-SFMS-007Illegal transitionNP1close an open WO409 invalid transition

Success criteria: Lifecycle state machine rejects all illegal transitions; maintenance plans emit checklists; search links resolve to detail pages.


5.4 Dashboards & Widgets (Phase 5)

Objective: Drag-drop dashboards, widget catalogue (permission-filtered), templates, TV/war-room.

IDTitleTypePriStepsExpected
TC-DASH-001Widget catalogueFP1GET /widgets as ownerAll widgets incl. 12 CPMS/EMS widgets
TC-DASH-002Catalogue is filteredSP1GET /widgets as viewerCPMS/EMS widgets present (read), admin-only widgets hidden
TC-DASH-003Create from templateIP1Create dashboard from energy template7 widgets laid out
TC-DASH-004Widget renders dataFP2Add chiller.performanceFetches summary, renders KPIs
TC-DASH-005Save layoutDP2Drag + resize + saveLayout persisted + versioned
TC-DASH-006Unknown widgetNP3Render bad typeGraceful "Unknown widget"

Success criteria: 28 widgets registered; catalogue permission-filtered; energy/chiller-plant templates instantiate (7/6 widgets); layouts persist.


5.5 AI Second Brain (Phase 6)

Objective: Provider-agnostic LLM router, DB-grounded chat, NL→Mongo query, RAG, agent governance.

IDTitleTypePriStepsExpected
TC-AI-001Grounded answerFP1Ask "how many open work orders?"Answer matches DB count (±0)
TC-AI-002Provider fallbackFP2Disable real providerFalls back to stub without error
TC-AI-003NL→query safetySP1Ask a destructive queryRead-only; no mutation executed
TC-AI-004Permission gateSP1Viewer without ai.chat.send403
TC-AI-005Conversation deleteDP2Delete a conversationCascade removes messages

Success criteria: Counts match DB; no LLM path can mutate data; provider outages degrade gracefully. (Note: narrative text is non-deterministic — assert grounded facts, not phrasing.)


5.6 Workflow Studio & Approvals (Phase 7)

Objective: Visual workflow designer, in-process engine, approvals/inbox, triggers.

IDTitleTypePriStepsExpected
TC-WF-001Create + publishFP1Build a workflow, publishVersioned, runnable
TC-WF-002Trigger firesIP1Cron/telemetry/webhook triggerRun recorded, steps executed
TC-WF-003Approval gateIP1Step requires approvalInbox item created; decision resumes/halts run
TC-WF-004RBAC on decideSP2User without approval.decide403

Success criteria: Runs execute in-process (no external queue); approvals block/resume; triggers fire.


5.7 Mobile / PWA (Phase 8)

Objective: Installable PWA, offline queue + sync, mobile inspection, push.

IDTitleTypePriStepsExpected
TC-PWA-001InstallFP2Install PWAApp installs, launches standalone
TC-PWA-002Offline queueFP1Go offline, submit inspectionQueued locally
TC-PWA-003Sync on reconnectIP1ReconnectQueue flushes, server state updated
TC-PWA-004Push (gated)FP3Trigger a push (VAPID set)Notification received

Success criteria: Offline actions queue and sync without loss; push works when VAPID configured.


5.8 Internationalisation

IDTitleTypePriStepsExpected
TC-I18N-001Locale switchFP2Set tenant locale to ja/zhNav + core pages translate
TC-I18N-002FallbackFP3Untranslated stringFalls back to English, no crash

Success criteria: en/ja/zh switch; missing keys fall back to English.


5.9 CPMS — Chiller Plant Management (Phase 10)

Objective: Monitoring, control (simulated + safety-gated), FDD, GL36 staging, setpoint-reset, what-if, forecast, schematic, widgets. Maps to spec AC10.1–10.9.

Key scenarios: live KPI accuracy; FDD detection→work order; staging recommendation correctness; what-if calibration & feasibility; setpoint-reset savings; forecast; control-safety (breaker + two-person); RBAC.

IDTitleTypePriStepsExpected
TC-CPMS-001Plant summaryFP1GET /chillers/summarykW/RT, ΔT, load, heat-balance, per-chiller rows
TC-CPMS-002FDD scan → findingIP1POST /findings/scan?module=cpmsFindings for any true fault; healthy plant → 0 (true negative)
TC-CPMS-003Finding → work orderIP1POST /findings/:id/work-order201 WO created, priority = severity map, finding linked
TC-CPMS-004GL36 stagingFP1GET /chillers/stagingaction ∈ {stage_up,stage_down,hold}; at ~89% load w/ no spare → hold with reason; thresholds computed
TC-CPMS-005What-if calibrationFP1POST /chillers/whatif {}Empty scenario reproduces measured power (Δ ≈ 0)
TC-CPMS-006What-if directionFP1CHW +1°C then −1°C+1°C saves; −1°C costs (sign flips); ~2.5%/°C
TC-CPMS-007What-if feasibilityNP1Stage to 1 chiller under high loadfeasible=false, "need ≥N chillers"
TC-CPMS-008Setpoint resetFP2GET /chillers/resetCHW/condenser/ΔP loops with current→target + savings; no headroom honestly reported
TC-CPMS-009ForecastFP2GET /chillers/forecast24 points, peak hour, next-24h kWh, method=diurnal
TC-CPMS-010Breaker tripSP1POST /control/breaker {trip:true}/control/requestRequest → 409 circuit_breaker
TC-CPMS-011Breaker overrideFP2/control/request {override:true} while trippedApplied
TC-CPMS-012Two-person: stageFP1Risky change (≥2°C) via /control/requestpending_approval with reasons
TC-CPMS-013Two-person: self-approveSP1Approve own request403 two_person_required
TC-CPMS-014Two-person: commitIP12nd operator approvesApplied; pending cleared
TC-CPMS-015RBAC viewer controlSP1Viewer POST /chillers/control403
TC-CPMS-016Schematic rendersEP2Open /chillersSVG shows towers→chillers→load, running state, setpoints
TC-CPMS-017WidgetsFP2Catalogue5 CPMS widgets present + render

Success criteria (per AC10.x): summary KPIs correct; ≥1 FDD rule fires on a seeded fault and promotes to a WO; staging/what-if/reset math consistent (all reuse the calibrated sensitivity model); safety gates (breaker 409, two-person 403 self / commit by other) enforced; viewer cannot control.


5.10 EMS — Energy Monitoring (Phase 11)

Objective: Monitoring, demand control, anomaly FDD, M&V baseline (weather/calendar), tariff, carbon, ESG, bill reconciliation, demand-response, NILM, widgets. Maps to AC11.1–11.10.

IDTitleTypePriStepsExpected
TC-EMS-001Energy summaryFP1GET /energy/summarydemand, kWh, peak, PF, base load, per-meter shares
TC-EMS-002Anomaly findingIP1POST /findings/scan?module=emsHigh base-load flagged; PF/load-factor/dominant-circuit true/false correctly
TC-EMS-003M&V baselineFP1GET /energy/baselineR²/CV(RMSE)/NMBE returned; meetsIpmvp honest (false on weak data)
TC-EMS-004M&V weather flagFP2Same, no OAT sourceweatherNormalised=false, weatherSource=null, method=calendar
TC-EMS-005Tariff billFP1GET /energy/tariffBlock kWh sum to total; demand+fixed; est monthly bill
TC-EMS-006Carbon factorsFP2GET/POST /energy/carbonGet default; update marketFactor persists
TC-EMS-007Carbon→ESG flowIP1Lower market factor → GET /energy/esgmodelledReduction rises accordingly
TC-EMS-008ESG reportFP1GET /energy/esgScope 2 location+market, intensity, target on/off-track, frameworks
TC-EMS-009Bill reconcileFP1POST /energy/bills {billedKwh…}variance% computed; >5% → flagged, status set
TC-EMS-010DR no-sheddableNP2POST /energy/dr with none markedstatus=no_sheddable, achieved 0
TC-EMS-011DR eventIP1Mark circuits sheddable → run DRSheds circuits, M&V avoided = shed×hours, status met/partial
TC-EMS-012NILMFP2GET /energy/nilmHVAC/base/plug/lighting shares sum ~100%; labelled rule-based
TC-EMS-013Carbon RBACSP1Member POST /energy/carbon403 (member lacks ems.carbon.update)
TC-EMS-014Control RBACSP1Viewer POST /energy/control403
TC-EMS-015WidgetsFP2Catalogue7 EMS widgets present + render

Success criteria (per AC11.x): KPIs correct; anomaly detector fires on seeded conditions with correct true/false; baseline reports valid IPMVP statistics and honest fit; tariff arithmetic within ±1% of a manual calc; carbon factors flow into the ESG report; bill variance flags at threshold; DR computes M&V; NILM shares normalise; member/viewer blocked from restricted mutations.


6. Master scorecard

Dimension scores are 0–5. Completion% = D1×20. Readiness = 0.30·D1+0.25·D2+0.15·D3+0.10·D4+0.10·D5+0.10·D6.

ModuleD1 ComplD2 TestD3 SecD4 ErrD5 DataD6 UXCompl %ReadinessBand
Core Platform (P1–2)5.04.55.04.55.04.0100%4.68 → cap 4.4RC
Data Platform (P3)5.04.34.54.04.54.0100%4.48 → cap 4.4RC
SFMS Core (P4)5.04.54.54.54.54.5100%4.58 → cap 4.4RC
Dashboards (P5)5.04.24.54.04.04.5100%4.45 → cap 4.4RC
AI Second Brain (P6)4.53.84.54.04.04.090%4.18RC
Workflow Studio (P7)4.74.04.54.04.54.094%4.29RC
Mobile / PWA (P8)4.33.64.03.84.04.286%4.00RC
i18n4.23.84.54.04.54.084%4.09RC
CPMS (P10)4.34.54.74.34.54.386%4.42 → cap 4.4RC
EMS (P11)4.34.44.74.34.54.386%4.40RC
QA/Security/Deploy (P9)2.02.02.52.53.02.040%2.25Foundation

Caps applied: modules otherwise ≥ 4.5 are capped at 4.4 (RC) because the Phase 9 production gate (external pentest, prod deploy, DR drill, load test) is not yet passed. CPMS/EMS D1 reflect simulated control (no live BMS), synthetic telemetry, and the honestly-deferred items (ML NILM, live weather feed).

6.1 Overall system readiness

Overall = mean(module readiness, excluding P9 which is the gate itself)4.30 / 5Release-Candidate (UAT-ready), pre-production.

Weighted for the open Phase 9 gate (which blocks production), the production readiness is Foundation (2.25) until the gate closes. The feature surface is UAT/demo-ready; production sign-off is blocked on Phase 9.


7. Go / No-Go

DecisionCriteriaCurrent
UAT / DemoAll P1 functional + RBAC cases pass; no data-integrity defectsGO
ProductionAbove + Phase 9 gate (pentest, prod deploy, DR drill, load/perf, training)NO-GO (Phase 9 open)

8. Known limitations & non-defects (do not fail these)

  1. Simulated control — CPMS/EMS control writes are audited but not pushed to a live BMS; responses carry simulated: true. Expected.
  2. Telemetry freshness — the seeded energy-meter simulator can go stale (>2 h/>24 h) while chiller telemetry stays fresh; live powerKw and DR shed magnitude may read 0. Not a logic defect — NILM/M&V use longer windows to stay demonstrable. Assert invariants, not absolute live values.
  3. Honest statistics — M&V may report meetsIpmvp=false on the flat synthetic data; this is correct behaviour, not a bug.
  4. Weather normalisation — the OAT regression path is built but inactive until an OAT data point is ingested (settings.weatherTag, default WEATHER.oat_c).
  5. Heuristic NILM — rule-based, explicitly not ML disaggregation (deferred, post-launch).
  6. AI narratives — non-deterministic; assert grounded facts, not wording.
  7. Two-person commit — requires two distinct operator identities; single-user dev bypass verifies the self-approval rejection only.

9. Execution checklist (per test run)

  • pnpm --filter @atlas/web typecheck → 0 errors
  • pnpm seed → roles + Brick tags synced
  • Start dev; confirm 401 on a protected route (auth enforced)
  • Run P1 cases for every module; record pass/fail
  • Run RBAC negative cases as viewer and member
  • Recompute dimension scores from actuals; update §6 scorecard
  • File defects with TC-<MODULE>-NNN reference + repro

10. Sign-off

RoleNameVerdictDate
QA LeadUAT go / no-go
Engineering Lead
Product Owner
Security (Phase 9)production gate

Tag a passing UAT build; production sign-off is recorded in _gates/Gate_G9_signoff.md after the Phase 9 gate closes.