251213:1509 Docunment Number Businee Rule not correct
This commit is contained in:
251
specs/06-tasks/TASK-BE-015-schema-v160-migration.md
Normal file
251
specs/06-tasks/TASK-BE-015-schema-v160-migration.md
Normal file
@@ -0,0 +1,251 @@
|
||||
# Task: Backend Schema v1.6.0 Migration
|
||||
|
||||
**Status:** ✅ Completed
|
||||
**Priority:** P1 (High - Breaking Changes)
|
||||
**Estimated Effort:** 3-5 days
|
||||
**Dependencies:** Schema v1.6.0 already created
|
||||
**Owner:** Backend Team
|
||||
|
||||
---
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
อัพเดท Backend Entities และ DTOs ให้ตรงกับ Schema v1.6.0 ที่มีการ Refactor โครงสร้างตาราง
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectives
|
||||
|
||||
- [x] Update Correspondence Entities
|
||||
- [x] Update RFA Entities (Shared PK Pattern)
|
||||
- [x] Update DTOs for new field names
|
||||
- [x] Update Services for new relationships
|
||||
- [x] Add/Update Unit Tests
|
||||
|
||||
---
|
||||
|
||||
## 📝 Schema Changes Summary
|
||||
|
||||
### Breaking Changes ⚠️
|
||||
|
||||
| Table | Change | Impact |
|
||||
| --------------------------- | ---------------------------------------------- | --------------- |
|
||||
| `correspondence_recipients` | FK → `correspondences(id)` | Update relation |
|
||||
| `rfa_items` | `rfarev_correspondence_id` → `rfa_revision_id` | Rename column |
|
||||
|
||||
### Column Changes
|
||||
|
||||
| Table | Old | New | Notes |
|
||||
| -------------------------- | ------------------- | ----------------------------- | ----------- |
|
||||
| `correspondence_revisions` | `title` | `subject` | Rename |
|
||||
| `correspondence_revisions` | - | `body`, `remarks` | Add columns |
|
||||
| `rfa_revisions` | `title` | `subject` | Rename |
|
||||
| `rfa_revisions` | `correspondence_id` | - | Remove |
|
||||
| `rfa_revisions` | - | `body`, `remarks`, `due_date` | Add columns |
|
||||
|
||||
### Architecture Changes
|
||||
|
||||
| Table | Change |
|
||||
| ------ | ---------------------------------------------------- |
|
||||
| `rfas` | Shared PK with `correspondences` (no AUTO_INCREMENT) |
|
||||
| `rfas` | `id` references `correspondences(id)` |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Implementation Steps
|
||||
|
||||
### 1. Update CorrespondenceRevision Entity
|
||||
|
||||
```typescript
|
||||
// File: backend/src/modules/correspondence/entities/correspondence-revision.entity.ts
|
||||
|
||||
// BEFORE
|
||||
@Column()
|
||||
title: string;
|
||||
|
||||
// AFTER
|
||||
@Column()
|
||||
subject: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
body: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
remarks: string;
|
||||
|
||||
@Column({ name: 'schema_version', default: 1 })
|
||||
schemaVersion: number;
|
||||
```
|
||||
|
||||
### 2. Update CorrespondenceRecipient Entity
|
||||
|
||||
```typescript
|
||||
// File: backend/src/modules/correspondence/entities/correspondence-recipient.entity.ts
|
||||
|
||||
// BEFORE
|
||||
@ManyToOne(() => CorrespondenceRevision, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'correspondence_id', referencedColumnName: 'correspondenceId' })
|
||||
revision: CorrespondenceRevision;
|
||||
|
||||
// AFTER
|
||||
@ManyToOne(() => Correspondence, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'correspondence_id' })
|
||||
correspondence: Correspondence;
|
||||
```
|
||||
|
||||
### 3. Update RFA Entity (Shared PK Pattern)
|
||||
|
||||
```typescript
|
||||
// File: backend/src/modules/rfa/entities/rfa.entity.ts
|
||||
|
||||
// BEFORE
|
||||
@PrimaryGeneratedColumn()
|
||||
id: number;
|
||||
|
||||
// AFTER
|
||||
@PrimaryColumn()
|
||||
id: number;
|
||||
|
||||
@OneToOne(() => Correspondence, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'id' })
|
||||
correspondence: Correspondence;
|
||||
```
|
||||
|
||||
### 4. Update RfaRevision Entity
|
||||
|
||||
```typescript
|
||||
// File: backend/src/modules/rfa/entities/rfa-revision.entity.ts
|
||||
|
||||
// REMOVE
|
||||
@Column({ name: 'correspondence_id' })
|
||||
correspondenceId: number;
|
||||
|
||||
// RENAME
|
||||
@Column()
|
||||
subject: string; // was: title
|
||||
|
||||
// ADD
|
||||
@Column({ type: 'text', nullable: true })
|
||||
body: string;
|
||||
|
||||
@Column({ type: 'text', nullable: true })
|
||||
remarks: string;
|
||||
|
||||
@Column({ name: 'due_date', type: 'datetime', nullable: true })
|
||||
dueDate: Date;
|
||||
```
|
||||
|
||||
### 5. Update RfaItem Entity
|
||||
|
||||
```typescript
|
||||
// File: backend/src/modules/rfa/entities/rfa-item.entity.ts
|
||||
|
||||
// BEFORE
|
||||
@Column({ name: 'rfarev_correspondence_id' })
|
||||
rfaRevCorrespondenceId: number;
|
||||
|
||||
// AFTER
|
||||
@Column({ name: 'rfa_revision_id' })
|
||||
rfaRevisionId: number;
|
||||
|
||||
@ManyToOne(() => RfaRevision, { onDelete: 'CASCADE' })
|
||||
@JoinColumn({ name: 'rfa_revision_id' })
|
||||
rfaRevision: RfaRevision;
|
||||
```
|
||||
|
||||
### 6. Update DTOs
|
||||
|
||||
```typescript
|
||||
// correspondence/dto/create-correspondence-revision.dto.ts
|
||||
export class CreateCorrespondenceRevisionDto {
|
||||
subject: string; // was: title
|
||||
body?: string;
|
||||
remarks?: string;
|
||||
}
|
||||
|
||||
// rfa/dto/create-rfa-revision.dto.ts
|
||||
export class CreateRfaRevisionDto {
|
||||
subject: string; // was: title
|
||||
body?: string;
|
||||
remarks?: string;
|
||||
dueDate?: Date;
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Files to Modify
|
||||
|
||||
### Entities
|
||||
|
||||
| File | Status | Changes |
|
||||
| ------------------------------------ | ------ | ----------------------------------------- |
|
||||
| `correspondence.entity.ts` | ✅ | Minor: add recipients relation |
|
||||
| `correspondence-revision.entity.ts` | ✅ | Rename title→subject, add body/remarks |
|
||||
| `correspondence-recipient.entity.ts` | ✅ | FK change to correspondence |
|
||||
| `rfa.entity.ts` | ✅ | Shared PK pattern |
|
||||
| `rfa-revision.entity.ts` | ✅ | Remove correspondenceId, add body/remarks |
|
||||
| `rfa-item.entity.ts` | ✅ | Rename column |
|
||||
|
||||
### DTOs
|
||||
|
||||
| File | Status | Changes |
|
||||
| --------------------------------------- | ------ | ------------------------------- |
|
||||
| `create-correspondence-revision.dto.ts` | ✅ | title→subject, add body/remarks |
|
||||
| `update-correspondence-revision.dto.ts` | ✅ | Same |
|
||||
| `create-rfa-revision.dto.ts` | ✅ | title→subject, add fields |
|
||||
| `update-rfa-revision.dto.ts` | ✅ | Same |
|
||||
| `create-rfa-item.dto.ts` | ✅ | Column rename |
|
||||
|
||||
### Services
|
||||
|
||||
| File | Status | Changes |
|
||||
| --------------------------- | ------ | -------------------------------- |
|
||||
| `correspondence.service.ts` | ✅ | Update queries for new relations |
|
||||
| `rfa.service.ts` | ✅ | Handle Shared PK creation |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Verification
|
||||
|
||||
### Unit Tests
|
||||
|
||||
```bash
|
||||
# Run existing tests to verify compatibility
|
||||
pnpm test:watch correspondence
|
||||
pnpm test:watch rfa
|
||||
```
|
||||
|
||||
### Integration Tests
|
||||
|
||||
1. Create new Correspondence → verify subject field saved
|
||||
2. Create new RFA → verify Shared PK pattern works
|
||||
3. Verify recipients linked to correspondence (not revision)
|
||||
4. Verify RFA items linked via rfa_revision_id
|
||||
|
||||
---
|
||||
|
||||
## 📚 Related Documents
|
||||
|
||||
- [Schema v1.6.0](../07-database/lcbp3-v1.6.0-schema.sql)
|
||||
- [Data Dictionary v1.6.0](../07-database/data-dictionary-v1.6.0.md)
|
||||
- [CHANGELOG v1.6.0](../../CHANGELOG.md)
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Risks & Mitigation
|
||||
|
||||
| Risk | Impact | Mitigation |
|
||||
| ----------------- | ------ | ------------------------------------ |
|
||||
| Breaking frontend | High | Update frontend types simultaneously |
|
||||
| Data migration | Medium | Schema already handles FK changes |
|
||||
| Test failures | Low | Update tests with new field names |
|
||||
|
||||
---
|
||||
|
||||
## 📌 Notes
|
||||
|
||||
- Schema v1.6.0 SQL files already exist in `specs/07-database/`
|
||||
- This task focuses on **backend code changes only**
|
||||
- Frontend will need separate task for DTO/type updates
|
||||
- Consider feature flag for gradual rollout
|
||||
263
specs/06-tasks/TASK-FE-016-schema-v160-adaptation.md
Normal file
263
specs/06-tasks/TASK-FE-016-schema-v160-adaptation.md
Normal file
@@ -0,0 +1,263 @@
|
||||
# Task: Frontend Schema v1.6.0 Adaptation
|
||||
|
||||
**Status:** ✅ Completed
|
||||
**Priority:** P1 (High - Breaking Changes)
|
||||
**Estimated Effort:** 2-3 days
|
||||
**Dependencies:** TASK-BE-015 (Backend Migration)
|
||||
**Owner:** Frontend Team
|
||||
|
||||
---
|
||||
|
||||
## 📋 Overview
|
||||
|
||||
อัพเดท Frontend Types, Services และ Forms ให้รองรับ Schema v1.6.0
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Objectives
|
||||
|
||||
- [x] Update TypeScript Interfaces/Types
|
||||
- [x] Update Form Components (field names)
|
||||
- [x] Update API Service Calls
|
||||
- [x] Update List/Table Columns
|
||||
- [x] Verify E2E functionality
|
||||
|
||||
---
|
||||
|
||||
## 📊 Business Rule Changes Analysis
|
||||
|
||||
### 1. Correspondence Revisions ⚠️ UI IMPACT
|
||||
|
||||
| Change | Old Field | New Field | Business Rule |
|
||||
| ---------- | --------- | --------- | --------------------------------------- |
|
||||
| **Rename** | `title` | `subject` | Form label เปลี่ยนจาก "หัวเรื่อง" เป็น "เรื่อง" |
|
||||
| **Add** | - | `body` | เพิ่ม Rich Text Editor สำหรับเนื้อความ |
|
||||
| **Add** | - | `remarks` | เพิ่ม Textarea สำหรับหมายเหตุ |
|
||||
| **Add** | - | `dueDate` | เพิ่ม Date Picker สำหรับกำหนดส่ง |
|
||||
|
||||
**UI Impact:**
|
||||
- Correspondence Form: เพิ่ม 3 fields ใหม่
|
||||
- Correspondence List: เปลี่ยน column header
|
||||
- Correspondence Detail: แสดง body และ remarks
|
||||
|
||||
### 2. Correspondence Recipients ⚠️ RELATION CHANGE
|
||||
|
||||
| Before | After | Business Rule |
|
||||
| ------------------------ | ---------------------- | -------------------------- |
|
||||
| Recipients ผูกกับ Revision | Recipients ผูกกับ Master | ผู้รับคงที่ตลอด Revisions ทั้งหมด |
|
||||
|
||||
**UI Impact:**
|
||||
- ย้าย Recipients Selection ออกจาก Revision Form
|
||||
- ไปอยู่ใน Master Correspondence Form แทน
|
||||
- Recipients จะไม่เปลี่ยนเมื่อสร้าง New Revision
|
||||
|
||||
### 3. RFA System 🔄 ARCHITECTURE CHANGE
|
||||
|
||||
| Change | Description | Business Rule |
|
||||
| ---------------- | -------------------------- | -------------------------------------------- |
|
||||
| **Shared ID** | RFA.id = Correspondence.id | สร้าง Correspondence ก่อน แล้ว RFA ใช้ ID เดียวกัน |
|
||||
| **Subject** | `title` → `subject` | เหมือนกับ Correspondence |
|
||||
| **Body/Remarks** | เพิ่ม fields ใหม่ | เหมือนกับ Correspondence |
|
||||
| **Due Date** | เพิ่ม field | กำหนดวันที่ต้องตอบกลับ |
|
||||
|
||||
**UI Impact:**
|
||||
- RFA Form: เพิ่ม body, remarks, dueDate
|
||||
- RFA Creation Flow: อาจต้อง adjust การ submit
|
||||
|
||||
### 4. RFA Items ⚠️ API CHANGE
|
||||
|
||||
| Before | After | Impact |
|
||||
| ------------------------ | --------------- | ------------------------------------------- |
|
||||
| `rfaRevCorrespondenceId` | `rfaRevisionId` | เปลี่ยน property name ใน API request/response |
|
||||
|
||||
---
|
||||
|
||||
## 🛠️ Implementation Steps
|
||||
|
||||
### 1. Update TypeScript Types
|
||||
|
||||
```typescript
|
||||
// lib/types/correspondence.ts
|
||||
|
||||
// BEFORE
|
||||
interface CorrespondenceRevision {
|
||||
title: string;
|
||||
// ...
|
||||
}
|
||||
|
||||
// AFTER
|
||||
interface CorrespondenceRevision {
|
||||
subject: string; // renamed from title
|
||||
body?: string; // NEW
|
||||
remarks?: string; // NEW
|
||||
dueDate?: string; // NEW
|
||||
schemaVersion?: number; // NEW
|
||||
// ...
|
||||
}
|
||||
|
||||
// Move recipients to master level
|
||||
interface Correspondence {
|
||||
// ...existing fields
|
||||
recipients: CorrespondenceRecipient[]; // MOVED from revision
|
||||
}
|
||||
```
|
||||
|
||||
```typescript
|
||||
// lib/types/rfa.ts
|
||||
|
||||
// BEFORE
|
||||
interface RfaRevision {
|
||||
correspondenceId: number;
|
||||
title: string;
|
||||
// ...
|
||||
}
|
||||
|
||||
// AFTER
|
||||
interface RfaRevision {
|
||||
// correspondenceId: REMOVED
|
||||
subject: string; // renamed from title
|
||||
body?: string; // NEW
|
||||
remarks?: string; // NEW
|
||||
dueDate?: string; // NEW
|
||||
// ...
|
||||
}
|
||||
|
||||
// BEFORE
|
||||
interface RfaItem {
|
||||
rfaRevCorrespondenceId: number;
|
||||
// ...
|
||||
}
|
||||
|
||||
// AFTER
|
||||
interface RfaItem {
|
||||
rfaRevisionId: number; // renamed
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Update Form Components
|
||||
|
||||
```typescript
|
||||
// app/(dashboard)/correspondences/new/page.tsx
|
||||
// app/(dashboard)/correspondences/[id]/edit/page.tsx
|
||||
|
||||
// CHANGES:
|
||||
// 1. Rename form field: title → subject
|
||||
// 2. Add new fields: body, remarks, dueDate
|
||||
// 3. Move recipients to master section (not revision)
|
||||
|
||||
<FormField name="subject" label="เรื่อง" required /> {/* was: title */}
|
||||
<FormField name="body" label="เนื้อความ" type="richtext" /> {/* NEW */}
|
||||
<FormField name="remarks" label="หมายเหตุ" type="textarea" /> {/* NEW */}
|
||||
<FormField name="dueDate" label="กำหนดส่ง" type="date" /> {/* NEW */}
|
||||
```
|
||||
|
||||
### 3. Update List Columns
|
||||
|
||||
```typescript
|
||||
// components/correspondence/correspondence-list.tsx
|
||||
|
||||
const columns = [
|
||||
// BEFORE: { header: 'หัวเรื่อง', accessorKey: 'title' }
|
||||
// AFTER:
|
||||
{ header: 'เรื่อง', accessorKey: 'subject' },
|
||||
{ header: 'กำหนดส่ง', accessorKey: 'dueDate' }, // NEW column
|
||||
];
|
||||
```
|
||||
|
||||
### 4. Update API Services
|
||||
|
||||
```typescript
|
||||
// lib/services/correspondence.service.ts
|
||||
// lib/services/rfa.service.ts
|
||||
|
||||
// Update DTO property names in API calls
|
||||
// Ensure field mapping matches backend changes
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🗂️ Files to Modify
|
||||
|
||||
### Types
|
||||
|
||||
| File | Status | Changes |
|
||||
| ----------------------------- | ------ | --------------------------------------- |
|
||||
| `lib/types/correspondence.ts` | ✅ | title→subject, add body/remarks/dueDate |
|
||||
| `lib/types/rfa.ts` | ✅ | Same + remove correspondenceId |
|
||||
|
||||
### Forms
|
||||
|
||||
| File | Status | Changes |
|
||||
| ---------------------------------------------------- | ------ | ---------------------- |
|
||||
| `app/(dashboard)/correspondences/new/page.tsx` | ✅ | Add new fields, rename |
|
||||
| `app/(dashboard)/correspondences/[id]/edit/page.tsx` | ✅ | Same |
|
||||
| `app/(dashboard)/rfas/new/page.tsx` | ✅ | Add new fields, rename |
|
||||
| `app/(dashboard)/rfas/[id]/edit/page.tsx` | ✅ | Same |
|
||||
|
||||
### Lists/Tables
|
||||
|
||||
| File | Status | Changes |
|
||||
| --------------------------------------------------- | ------ | ------------- |
|
||||
| `components/correspondence/correspondence-list.tsx` | ✅ | Column rename |
|
||||
| `components/rfa/rfa-list.tsx` | ✅ | Column rename |
|
||||
|
||||
### Services
|
||||
|
||||
| File | Status | Changes |
|
||||
| ---------------------------------------- | ------ | ----------- |
|
||||
| `lib/services/correspondence.service.ts` | ✅ | DTO mapping |
|
||||
| `lib/services/rfa.service.ts` | ✅ | DTO mapping |
|
||||
|
||||
---
|
||||
|
||||
## ✅ Verification
|
||||
|
||||
### Manual Testing
|
||||
|
||||
1. **Correspondence Flow:**
|
||||
- [ ] Create new correspondence → verify subject, body, remarks saved
|
||||
- [ ] Edit existing → verify field display correctly
|
||||
- [ ] List view shows "เรื่อง" column
|
||||
|
||||
2. **RFA Flow:**
|
||||
- [ ] Create new RFA → verify new fields
|
||||
- [ ] Add RFA Items → verify API works with new field names
|
||||
- [ ] Due date displays and functions correctly
|
||||
|
||||
3. **Recipients:**
|
||||
- [ ] Recipients assigned at master level
|
||||
- [ ] Creating new revision doesn't reset recipients
|
||||
|
||||
### E2E Tests
|
||||
|
||||
```bash
|
||||
pnpm test:e2e -- --grep "correspondence"
|
||||
pnpm test:e2e -- --grep "rfa"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📚 Related Documents
|
||||
|
||||
- [TASK-BE-015](./TASK-BE-015-schema-v160-migration.md) - Backend Migration
|
||||
- [Schema v1.6.0](../07-database/lcbp3-v1.6.0-schema.sql)
|
||||
- [CHANGELOG v1.6.0](../../CHANGELOG.md)
|
||||
|
||||
---
|
||||
|
||||
## 🚨 Risks & Mitigation
|
||||
|
||||
| Risk | Impact | Mitigation |
|
||||
| ---------------------- | ------ | ---------------------------- |
|
||||
| Field name mismatch | High | Coordinate with backend team |
|
||||
| Form validation errors | Medium | Test all forms thoroughly |
|
||||
| List display issues | Low | Update column configs |
|
||||
|
||||
---
|
||||
|
||||
## 📌 Notes
|
||||
|
||||
- ต้องรอ Backend deploy ก่อน จึงจะ test ได้
|
||||
- Recipients logic change อาจส่งผลต่อ business flow
|
||||
- Consider feature flag for gradual rollout
|
||||
@@ -20,6 +20,7 @@
|
||||
| **TASK-BE-011** | Notification & Audit | ✅ **Done** | 100% | Global Audit Interceptor & Notification Module active. |
|
||||
| **TASK-BE-012** | Master Data Management | ✅ **Done** | 100% | Disciplines, SubTypes, Tags, Config APIs complete. |
|
||||
| **TASK-BE-013** | User Management | ✅ **Done** | 100% | CRUD, Assignments, Preferences, Soft Delete complete. |
|
||||
| **TASK-BE-015** | Schema v1.6.0 Migration | ✅ **Done** | 100% | Correspondence/RFA Shared PK, New Fields (2025-12-13). |
|
||||
|
||||
## 🛠 Detailed Findings by Component
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
| **TASK-FE-013** | Circulation & Transmittal | ✅ **Done** | 100% | Circulation and Transmittal modules implemented with DataTable. |
|
||||
| **TASK-FE-014** | Reference Data UI | ✅ **Done** | 100% | Generic CRUD Table refactored (Skeleton/Dialogs). All pages linked. |
|
||||
| **TASK-FE-015** | Security Admin UI | ✅ **Done** | 100% | RBAC Matrix, Roles, Active Sessions, System Logs implemented. |
|
||||
| **TASK-FE-016** | Schema v1.6.0 Adaptation | ✅ **Done** | 100% | Update Forms/Types/Lists for v1.6.0 changes (2025-12-13). |
|
||||
|
||||
## 🛠 Detailed Status by Component
|
||||
|
||||
|
||||
Reference in New Issue
Block a user