Files
Ho Ngoc Hai 76d75c753b Migrate
2026-05-23 18:37:02 +07:00

17 KiB

QA Engineer — Audit Report: GoodGo POS System

Date: 2026-03-20 Auditor: QA Engineer (TechBi / GoodGo Platform) Scope: Test coverage, test quality, CI/CD test pipelines, missing test scenarios Working Directory: /Users/velikho/Desktop/WORKING/pos-system


Executive Summary

The GoodGo POS System has a well-structured testing foundation for backend .NET microservices — all 26 services follow Clean Architecture test patterns with xUnit + Moq + FluentAssertions, and the IAM service demonstrates a gold-standard test suite. However, only 1 of 26 services has a CI test pipeline, there is zero coverage for the MCP server (a critical AI operations component with 12 tools), no contract testing between microservices, and no performance testing anywhere in the stack. Coverlet is installed in all test projects but never generates reports or enforces thresholds. Frontend testing is surface-level smoke tests only beyond 8 Playwright E2E specs.


Critical Issues

C1 — Only 1 of 26 Services Has CI Test Pipeline

Severity: Critical (P0) File: .github/workflows/ci-iam-service.yml

Only iam-service-net has a dedicated CI workflow that runs unit tests and functional tests on pull requests. The remaining 25 services (merchant, order, fnb-engine, booking, catalog, inventory, wallet, promotion, membership, chat, social, storage, mining, mission, ads-manager, ads-serving, ads-billing, ads-tracking, ads-analytics, mkt-facebook, mkt-whatsapp, mkt-x, mkt-zalo, and both template services) have no automated test execution on PRs or merges.

This means regressions in 25 services are not caught until staging deployment or manual testing.

Impact: A broken handler, validator, or domain entity in any of the 25 uncovered services can be deployed to staging undetected.

Evidence:

  • .github/workflows/ci-iam-service.yml — only service CI that runs tests
  • No ci-merchant-service.yml, ci-order-service.yml, etc.
  • deploy-staging.yml runs EF Core migrations but NOT test suites before deployment

C2 — MCP Server Has Zero Tests (12 Production Tools)

Severity: Critical (P0) File: services/goodgo-mcp-server/package.json, services/goodgo-mcp-server/src/

The goodgo-mcp-server is a TypeScript MCP server providing 12 tools for AI-assisted F&B operations:

  • Catalog tools (src/tools/catalog-tools.ts): list/create/update/delete products, menu items
  • Inventory tools (src/tools/inventory-tools.ts): check stock, record intake (nhập kho), record usage (xuất kho), low-stock alerts
  • Recipe tools (src/tools/recipe-tools.ts): list/create recipes with ingredients
  • Analytics tools (src/tools/analytics-tools.ts): popular items, cost analysis

The package.json has no test script, no test framework (Jest, Vitest, Mocha) installed, and no test files exist in the project directory.

Impact: Any bug in the MCP tool definitions, input validation via zod, API client error handling (src/services/error-handler.ts), or tool logic will silently surface as incorrect AI-generated operations on merchant data.


C3 — No Coverage Thresholds or Reports Enforced

Severity: Critical (P0) File: All *.UnitTests.csproj files (e.g., services/order-service-net/tests/OrderService.UnitTests/OrderService.UnitTests.csproj)

All test projects include coverlet.collector v6.0.2, but:

  • No .runsettings or coverlet.runsettings file defines coverage thresholds
  • No CI step collects or uploads coverage reports
  • No quality gate exists to fail a build below a coverage percentage
  • Minimum 80% coverage standard (per project requirements) is stated but not enforced

Evidence:

<!-- In OrderService.UnitTests.csproj — coverlet installed but unconfigured -->
<PackageReference Include="coverlet.collector" Version="6.0.2">
  <IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
  <PrivateAssets>all</PrivateAssets>
</PackageReference>

No --collect:"XPlat Code Coverage" flag in any CI dotnet test command outside ci-iam-service.yml, and even there, no coverage threshold or report upload step exists.


C4 — No Contract Testing Between Microservices

Severity: Critical (P0)

