chore: update project documentation, audit reports, and initialize IDE configuration files
Some checks failed
CI / Lint → Typecheck → Test → Build (22) (push) Failing after 29s
CI / E2E Tests (push) Has been skipped
CodeQL Analysis / CodeQL (javascript-typescript) (push) Failing after 2m42s
Deploy / Build Web Image (push) Failing after 27s
Deploy / Build AI Services Image (push) Failing after 29s
E2E Tests / Playwright E2E (push) Failing after 43s
Deploy / Build API Image (push) Failing after 1m31s
Security Scanning / Dependency Audit (pnpm) (push) Failing after 6s
Security Scanning / Trivy Scan — API Image (push) Failing after 5m35s
Security Scanning / Trivy Scan — AI Services Image (push) Failing after 3m45s
Deploy / Deploy to Staging (push) Has been skipped
Deploy / Smoke Test Staging (push) Has been skipped
Deploy / Deploy to Production (push) Has been skipped
Deploy / Smoke Test Production (push) Has been skipped
Deploy / Rollback Staging (push) Has been skipped
Deploy / Rollback Production (push) Has been skipped
Security Scanning / Trivy Scan — Web Image (push) Failing after 13m51s
Security Scanning / Trivy Filesystem Scan (push) Failing after 14m46s
Security Scanning / Security Gate (push) Has been cancelled

This commit is contained in:
Ho Ngoc Hai
2026-04-19 03:12:54 +07:00
parent 3be106074d
commit 11f2bf26e6
101 changed files with 21312 additions and 20672 deletions

View File

