Add comprehensive project documentation including changelog, QA tracker, code quality audit, implementation guide, K6 load testing guide, frontend exploration notes, and file mapping reference. Co-Authored-By: Paperclip <noreply@paperclip.ing>
585 lines
28 KiB
Markdown
585 lines
28 KiB
Markdown
# QA Tracker - GoodGo Platform
|
|
|
|
**Last Updated**: 2026-04-09
|
|
**QA Engineer**: QA Agent (TEC-1568)
|
|
**Platform Version**: goodgo-platform v0.1.0
|
|
**Test Environment**: macOS local development (Node 22, pnpm 10)
|
|
|
|
---
|
|
|
|
## Executive Summary
|
|
|
|
| Metric | Value |
|
|
|--------|-------|
|
|
| Unit Test Files | 120 |
|
|
| Unit Tests | 624 |
|
|
| Unit Test Pass Rate | **100%** (624/624) |
|
|
| E2E Test Files | 29 (14 API + 15 Web) |
|
|
| E2E Test Status | **Not executable** (PostgreSQL + Frontend not running) |
|
|
| TypeScript Errors | **0** |
|
|
| ESLint Errors | **10** (all auto-fixable import order) |
|
|
| API Bugs Found | **5** (2 Critical, 2 Medium, 1 Low) |
|
|
| Infrastructure Issues | **2** (DB down, Frontend not running) |
|
|
|
|
---
|
|
|
|
## 1. Unit Test Results (Vitest)
|
|
|
|
**Status: ALL PASSING**
|
|
**Run Date**: 2026-04-09
|
|
**Duration**: 11.75s (transform 7.41s, tests 37.45s across parallel workers)
|
|
|
|
### Module Coverage Matrix
|
|
|
|
| Module | Test Files | Tests | Status | Coverage Areas |
|
|
|--------|-----------|-------|--------|----------------|
|
|
| **Auth** | 12 | ~55 | PASS | Register, login, refresh, OAuth (Google/Zalo), token service, user entity, email/phone/password VOs, events |
|
|
| **Payments** | 9 | ~45 | PASS | Create/refund/status, callback handling, edge cases, VNPay/MoMo/ZaloPay services, payment entity, money VO, events |
|
|
| **Listings** | 12 | ~60 | PASS | CRUD, media upload, search, moderation, pending queue, duplicate detector, property/listing entities, events, VOs |
|
|
| **Subscriptions** | 10 | ~50 | PASS | Create/upgrade/cancel, quota check, meter usage, billing history, plan retrieval, subscription lifecycle, events, quota guard |
|
|
| **Admin** | 13 | ~55 | PASS | KYC approve/reject, moderation queue/approve/reject, bulk moderate, user management, ban, dashboard stats, revenue, events |
|
|
| **Analytics** | 11 | ~50 | PASS | Price trends, market reports, heatmaps, district stats, valuation, market index, event tracking, controller |
|
|
| **Search** | 8 | ~35 | PASS | Geo search, property search, sync/reindex, Typesense repository, listing indexer, listing-approved handler, controller |
|
|
| **Notifications** | 13 | ~60 | PASS | 7 event listeners (user registered, payment completed, listing approved/rejected, quota exceeded, subscription expiring, inquiry received, agent verified), FCM/email services, template service, repositories, controller |
|
|
| **Reviews** | 6 | ~25 | PASS | Create/delete, get by user/target, average rating, domain entities |
|
|
| **Shared** | 10 | ~50 | PASS | Currency formatter, slug generator, phone validator, PII masker, exception filter, throttler guard, cache service, VOs, result type, domain base classes |
|
|
| **Metrics** | 2 | ~10 | PASS | Metrics service, HTTP interceptor |
|
|
| **Health** | — | — | — | No dedicated unit tests (integration tested via E2E) |
|
|
| **MCP** | — | — | — | No unit tests (tested via integration) |
|
|
| **TOTAL** | **120** | **624** | **ALL PASS** | |
|
|
|
|
### Unit Test File Inventory
|
|
|
|
<details>
|
|
<summary>Complete list of 120 test files (click to expand)</summary>
|
|
|
|
#### Auth Module (12 files)
|
|
- `auth/application/__tests__/login-user.handler.spec.ts`
|
|
- `auth/application/__tests__/refresh-token.handler.spec.ts`
|
|
- `auth/application/__tests__/register-user.handler.spec.ts`
|
|
- `auth/domain/__tests__/auth-events.spec.ts`
|
|
- `auth/domain/__tests__/email.vo.spec.ts`
|
|
- `auth/domain/__tests__/hashed-password.vo.spec.ts`
|
|
- `auth/domain/__tests__/phone.vo.spec.ts`
|
|
- `auth/domain/__tests__/user.entity.spec.ts`
|
|
- `auth/infrastructure/__tests__/google-oauth.strategy.spec.ts`
|
|
- `auth/infrastructure/__tests__/oauth.service.spec.ts`
|
|
- `auth/infrastructure/__tests__/token.service.spec.ts`
|
|
- `auth/infrastructure/__tests__/zalo-oauth.strategy.spec.ts`
|
|
- `auth/__tests__/auth.integration.spec.ts` (excluded from Vitest, integration only)
|
|
|
|
#### Payments Module (9 files)
|
|
- `payments/application/__tests__/create-payment.handler.spec.ts`
|
|
- `payments/application/__tests__/get-payment-status.handler.spec.ts`
|
|
- `payments/application/__tests__/handle-callback-edge-cases.handler.spec.ts`
|
|
- `payments/application/__tests__/handle-callback.handler.spec.ts`
|
|
- `payments/application/__tests__/list-transactions.handler.spec.ts`
|
|
- `payments/application/__tests__/refund-payment.handler.spec.ts`
|
|
- `payments/domain/__tests__/money.vo.spec.ts`
|
|
- `payments/domain/__tests__/payment-events.spec.ts`
|
|
- `payments/domain/__tests__/payment.entity.spec.ts`
|
|
- `payments/infrastructure/__tests__/momo.service.spec.ts`
|
|
- `payments/infrastructure/__tests__/payment-gateway.factory.spec.ts`
|
|
- `payments/infrastructure/__tests__/vnpay.service.spec.ts`
|
|
- `payments/infrastructure/__tests__/zalopay.service.spec.ts`
|
|
|
|
#### Listings Module (12 files)
|
|
- `listings/application/__tests__/create-listing.handler.spec.ts`
|
|
- `listings/application/__tests__/get-listing.handler.spec.ts`
|
|
- `listings/application/__tests__/get-pending-moderation.handler.spec.ts`
|
|
- `listings/application/__tests__/moderate-listing.handler.spec.ts`
|
|
- `listings/application/__tests__/search-listings.handler.spec.ts`
|
|
- `listings/application/__tests__/update-listing-status.handler.spec.ts`
|
|
- `listings/application/__tests__/upload-media.handler.spec.ts`
|
|
- `listings/domain/__tests__/duplicate-detector.spec.ts`
|
|
- `listings/domain/__tests__/listing-events.spec.ts`
|
|
- `listings/domain/__tests__/listing.entity.spec.ts`
|
|
- `listings/domain/__tests__/property.entity.spec.ts`
|
|
- `listings/domain/__tests__/value-objects.spec.ts`
|
|
|
|
#### Subscriptions Module (10 files)
|
|
- `subscriptions/application/__tests__/cancel-subscription.handler.spec.ts`
|
|
- `subscriptions/application/__tests__/check-quota.handler.spec.ts`
|
|
- `subscriptions/application/__tests__/create-subscription.handler.spec.ts`
|
|
- `subscriptions/application/__tests__/get-billing-history.handler.spec.ts`
|
|
- `subscriptions/application/__tests__/get-plan.handler.spec.ts`
|
|
- `subscriptions/application/__tests__/meter-usage.handler.spec.ts`
|
|
- `subscriptions/application/__tests__/upgrade-subscription.handler.spec.ts`
|
|
- `subscriptions/domain/__tests__/quota-exceeded.event.spec.ts`
|
|
- `subscriptions/domain/__tests__/subscription-events.spec.ts`
|
|
- `subscriptions/domain/__tests__/subscription-lifecycle.spec.ts`
|
|
- `subscriptions/domain/__tests__/subscription.entity.spec.ts`
|
|
- `subscriptions/infrastructure/__tests__/listing-created-usage.handler.spec.ts`
|
|
- `subscriptions/presentation/__tests__/quota.guard.spec.ts`
|
|
|
|
#### Admin Module (13 files)
|
|
- `admin/application/__tests__/adjust-subscription.handler.spec.ts`
|
|
- `admin/application/__tests__/approve-kyc.handler.spec.ts`
|
|
- `admin/application/__tests__/approve-listing.handler.spec.ts`
|
|
- `admin/application/__tests__/ban-user.handler.spec.ts`
|
|
- `admin/application/__tests__/bulk-moderate-listings.handler.spec.ts`
|
|
- `admin/application/__tests__/get-dashboard-stats.handler.spec.ts`
|
|
- `admin/application/__tests__/get-kyc-queue.handler.spec.ts`
|
|
- `admin/application/__tests__/get-moderation-queue.handler.spec.ts`
|
|
- `admin/application/__tests__/get-user-detail.handler.spec.ts`
|
|
- `admin/application/__tests__/get-users.handler.spec.ts`
|
|
- `admin/application/__tests__/reject-kyc.handler.spec.ts`
|
|
- `admin/application/__tests__/update-user-status.handler.spec.ts`
|
|
- `admin/domain/__tests__/admin-events.spec.ts`
|
|
|
|
#### Analytics Module (11 files)
|
|
- `analytics/application/__tests__/generate-report.handler.spec.ts`
|
|
- `analytics/application/__tests__/get-district-stats.handler.spec.ts`
|
|
- `analytics/application/__tests__/get-heatmap.handler.spec.ts`
|
|
- `analytics/application/__tests__/get-market-report.handler.spec.ts`
|
|
- `analytics/application/__tests__/get-price-trend.handler.spec.ts`
|
|
- `analytics/application/__tests__/track-event.handler.spec.ts`
|
|
- `analytics/application/__tests__/update-market-index.handler.spec.ts`
|
|
- `analytics/domain/__tests__/analytics-events.spec.ts`
|
|
- `analytics/domain/__tests__/market-index.entity.spec.ts`
|
|
- `analytics/domain/__tests__/valuation.entity.spec.ts`
|
|
- `analytics/infrastructure/__tests__/prisma-market-index.repository.spec.ts`
|
|
- `analytics/infrastructure/__tests__/prisma-valuation.repository.spec.ts`
|
|
- `analytics/presentation/__tests__/analytics.controller.spec.ts`
|
|
|
|
#### Search Module (8 files)
|
|
- `search/application/__tests__/geo-search.handler.spec.ts`
|
|
- `search/application/__tests__/reindex-all.handler.spec.ts`
|
|
- `search/application/__tests__/search-properties.handler.spec.ts`
|
|
- `search/application/__tests__/sync-listing.handler.spec.ts`
|
|
- `search/domain/__tests__/search-domain.spec.ts`
|
|
- `search/infrastructure/__tests__/listing-approved.handler.spec.ts`
|
|
- `search/infrastructure/__tests__/listing-indexer.service.spec.ts`
|
|
- `search/infrastructure/__tests__/typesense-search.repository.spec.ts`
|
|
- `search/presentation/__tests__/search.controller.spec.ts`
|
|
|
|
#### Notifications Module (13 files)
|
|
- `notifications/application/__tests__/agent-verified.listener.spec.ts`
|
|
- `notifications/application/__tests__/inquiry-received.listener.spec.ts`
|
|
- `notifications/application/__tests__/listing-approved.listener.spec.ts`
|
|
- `notifications/application/__tests__/listing-rejected.listener.spec.ts`
|
|
- `notifications/application/__tests__/payment-completed.listener.spec.ts`
|
|
- `notifications/application/__tests__/quota-exceeded.listener.spec.ts`
|
|
- `notifications/application/__tests__/send-notification.handler.spec.ts`
|
|
- `notifications/application/__tests__/subscription-expiring.listener.spec.ts`
|
|
- `notifications/application/__tests__/user-registered.listener.spec.ts`
|
|
- `notifications/domain/__tests__/notifications-domain.spec.ts`
|
|
- `notifications/infrastructure/__tests__/email.service.spec.ts`
|
|
- `notifications/infrastructure/__tests__/fcm.service.spec.ts`
|
|
- `notifications/infrastructure/__tests__/prisma-notification-preference.repository.spec.ts`
|
|
- `notifications/infrastructure/__tests__/prisma-notification.repository.spec.ts`
|
|
- `notifications/infrastructure/__tests__/template.service.spec.ts`
|
|
- `notifications/presentation/__tests__/notifications.controller.spec.ts`
|
|
|
|
#### Reviews Module (6 files)
|
|
- `reviews/application/__tests__/create-review.handler.spec.ts`
|
|
- `reviews/application/__tests__/delete-review.handler.spec.ts`
|
|
- `reviews/application/__tests__/get-average-rating.handler.spec.ts`
|
|
- `reviews/application/__tests__/get-reviews-by-target.handler.spec.ts`
|
|
- `reviews/application/__tests__/get-reviews-by-user.handler.spec.ts`
|
|
- `reviews/domain/__tests__/reviews-domain.spec.ts`
|
|
|
|
#### Shared Module (10 files)
|
|
- `shared/domain/__tests__/aggregate-root.spec.ts`
|
|
- `shared/domain/__tests__/domain-exception.spec.ts`
|
|
- `shared/domain/__tests__/result.spec.ts`
|
|
- `shared/domain/__tests__/value-object.spec.ts`
|
|
- `shared/infrastructure/__tests__/cache.service.spec.ts`
|
|
- `shared/infrastructure/__tests__/global-exception.filter.spec.ts`
|
|
- `shared/infrastructure/__tests__/pii-masker.spec.ts`
|
|
- `shared/infrastructure/__tests__/throttler-behind-proxy.guard.spec.ts`
|
|
- `shared/utils/__tests__/currency.formatter.spec.ts`
|
|
- `shared/utils/__tests__/slug.generator.spec.ts`
|
|
- `shared/utils/__tests__/vietnam-phone.validator.spec.ts`
|
|
|
|
#### Metrics Module (2 files)
|
|
- `metrics/infrastructure/__tests__/metrics.service.spec.ts`
|
|
- `metrics/presentation/interceptors/__tests__/http-metrics.interceptor.spec.ts`
|
|
|
|
</details>
|
|
|
|
---
|
|
|
|
## 2. E2E Test Inventory (Playwright)
|
|
|
|
**Status: NOT EXECUTABLE** — PostgreSQL not running, Next.js frontend not started.
|
|
**Configured Projects**: `api` (APIRequestContext), `web` (Desktop Chrome)
|
|
|
|
### API E2E Tests (14 files)
|
|
|
|
| Test File | Coverage | Status |
|
|
|-----------|----------|--------|
|
|
| `e2e/api/auth-register.spec.ts` | User registration flow | Blocked (DB) |
|
|
| `e2e/api/auth-login.spec.ts` | Login + token issuance | Blocked (DB) |
|
|
| `e2e/api/auth-refresh.spec.ts` | Token refresh flow | Blocked (DB) |
|
|
| `e2e/api/auth-profile.spec.ts` | Profile retrieval | Blocked (DB) |
|
|
| `e2e/api/auth-agent-profile.spec.ts` | Agent profile retrieval | Blocked (DB) |
|
|
| `e2e/api/auth-kyc.spec.ts` | KYC verification flow | Blocked (DB) |
|
|
| `e2e/api/listings.spec.ts` | Listings CRUD | Blocked (DB) |
|
|
| `e2e/api/listings-media.spec.ts` | Media upload for listings | Blocked (DB) |
|
|
| `e2e/api/listings-moderate.spec.ts` | Listing moderation | Blocked (DB) |
|
|
| `e2e/api/search.spec.ts` | Search & geo search | Blocked (DB) |
|
|
| `e2e/api/subscriptions.spec.ts` | Subscription lifecycle | Blocked (DB) |
|
|
| `e2e/api/payments.spec.ts` | Payment creation | Blocked (DB) |
|
|
| `e2e/api/payments-callback.spec.ts` | Payment webhook callbacks | Blocked (DB) |
|
|
| `e2e/api/admin.spec.ts` | Admin operations | Blocked (DB) |
|
|
|
|
### Web E2E Tests (15 files)
|
|
|
|
| Test File | Coverage | Status |
|
|
|-----------|----------|--------|
|
|
| `e2e/web/auth-register.spec.ts` | Registration UI flow | Blocked (Frontend) |
|
|
| `e2e/web/auth-login.spec.ts` | Login UI flow | Blocked (Frontend) |
|
|
| `e2e/web/auth-oauth-callback.spec.ts` | OAuth callback handling | Blocked (Frontend) |
|
|
| `e2e/web/homepage.spec.ts` | Homepage rendering | Blocked (Frontend) |
|
|
| `e2e/web/navigation.spec.ts` | Navigation/routing | Blocked (Frontend) |
|
|
| `e2e/web/search.spec.ts` | Search functionality | Blocked (Frontend) |
|
|
| `e2e/web/listing-detail.spec.ts` | Listing detail page | Blocked (Frontend) |
|
|
| `e2e/web/create-listing.spec.ts` | Create listing form | Blocked (Frontend) |
|
|
| `e2e/web/dashboard.spec.ts` | User dashboard | Blocked (Frontend) |
|
|
| `e2e/web/responsive.spec.ts` | Responsive layout | Blocked (Frontend) |
|
|
| `e2e/web/analytics.spec.ts` | Analytics dashboard | Blocked (Frontend) |
|
|
| `e2e/web/admin-dashboard.spec.ts` | Admin dashboard | Blocked (Frontend) |
|
|
| `e2e/web/admin-users.spec.ts` | Admin user management | Blocked (Frontend) |
|
|
| `e2e/web/admin-kyc.spec.ts` | Admin KYC queue | Blocked (Frontend) |
|
|
| `e2e/web/admin-moderation.spec.ts` | Admin moderation queue | Blocked (Frontend) |
|
|
|
|
---
|
|
|
|
## 3. Static Analysis
|
|
|
|
### TypeScript Type Checking
|
|
|
|
| Package | Status | Errors |
|
|
|---------|--------|--------|
|
|
| `@goodgo/api` | PASS | 0 |
|
|
| `@goodgo/web` | PASS | 0 |
|
|
| `@goodgo/mcp-servers` | PASS | 0 |
|
|
|
|
### ESLint
|
|
|
|
**Total Errors**: 10 (all auto-fixable with `--fix`)
|
|
**Error Type**: `import-x/order` (import ordering)
|
|
|
|
| File | Error |
|
|
|------|-------|
|
|
| `listings/domain/__tests__/property.entity.spec.ts` | Import order: `property-media.entity` before `property.entity` |
|
|
| `mcp/presentation/mcp-transport.controller.ts` | Import order: `@goodgo/mcp-servers` before `@nestjs/common` |
|
|
| `payments/domain/__tests__/payment-events.spec.ts` | Import order: `payment-completed.event` before `payment-created.event` |
|
|
| `search/domain/__tests__/search-domain.spec.ts` | Import order: `geo-filter.vo` before `search-filter.vo` |
|
|
| `subscriptions/domain/__tests__/subscription-events.spec.ts` | Import order: `subscription-cancelled.event` before `subscription-created.event` |
|
|
| + 5 additional similar import order violations | |
|
|
|
|
---
|
|
|
|
## 4. API Endpoint Test Results (Live Testing)
|
|
|
|
**Test Date**: 2026-04-09
|
|
**API Running**: Yes (port 3001)
|
|
**Database**: **NOT RUNNING** (PostgreSQL unavailable)
|
|
**Redis**: Unknown (not independently verified)
|
|
|
|
### Root/Health Endpoints
|
|
|
|
| Endpoint | Method | Expected | Actual | Status |
|
|
|----------|--------|----------|--------|--------|
|
|
| `GET /` | GET | 200 `{status: "ok"}` | 200 `{status: "ok", service: "goodgo-api"}` | PASS |
|
|
| `GET /health` | GET | 200 | 404 | **FAIL** (see BUG-005) |
|
|
| `GET /ready` | GET | 200 or 503 | 404 | **FAIL** (see BUG-005) |
|
|
|
|
### Authentication Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `POST /auth/register` | Missing fields | 400 + validation | 400 + field errors | PASS |
|
|
| `POST /auth/register` | Invalid phone | 400 | 400 + specific validation | PASS |
|
|
| `POST /auth/register` | Valid registration | 201 + tokens | 500 Internal Error | **FAIL** (DB down) |
|
|
| `POST /auth/login` | Missing credentials | 401 | 401 Unauthorized | PASS |
|
|
| `POST /auth/login` | Wrong credentials | 401 Unauthorized | **500 Internal Error** | **FAIL** (BUG-001) |
|
|
| `POST /auth/login` | Valid login | 200 + tokens | 500 Internal Error | **FAIL** (DB down) |
|
|
| `GET /auth/profile` | No auth token | 401 | 401 Unauthorized | PASS |
|
|
| `POST /auth/refresh` | No refresh token | 400 | 400 + validation | PASS |
|
|
|
|
### Listings Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `POST /listings` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `GET /listings` | Public list | 200 + data | 500 Internal Error | **FAIL** (DB down) |
|
|
| `GET /listings/:id` | Non-existent ID | 404 | **500 Internal Error** | **FAIL** (BUG-002) |
|
|
|
|
### Search Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /search?q=apartment` | Public search | 200 | 500 Internal Error | **FAIL** (DB/Typesense down) |
|
|
| `GET /search/geo?lat=..&lng=..&radius=5` | Wrong param name | 400 | 400 (correct validation) | PASS |
|
|
| `GET /search/geo?lat=..&lng=..&radiusKm=5` | Correct params | 200 | 500 Internal Error | **FAIL** (DB/Typesense down) |
|
|
|
|
### Payment Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `POST /payments` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `POST /payments/callback/invalid` | Invalid provider | 400 | 400 (Vietnamese error) | PASS |
|
|
| `POST /payments/:id/refund` | No auth | 401 | 401 Unauthorized | PASS |
|
|
|
|
### Admin Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /admin/dashboard` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `GET /admin/users` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `GET /admin/kyc` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `GET /admin/moderation` | No auth | 401 | 401 Unauthorized | PASS |
|
|
|
|
### Subscription Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /subscriptions/plans` | Public | 200 | 500 Internal Error | **FAIL** (DB down) |
|
|
| `POST /subscriptions` | No auth | 401 | 401 Unauthorized | PASS |
|
|
|
|
### Notification Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /notifications/history` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `GET /notifications/preferences` | No auth | 401 | 401 Unauthorized | PASS |
|
|
| `GET /notifications/unread` | No auth | 401 | 401 Unauthorized | PASS |
|
|
|
|
### Reviews Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /reviews` | Public list | 200 | **404 Not Found** | **FAIL** (BUG-003) |
|
|
| `GET /reviews/stats` | Public stats | 200 | **404 Not Found** | **FAIL** (BUG-003) |
|
|
| `POST /reviews` | Any request | 401 (no auth) | **404 Not Found** | **FAIL** (BUG-003) |
|
|
|
|
### MCP Endpoints
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /mcp/servers` | No auth | 401 | **200 + server list** | **FAIL** (BUG-004) |
|
|
|
|
### Miscellaneous
|
|
|
|
| Endpoint | Test Case | Expected | Actual | Status |
|
|
|----------|-----------|----------|--------|--------|
|
|
| `GET /nonexistent` | Unknown route | 404 | 404 (correct format) | PASS |
|
|
| `GET /api/docs` | Swagger docs | 200 HTML | 200 HTML | PASS |
|
|
| `POST /auth/register` | text/plain Content-Type | 415 or 400 | 400 (treated as empty body) | PASS (acceptable) |
|
|
|
|
---
|
|
|
|
## 5. Bug Tracker
|
|
|
|
### BUG-001: Login with wrong credentials returns 500 instead of 401 (CRITICAL)
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | Critical |
|
|
| **Module** | Auth |
|
|
| **Endpoint** | `POST /auth/login` |
|
|
| **Steps** | Send login request with valid phone format but wrong password |
|
|
| **Expected** | 401 Unauthorized with error message |
|
|
| **Actual** | 500 Internal Server Error |
|
|
| **Root Cause** | Likely unhandled exception in LocalAuthGuard/strategy when user lookup fails against database, or missing error handling for invalid credentials case |
|
|
| **Impact** | Security concern: leaks server state via generic 500; poor UX; login failure ambiguous |
|
|
|
|
### BUG-002: Non-existent listing ID returns 500 instead of 404 (MEDIUM)
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | Medium |
|
|
| **Module** | Listings |
|
|
| **Endpoint** | `GET /listings/:id` |
|
|
| **Steps** | Request listing with any non-existent ID string |
|
|
| **Expected** | 404 Not Found |
|
|
| **Actual** | 500 Internal Server Error |
|
|
| **Root Cause** | Likely Prisma `findUnique` returning null, then code tries to access properties on null; or unhandled `RecordNotFound` from Prisma |
|
|
| **Impact** | Poor UX; potential information leakage in logs |
|
|
|
|
### BUG-003: Reviews module routes return 404 (CRITICAL)
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | Critical |
|
|
| **Module** | Reviews |
|
|
| **Endpoints** | All `/reviews/*` routes |
|
|
| **Steps** | Any request to `/reviews`, `/reviews/stats`, `POST /reviews` |
|
|
| **Expected** | Appropriate response (200, 401, 400) |
|
|
| **Actual** | 404 Not Found for ALL review routes |
|
|
| **Root Cause** | Module is registered in `app.module.ts` and controller is in `reviews.module.ts`, but routes are not being served. Possible runtime DI failure (e.g., CQRS handler registration issue, provider resolution error silently caught by NestJS) |
|
|
| **Impact** | Entire reviews feature non-functional; users cannot create/view/delete reviews |
|
|
|
|
### BUG-004: MCP servers endpoint accessible without authentication (MEDIUM)
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | Medium |
|
|
| **Module** | MCP |
|
|
| **Endpoint** | `GET /mcp/servers` |
|
|
| **Steps** | Call endpoint with no Authorization header |
|
|
| **Expected** | 401 Unauthorized (endpoint should require JWT) |
|
|
| **Actual** | 200 with server list `["valuation","property-search","market-analytics"]` |
|
|
| **Root Cause** | Missing `@UseGuards(JwtAuthGuard)` on the `listServers` endpoint, or guard not applied at controller level |
|
|
| **Impact** | Information disclosure; unauthenticated users can enumerate available MCP servers |
|
|
|
|
### BUG-005: Health check endpoints not responding (LOW)
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | Low |
|
|
| **Module** | Health |
|
|
| **Endpoints** | `GET /health`, `GET /ready` |
|
|
| **Steps** | Call health or ready endpoints |
|
|
| **Expected** | 200 OK (liveness) or 503 (readiness if DB down) |
|
|
| **Actual** | 404 Not Found |
|
|
| **Root Cause** | Health module may not be properly registered, or health controller routes may be shadowed/excluded. Root endpoint `GET /` works and returns status, suggesting health module is either disabled or misconfigured |
|
|
| **Impact** | Cannot use standard Kubernetes probes; monitoring/alerting cannot detect service health |
|
|
|
|
---
|
|
|
|
## 6. Infrastructure Issues
|
|
|
|
### INFRA-001: PostgreSQL not running
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | High (blocks E2E and integration testing) |
|
|
| **Details** | PostgreSQL service on localhost:5432 is unreachable |
|
|
| **Expected** | PostgreSQL 16 with PostGIS running via Docker or brew |
|
|
| **Impact** | All DB-dependent API endpoints return 500; E2E tests cannot execute; registration/login flows completely broken |
|
|
| **Resolution** | Run `docker compose up -d` or `brew services start postgresql@16` |
|
|
|
|
### INFRA-002: Next.js frontend not running
|
|
|
|
| Field | Value |
|
|
|-------|-------|
|
|
| **Severity** | Medium (blocks Web E2E tests) |
|
|
| **Details** | No response on localhost:3000 |
|
|
| **Expected** | Next.js dev server running |
|
|
| **Impact** | Web E2E tests (15 test files) cannot execute; frontend user journeys untestable |
|
|
| **Resolution** | Run `pnpm dev` to start all services including frontend |
|
|
|
|
---
|
|
|
|
## 7. Edge Case & Security Test Results
|
|
|
|
### Input Validation
|
|
|
|
| Test | Endpoint | Result |
|
|
|------|----------|--------|
|
|
| Empty JSON body for registration | `POST /auth/register` | PASS - Returns specific field validation errors |
|
|
| Invalid phone format | `POST /auth/register` | PASS - Validates phone field |
|
|
| Short password (<8 chars) | `POST /auth/register` | PASS - Returns password length validation |
|
|
| Invalid payment provider | `POST /payments/callback/:provider` | PASS - Vietnamese error message for unsupported provider |
|
|
| Wrong geo-search param name | `GET /search/geo?radius=5` | PASS - Validates `radiusKm` param name, rejects `radius` |
|
|
| Non-JSON Content-Type | `POST /auth/register` | PASS - Gracefully handles as empty body |
|
|
|
|
### Authentication Guard Tests
|
|
|
|
| Test | Result |
|
|
|------|--------|
|
|
| Protected endpoints reject unauthenticated requests | PASS (admin, listings create, payments, notifications) |
|
|
| Admin endpoints require admin role | PASS (returns 401 without token) |
|
|
| Public endpoints accessible without auth | PARTIAL (some return 500 due to DB) |
|
|
| MCP servers accessible without auth | **FAIL** (BUG-004) |
|
|
|
|
### Error Response Format Consistency
|
|
|
|
| Test | Result |
|
|
|------|--------|
|
|
| All errors include `statusCode` | PASS |
|
|
| All errors include `errorCode` | PASS |
|
|
| All errors include `message` | PASS |
|
|
| All errors include `correlationId` | PASS |
|
|
| All errors include `timestamp` | PASS |
|
|
| Error format is consistent across modules | PASS |
|
|
| 500 errors do not leak stack traces | PASS |
|
|
|
|
---
|
|
|
|
## 8. Code Quality Observations
|
|
|
|
### Strengths
|
|
- Comprehensive unit test coverage (120 files, 624 tests, 100% pass rate)
|
|
- Clean DDD/CQRS architecture consistently applied across all 15 modules
|
|
- Proper input validation using class-validator
|
|
- Consistent error response format with correlation IDs
|
|
- Vietnamese localization in payment error messages
|
|
- PII masking service for logs
|
|
- Rate limiting/throttling configured with per-route overrides
|
|
- Swagger/OpenAPI documentation auto-generated
|
|
|
|
### Areas for Improvement
|
|
- No dedicated health check endpoint functional (blocks K8s-style deployments)
|
|
- Generic 500 errors for all DB failures (should degrade gracefully)
|
|
- Reviews module completely non-functional at runtime despite passing unit tests
|
|
- MCP endpoint missing auth guard (security gap)
|
|
- 10 import order lint violations (trivially fixable)
|
|
- No integration test suite between unit and E2E layers
|
|
- No test coverage reporting configured (Istanbul/c8)
|
|
- No contract testing between API and frontend
|
|
|
|
---
|
|
|
|
## 9. Test Coverage Gaps
|
|
|
|
| Area | Current Coverage | Gap |
|
|
|------|-----------------|-----|
|
|
| Health endpoints | None (unit or E2E) | Need unit tests for health/ready controllers |
|
|
| MCP module | No unit tests | Need tests for transport controller, SSE, message handling |
|
|
| Integration tests | 1 file (auth integration, excluded) | Need integration tests for cross-module flows |
|
|
| Performance tests | None | Need load testing for search, listing queries |
|
|
| Contract tests | None | Need API contract tests (Pact or similar) |
|
|
| Security tests | Manual only (this report) | Need automated security scan (OWASP ZAP or similar) |
|
|
| Accessibility tests | None | Need a11y tests for frontend (axe-core) |
|
|
| Visual regression | Blocked (TEC-645) | Cross-platform snapshots pending |
|
|
| Cross-browser E2E | Blocked (TEC-545) | Firefox + WebKit CI pipeline pending |
|
|
| PWA offline tests | Blocked (TEC-546) | Service worker E2E tests pending |
|
|
|
|
---
|
|
|
|
## 10. Recommendations (Priority Order)
|
|
|
|
1. **[Critical]** Fix BUG-003: Debug and fix Reviews module routing — entire feature broken
|
|
2. **[Critical]** Fix BUG-001: Handle wrong credentials gracefully (return 401, not 500)
|
|
3. **[High]** Start PostgreSQL + seed database before running E2E tests
|
|
4. **[Medium]** Fix BUG-004: Add `@UseGuards(JwtAuthGuard)` to MCP servers endpoint
|
|
5. **[Medium]** Fix BUG-002: Handle non-existent listing IDs properly (return 404)
|
|
6. **[Medium]** Fix BUG-005: Ensure health/ready endpoints are functional
|
|
7. **[Low]** Auto-fix 10 ESLint import order violations (`pnpm lint --fix`)
|
|
8. **[Low]** Add test coverage reporting (c8 or Istanbul) to Vitest config
|
|
9. **[Low]** Add integration test layer between unit and E2E
|
|
|
|
---
|
|
|
|
## Appendix: Test Environment Configuration
|
|
|
|
```
|
|
Node.js: >= 22.0.0
|
|
pnpm: 10.27.0
|
|
Vitest: (via @goodgo/api)
|
|
Playwright: 1.59.1
|
|
TypeScript: (strict mode)
|
|
PostgreSQL: 16 + PostGIS (expected, not running)
|
|
Redis: localhost:6379 (expected, not verified)
|
|
Typesense: (expected for search, not verified)
|
|
```
|
|
|
|
### Vitest Configuration
|
|
- **Globals**: enabled
|
|
- **Include**: `src/**/*.spec.ts`
|
|
- **Exclude**: `*.integration.spec.ts`
|
|
- **Alias**: `@modules` → `src/modules`
|
|
|
|
### Playwright Configuration
|
|
- **Projects**: `api` (APIRequestContext), `web` (Desktop Chrome)
|
|
- **Retries**: 2 in CI, 0 locally
|
|
- **Screenshots**: on failure
|
|
- **Traces**: on failure
|
|
- **Global Setup**: DB migrations + seed
|
|
- **Global Teardown**: DB cleanup
|