The system has 26 microservices communicating via REST API and RabbitMQ events. There is no contract testing (Pact.io or similar) anywhere in the codebase. Service contracts are verified only by:

  • Shared TypeScript types in packages/types/ (but packages have no tests either)
  • Integration test patterns that use InMemoryDatabase (no real cross-service calls)

In a microservice architecture, breaking changes to API contracts — even minor ones like renaming a field from merchantId to merchant_id — can silently break consumers. Currently, such breaks would only surface after both services are deployed.

Evidence: Search across entire codebase found no Pact files, no pactum package, no consumer/provider test annotations.


Warnings

W1 — Shared Packages Have No Tests

Severity: High (P1) Files: packages/ directory (6 packages)

All 6 shared Node.js packages have zero test coverage:

  • packages/types/@goodgo/types (shared TypeScript types used across frontend + MCP server)
  • packages/http-client/@goodgo/http-client (axios wrapper used by all frontends)
  • packages/auth-sdk/@goodgo/auth-sdk (JWT utilities for auth flows)
  • packages/logger/@goodgo/logger
  • packages/tracing/@goodgo/tracing
  • packages/config/@goodgo/config

A breaking change in @goodgo/http-client or @goodgo/auth-sdk can cascade through all frontend applications (3 apps), the MCP server, and any consumer service.


W2 — E2E Tests Require Live Backend (No Mocking)

Severity: High (P1) File: apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/playwright.config.ts

The Playwright config targets http://localhost:5092 with no mock server or fixture setup. The E2E tests depend on a fully running backend stack (IAM service, Merchant service, etc.) to function. In CI (ci-web.yml), these tests run against hardcoded test credentials (admin@goodgo.vn / Admin@123) with no evidence of a test database being seeded.

This means:

  • E2E tests are brittle — they fail if the backend is not pre-seeded
  • Tests cannot run in isolation for frontend-only changes
  • Test data hardcoded in helpers/test-data.ts uses magic UUIDs (TEST_SHOP_ID = 00000000-0000-0000-0000-000000000001) that must exist in a live DB

Evidence:

// helpers/test-data.ts
export const TEST_SHOP_ID = '00000000-0000-0000-0000-000000000001';
export const ADMIN_USER = { email: 'admin@goodgo.vn', password: 'Admin@123' };

W3 — Playwright Tests Do Not Cover Mutation Scenarios

