Skip to main content

AI Audit Fetch Endpoints Implementation Plan

For Claude: REQUIRED SUB-SKILL: Use superpowers-extended-cc:executing-plans to implement this plan task-by-task.

Goal: Register and test the two AI Audit fetch endpoints — GET /audit/transformers/:id/ai-audit/installations (tagging table) and GET /audit/transformers/:id/ai-audit/remarks (remarks table).

Architecture: Both controllers already exist (fetchAiAuditInstallations.js, fetchAiAuditRemarks.js) — they read from the ai-audit-installation staging collection created by the Run AI Audit endpoint. This plan covers route registration, Bruno API client files, and live testing against seed data on Atlas.

Tech Stack: Fastify v5 (ESM), Mongoose, MongoDB Atlas, Bruno API client


Task 0: Review existing controllers against LLD

Files:

  • Review: api/src/entities/audit/controller/fetchAiAuditInstallations.js
  • Review: api/src/entities/audit/controller/fetchAiAuditRemarks.js
  • Reference: docs/api/LLD-ai-audit-fetch.md

Step 1: Verify fetchAiAuditInstallations.js matches LLD

Cross-check these items:

  • Imports: aiAuditResultModel, aiAuditInstallationModel, baseUserModel
  • Default month: dayjs().format("YYYY-MM")
  • Find AI audit result: findOne({ tcId: id, month })
  • AE section validation: checks aiAuditResult.location.sectionCode vs user.location.sectionCode
  • Filter mapping: ALL (no filter), CHANGES_SUGGESTED ({ $in: ["TAG", "UNTAG"] }), NO_CHANGES_REQUIRED ("NO_CHANGE")
  • Search: $regex with escapeRegex
  • Projection: excludes internal fields (_id, __v, createdAt, updatedAt, aiAuditResultId, tcId, month) + remarks fields (hasRemark, remarkType, avgConsumption6Months, aiSuggestsConsumption) + billing flags
  • Sort: { distanceFromTC: 1 } (closest first)
  • $facet for filter counts: all / changesSuggested / noChangesRequired
  • Pagination: page, limit, totalDocs, totalPages
  • Handler/Schema/Config exports follow existing pattern
  • Route config: { action: "read", resource: "audit" }

Step 2: Verify fetchAiAuditRemarks.js matches LLD

Cross-check these items:

  • Same auth + AE validation pattern as installations endpoint
  • Base filter: { aiAuditResultId, hasRemark: true } (always)
  • Filter enum: ALL, UNBILLED, MNR, VACANT, ZERO_CONSUMPTION, DOORLOCK, ABNORMAL, SUBNORMAL
  • Filter mapping: when not ALL, sets filter.remarkType = filterParam
  • Projection: excludes internal fields + GPS fields (gpsCoordinates, distanceFromTC) + source TC fields (sourceTcId, sourceTcNumber) + billing flags + hasRemark (redundant)
  • Sort: { remarkType: 1, rrNumber: 1 } (group by remark, then RR number)
  • $facet for 8 remark counts: all, unbilled, mnr, vacant, zeroConsumption, doorlock, abnormal, subnormal
  • Response serialization includes withinRange, currentTaggingStatus, aiSuggestion for frontend graying
  • Handler/Schema/Config exports follow existing pattern

Step 3: Confirm — both controllers are LLD-complete, move to next task

No code changes needed — controllers are ready.


Task 1: Register routes in audit.route.v1.js

Files:

  • Modify: api/src/entities/audit/audit.route.v1.js

Step 1: Add imports for both controllers

Add after the existing aiAuditTC import (line 37):

import {
fetchAiAuditInstallationsHandler,
fetchAiAuditInstallationsSchema,
fetchAiAuditInstallationsConfig,
} from "./controller/fetchAiAuditInstallations.js";

import {
fetchAiAuditRemarksHandler,
fetchAiAuditRemarksSchema,
fetchAiAuditRemarksConfig,
} from "./controller/fetchAiAuditRemarks.js";

Step 2: Add route entries to the returned array

Add after the POST /audit/transformers/:id/ai-audit entry (after line 94):

{
method: "GET",
url: "/audit/transformers/:id/ai-audit/installations",
schema: fetchAiAuditInstallationsSchema,
handler: fetchAiAuditInstallationsHandler,
config: fetchAiAuditInstallationsConfig,
},
{
method: "GET",
url: "/audit/transformers/:id/ai-audit/remarks",
schema: fetchAiAuditRemarksSchema,
handler: fetchAiAuditRemarksHandler,
config: fetchAiAuditRemarksConfig,
},

Step 3: Verify — run the API server and confirm routes register

yarn api-dev:pretty

Look for log lines showing /dtcea-mumbai-demo/v1/audit/transformers/:id/ai-audit/installations and /dtcea-mumbai-demo/v1/audit/transformers/:id/ai-audit/remarks in the startup output.


Task 2: Create Bruno files for AI Audit Fetch Installations

Files:

  • Create: bruno/AI Audit/TC/AI Audit Fetch/AE - Fetch AI Audit Installations.bru
  • Create: bruno/AI Audit/TC/AI Audit Fetch/CIO - Fetch AI Audit Installations.bru

Step 1: Create AE request file

meta {
name: AE - Fetch AI Audit Installations
type: http
seq: 1
}

get {
url: {{BASE_URL}}/dtcea-mumbai-demo/v1/audit/transformers/:id/ai-audit/installations?month=2025-10
body: none
auth: bearer
}

