251217:1704 Docunment Number: Update to 1.6.2
This commit is contained in:
166
specs/06-tasks/TASK-BE-017-document-numbering-refactor.md
Normal file
166
specs/06-tasks/TASK-BE-017-document-numbering-refactor.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# TASK-BE-017: Document Numbering Backend Refactor
|
||||
|
||||
---
|
||||
status: TODO
|
||||
priority: HIGH
|
||||
estimated_effort: 3-5 days
|
||||
dependencies:
|
||||
- specs/01-requirements/03.11-document-numbering.md (v1.6.2)
|
||||
- specs/03-implementation/document-numbering.md (v1.6.2)
|
||||
related_task: TASK-FE-017-document-numbering-refactor.md
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Refactor Document Numbering module ตาม specification v1.6.2 โดยเน้น:
|
||||
- Number State Machine (RESERVED → CONFIRMED → VOID → CANCELLED)
|
||||
- Idempotency-Key support
|
||||
- Counter Key alignment ตาม requirements
|
||||
|
||||
---
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
### 1. Entity Updates
|
||||
|
||||
#### 1.1 DocumentNumberCounter Entity
|
||||
- [ ] Rename `current_year` → ใช้ `reset_scope` pattern (YEAR_2025, NONE)
|
||||
- [ ] Ensure FK columns match: `correspondence_type_id`, `originator_organization_id`, `recipient_organization_id`
|
||||
- [ ] Add `rfa_type_id`, `sub_type_id`, `discipline_id` columns if missing
|
||||
- [ ] Update Primary Key ให้ตรงกับ requirements spec
|
||||
|
||||
```typescript
|
||||
// Expected Counter Key structure
|
||||
interface CounterKey {
|
||||
projectId: number;
|
||||
originatorOrganizationId: number;
|
||||
recipientOrganizationId: number; // 0 for RFA
|
||||
correspondenceTypeId: number;
|
||||
subTypeId: number; // 0 if not applicable
|
||||
rfaTypeId: number; // 0 if not applicable
|
||||
disciplineId: number; // 0 if not applicable
|
||||
resetScope: string; // 'YEAR_2025', 'NONE'
|
||||
}
|
||||
```
|
||||
|
||||
#### 1.2 DocumentNumberAudit Entity
|
||||
- [ ] Add `operation` enum: `RESERVE`, `CONFIRM`, `CANCEL`, `MANUAL_OVERRIDE`, `VOID`, `GENERATE`
|
||||
- [ ] Ensure `counter_key` is stored as JSON
|
||||
- [ ] Add `idempotency_key` column
|
||||
|
||||
#### 1.3 DocumentNumberReservation Entity (NEW if not exists)
|
||||
- [ ] Create entity for Two-Phase Commit reservations
|
||||
- [ ] Fields: `token`, `document_number`, `status`, `expires_at`, `metadata`
|
||||
|
||||
---
|
||||
|
||||
### 2. Service Updates
|
||||
|
||||
#### 2.1 DocumentNumberingService
|
||||
- [ ] Implement `reserveNumber()` - Phase 1 of Two-Phase Commit
|
||||
- [ ] Implement `confirmNumber()` - Phase 2 of Two-Phase Commit
|
||||
- [ ] Implement `cancelNumber()` - Explicit cancel reservation
|
||||
- [ ] Add Idempotency-Key checking logic
|
||||
- [ ] Update `generateNextNumber()` to use new CounterKey structure
|
||||
|
||||
#### 2.2 Counter Key Builder
|
||||
- [ ] Create helper to build counter key based on document type:
|
||||
- Global (LETTER, MEMO, RFI): `(project, orig, recip, type, 0, 0, 0, YEAR_XXXX)`
|
||||
- TRANSMITTAL: `(project, orig, recip, type, subType, 0, 0, YEAR_XXXX)`
|
||||
- RFA: `(project, orig, 0, type, 0, rfaType, discipline, NONE)`
|
||||
|
||||
#### 2.3 ManualOverrideService
|
||||
- [ ] Implement `manualOverride()` with validation
|
||||
- [ ] Auto-update counter if manual number > current
|
||||
|
||||
#### 2.4 VoidReplaceService
|
||||
- [ ] Implement `voidAndReplace()` workflow
|
||||
- [ ] Link new document to voided document
|
||||
|
||||
---
|
||||
|
||||
### 3. Controller Updates
|
||||
|
||||
#### 3.1 DocumentNumberingController
|
||||
- [ ] Add `POST /reserve` endpoint
|
||||
- [ ] Add `POST /confirm` endpoint
|
||||
- [ ] Add `POST /cancel` endpoint
|
||||
- [ ] Add `Idempotency-Key` header validation middleware
|
||||
|
||||
#### 3.2 DocumentNumberingAdminController
|
||||
- [ ] Add `POST /manual-override` endpoint
|
||||
- [ ] Add `POST /void-and-replace` endpoint
|
||||
- [ ] Add `POST /bulk-import` endpoint
|
||||
- [ ] Add `GET /metrics` endpoint for monitoring dashboard
|
||||
|
||||
---
|
||||
|
||||
### 4. Number State Machine
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> RESERVED: reserve()
|
||||
RESERVED --> CONFIRMED: confirm()
|
||||
RESERVED --> CANCELLED: cancel() or TTL expired
|
||||
CONFIRMED --> VOID: void()
|
||||
CANCELLED --> [*]
|
||||
VOID --> [*]
|
||||
```
|
||||
|
||||
#### 4.1 State Transitions
|
||||
- [ ] Implement state validation before transitions
|
||||
- [ ] Log all transitions to audit table
|
||||
- [ ] TTL 5 minutes for RESERVED state
|
||||
|
||||
---
|
||||
|
||||
### 5. Testing
|
||||
|
||||
#### 5.1 Unit Tests
|
||||
- [ ] CounterService.incrementCounter()
|
||||
- [ ] ReservationService.reserve/confirm/cancel()
|
||||
- [ ] TemplateValidator.validate()
|
||||
- [ ] CounterKeyBuilder
|
||||
|
||||
#### 5.2 Integration Tests
|
||||
- [ ] Two-Phase Commit flow
|
||||
- [ ] Idempotency-Key duplicate prevention
|
||||
- [ ] Redis lock + DB optimistic lock
|
||||
|
||||
#### 5.3 Load Tests
|
||||
- [ ] Concurrent number generation (1000 req/s)
|
||||
- [ ] Zero duplicates verification
|
||||
|
||||
---
|
||||
|
||||
## Files to Create/Modify
|
||||
|
||||
| Action | Path |
|
||||
| ------ | ------------------------------------------------------------------------------------------- |
|
||||
| MODIFY | `backend/src/modules/document-numbering/entities/document-number-counter.entity.ts` |
|
||||
| MODIFY | `backend/src/modules/document-numbering/entities/document-number-audit.entity.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/entities/document-number-reservation.entity.ts` |
|
||||
| MODIFY | `backend/src/modules/document-numbering/services/document-numbering.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/reservation.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/manual-override.service.ts` |
|
||||
| MODIFY | `backend/src/modules/document-numbering/controllers/document-numbering.controller.ts` |
|
||||
| MODIFY | `backend/src/modules/document-numbering/controllers/document-numbering-admin.controller.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/guards/idempotency.guard.ts` |
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] All Counter Key ตรงกับ requirements v1.6.2
|
||||
- [ ] Number State Machine ทำงานถูกต้อง
|
||||
- [ ] Idempotency-Key ป้องกัน duplicate requests
|
||||
- [ ] Zero duplicate numbers ใน concurrent load test
|
||||
- [ ] Audit logs บันทึกทุก operation
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Requirements v1.6.2](file:///d:/nap-dms.lcbp3/specs/01-requirements/03.11-document-numbering.md)
|
||||
- [Implementation Guide v1.6.2](file:///d:/nap-dms.lcbp3/specs/03-implementation/document-numbering.md)
|
||||
- [ADR-002](file:///d:/nap-dms.lcbp3/specs/05-decisions/ADR-002-document-numbering-strategy.md)
|
||||
192
specs/06-tasks/TASK-FE-017-document-numbering-refactor.md
Normal file
192
specs/06-tasks/TASK-FE-017-document-numbering-refactor.md
Normal file
@@ -0,0 +1,192 @@
|
||||
# TASK-FE-017: Document Numbering Frontend Refactor
|
||||
|
||||
---
|
||||
status: TODO
|
||||
priority: HIGH
|
||||
estimated_effort: 2-3 days
|
||||
dependencies:
|
||||
- TASK-BE-017-document-numbering-refactor.md
|
||||
- specs/01-requirements/03.11-document-numbering.md (v1.6.2)
|
||||
- specs/03-implementation/document-numbering.md (v1.6.2)
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Refactor Frontend Document Numbering ตาม specification v1.6.2:
|
||||
- ป้องกัน User แก้ไขเลขที่เอกสาร
|
||||
- สร้าง Admin Dashboard ด้วย Metrics
|
||||
- Implement Admin Tools (Manual Override, Void/Replace)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Checklist
|
||||
|
||||
### 1. User Mode Forms (Create/Edit)
|
||||
|
||||
#### 1.1 Correspondence Form
|
||||
- [ ] **Create Mode**: แสดง "Auto Generated" หรือ Preview เลขที่เอกสาร
|
||||
- [ ] **Edit Mode**: ช่อง Document No เป็น **Read-Only** เสมอ
|
||||
- [ ] **API Integration**: ตัดการส่ง field `documentNumber` ไป Backend ใน Edit mode
|
||||
|
||||
#### 1.2 RFA Form
|
||||
- [ ] Same as above - Read-Only document number
|
||||
|
||||
#### 1.3 Transmittal Form
|
||||
- [ ] Same as above - Read-Only document number
|
||||
|
||||
**Files:**
|
||||
- `frontend/components/correspondences/form.tsx`
|
||||
- `frontend/components/rfas/form.tsx`
|
||||
- `frontend/components/transmittals/form.tsx`
|
||||
|
||||
---
|
||||
|
||||
### 2. Admin Dashboard (`/admin/numbering`)
|
||||
|
||||
#### 2.1 Tab Structure
|
||||
```
|
||||
/admin/numbering
|
||||
├── Templates (existing - keep as is)
|
||||
├── Metrics & Audit (NEW)
|
||||
└── Admin Tools (NEW)
|
||||
```
|
||||
|
||||
#### 2.2 Templates Tab (Existing)
|
||||
- [ ] Keep current functionality
|
||||
- [ ] เป็น Tab แรก (default)
|
||||
|
||||
#### 2.3 Metrics & Audit Tab (NEW)
|
||||
- [ ] Fetch metrics from `GET /admin/document-numbering/metrics`
|
||||
- [ ] Display:
|
||||
- Sequence utilization gauge
|
||||
- Lock wait time chart
|
||||
- Generation rate chart
|
||||
- Recent errors table
|
||||
- Audit logs table with filters
|
||||
|
||||
#### 2.4 Admin Tools Tab (NEW)
|
||||
- [ ] **Manual Override Form**:
|
||||
- Input: document_type, document_number, reason
|
||||
- Calls `POST /admin/document-numbering/manual-override`
|
||||
|
||||
- [ ] **Void & Replace Form**:
|
||||
- Input: document_id, reason
|
||||
- Calls `POST /admin/document-numbering/void-and-replace`
|
||||
|
||||
- [ ] **Bulk Import Form**:
|
||||
- Upload CSV/Excel file
|
||||
- Preview before import
|
||||
- Calls `POST /admin/document-numbering/bulk-import`
|
||||
|
||||
---
|
||||
|
||||
### 3. API Integration
|
||||
|
||||
#### 3.1 New API Endpoints
|
||||
```typescript
|
||||
// services/document-numbering.service.ts (frontend)
|
||||
|
||||
interface NumberingMetrics {
|
||||
sequenceUtilization: number;
|
||||
lockWaitTimeP95: number;
|
||||
generationRate: number;
|
||||
recentErrors: ErrorEntry[];
|
||||
}
|
||||
|
||||
// GET /admin/document-numbering/metrics
|
||||
getMetrics(): Promise<NumberingMetrics>
|
||||
|
||||
// POST /admin/document-numbering/manual-override
|
||||
manualOverride(dto: ManualOverrideDto): Promise<void>
|
||||
|
||||
// POST /admin/document-numbering/void-and-replace
|
||||
voidAndReplace(dto: VoidReplaceDto): Promise<{ newDocumentNumber: string }>
|
||||
|
||||
// POST /admin/document-numbering/bulk-import
|
||||
bulkImport(file: File): Promise<ImportResult>
|
||||
|
||||
// GET /document-numbering/logs/audit
|
||||
getAuditLogs(params: AuditQueryParams): Promise<PaginatedAuditLogs>
|
||||
```
|
||||
|
||||
#### 3.2 DTOs
|
||||
```typescript
|
||||
interface ManualOverrideDto {
|
||||
documentType: string;
|
||||
documentNumber: string;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
interface VoidReplaceDto {
|
||||
documentId: number;
|
||||
reason: string;
|
||||
}
|
||||
|
||||
interface AuditQueryParams {
|
||||
operation?: 'RESERVE' | 'CONFIRM' | 'CANCEL' | 'MANUAL_OVERRIDE' | 'VOID' | 'GENERATE';
|
||||
dateFrom?: string;
|
||||
dateTo?: string;
|
||||
userId?: number;
|
||||
page?: number;
|
||||
limit?: number;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
### 4. Components to Create
|
||||
|
||||
| Component | Path | Description |
|
||||
| ------------------ | ----------------------------------------------- | --------------------------- |
|
||||
| MetricsDashboard | `components/numbering/metrics-dashboard.tsx` | Metrics charts and gauges |
|
||||
| AuditLogsTable | `components/numbering/audit-logs-table.tsx` | Filterable audit log viewer |
|
||||
| ManualOverrideForm | `components/numbering/manual-override-form.tsx` | Admin tool form |
|
||||
| VoidReplaceForm | `components/numbering/void-replace-form.tsx` | Admin tool form |
|
||||
| BulkImportForm | `components/numbering/bulk-import-form.tsx` | CSV/Excel uploader |
|
||||
|
||||
---
|
||||
|
||||
### 5. UI/UX Requirements
|
||||
|
||||
#### 5.1 Document Number Display
|
||||
- ใช้ Badge หรือ Chip style สำหรับ Document Number
|
||||
- สี: Info (blue) สำหรับ Auto-generated
|
||||
- สี: Warning (amber) สำหรับ Manual Override
|
||||
- สี: Destructive (red) สำหรับ Voided
|
||||
|
||||
#### 5.2 Admin Tools Access Control
|
||||
- ซ่อน Admin Tools tab สำหรับ users ที่ไม่มี permission `system.manage_settings`
|
||||
- แสดง confirmation dialog ก่อน Manual Override / Void
|
||||
|
||||
---
|
||||
|
||||
## Files to Create/Modify
|
||||
|
||||
| Action | Path |
|
||||
| ------ | -------------------------------------------------------- |
|
||||
| MODIFY | `frontend/app/(admin)/admin/numbering/page.tsx` |
|
||||
| CREATE | `frontend/components/numbering/metrics-dashboard.tsx` |
|
||||
| CREATE | `frontend/components/numbering/audit-logs-table.tsx` |
|
||||
| CREATE | `frontend/components/numbering/manual-override-form.tsx` |
|
||||
| CREATE | `frontend/components/numbering/void-replace-form.tsx` |
|
||||
| CREATE | `frontend/components/numbering/bulk-import-form.tsx` |
|
||||
| MODIFY | `frontend/services/document-numbering.service.ts` |
|
||||
| MODIFY | `frontend/components/correspondences/form.tsx` |
|
||||
|
||||
---
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
- [ ] Document Number เป็น Read-Only ใน Edit mode ทุก form
|
||||
- [ ] Admin Dashboard แสดง Metrics ได้ถูกต้อง
|
||||
- [ ] Manual Override ทำงานได้และบันทึก Audit
|
||||
- [ ] Void/Replace สร้างเลขใหม่และ link กับเอกสารเดิม
|
||||
- [ ] Permission check ถูกต้องสำหรับ Admin Tools
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Requirements v1.6.2](file:///d:/nap-dms.lcbp3/specs/01-requirements/03.11-document-numbering.md)
|
||||
- [Frontend Guidelines](file:///d:/nap-dms.lcbp3/specs/03-implementation/frontend-guidelines.md)
|
||||
- [REQ-009 Original Task](file:///d:/nap-dms.lcbp3/specs/06-tasks/REQ-009-DocumentNumbering.md)
|
||||
Reference in New Issue
Block a user