Severity: High (P1) Files: apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/tests/*.spec.ts

All 8 Playwright E2E specs are read-only / navigation-only tests. They verify that pages load and elements are visible, but do not test:

  • Creating an order (POST to order-service)
  • Adding items to a POS order session
  • Processing a payment (wallet-service integration)
  • Creating a booking (booking-service)
  • Staff login with RBAC restrictions
  • Merchant onboarding wizard submission
  • CRM campaign creation
  • Promotions applied to orders
  • Inventory decrement after order

The E2E layer only validates that pages render, not that they function end-to-end.


W4 — No Performance / Load Testing

Severity: Medium (P2)

No k6, Artillery, Gatling, or any load testing framework exists in the repository. Critical paths with known performance sensitivity have no benchmarks:

  • POST /api/v1/orders — Order creation under concurrent load
  • GET /api/v1/catalog/products — Catalog listing (expected high read volume)
  • POST /api/v1/ads-tracking/events — Ad event ingestion (bursty, high-throughput)
  • SignalR connections in chat-service-net — WebSocket scalability
  • goodgo-mcp-server — LLM tool calls during peak restaurant hours

Without baselines, there is no way to detect performance regressions introduced by refactors.


W5 — Frontend Has No Component-Level Tests

Severity: Medium (P2) Files: apps/web-client-tpos-net/, apps/web-client-base-net/

The Blazor WASM apps have only:

  • 2 unit tests in WebClientTpos.SmokeTests/ApiResponseTests.cs (tests ApiResponse<T> DTO, not Razor components)
  • 8 Playwright E2E specs for the POS app

There are no component-level tests for:

  • AuthButton (5 variants: orange, blue, green, outline, ghost)
  • OtpInput — complex state management, timer countdown
  • PosDataService — 4-format deserialization logic (critical business logic in frontend service)
  • AuthStateService — singleton JWT token state management
  • MudBlazor form validation in onboarding wizard
  • Shop sidebar vertical-specific menus (ShopSidebarConfig)

Note: PosDataService with 4-format deserialization (plain array, paged {items}, wrapped {data:{items}}, direct {data:[]}) is exactly the kind of complex branching logic that should have unit tests. A regression here silently breaks API data display for all merchants.


W6 — MAUI and Swift Apps Have Minimal Testing

Severity: Medium (P2) Files: apps/app-client-base-net/tests/, apps/app-client-base-swift/

  • MAUI (app-client-base-net): 1 unit test file (AppClientBase.UnitTests) — content not analyzed but project is described as "Template phase"
  • Swift iOS (app-client-base-swift): 1 smoke test referenced in ci-mobile.yml — no Xcode test plans found

Mobile apps in "template phase" with near-zero tests will carry this debt forward into feature development.


W7 — Test Parallelism Disabled in Playwright

Severity: Low (P3) File: apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/playwright.config.ts

fullyParallel: false,
workers: process.env.CI ? 1 : undefined,

With 8 spec files and no parallelism, E2E runs are unnecessarily slow. Parallel execution is safe when tests are properly isolated (each test navigates independently). Disabling parallelism suggests tests may be sharing state or there are concerns about race conditions on the backend — both are red flags.


Improvements

I1 — Add CI Pipelines for All 25 Missing Services

Use ci-iam-service.yml as the template. Each service pipeline should:

  1. Trigger on changes to services/{service-name}/**
  2. Spin up PostgreSQL 16-alpine service container
  3. Run dotnet test with --collect:"XPlat Code Coverage" flag
  4. Upload coverage to Codecov or similar
  5. Fail the build if coverage drops below 80%

Reference: .github/workflows/ci-iam-service.yml Effort: Low (copy-paste + variable substitution for 25 services)


I2 — Add Tests for goodgo-mcp-server

Add Vitest (preferred for TypeScript ESM) with the following coverage targets:

services/goodgo-mcp-server/
  src/
    tools/
      catalog-tools.test.ts   ← mock axios, test zod validation, tool schema
      inventory-tools.test.ts ← test stock calculation, low-stock alerts
      recipe-tools.test.ts    ← test recipe ingredient validation
      analytics-tools.test.ts ← test aggregation logic
    services/
      error-handler.test.ts   ← test all error code paths
      api-client.test.ts      ← test interceptors, auth headers

Effort: Medium (3-5 days)


I3 — Enforce Coverage Thresholds in CI

Add a .runsettings file at repo root:

<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
  <DataCollectionRunSettings>
    <DataCollectors>
      <DataCollector friendlyName="XPlat Code Coverage">
        <Configuration>
          <Format>cobertura</Format>
          <Threshold>80</Threshold>
          <ThresholdType>Line</ThresholdType>
          <ThresholdStat>Minimum</ThresholdStat>
        </Configuration>
      </DataCollector>
    </DataCollectors>
  </DataCollectionRunSettings>
</RunSettings>

And update CI test commands:

dotnet test --settings ../../.runsettings --collect:"XPlat Code Coverage"

I4 — Add Contract Tests for Critical Service Boundaries

Priority contracts to establish (consumer → provider):

  1. order-servicecatalog-service (product price, availability)
  2. order-servicewallet-service (payment processing)
  3. order-serviceinventory-service (stock decrement)
  4. merchant-serviceiam-service (user/RBAC validation)
  5. promotion-serviceorder-service (discount application)

Use Pact.io with .NET consumer SDK (PactNet) and add contract verification to each service's CI pipeline.


I5 — Add Mutation E2E Tests for Critical Workflows

Extend Playwright specs to cover actual business transactions:

  • Complete order creation: table selection → add items → submit → verify order in KDS
  • Payment flow: order total → wallet/VNPay mock → confirm receipt
  • Booking creation: select date/time → confirm → verify in calendar
  • Inventory: place order → verify stock decremented

File to extend: apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/tests/pos-restaurant.spec.ts


I6 — Unit Test PosDataService (Frontend)

PosDataService deserializes 4 different API response formats. Add unit tests in WebClientTpos.SmokeTests/ or a new WebClientTpos.UnitTests/ project:

// PosDataServiceTests.cs
[Fact]
public async Task Deserialize_PlainArray_ShouldReturnItems();

[Fact]
public async Task Deserialize_PagedResponse_ShouldReturnItemsWithCount();

[Fact]
public async Task Deserialize_WrappedDataResponse_ShouldUnwrapCorrectly();

[Fact]
public async Task Deserialize_DirectDataArray_ShouldReturnItems();

I7 — Add k6 Performance Tests for Critical Paths

Create tests/performance/ at repo root:

tests/performance/
  k6/
    order-creation.js       ← VUs: 100, ramp to 500
    catalog-listing.js      ← VUs: 200, sustained load
    ads-event-ingestion.js  ← VUs: 1000 burst
    auth-token-refresh.js   ← VUs: 50

Add a weekly performance-test.yml GitHub Actions workflow that runs k6 against staging.


Action Items (Prioritized)

# Priority Action Effort Owner
A1 P0 — Critical Generate CI pipelines for 25 missing services (copy ci-iam-service.yml template) 1 day DevOps
A2 P0 — Critical Add Vitest + test suite to goodgo-mcp-server (12 tools, error handler, api-client) 3-5 days Backend Dev
A3 P0 — Critical Add .runsettings coverage threshold (80% minimum) and upload in all CI pipelines 0.5 days DevOps
A4 P0 — Critical Add Pact.io contract tests for top 5 service boundaries 5-7 days Backend Dev
A5 P1 — High Add unit tests for all 6 shared packages in packages/ 3-4 days Frontend Dev
A6 P1 — High Fix E2E backend dependency: add DB seeding/reset step in ci-web.yml 2 days DevOps
A7 P1 — High Extend Playwright specs with mutation tests (order creation, payment, booking) 3-4 days QA
A8 P2 — Medium Add PosDataService unit tests (4-format deserialization) 1 day Frontend Dev
A9 P2 — Medium Enable Playwright fullyParallel: true with proper test isolation 0.5 days QA
A10 P2 — Medium Add k6 performance baseline tests for 4 critical paths 3 days QA
A11 P3 — Low Expand MAUI unit test coverage beyond template placeholder 2-3 days Mobile Dev
A12 P3 — Low Add Xcode test plan for Swift iOS app 2-3 days Mobile Dev

Appendix: Current Test Inventory

Backend (.NET)

Layer Count Framework
Unit Tests (all services) ~100+ files xUnit + Moq + FluentAssertions
Functional Tests (all services) ~50+ files xUnit + WebApplicationFactory + InMemory DB
Smoke Tests (Blazor) 4 projects xUnit
MAUI Unit Tests 1 project xUnit

Frontend (TypeScript)

Layer Count Framework
E2E Specs (Playwright) 8 files Playwright/test (Chromium only)
Smoke DTO Tests 2 tests xUnit via .NET project
Shared package tests 0
MCP server tests 0

CI Coverage

Service Has CI Tests?
iam-service-net Yes (ci-iam-service.yml)
25 other services No
web-client-tpos-net ⚠️ Partial (E2E in ci-web.yml)
goodgo-mcp-server No
packages/* (6) No

Key Test Files Referenced

  • IAM unit test: services/iam-service-net/tests/IamService.UnitTests/Application/Commands/RegisterUserCommandHandlerTests.cs
  • IAM functional test: services/iam-service-net/tests/IamService.FunctionalTests/Controllers/AuthControllerTests.cs
  • Template unit test: services/_template_dot_net/tests/MyService.UnitTests/Application/CreateSampleCommandHandlerTests.cs
  • Playwright config: apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/playwright.config.ts
  • Playwright helpers: apps/web-client-tpos-net/tests/WebClientTpos.E2ETests/helpers/test-data.ts
  • Smoke test: apps/web-client-tpos-net/tests/WebClientTpos.SmokeTests/ApiResponseTests.cs