params:query {
month: 2025-10
}

params:path {
id: TC-01
}

auth:bearer {
token: {{AE_SESSION}}
}

Step 2: Create CIO request file

meta {
name: CIO - Fetch AI Audit Installations
type: http
seq: 2
}

get {
url: {{BASE_URL}}/dtcea-mumbai-demo/v1/audit/transformers/:id/ai-audit/installations?month=2025-10
body: none
auth: bearer
}

params:query {
month: 2025-10
}

params:path {
id: TC-01
}

auth:bearer {
token: {{CIO_SESSION}}
}

Task 3: Create Bruno files for AI Audit Fetch Remarks

Files:

  • Create: bruno/AI Audit/TC/AI Audit Fetch/AE - Fetch AI Audit Remarks.bru
  • Create: bruno/AI Audit/TC/AI Audit Fetch/CIO - Fetch AI Audit Remarks.bru

Step 1: Create AE request file

meta {
name: AE - Fetch AI Audit Remarks
type: http
seq: 3
}

get {
url: {{BASE_URL}}/dtcea-mumbai-demo/v1/audit/transformers/:id/ai-audit/remarks?month=2025-10
body: none
auth: bearer
}

params:query {
month: 2025-10
}

params:path {
id: TC-01
}

auth:bearer {
token: {{AE_SESSION}}
}

Step 2: Create CIO request file

meta {
name: CIO - Fetch AI Audit Remarks
type: http
seq: 4
}

get {
url: {{BASE_URL}}/dtcea-mumbai-demo/v1/audit/transformers/:id/ai-audit/remarks?month=2025-10
body: none
auth: bearer
}

params:query {
month: 2025-10
}

params:path {
id: TC-01
}

auth:bearer {
token: {{CIO_SESSION}}
}

Task 4: Test — Fetch AI Audit Installations endpoint

Pre-requisite: AI Audit Run must have been executed on TC-01 for month 2025-10 (already done in previous session — data exists in Atlas).

Step 1: Start the API server

yarn api-dev:pretty

Step 2: Test default (ALL filter) via Bruno

Run: AE - Fetch AI Audit Installations in Bruno

Expected response (200):

  • data.installations — array of installation objects with accountId, rrNumber, consumerName, gpsCoordinates, distanceFromTC, withinRange, currentTaggingStatus, aiSuggestion
  • data.pagination{ page: 1, limit: 10, totalDocs: N, totalPages: M }
  • data.filterCounts{ all: N, changesSuggested: X, noChangesRequired: Y } where X + Y = N
  • Installations sorted by distanceFromTC ascending (closest first)
  • No remarks fields (remarkType, avgConsumption6Months, aiSuggestsConsumption should be absent)

Step 3: Test CHANGES_SUGGESTED filter

In Bruno, add &filter=CHANGES_SUGGESTED to the query string.

Expected:

  • Only installations with aiSuggestion of TAG or UNTAG
  • totalDocs should match filterCounts.changesSuggested

Step 4: Test search parameter

Add &search=RR to the query string.

Expected:

  • Only installations whose rrNumber contains "RR" (case-insensitive)
  • Filter counts reflect the search-filtered subset

Step 5: Test 404 — AI audit not run

Change :id to a TC that hasn't had AI audit run (e.g., NONEXISTENT).

Expected: 404 — "AI audit result not found"


Task 5: Test — Fetch AI Audit Remarks endpoint

Step 1: Test default (ALL filter) via Bruno

Run: AE - Fetch AI Audit Remarks in Bruno

Expected response (200):

  • data.installations — only installations with remarks (remarkType present on every item)
  • Each installation has remarkType, avgConsumption6Months, aiSuggestsConsumption, consumption, withinRange, currentTaggingStatus, aiSuggestion
  • No GPS fields (gpsCoordinates, distanceFromTC should be absent)
  • data.filterCounts — 8 remark type counts, all = sum of individual counts
  • Sorted by remarkType then rrNumber

Step 2: Test specific remark filter

Add &filter=MNR to the query string.

Expected:

  • Only installations with remarkType: "MNR"
  • totalDocs should match filterCounts.mnr

Step 3: Test empty remark type

Add &filter=ABNORMAL (or a type with 0 count).

Expected:

  • Empty installations array
  • totalDocs: 0, totalPages: 0

Task 6: Update scope tracker

Files:

  • Modify: docs/scope.md

Step 1: Update API Quick Reference table

Change status for both endpoints from Not started to Done:

| GET | `/audit/transformers/:id/ai-audit/installations` | [LLD](api/LLD-ai-audit-fetch.md) | Done |
| GET | `/audit/transformers/:id/ai-audit/remarks` | [LLD](api/LLD-ai-audit-fetch.md) | Done |

Step 2: Move Section 11 from Remaining to Completed

Move "AI Audit — Fetch Installations + Remarks" from ## Remaining to ## Completed and mark as Done.

Step 3: Update progress summary

Update the counts:

  • Completed endpoints: 17 → 19
  • New endpoints remaining: 3 → 1 (only freeze left)

Task 7: Commit

Step 1: Stage and commit (ask user first!)

git add api/src/entities/audit/audit.route.v1.js \
api/src/entities/audit/controller/fetchAiAuditInstallations.js \
api/src/entities/audit/controller/fetchAiAuditRemarks.js \
"bruno/AI Audit/TC/AI Audit Fetch/" \
docs/scope.md

git commit -m "feat: add AI audit fetch endpoints (installations tagging + remarks)"