@@ -1,33 +1,33 @@
# Quick File Reference for Admin Module Audit Logging
# Tài liệu Tham chiếu Nhanh cho Ghi nhật ký Kiểm toán Module Admin
## MUST READ FIRST (15 min total)
## ĐỌC TRƯỚC (tổng cộng 15 phút)
### 1. Main Controllers (Define what actions need audit)
-`apps/api/src/modules/admin/presentation/controllers/admin.controller.ts` (155 lines)
- User management: ban, update status, adjust subscription
- All endpoints have @CurrentUser() decorator to capture admin ID
### 1. Các Controller Chính (Xác định những hành động cần kiểm toán)
-`apps/api/src/modules/admin/presentation/controllers/admin.controller.ts` (155 dòng)
- Quản lý người dùng: cấm, cập nhật trạng thái, điều chỉnh gói đăng ký
- Tất cả các endpoint đều có decorator @CurrentUser() để ghi lại ID admin
-`apps/api/src/modules/admin/presentation/controllers/admin-moderation.controller.ts` (157 lines)
- Listing approval/rejection
- KYC approval/rejection
- Bulk moderation
-`apps/api/src/modules/admin/presentation/controllers/admin-moderation.controller.ts` (157 dòng)
- Duyệt/từ chối tin đăng
- Duyệt/từ chối KYC
- Kiểm duyệt hàng loạt
### 2. Command Handlers (Where to hook audit logging)
Each command publishes a domain event. Audit logging listener should listen to these events.
### 2. Các Command Handler (Nơi để gắn ghi nhật ký kiểm toán)
Mỗi command phát ra một sự kiện domain. Listener ghi nhật ký kiểm toán nên lắng nghe các sự kiện này.
**Ban User Flow:**
- Input: `apps/api/src/modules/admin/presentation/dto/ban-user.dto.ts`
**Luồng Cấm Người Dùng:**
- Đầu vào: `apps/api/src/modules/admin/presentation/dto/ban-user.dto.ts`
- Command: `apps/api/src/modules/admin/application/commands/ban-user/ban-user.command.ts`
- Handler: `apps/api/src/modules/admin/application/commands/ban-user/ban-user.handler.ts` (70 lines)
- Line 62: `this.eventBus.publish(new UserBannedEvent(...))`
- Handler: `apps/api/src/modules/admin/application/commands/ban-user/ban-user.handler.ts` (70 dòng)
- Dòng 62: `this.eventBus.publish(new UserBannedEvent(...))`
**Approve Listing Flow:**
- Input: `apps/api/src/modules/admin/presentation/dto/approve-listing.dto.ts`
**Luồng Duyệt Tin Đăng:**
- Đầu vào: `apps/api/src/modules/admin/presentation/dto/approve-listing.dto.ts`
- Command: `apps/api/src/modules/admin/application/commands/approve-listing/approve-listing.command.ts`
- Handler: `apps/api/src/modules/admin/application/commands/approve-listing/approve-listing.handler.ts` (52 lines)
- Line 42-44: `this.eventBus.publish(new ListingApprovedEvent(...))`
- Handler: `apps/api/src/modules/admin/application/commands/approve-listing/approve-listing.handler.ts` (52 dòng)
- Dòng 42-44: `this.eventBus.publish(new ListingApprovedEvent(...))`
### 3. Domain Events (What information is published)
### 3. Các Sự kiện Domain (Thông tin được phát ra)
```
apps/api/src/modules/admin/domain/events/
├── user-banned.event.ts
@@ -39,183 +39,183 @@ apps/api/src/modules/admin/domain/events/
└── kyc-rejected.event.ts
```
Each event has:
- `eventName` (e.g., 'user.banned')
- `occurredAt` (timestamp)
- `aggregateId` (userId or listingId)
- `adminId` (the admin who performed the action)
- Additional context (reason, notes, etc.)
Mỗi sự kiện có:
- `eventName` (ví dụ: 'user.banned')
- `occurredAt` (dấu thời gian)
- `aggregateId` (userId hoặc listingId)
- `adminId` (admin đã thực hiện hành động)
- Ngữ cảnh bổ sung (lý do, ghi chú, v.v.)
### 4. Existing Event Listener Pattern (Template)
-`apps/api/src/modules/admin/application/listeners/user-banned.listener.ts` (52 lines)
- Shows @OnEvent() decorator
- Shows how to access event data
- Shows side effects (deactivate listings, send notification)
- **THIS IS YOUR TEMPLATE FOR AUDIT LOGGING LISTENER**
### 4. Mẫu Event Listener Hiện có (Template)
-`apps/api/src/modules/admin/application/listeners/user-banned.listener.ts` (52 dòng)
- Minh hoạ decorator @OnEvent()
- Minh hoạ cách truy cập dữ liệu sự kiện
- Minh hoạ các hiệu ứng phụ (vô hiệu hoá tin đăng, gửi thông báo)
- **ĐÂY LÀ TEMPLATE CHO AUDIT LOGGING LISTENER CỦA BẠN**
### 5. Logger Service (Where to log)
-`apps/api/src/modules/shared/infrastructure/logger.service.ts` (65 lines)
- Pino-based structured logging
- Auto PII redaction
- Methods: log(), error(), warn(), debug(), verbose()
### 5. Logger Service (Nơi ghi log)
-`apps/api/src/modules/shared/infrastructure/logger.service.ts` (65 dòng)
- Ghi log có cấu trúc dựa trên Pino
- Tự động che giấu thông tin PII
- Các phương thức: log(), error(), warn(), debug(), verbose()
### 6. Exception Filter (For error logging)
-`apps/api/src/modules/shared/infrastructure/filters/global-exception.filter.ts` (145 lines)
- Catches all exceptions
- Logs with correlationId
- Could capture failed admin actions
### 6. Exception Filter (Để ghi log lỗi)
-`apps/api/src/modules/shared/infrastructure/filters/global-exception.filter.ts` (145 dòng)
- Bắt tất cả các ngoại lệ
- Ghi log kèm correlationId
- Có thể ghi lại các hành động admin thất bại
---
## ARCHITECTURE REFERENCES
## THAM CHIẾU KIẾN TRÚC
### Repository Pattern
- Domain Interface: `apps/api/src/modules/admin/domain/repositories/admin-query.repository.ts`
- Prisma Implementation: `apps/api/src/modules/admin/infrastructure/repositories/prisma-admin-query.repository.ts`
- **FOLLOW THIS PATTERN** for AuditLog repository
### Mẫu Repository
- Giao diện Domain: `apps/api/src/modules/admin/domain/repositories/admin-query.repository.ts`
- Triển khai Prisma: `apps/api/src/modules/admin/infrastructure/repositories/prisma-admin-query.repository.ts`
- **TUÂN THEO MẪU NÀY** cho AuditLog repository
### Module Bootstrap
- `apps/api/src/modules/admin/admin.module.ts` (64 lines)
- Shows how to register repositories via DI
- Shows how to register listeners
- Shows how to import CQRS module
### Khởi tạo Module
- `apps/api/src/modules/admin/admin.module.ts` (64 dòng)
- Minh hoạ cách đăng ký repository qua DI
- Minh hoạ cách đăng ký listener
- Minh hoạ cách import CQRS module
### Global App Setup
- `apps/api/src/app.module.ts` (100+ lines)
- Shows APP_FILTER, APP_GUARD, APP_INTERCEPTOR registration
- Shows CqrsModule.forRoot() setup
- Shows middleware configuration
### Cấu hình App Toàn cục
- `apps/api/src/app.module.ts` (100+ dòng)
- Minh hoạ đăng ký APP_FILTER, APP_GUARD, APP_INTERCEPTOR
- Minh hoạ cấu hình CqrsModule.forRoot()
- Minh hoạ cấu hình middleware
---
## PRISMA SCHEMA
### Current Models (What we're auditing)
- `prisma/schema.prisma` (602 lines total)
### Các Model Hiện tại (Những gì chúng ta đang kiểm toán)
- `prisma/schema.prisma` (602 dòng tổng cộng)
**User Model** (lines 34-71):
- Fields to audit: isActive, kycStatus, role
**User Model** (dòng 34-71):
- Các trường cần kiểm toán: isActive, kycStatus, role
**Listing Model** (lines 227-276):
- Fields to audit: status, moderationScore, moderationNotes
**Listing Model** (dòng 227-276):
- Các trường cần kiểm toán: status, moderationScore, moderationNotes
**NO AUDIT MODEL YET** - Opportunity to create from scratch
**CHƯA CÓ AUDIT MODEL** - Cơ hội để to từ đầu
---
## EXACT ENDPOINTS TO AUDIT (From Controllers)
## CÁC ENDPOINT CẦN KIỂM TOÁN (Từ Controllers)
### AdminController Actions:
1. `PATCH /admin/users/status` - Update user active status
2. `POST /admin/users/ban` - Ban/unban user
3. `POST /admin/subscriptions/adjust` - Adjust subscription
### Hành động của AdminController:
1. `PATCH /admin/users/status` - Cập nhật trạng thái hoạt động của người dùng
2. `POST /admin/users/ban` - Cấm/bỏ cấm người dùng
3. `POST /admin/subscriptions/adjust` - Điều chỉnh gói đăng ký
### AdminModerationController Actions:
1. `POST /admin/moderation/approve` - Approve listing
2. `POST /admin/moderation/reject` - Reject listing
3. `POST /admin/moderation/bulk` - Bulk moderate listings
4. `POST /admin/kyc/approve` - Approve KYC
5. `POST /admin/kyc/reject` - Reject KYC
### Hành động của AdminModerationController:
1. `POST /admin/moderation/approve` - Duyệt tin đăng
2. `POST /admin/moderation/reject` - Từ chối tin đăng
3. `POST /admin/moderation/bulk` - Kiểm duyệt hàng loạt tin đăng
4. `POST /admin/kyc/approve` - Duyệt KYC
5. `POST /admin/kyc/reject` - Từ chối KYC
Each action:
- Already captures admin ID from JWT
- Already publishes a domain event
- Already has a command handler
- Needs: Audit logging listener to capture to database
Mỗi hành động:
- Đã ghi lại ID admin từ JWT
- Đã phát ra sự kiện domain
- Đã có command handler
- Cần: Audit logging listener để lưu vào cơ sở dữ liệu
---
## DEPENDENCIES ALREADY IMPORTED
## CÁC PHỤ THUỘC ĐÃ ĐƯỢC IMPORT
### In AdminModule:
### Trong AdminModule:
```typescript
// Already available:
// Đã sẵn sàng:
- CqrsModule (from @nestjs/cqrs)
- AuthModule (auth guards/decorators)
- ListingsModule (for listing operations)
- SubscriptionsModule (for subscription operations)
// In providers:
- CommandHandlers (8 total)
- QueryHandlers (6 total)
- Event Listeners (2 existing + need to add AuditLoggingListener)
// Trong providers:
- CommandHandlers (8 tổng cộng)
- QueryHandlers (6 tổng cộng)
- Event Listeners (2 hiện + cần thêm AuditLoggingListener)
```
### From SharedModule:
- `PrismaService` (database)
- `LoggerService` (logging)
- Exception types (NotFoundException, ValidationException, etc.)
### Từ SharedModule:
- `PrismaService` (cơ sở dữ liệu)
- `LoggerService` (ghi log)
- Các loại ngoại lệ (NotFoundException, ValidationException, v.v.)
---
## IMPLEMENTATION CHECKLIST
## DANH SÁCH KIỂM TRA TRIỂN KHAI
### Phase 1: Database & Repository
- [ ] Create AuditLog Prisma model in schema.prisma
- [ ] Create IAuditLogRepository interface
- [ ] Create PrismaAuditLogRepository implementation
- [ ] Add to AdminModule providers
### Giai đoạn 1: Cơ sở dữ liệu & Repository
- [ ] Tạo AuditLog Prisma model trong schema.prisma
- [ ] Tạo interface IAuditLogRepository
- [ ] Tạo triển khai PrismaAuditLogRepository
- [ ] Thêm vào providers của AdminModule
### Phase 2: Events & Listeners
- [ ] Create AuditEvent domain event (if needed as wrapper)
- [ ] Create AuditLoggingListener to @OnEvent() for all admin events
- [ ] Inject AuditLogRepository into listener
- [ ] Persist audit records on event
### Giai đoạn 2: Events & Listeners
- [ ] Tạo AuditEvent domain event (nếu cần làm wrapper)
- [ ] Tạo AuditLoggingListener để @OnEvent() cho tất cả các sự kiện admin
- [ ] Inject AuditLogRepository o listener
- [ ] Lưu bản ghi kiểm toán khi có sự kiện
### Phase 3: Query & API
- [ ] Create GetAuditLogsQuery
- [ ] Create GetAuditLogsHandler
- [ ] Create IAuditLogQueryRepository method
- [ ] Add to QueryHandlers in module
### Giai đoạn 3: Query & API
- [ ] Tạo GetAuditLogsQuery
- [ ] Tạo GetAuditLogsHandler
- [ ] Tạo phương thức IAuditLogQueryRepository
- [ ] Thêm vào QueryHandlers trong module
### Phase 4: Controller Endpoint
- [ ] Add GET /admin/audit-logs endpoint
- [ ] Add filtering DTOs (dateRange, adminId, actionType, resourceId)
- [ ] Add pagination support
### Giai đoạn 4: Endpoint Controller
- [ ] Thêm endpoint GET /admin/audit-logs
- [ ] Thêm các DTO lọc (dateRange, adminId, actionType, resourceId)
- [ ] Thêm hỗ trợ phân trang
### Phase 5: Testing
- [ ] Unit tests for AuditLoggingListener
- [ ] Integration tests for audit persistence
- [ ] E2E tests for audit log retrieval
### Giai đoạn 5: Kiểm thử
- [ ] Unit tests cho AuditLoggingListener
- [ ] Integration tests cho việc lưu kiểm toán
- [ ] E2E tests cho việc truy xuất nhật ký kiểm toán
---
## CRITICAL PATTERNS TO FOLLOW
## CÁC MẪU QUAN TRỌNG CẦN TUÂN THEO
### 1. Command Pattern (Already Used)
### 1. Command Pattern (Đã được sử dụng)
```typescript
// DTOs validate input
// Commands encapsulate business intent
// Handlers execute + publish events
// Events trigger side effects via listeners
// DTO xác thực đầu vào
// Command đóng gói ý định nghiệp vụ
// Handler thực thi + phát sự kiện
// Event kích hoạt hiệu ứng phụ qua listener
```
### 2. DDD Layer Structure
### 2. Cấu trúc Tầng DDD
```
Presentation (DTO validation)
Presentation (xác thực DTO)
Application (Command/Query execution + Event publishing)
Application (thực thi Command/Query + phát Event)
Domain (Event definitions, Repository interfaces)
Domain (định nghĩa Event, giao diện Repository)
Infrastructure (Database implementation)
Infrastructure (triển khai cơ sở dữ liệu)
```
### 3. Dependency Injection
```typescript
// Always use Symbol for tokens:
// Luôn dùng Symbol cho token:
export const AUDIT_LOG_REPOSITORY = Symbol('AUDIT_LOG_REPOSITORY');
// Register in module:
// Đăng ký trong module:
{ provide: AUDIT_LOG_REPOSITORY, useClass: PrismaAuditLogRepository }
// Inject in service:
// Inject vào service:
constructor(
@Inject(AUDIT_LOG_REPOSITORY) private readonly auditRepo: IAuditLogRepository,
) {}
```
### 4. Event Listener Pattern
### 4. Mẫu Event Listener
```typescript
@Injectable()
export class AuditLoggingListener {
@@ -226,72 +226,71 @@ export class AuditLoggingListener {
@OnEvent('user.banned', { async: true })
async handleUserBanned(event: UserBannedEvent): Promise<void> {
// Extract data from event
// Persist to database
// Log if successful/failed
// Trích xuất dữ liệu từ sự kiện
// Lưu vào cơ sở dữ liệu
// Ghi log nếu thành công/thất bại
}
}
```
---
## WHERE TO ADD CODE
## NƠI THÊM CODE
```
apps/api/src/modules/admin/
├── domain/
│ ├── events/
│ │ └── audit-logged.event.ts (NEW - optional wrapper)
│ │ └── audit-logged.event.ts (MỚI - wrapper tuỳ chọn)
│ └── repositories/
│ ├── audit-log.repository.ts (NEW - interface)
│ └── index.ts (update exports)
│ ├── audit-log.repository.ts (MỚI - interface)
│ └── index.ts (cập nhật exports)
├── application/
│ ├── queries/
│ │ ├── get-audit-logs/ (NEW)
│ │ ├── get-audit-logs/ (MỚI)
│ │ │ ├── get-audit-logs.query.ts
│ │ │ └── get-audit-logs.handler.ts
│ │ └── index.ts (update exports)
│ │ └── index.ts (cập nhật exports)
│ │
│ └── listeners/
│ ├── audit-logging.listener.ts (NEW)
│ └── index.ts (update if needed)
│ ├── audit-logging.listener.ts (MỚI)
│ └── index.ts (cập nhật nếu cần)
├── infrastructure/
│ └── repositories/
│ ├── prisma-audit-log.repository.ts (NEW)
│ └── index.ts (update exports)
│ ├── prisma-audit-log.repository.ts (MỚI)
│ └── index.ts (cập nhật exports)
└── presentation/
├── controllers/
│ ├── admin.controller.ts (ADD ENDPOINT)
│ └── admin-moderation.controller.ts (UPDATE if needed)
│ ├── admin.controller.ts (THÊM ENDPOINT)
│ └── admin-moderation.controller.ts (CẬP NHẬT nếu cần)
└── dto/
├── get-audit-logs-query.dto.ts (NEW)
└── index.ts (update exports)
├── get-audit-logs-query.dto.ts (MỚI)
└── index.ts (cập nhật exports)
prisma/
└── schema.prisma (ADD AuditLog MODEL)
└── schema.prisma (THÊM AuditLog MODEL)
```
---
## EVENTS TO LISTEN TO
## CÁC SỰ KIỆN CẦN LẮNG NGHE
1. 'user.banned' - from UserBannedEvent
2. 'user.unbanned' - from UserUnbannedEvent
3. 'listing.approved' - from ListingApprovedEvent
4. 'listing.rejected' - from ListingRejectedEvent
5. 'kyc.approved' - from KycApprovedEvent
6. 'kyc.rejected' - from KycRejectedEvent
7. 'subscription.adjusted' - from SubscriptionAdjustedEvent
8. 'user.deactivated' - (if exists in auth module)
Each gets logged with:
- Admin ID (from event)
- Resource ID (aggregateId from event)
- Resource Type (derived from eventName)
- Timestamp (from event.occurredAt)
- Additional context (reason, notes, etc.)
1. 'user.banned' - từ UserBannedEvent
2. 'user.unbanned' - từ UserUnbannedEvent
3. 'listing.approved' - từ ListingApprovedEvent
4. 'listing.rejected' - từ ListingRejectedEvent
5. 'kyc.approved' - từ KycApprovedEvent
6. 'kyc.rejected' - từ KycRejectedEvent
7. 'subscription.adjusted' - từ SubscriptionAdjustedEvent
8. 'user.deactivated' - (nếu tồn tại trong auth module)
Mỗi sự kiện được ghi lại kèm:
- ID Admin (từ sự kiện)
- ID Tài nguyên (aggregateId từ sự kiện)
- Loại Tài nguyên (suy ra từ eventName)
- Dấu thời gian (từ event.occurredAt)
- Ngữ cảnh bổ sung (lý do, ghi chú, v.v.)