Skip to content

admin-service Agent Tasks

Agent workflow: follow README.md for Audit -> Investigate -> Code -> Test -> Fix; keep this pack's writable scope and verification commands authoritative.

Dispatch type: per-service

Dispatch ID: SVC-023

Current implementation: services/admin-service.

Owns: feature maintenance state, admin compatibility read models, moderation workflows, operational dashboard projections, and temporary admin audit compatibility until audit-service route migration is explicit.

Must read:

  • docs/agents/handoff-phase-9-admin-foundation.md
  • legacy admin/support modules: /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/admin/feature-maintenance.service.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/admin/operations.controller.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/admin/admin-dashboard.controller.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/admin/inbox.controller.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/support/support.service.ts, /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/common/feature-maintenance.guard.ts.

Legacy source evidence:

  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/admin/**
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/modules/support/**
  • /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/src/common/feature-maintenance.guard.ts
  • admin dashboard/read-model rows in /Users/velikho/Desktop/WORKING/HOCTAPAZ/node-platform/apps/api/prisma/schema.prisma.

Writable files:

  • services/admin-service/**
  • contracts/openapi/services/admin-service.yaml
  • docs/api/admin-service.md

Orchestrator-owned files:

  • audit-service storage migration, IAM credentials/profile/payment/wallet boundaries, gateway route cutovers, and shared deploy manifests unless delegated.

Delegated gateway verification scope:

  • Only when the orchestrator assigns an admin route/live/browser proof subtask, this service agent may update non-default deploy/gateway/routes.feature-maintenance-*.json, deploy/gateway/routes.admin-audit-*.json, deploy/gateway/routes.audit-admin-compat-*.json, matching scripts/test/*admin*.sh or scripts/test/feature-maintenance-*.sh, docs/qa/admin-*.md, and root Makefile test-feature-maintenance-*, test-admin-*, or test-audit-admin-* targets.
  • Audit-service compatibility storage, IAM/profile/payment/wallet ownership, broad admin default routes, and frontend admin screens remain orchestrator-owned unless explicitly delegated. Public promotion still requires browser/runtime proof and rollback notes.

Initial tasks:

  • Keep feature maintenance and admin audit foundation stable.
  • Done: add a maintenance guard adapter slice. GET /v1/feature-maintenance/guard/{key} lets gateway/BFF query native feature-maintenance state, preserve exact Vietnamese labels, and keep read-only AI classification job bypass behavior while default routes remain rollback-safe.
  • Done: add an admin operations/dashboard source-map slice before implementation. GET /v1/admin/operations/source-map maps health to gateway/service health checks, queues/import jobs to the worker/import owner, outbox state to emitting owner projections, AI provider status to ai-classifier-service, wallet review summaries to wallet/payment owners, support queues to support/notification owners, identity/profile counts to IAM/profile APIs, and audit history to audit-service.
  • Done: expand the source-map contract for remaining legacy admin dashboard and operations parity areas before metric adapters are added. The map now includes organization roster/member counts, classroom/exam counts, attempt metrics, document totals/pending reviews, full queue depth projections, queue retry commands, and outbox clear commands with owner services/APIs named. It still does not execute commands or aggregate metric counts inside admin-service.
  • Done: point DOCX import queue failures/depths at docx-import-service GET /v1/admin/import/docx/queue-summary, and point DOCX Fast retry at POST /v1/import/docx/docx-fast-jobs/{id}/reprocess. Admin-service may probe those owner routes through source snapshots, but must not read docx_import_jobs, payload spools, Redis BullMQ keys, or import worker memory directly. The import.jobs source-map key points at docx-import-service GET /v1/import/docx/jobs.
  • Done: point AI classifier queue depth at ai-classifier-service GET /v1/admin/ai-classifier/queue-summary and AI retry at POST /v1/ai-classifier/jobs/{id}/retry. Admin-service may probe those owner routes through source snapshots, but must not read classification_jobs directly.
  • Done: point organization.roster at school-service GET /v1/admin/organizations/roster-summary once the owner API existed. Admin-service still only maps/probes owner APIs; it does not copy organization data or take IAM membership authority.
  • Done: point learning.classroom-counts at classroom-service GET /v1/admin/classrooms/summary once the owner API existed. Admin-service still does not copy classroom roster state or own classroom metrics.
  • Done: point learning.exam-counts at exam-service GET /v1/admin/exams/summary once the owner API existed. Admin-service still does not copy exam rows, access links, assignments, attempts, or analytics state.
  • Done: point learning.attempt-metrics at attempt-service GET /v1/admin/attempts/summary once the owner API existed. Admin-service still does not copy attempt rows or own analytics rollups.
  • Done: ai.providers now has ai-classifier-service owner GET /v1/ai/providers/status; admin-service source snapshots may probe that endpoint when configured, but provider settings and secrets stay AI-owned.
  • Done: identity.counts now names IAM owner GET /v1/admin/identity/summary and profile-service owner GET /v1/admin/profiles/summary; admin-service must not synthesize these counts from its own storage or merge IAM/profile ownership.
  • Done: support.queues now names notification-service owner API GET /v1/admin/support/notification-summary, which summarizes support notification/event/delivery state only. Admin-service must not store support tickets, discover recipients, or synthesize support queue totals.
  • Done: add a service-local admin operations/dashboard source snapshot slice. GET /v1/admin/operations/source-snapshots uses the source-map keys as the required contract and probes only owner endpoints configured through ADMIN_OPERATIONS_SOURCE_TARGETS (key=url,key=url). Missing owner targets return status=unconfigured; failing owner endpoints return status=degraded or status=unavailable. It does not read legacy Prisma tables, BullMQ queues, or service databases directly, and it does not promote public admin dashboard/operations routes.
  • Done: configured owner snapshot probes use bounded parallelism (eight in flight) while preserving source-map order and each owner latency/status. A slow owner no longer serially delays every other configured probe.
  • Done: the orchestrator-owned admin-web operations panel now reads those snapshot statuses only through the non-default Gateway rehearsal. It keeps fixture workflow rows as a fallback and never turns owner health/status into admin-service totals or dashboard aggregation.
  • Define admin operations/dashboard read models without taking ownership from domain services: health, queues, outbox, imports, AI provider status, wallet review summaries, and support queues must come from owner APIs/projections.
  • Add admin inbox/broadcast and support moderation slices in coordination with notification-service and audit-service; admin-service may coordinate the workflow but must not own notification delivery or compliance audit storage.
  • Done: add explicit-recipient admin notification broadcast producer at POST /v1/admin/notification-broadcasts. It requires a caller-supplied clientRequestId and concrete recipientIds, writes a local admin audit log, and best-effort emits admin.notification.broadcast.v1 to notification-service with sourceEventId=admin:broadcast:{clientRequestId}. Legacy ALL/ROLES target discovery remains pending until IAM/profile/gateway resolvers supply concrete recipients.
  • Done: add a first support ticket notification producer at POST /v1/support/notification-events. It requires caller-supplied ticketId, clientRequestId, concrete recipientIds, title, and content, writes a local support audit log, and best-effort emits support.ticket.notification.v1 to notification-service with sourceEventId=support:ticket:{ticketId}:notification:{clientRequestId}, preferenceType=SUPPORT_TICKET, entity=SupportTicket, and legacy inbox types such as SUPPORT_TICKET_CREATED, SUPPORT_TICKET_REPLY, or SUPPORT_TICKET_STATUS supplied through type. It does not store support tickets, discover admins/requesters, or write notification rows directly.
  • Done: add optional best-effort admin audit projection to audit-service. AUDIT_SERVICE_URL/AUDIT_SERVICE_BASE_URL enables posting newly written admin audit logs to /v1/audit-events with sourceService=admin-service, sourceEventId=<admin audit log id>, category=ADMIN, severity=INFO, retentionPolicy=admin-operations, and createdAt -> occurredAt; projection failures do not block the current admin audit write path.
  • Coordinate with the existing audit-service foundation before moving audit storage or public admin audit compatibility routes.
  • Teacher KYC review storage/list/detail/approve/reject is profile-service owned at /v1/admin/users/kyc/teacher*; non-default gateway route rehearsal can route /api/admin/users/kyc/teacher* directly to profile-service. Admin-service may later add a public compatibility wrapper only after response parity, browser evidence, and wrapper ownership are explicit, and must not persist KYC document fields or hashes.

Acceptance:

  • Admin-service does not own wallet ledger, payment rails, IAM credentials, or profile storage.
  • Feature maintenance keys and Vietnamese labels are unchanged.
  • Maintenance guard decisions preserve the read-only GET bypass for /api/questions/ai-classify/jobs* on assessment.questionBankAiClassification.
  • Admin dashboards read from APIs/projections, not service DB joins.
  • /api/admin/operations/audit remains on the existing admin-service compatibility route until audit-service has browser/runtime proof, rollback evidence, and legacy response/backfill parity proof.
  • make test-audit-admin-compat-routes covers the separate audit-service compatibility-preview route rehearsal; it does not promote the default route table.
  • Admin operations/dashboard source maps must list the owner API for every displayed count or command before code is added.
  • Admin operations/dashboard source snapshots may report only configured owner endpoint health/status. They must not synthesize totals, queue counts, wallet review counts, or identity/profile counts from admin-service storage.
  • Support/admin inbox flows emit notification and audit events through their owner-service APIs instead of writing those stores directly. The native admin broadcast and support notification slices are currently explicit-recipient only.
  • Admin teacher KYC compatibility work delegates to profile-service owner APIs and never stores plaintext CCCD, cccdNumberHash, or KYC document URLs in admin-service.

Verification:

  • GOTOOLCHAIN=go1.25.11 go test ./services/admin-service/...
  • make test-feature-maintenance-routes test-admin-audit-routes test-admin-owner-source-routes
  • make test-admin-owner-source-browser for the memory-only Admin Operations source-status candidate, including owner internal authentication and default legacy rollback; it is not dashboard parity or default-route proof.
  • Future dashboard/support/broadcast slices must add focused service tests, route guards for promoted paths, and browser/runtime evidence before default admin route cutover.

Go-platform documentation is generated from repository Markdown.