251223:1649 On going update to 1.7.0: Refoctory drawing Module & document number Module
This commit is contained in:
@@ -254,19 +254,39 @@ AD-DN-001: Single Source of Truth for Numbering ระบบ เลือกใ
|
||||
|
||||
**Counter Key**: `(project_id, originator_org_id, 0, correspondence_type_id, 0, rfa_type_id, discipline_id, 'NONE')`
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
### 3.11.3.4 Drawing
|
||||
|
||||
**Status**: 🚧 **To Be Determined**
|
||||
#### 3.11.3.4.1 Shop Drawing
|
||||
**Example**: `LCBP3-C2-SDW-SW-BST-002-1`
|
||||
|
||||
Drawing Numbering ยังไม่ได้กำหนด Template เนื่องจาก:
|
||||
**Token Breakdown**:
|
||||
|
||||
- มีความซับซ้อนสูง (Contract Drawing และ Shop Drawing มีกฎต่างกัน)
|
||||
- อาจต้องใช้ระบบ Numbering แยกต่างหาก
|
||||
- ต้องพิจารณาร่วมกับ RFA ที่เกี่ยวข้อง
|
||||
- `LCBP3-C2` = {PROJECT} = รหัสโครงการ
|
||||
- `SDW` = {DRAWING_TYPE} = ประเภทแบบ (SDW=Shop Drawing)
|
||||
- `SW` = {main_category} = รหัสหมวดหลัก
|
||||
- `BST` = {sub_category} = รหัสหมวดย่อย
|
||||
- `002` = {SEQ:3}
|
||||
- `1` = {REV} = Revision code
|
||||
|
||||
**Counter Key**: `(project_id, DRAWING_TYPE, main_category, sub_category)`
|
||||
|
||||
#### 3.11.3.4.2 As Built Drawing
|
||||
|
||||
**Example**: `LCBP3-C2-ASB-SW-BST-002-1`
|
||||
|
||||
**Token Breakdown**:
|
||||
|
||||
- `LCBP3-C2` = {PROJECT} = รหัสโครงการ
|
||||
- `ASB` = {DRAWING_TYPE} = ประเภทแบบ (ASB=As Built Arawing)
|
||||
- `SW` = {main_category} = รหัสหมวดหลัก
|
||||
- `BST` = {sub_category} = รหัสหมวดย่อย
|
||||
- `002` = {SEQ:3}
|
||||
- `1` = {REV} = Revision code
|
||||
|
||||
**Counter Key**: `(project_id, DRAWING_TYPE, main_category, sub_category)`
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -261,9 +261,9 @@ FCO (For Construction) / ASB (As-Built) / 3R (Revise) / 4X (Reject)
|
||||
**Hierarchy:**
|
||||
|
||||
```
|
||||
Volume (เล่ม)
|
||||
Volume (เล่ม) - has volume_page
|
||||
└─ Category (หมวดหมู่หลัก)
|
||||
└─ Sub-Category (หมวดหมู่ย่อย)
|
||||
└─ Sub-Category (หมวดหมู่ย่อย) -- Linked via Map Table
|
||||
└─ Drawing (แบบ)
|
||||
```
|
||||
|
||||
@@ -271,24 +271,39 @@ Volume (เล่ม)
|
||||
|
||||
**Tables:**
|
||||
|
||||
- `shop_drawing_main_categories` - หมวดหมู่หลัก (ARCH, STR, MEP, etc.)
|
||||
- `shop_drawing_sub_categories` - หมวดหมู่ย่อย
|
||||
- `shop_drawings` - Master แบบก่อสร้าง
|
||||
- `shop_drawing_revisions` - Revisions
|
||||
- `shop_drawing_main_categories` - หมวดหมู่หลัก (Project Specific)
|
||||
- `shop_drawing_sub_categories` - หมวดหมู่ย่อย (Project Specific)
|
||||
- `shop_drawings` - Master แบบก่อสร้าง (No title, number only)
|
||||
- `shop_drawing_revisions` - Revisions (Holds Title & Legacy Number)
|
||||
- `shop_drawing_revision_contract_refs` - M:N อ้างอิงแบบคู่สัญญา
|
||||
|
||||
**Revision Tracking:**
|
||||
|
||||
```sql
|
||||
-- Get latest revision of a shop drawing
|
||||
SELECT sd.drawing_number, sdr.revision_label, sdr.revision_date
|
||||
SELECT sd.shop_drawing_number, sdr.revision_label, sdr.revision_date
|
||||
FROM shop_drawings sd
|
||||
JOIN shop_drawing_revisions sdr ON sd.id = sdr.shop_drawing_id
|
||||
WHERE sd.drawing_number = 'SD-STR-001'
|
||||
WHERE sd.shop_drawing_number = 'SD-STR-001'
|
||||
ORDER BY sdr.revision_number DESC
|
||||
LIMIT 1;
|
||||
```
|
||||
|
||||
#### 5.3 As Built Drawings (แบบสร้างจริง) [NEW v1.7.0]
|
||||
|
||||
**Tables:**
|
||||
|
||||
- `asbuilt_drawings` - Master แบบสร้างจริง
|
||||
- `asbuilt_drawing_revisions` - Revisions history
|
||||
- `asbuilt_revision_shop_revisions_refs` - เชื่อมโยงกับ Shop Drawing Revision source
|
||||
- `asbuilt_drawing_revision_attachments` - ไฟล์แนบ (PDF/DWG)
|
||||
|
||||
**Business Rules:**
|
||||
|
||||
- As Built 1 ใบ อาจมาจาก Shop Drawing หลายใบ (Many-to-Many via refs table)
|
||||
- แยก Counter distinct จาก Shop Drawing และ Contract Drawing
|
||||
- รองรับไฟล์แนบหลายประเภท (PDF, DWG, SOURCE)
|
||||
|
||||
---
|
||||
|
||||
### 6. 🔄 Circulations & Transmittals
|
||||
@@ -400,7 +415,16 @@ CREATE TABLE document_number_counters (
|
||||
current_year INT,
|
||||
version INT DEFAULT 0, -- Optimistic Lock
|
||||
last_number INT DEFAULT 0,
|
||||
PRIMARY KEY (project_id, originator_organization_id, correspondence_type_id, discipline_id, current_year)
|
||||
PRIMARY KEY (
|
||||
project_id,
|
||||
originator_organization_id,
|
||||
recipient_organization_id,
|
||||
correspondence_type_id,
|
||||
sub_type_id,
|
||||
rfa_type_id,
|
||||
discipline_id,
|
||||
reset_scope
|
||||
)
|
||||
);
|
||||
```
|
||||
|
||||
|
||||
@@ -116,7 +116,7 @@ CREATE TABLE document_number_counters (
|
||||
rfa_type_id INT DEFAULT 0,
|
||||
discipline_id INT DEFAULT 0,
|
||||
reset_scope VARCHAR(20) NOT NULL,
|
||||
last_number INT DEFAULT 0 NOT NULL,,
|
||||
last_number INT DEFAULT 0 NOT NULL,
|
||||
version INT DEFAULT 0 NOT NULL,
|
||||
created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
@@ -124,7 +124,7 @@ CREATE TABLE document_number_counters (
|
||||
PRIMARY KEY (
|
||||
project_id,
|
||||
originator_organization_id,
|
||||
COALESCE(recipient_organization_id, 0),
|
||||
recipient_organization_id,
|
||||
correspondence_type_id,
|
||||
sub_type_id,
|
||||
rfa_type_id,
|
||||
@@ -142,10 +142,8 @@ CREATE TABLE document_number_counters (
|
||||
|
||||
CONSTRAINT chk_last_number_positive CHECK (last_number >= 0),
|
||||
CONSTRAINT chk_reset_scope_format CHECK (
|
||||
reset_scope IN ('NONE') OR
|
||||
reset_scope LIKE 'YEAR_%' OR
|
||||
reset_scope LIKE 'MONTH_%' OR
|
||||
reset_scope LIKE 'CONTRACT_%'
|
||||
reset_scope = 'NONE' OR
|
||||
reset_scope LIKE 'YEAR_%'
|
||||
)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci
|
||||
COMMENT='Running Number Counters';
|
||||
|
||||
@@ -140,19 +140,28 @@ CREATE TABLE document_number_formats (
|
||||
-- Counter Table with Optimistic Locking
|
||||
CREATE TABLE document_number_counters (
|
||||
project_id INT NOT NULL,
|
||||
doc_type_id INT NOT NULL,
|
||||
sub_type_id INT DEFAULT 0 COMMENT 'For Correspondence types, 0 = fallback',
|
||||
discipline_id INT DEFAULT 0 COMMENT 'For RFA/Drawing, 0 = fallback',
|
||||
recipient_type VARCHAR(20) DEFAULT NULL COMMENT 'For Transmittal: OWNER, CONTRACTOR, CONSULTANT, OTHER',
|
||||
year INT NOT NULL COMMENT 'ปี พ.ศ. หรือ ค.ศ. ตาม template',
|
||||
last_number INT DEFAULT 0,
|
||||
version INT DEFAULT 0 NOT NULL COMMENT 'Version for Optimistic Lock',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (project_id, doc_type_id, sub_type_id, discipline_id, COALESCE(recipient_type, ''), year),
|
||||
FOREIGN KEY (project_id) REFERENCES projects(id),
|
||||
FOREIGN KEY (doc_type_id) REFERENCES document_types(id),
|
||||
INDEX idx_counter_lookup (project_id, doc_type_id, year)
|
||||
) ENGINE=InnoDB COMMENT='Running number counters with optimistic locking';
|
||||
correspondence_type_id INT NULL,
|
||||
originator_organization_id INT NOT NULL,
|
||||
recipient_organization_id INT NOT NULL DEFAULT 0, -- 0 = no recipient (RFA)
|
||||
sub_type_id INT DEFAULT 0,
|
||||
rfa_type_id INT DEFAULT 0,
|
||||
discipline_id INT DEFAULT 0,
|
||||
reset_scope VARCHAR(20) NOT NULL,
|
||||
last_number INT DEFAULT 0 NOT NULL,
|
||||
version INT DEFAULT 0 NOT NULL,
|
||||
created_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6),
|
||||
updated_at DATETIME(6) DEFAULT CURRENT_TIMESTAMP(6) ON UPDATE CURRENT_TIMESTAMP(6),
|
||||
PRIMARY KEY (
|
||||
project_id,
|
||||
originator_organization_id,
|
||||
recipient_organization_id,
|
||||
correspondence_type_id,
|
||||
sub_type_id,
|
||||
rfa_type_id,
|
||||
discipline_id,
|
||||
reset_scope
|
||||
)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='Running Number Counters';
|
||||
|
||||
-- Audit Trail
|
||||
CREATE TABLE document_number_audit (
|
||||
|
||||
@@ -5,17 +5,20 @@ 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)
|
||||
- specs/01-requirements/01-03.11-document-numbering.md (v1.6.2)
|
||||
- specs/03-implementation/03-04-document-numbering.md (v1.6.2)
|
||||
related_task: TASK-FE-017-document-numbering-refactor.md
|
||||
---
|
||||
|
||||
## Objective
|
||||
|
||||
Refactor Document Numbering module ตาม specification v1.6.2 โดยเน้น:
|
||||
Refactor Document Numbering module ตาม specification v1.6.2 และ Implementation Guide โดยเน้น:
|
||||
- Single Numbering System (Option A)
|
||||
- Number State Machine (RESERVED → CONFIRMED → VOID → CANCELLED)
|
||||
- Two-Phase Commit implementation
|
||||
- Redis Distributed Lock
|
||||
- Idempotency-Key support
|
||||
- Counter Key alignment ตาม requirements
|
||||
- Complete Audit & Metrics
|
||||
|
||||
---
|
||||
|
||||
@@ -24,138 +27,128 @@ Refactor Document Numbering module ตาม specification v1.6.2 โดยเ
|
||||
### 1. Entity Updates
|
||||
|
||||
#### 1.1 DocumentNumberCounter Entity
|
||||
- [ ] Rename `current_year` → ใช้ `reset_scope` pattern (YEAR_2025, NONE)
|
||||
- [ ] 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
|
||||
- [ ] Add `rfa_type_id`, `sub_type_id`, `discipline_id` columns
|
||||
- [ ] Update Primary Key & Indices
|
||||
- [ ] Add `version` column for optimistic locking
|
||||
|
||||
```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`
|
||||
#### 1.2 New Entities (Create)
|
||||
- [ ] **DocumentNumberFormat**: Store templates per project/type (`document_number_formats` table)
|
||||
- [ ] **DocumentNumberReservation**: Store active reservations (`document_number_reservations` table)
|
||||
- [ ] **DocumentNumberAudit**: Store complete audit trail (`document_number_audit` table)
|
||||
- [ ] **DocumentNumberError**: Store error logs (`document_number_errors` table)
|
||||
|
||||
---
|
||||
|
||||
### 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.1 Core Services
|
||||
- [ ] **DocumentNumberingService**: Main orchestration (Reserve, Confirm, Cancel, Preview)
|
||||
- [ ] **CounterService**: Handle `incrementCounter` with DB optimistic lock & retry logic
|
||||
- [ ] **DocumentNumberingLockService**: Implement Redis Redlock (`acquireLock`, `releaseLock`)
|
||||
- [ ] **ReservationService**: Handle Two-Phase Commit logic (TTL, cleanup)
|
||||
|
||||
#### 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.2 Helper Services
|
||||
- [ ] **FormatService**: Format number string based on template & tokens
|
||||
- [ ] **TemplateService**: CRUD operations for `DocumentNumberFormat` and validation
|
||||
- [ ] **AuditService**: Async logging to `DocumentNumberAudit`
|
||||
- [ ] **MetricsService**: Prometheus counters/gauges (utilization, lock wait time)
|
||||
|
||||
#### 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
|
||||
#### 2.3 Feature Services
|
||||
- [ ] **ManualOverrideService**: Handle manual number assignment & sequence adjustment
|
||||
- [ ] **MigrationService**: Handle bulk import / legacy data migration
|
||||
|
||||
---
|
||||
|
||||
### 3. Controller Updates
|
||||
|
||||
#### 3.1 DocumentNumberingController
|
||||
- [ ] Add `POST /reserve` endpoint
|
||||
- [ ] Add `POST /confirm` endpoint
|
||||
- [ ] Add `POST /cancel` endpoint
|
||||
- [ ] Add `Idempotency-Key` header validation middleware
|
||||
- [ ] `POST /reserve`: Reserve number (Phase 1)
|
||||
- [ ] `POST /confirm`: Confirm number (Phase 2)
|
||||
- [ ] `POST /cancel`: Cancel reservation
|
||||
- [ ] `POST /preview`: Preview next number
|
||||
- [ ] `GET /sequences`: Get current sequence status
|
||||
- [ ] Add `Idempotency-Key` header validation
|
||||
|
||||
#### 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
|
||||
- [ ] `POST /manual-override`
|
||||
- [ ] `POST /void-and-replace`
|
||||
- [ ] `POST /bulk-import`
|
||||
- [ ] `POST /templates`: Manage templates
|
||||
|
||||
#### 3.3 NumberingMetricsController
|
||||
- [ ] `GET /metrics`: Expose utilization & health metrics for dashboard
|
||||
|
||||
---
|
||||
|
||||
### 4. Number State Machine
|
||||
### 4. Logic & Algorithms
|
||||
|
||||
```mermaid
|
||||
stateDiagram-v2
|
||||
[*] --> RESERVED: reserve()
|
||||
RESERVED --> CONFIRMED: confirm()
|
||||
RESERVED --> CANCELLED: cancel() or TTL expired
|
||||
CONFIRMED --> VOID: void()
|
||||
CANCELLED --> [*]
|
||||
VOID --> [*]
|
||||
```
|
||||
#### 4.1 Counter Key Builder
|
||||
- Implement logic to build unique key tuple:
|
||||
- Global: `(proj, orig, recip, type, 0, 0, 0, YEAR_XXXX)`
|
||||
- Transmittal: `(proj, orig, recip, type, subType, 0, 0, YEAR_XXXX)`
|
||||
- RFA: `(proj, orig, 0, type, 0, rfaType, discipline, NONE)`
|
||||
- Drawing: `(proj, TYPE, main, sub)` (separate namespace)
|
||||
|
||||
#### 4.1 State Transitions
|
||||
- [ ] Implement state validation before transitions
|
||||
- [ ] Log all transitions to audit table
|
||||
- [ ] TTL 5 minutes for RESERVED state
|
||||
#### 4.2 State Machine
|
||||
- [ ] Validate transitions: RESERVED -> CONFIRMED
|
||||
- [ ] Auto-expire RESERVED -> CANCELLED (via Cron/TTL)
|
||||
- [ ] CONFIRMED -> VOID
|
||||
|
||||
#### 4.3 Lock Strategy
|
||||
- [ ] Try Redis Lock -> if valid -> Increment -> Release
|
||||
- [ ] Fallback to DB Lock if Redis unavailable (optional/advanced)
|
||||
|
||||
---
|
||||
|
||||
### 5. Testing
|
||||
|
||||
#### 5.1 Unit Tests
|
||||
- [ ] CounterService.incrementCounter()
|
||||
- [ ] ReservationService.reserve/confirm/cancel()
|
||||
- [ ] TemplateValidator.validate()
|
||||
- [ ] CounterKeyBuilder
|
||||
- [ ] `CounterService` optimistic locking
|
||||
- [ ] `TemplateValidator` grammar check
|
||||
- [ ] `ReservationService` expiry logic
|
||||
|
||||
#### 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
|
||||
- [ ] Full Two-Phase Commit flow
|
||||
- [ ] Concurrent requests (check for duplicates)
|
||||
- [ ] Idempotency-Key behavior
|
||||
|
||||
---
|
||||
|
||||
## Files to Create/Modify
|
||||
|
||||
| Action | Path |
|
||||
| ------ | ------------------------------------------------------------------------------------------- |
|
||||
| :----- | :------------------------------------------------------------------------------------------ |
|
||||
| MODIFY | `backend/src/modules/document-numbering/document-numbering.module.ts` |
|
||||
| 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-format.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/entities/document-number-audit.entity.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/entities/document-number-error.entity.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/controllers/numbering-metrics.controller.ts` |
|
||||
| MODIFY | `backend/src/modules/document-numbering/services/document-numbering.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/counter.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/document-numbering-lock.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/reservation.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/manual-override.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/format.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/template.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/audit.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/services/metrics.service.ts` |
|
||||
| CREATE | `backend/src/modules/document-numbering/validators/template.validator.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
|
||||
- [ ] Schema matches `specs/03-implementation/03-04-document-numbering.md`
|
||||
- [ ] All 3 levels of locking (Redis, DB Optimistic, Unique Constraints) implemented
|
||||
- [ ] Zero duplicates in load test
|
||||
- [ ] Full audit trail visible
|
||||
|
||||
---
|
||||
|
||||
|
||||
37
specs/06-tasks/TASK-BE-018-v170-refactor.md
Normal file
37
specs/06-tasks/TASK-BE-018-v170-refactor.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: 'Task: Backend Refactoring for Schema v1.7.0'
|
||||
status: DONE
|
||||
owner: Backend Team
|
||||
created_at: 2025-12-23
|
||||
related:
|
||||
- specs/01-requirements/01-03.11-document-numbering.md
|
||||
- specs/07-database/lcbp3-v1.7.0-schema.sql
|
||||
- specs/07-database/data-dictionary-v1.7.0.md
|
||||
---
|
||||
|
||||
## Objective
|
||||
Update backend entities and logic to align with schema v1.7.0 and revised document numbering specifications.
|
||||
|
||||
## Scope of Work
|
||||
|
||||
### 1. Drawing Module
|
||||
- **Contract Drawings:**
|
||||
- Update `ContractDrawing` entity (map_cat_id, volume_page)
|
||||
- Create `ContractDrawingSubcatCatMap` entity
|
||||
- **Shop Drawings:**
|
||||
- Update `ShopDrawingMainCategory` (add project_id)
|
||||
- Update `ShopDrawingSubCategory` (add project_id, remove main_cat_id)
|
||||
- Update `ShopDrawing` (remove title)
|
||||
- Update `ShopDrawingRevision` (add title, legacy_number)
|
||||
- **As Built Drawings (New):**
|
||||
- Create entities for `asbuilt_drawings` and related tables.
|
||||
|
||||
### 2. Document Numbering Module
|
||||
- **Counters:**
|
||||
- Update `DocumentNumberCounter` entity to match 8-part Composite Key.
|
||||
- Ensure strict typing for `reset_scope`.
|
||||
|
||||
## Definition of Done
|
||||
- [x] All entities match v1.7.0 schema
|
||||
- [x] Application compiles without type errors
|
||||
- [x] Document Numbering service supports new key structure
|
||||
@@ -5,9 +5,9 @@ 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)
|
||||
- specs/06-tasks/TASK-BE-017-document-numbering-refactor.md
|
||||
- specs/01-requirements/01-03.11-document-numbering.md (v1.6.2)
|
||||
- specs/03-implementation/03-04-document-numbering.md (v1.6.2)
|
||||
---
|
||||
|
||||
## Objective
|
||||
@@ -136,13 +136,13 @@ interface AuditQueryParams {
|
||||
|
||||
### 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 |
|
||||
| Component | Path | Description |
|
||||
| ------------------ | -------------------------------------------------------- | --------------------------- |
|
||||
| MetricsDashboard | `frontend/components/numbering/metrics-dashboard.tsx` | Metrics charts and gauges |
|
||||
| AuditLogsTable | `frontend/components/numbering/audit-logs-table.tsx` | Filterable audit log viewer |
|
||||
| ManualOverrideForm | `frontend/components/numbering/manual-override-form.tsx` | Admin tool form |
|
||||
| VoidReplaceForm | `frontend/components/numbering/void-replace-form.tsx` | Admin tool form |
|
||||
| BulkImportForm | `frontend/components/numbering/bulk-import-form.tsx` | CSV/Excel uploader |
|
||||
|
||||
---
|
||||
|
||||
|
||||
53
specs/06-tasks/TASK-FE-019-v170-refactor.md
Normal file
53
specs/06-tasks/TASK-FE-019-v170-refactor.md
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: 'Task: Frontend Refactoring for Schema v1.7.0'
|
||||
status: IN_PROGRESS
|
||||
owner: Frontend Team
|
||||
created_at: 2025-12-23
|
||||
related:
|
||||
- specs/06-tasks/TASK-BE-018-v170-refactor.md
|
||||
- specs/07-database/data-dictionary-v1.7.0.md
|
||||
---
|
||||
|
||||
## Objective
|
||||
Update frontend application to align with the refactored backend (v1.7.0 schema). This includes supporting new field mappings, new As Built drawing type, and updated document numbering logic.
|
||||
|
||||
## Scope of Work
|
||||
|
||||
### 1. Type Definitions & API Client
|
||||
- **Types**: Update `Drawing`, `ContractDrawing`, `ShopDrawing` interfaces to match new backend entities (e.g. `mapCatId`, `projectId` in categories).
|
||||
- **API**: Update `drawing.service.ts` to support new filter parameters (`mapCatId`) and new endpoints for As Built drawings.
|
||||
|
||||
### 2. Drawing Upload Form (`DrawingUploadForm`)
|
||||
- **General**: Refactor to support dynamic fields based on Drawing Type.
|
||||
- **Contract Drawings**:
|
||||
- Replace `subCategoryId` with `mapCatId` (fetch from `contract-drawing-categories`?).
|
||||
- Add `volumePage` input.
|
||||
- **Shop Drawings**:
|
||||
- Remove `sheetNumber` (if not applicable) or map to `legacyDrawingNumber`.
|
||||
- Add `legacyDrawingNumber` input.
|
||||
- Handle `title` input (sent as revision title).
|
||||
- Use Project-specific categories.
|
||||
- **As Built Drawings (New)**:
|
||||
- Add "AS_BUILT" option.
|
||||
- Implement form fields similar to Shop Drawings (or Contract depending on spec).
|
||||
|
||||
### 3. Drawing List & Views (`DrawingList`)
|
||||
- **Contract Drawings**: Show `volumePage`.
|
||||
- **Shop Drawings**:
|
||||
- Display `legacyDrawingNumber`.
|
||||
- Display Title from *Current Revision*.
|
||||
- Remove direct title column from sort/filter if backend doesn't support it anymore on master.
|
||||
- **As Built Drawings**:
|
||||
- Add new Tab/Page for As Built.
|
||||
- Implement List View.
|
||||
|
||||
### 4. Logic & Hooks
|
||||
- Update `useDrawings`, `useCreateDrawing` hooks to handle new types.
|
||||
- Ensure validation schemas (`zod`) match backend constraints.
|
||||
|
||||
## Definition of Done
|
||||
- [x] Contract Drawing Upload works with `mapCatId` and `volumePage`
|
||||
- [x] Shop Drawing Upload works with `legacyDrawingNumber` and Revision Title
|
||||
- [x] As Built Drawing Upload and List implemented
|
||||
- [x] Drawing List displays correct columns for all types
|
||||
- [x] No TypeScript errors
|
||||
@@ -2,11 +2,18 @@
|
||||
|
||||
เอกสารนี้สรุปโครงสร้างตาราง,
|
||||
FOREIGN KEYS (FK),
|
||||
และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3 - DMS (v1.7.0) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด ** สถานะ: ** FINAL GUIDELINE ** วันที่: ** 2025 -12 -18 ** อ้างอิง: ** Requirements v1.7.0 & FullStackJS Guidelines v1.7.0 ** Classification: ** Internal Technical Documentation ## 📝 สรุปรายการปรับปรุง (Summary of Changes in v1.7.0)
|
||||
1. **Document Numbering Overhaul**: ปรับปรุงโครงสร้าง `document_number_counters` เปลี่ยน PK เป็น Composite 8 columns และใช้ `reset_scope` แทน `current_year`
|
||||
2. **Audit & Error Logging**: ปรับปรุงตาราง `document_number_audit`, `document_number_errors` และเพิ่ม `document_number_reservations`
|
||||
3. **JSON Schemas**: เพิ่ม columns `version`, `table_name`, `ui_schema`, `virtual_columns`, `migration_script` ในตาราง `json_schemas`
|
||||
4. **Schema Cleanup**: ลบ `correspondence_id` ออกจาก `rfa_revisions` และปรับปรุง Virtual Columns ใน `correspondence_revisions` ---
|
||||
และ Constraints ที่สำคัญทั้งหมดในฐานข้อมูล LCBP3 - DMS (v1.7.0) เพื่อใช้เป็นเอกสารอ้างอิงสำหรับทีมพัฒนา Backend (NestJS) และ Frontend (Next.js) โดยอิงจาก Requirements และ SQL Script ล่าสุด ** สถานะ: ** FINAL GUIDELINE ** วันที่: ** 2025 -12 -23 ** อ้างอิง: ** Requirements v1.7.0 & FullStackJS Guidelines v1.7.0 ** Classification: ** Internal Technical Documentation ## 📝 สรุปรายการปรับปรุง (Summary of Changes in v1.7.0)
|
||||
1. **Drawing Tables Restructuring**:
|
||||
- `contract_drawing_subcat_cat_maps`: เปลี่ยน PK จาก composite เป็น `id` AUTO_INCREMENT พร้อม UNIQUE constraint
|
||||
- `contract_drawings`: เปลี่ยน `sub_cat_id` → `map_cat_id` และเพิ่ม `volume_page`
|
||||
- `shop_drawing_main_categories` และ `shop_drawing_sub_categories`: เพิ่ม `project_id` (เปลี่ยนจาก global เป็น project-specific)
|
||||
- `shop_drawings`: ย้าย `title` ไปยัง `shop_drawing_revisions`
|
||||
- `shop_drawing_revisions`: เพิ่ม `title` และ `legacy_drawing_number`
|
||||
2. **AS Built Drawings (NEW)**: เพิ่มตาราง `asbuilt_drawings`, `asbuilt_drawing_revisions`, `asbuilt_revision_shop_revisions_refs`, และ `asbuilt_drawing_revision_attachments`
|
||||
3. **Document Numbering Overhaul**: ปรับปรุงโครงสร้าง `document_number_counters` เปลี่ยน PK เป็น Composite 8 columns และใช้ `reset_scope` แทน `current_year`
|
||||
4. **Audit & Error Logging**: ปรับปรุงตาราง `document_number_audit`, `document_number_errors` และเพิ่ม `document_number_reservations`
|
||||
5. **JSON Schemas**: เพิ่ม columns `version`, `table_name`, `ui_schema`, `virtual_columns`, `migration_script` ในตาราง `json_schemas`
|
||||
6. **Schema Cleanup**: ลบ `correspondence_id` ออกจาก `rfa_revisions` และปรับปรุง Virtual Columns ใน `correspondence_revisions` ---
|
||||
|
||||
## **1. 🏢 Core & Master Data Tables (องค์กร, โครงการ, สัญญา)**
|
||||
|
||||
@@ -718,19 +725,21 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
|
||||
---
|
||||
|
||||
### 5.4 contract_drawing_subcat_cat_maps
|
||||
### 5.4 contract_drawing_subcat_cat_maps (UPDATE v1.7.0)
|
||||
|
||||
**Purpose**: Junction table mapping sub-categories to main categories (M:N)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ----------- | --------- | --------------- | -------------------------- |
|
||||
| project_id | INT | PRIMARY KEY, FK | Reference to projects |
|
||||
| sub_cat_id | INT | PRIMARY KEY, FK | Reference to sub-category |
|
||||
| cat_id | INT | PRIMARY KEY, FK | Reference to main category |
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ----------- | --------- | ------------------------------- | -------------------------- |
|
||||
| **id** | **INT** | **PRIMARY KEY, AUTO_INCREMENT** | **Unique mapping ID** |
|
||||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||||
| sub_cat_id | INT | NOT NULL, FK | Reference to sub-category |
|
||||
| cat_id | INT | NOT NULL, FK | Reference to main category |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (project_id, sub_cat_id, cat_id)
|
||||
* PRIMARY KEY (id)
|
||||
* **UNIQUE KEY (project_id, sub_cat_id, cat_id)**
|
||||
* FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
||||
* FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats(id) ON DELETE CASCADE
|
||||
* FOREIGN KEY (cat_id) REFERENCES contract_drawing_cats(id) ON DELETE CASCADE
|
||||
@@ -740,47 +749,49 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
**Relationships**:
|
||||
|
||||
* Parent: projects, contract_drawing_sub_cats, contract_drawing_cats
|
||||
* Referenced by: contract_drawings
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Allows flexible categorization
|
||||
* One sub-category can belong to multiple main categories
|
||||
* All three fields required for uniqueness
|
||||
* Composite uniqueness enforced via UNIQUE constraint
|
||||
|
||||
---
|
||||
|
||||
### 5.5 contract_drawings
|
||||
### 5.5 contract_drawings (UPDATE v1.7.0)
|
||||
|
||||
**Purpose**: Master table for contract drawings (from contract specifications)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ----------- | ------------ | ----------------------------------- | ------------------------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID |
|
||||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||||
| condwg_no | VARCHAR(255) | NOT NULL | Contract drawing number |
|
||||
| title | VARCHAR(255) | NOT NULL | Drawing title |
|
||||
| sub_cat_id | INT | NULL, FK | Reference to sub-category |
|
||||
| volume_id | INT | NULL, FK | Reference to volume |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp |
|
||||
| deleted_at | DATETIME | NULL | Soft delete timestamp |
|
||||
| updated_by | INT | NULL, FK | User who last updated |
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| --------------- | ------------ | ----------------------------------- | ---------------------------------------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID |
|
||||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||||
| condwg_no | VARCHAR(255) | NOT NULL | Contract drawing number |
|
||||
| title | VARCHAR(255) | NOT NULL | Drawing title |
|
||||
| **map_cat_id** | **INT** | **NULL, FK** | **[CHANGED] Reference to mapping table** |
|
||||
| volume_id | INT | NULL, FK | Reference to volume |
|
||||
| **volume_page** | **INT** | **NULL** | **[NEW] Page number within volume** |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp |
|
||||
| deleted_at | DATETIME | NULL | Soft delete timestamp |
|
||||
| updated_by | INT | NULL, FK | User who last updated |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (id)
|
||||
* FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE
|
||||
* FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats(id) ON DELETE RESTRICT
|
||||
* **FOREIGN KEY (map_cat_id) REFERENCES contract_drawing_subcat_cat_maps(id) ON DELETE RESTRICT**
|
||||
* FOREIGN KEY (volume_id) REFERENCES contract_drawing_volumes(id) ON DELETE RESTRICT
|
||||
* FOREIGN KEY (updated_by) REFERENCES users(user_id)
|
||||
* UNIQUE KEY (project_id, condwg_no)
|
||||
* INDEX (sub_cat_id)
|
||||
* INDEX (map_cat_id)
|
||||
* INDEX (volume_id)
|
||||
* INDEX (deleted_at)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Parent: projects, contract_drawing_sub_cats, contract_drawing_volumes, users
|
||||
* Parent: projects, contract_drawing_subcat_cat_maps, contract_drawing_volumes, users
|
||||
* Referenced by: shop_drawing_revision_contract_refs, contract_drawing_attachments
|
||||
|
||||
**Business Rules**:
|
||||
@@ -789,16 +800,18 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
* Represents baseline/contract drawings
|
||||
* Referenced by shop drawings for compliance tracking
|
||||
* Soft delete preserves history
|
||||
* **map_cat_id references the mapping table for flexible categorization**
|
||||
|
||||
---
|
||||
|
||||
### 5.6 shop_drawing_main_categories
|
||||
### 5.6 shop_drawing_main_categories (UPDATE v1.7.0)
|
||||
|
||||
**Purpose**: Master table for shop drawing main categories (discipline-level)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ------------------ | ------------ | ----------------------------------- | ------------------------------------ |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique category ID |
|
||||
| **project_id** | **INT** | **NOT NULL, FK** | **[NEW] Reference to projects** |
|
||||
| main_category_code | VARCHAR(50) | NOT NULL, UNIQUE | Category code (ARCH, STR, MEP, etc.) |
|
||||
| main_category_name | VARCHAR(255) | NOT NULL | Category name |
|
||||
| description | TEXT | NULL | Category description |
|
||||
@@ -810,31 +823,33 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (id)
|
||||
* **FOREIGN KEY (project_id) REFERENCES projects(id)**
|
||||
* UNIQUE (main_category_code)
|
||||
* INDEX (is_active)
|
||||
* INDEX (sort_order)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Referenced by: shop_drawing_sub_categories, shop_drawings
|
||||
* **Parent: projects**
|
||||
* Referenced by: shop_drawings, asbuilt_drawings
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Global categories (not project-specific)
|
||||
* **[CHANGED] Project-specific categories (was global)**
|
||||
* Typically represents engineering disciplines
|
||||
|
||||
---
|
||||
|
||||
### 5.7 shop_drawing_sub_categories
|
||||
### 5.7 shop_drawing_sub_categories (UPDATE v1.7.0)
|
||||
|
||||
**Purpose**: Master table for shop drawing sub-categories (component-level)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ----------------- | ------------ | ----------------------------------- | ----------------------------------------------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique sub-category ID |
|
||||
| **project_id** | **INT** | **NOT NULL, FK** | **[NEW] Reference to projects** |
|
||||
| sub_category_code | VARCHAR(50) | NOT NULL, UNIQUE | Sub-category code (STR-COLUMN, ARCH-DOOR, etc.) |
|
||||
| sub_category_name | VARCHAR(255) | NOT NULL | Sub-category name |
|
||||
| main_category_id | INT | NOT NULL, FK | Reference to main category |
|
||||
| description | TEXT | NULL | Sub-category description |
|
||||
| sort_order | INT | DEFAULT 0 | Display order |
|
||||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||||
@@ -844,26 +859,25 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (id)
|
||||
* **FOREIGN KEY (project_id) REFERENCES projects(id)**
|
||||
* UNIQUE (sub_category_code)
|
||||
* FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories(id)
|
||||
* INDEX (main_category_id)
|
||||
* INDEX (is_active)
|
||||
* INDEX (sort_order)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Parent: shop_drawing_main_categories
|
||||
* Referenced by: shop_drawings
|
||||
* **Parent: projects**
|
||||
* Referenced by: shop_drawings, asbuilt_drawings
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Global sub-categories (not project-specific)
|
||||
* Hierarchical under main categories
|
||||
* **[CHANGED] Project-specific sub-categories (was global)**
|
||||
* **[REMOVED] No longer hierarchical under main categories**
|
||||
* Represents specific drawing types or components
|
||||
|
||||
---
|
||||
|
||||
### 5.8 shop_drawings
|
||||
### 5.8 shop_drawings (UPDATE v1.7.0)
|
||||
|
||||
**Purpose**: Master table for shop drawings (contractor-submitted)
|
||||
|
||||
@@ -872,7 +886,6 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID |
|
||||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||||
| drawing_number | VARCHAR(100) | NOT NULL, UNIQUE | Shop drawing number |
|
||||
| title | VARCHAR(500) | NOT NULL | Drawing title |
|
||||
| main_category_id | INT | NOT NULL, FK | Reference to main category |
|
||||
| sub_category_id | INT | NOT NULL, FK | Reference to sub-category |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||||
@@ -904,22 +917,25 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
* Represents contractor shop drawings
|
||||
* Can have multiple revisions
|
||||
* Soft delete preserves history
|
||||
* **[CHANGED] Title moved to shop_drawing_revisions table**
|
||||
|
||||
---
|
||||
|
||||
### 5.9 shop_drawing_revisions
|
||||
### 5.9 shop_drawing_revisions (UPDATE v1.7.0)
|
||||
|
||||
**Purpose**: Child table storing revision history of shop drawings (1:N)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| --------------- | ----------- | --------------------------- | ------------------------------ |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID |
|
||||
| shop_drawing_id | INT | NOT NULL, FK | Master shop drawing ID |
|
||||
| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) |
|
||||
| revision_label | VARCHAR(10) | NULL | Display revision (A, B, C...) |
|
||||
| revision_date | DATE | NULL | Revision date |
|
||||
| description | TEXT | NULL | Revision description/changes |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp |
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ------------------------- | ---------------- | --------------------------- | ---------------------------------------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID |
|
||||
| shop_drawing_id | INT | NOT NULL, FK | Master shop drawing ID |
|
||||
| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) |
|
||||
| revision_label | VARCHAR(10) | NULL | Display revision (A, B, C...) |
|
||||
| revision_date | DATE | NULL | Revision date |
|
||||
| **title** | **VARCHAR(500)** | **NOT NULL** | **[NEW] Drawing title** |
|
||||
| description | TEXT | NULL | Revision description/changes |
|
||||
| **legacy_drawing_number** | **VARCHAR(100)** | **NULL** | **[NEW] Original/legacy drawing number** |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
@@ -931,7 +947,7 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
**Relationships**:
|
||||
|
||||
* Parent: shop_drawings
|
||||
* Referenced by: rfa_items, shop_drawing_revision_contract_refs, shop_drawing_revision_attachments
|
||||
* Referenced by: rfa_items, shop_drawing_revision_contract_refs, shop_drawing_revision_attachments, asbuilt_revision_shop_revisions_refs
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
@@ -939,6 +955,8 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
* Each revision can reference multiple contract drawings
|
||||
* Each revision can have multiple file attachments
|
||||
* Linked to RFAs for approval tracking
|
||||
* **[NEW] Title stored at revision level for version-specific naming**
|
||||
* **[NEW] legacy_drawing_number supports data migration from old systems**
|
||||
|
||||
---
|
||||
|
||||
@@ -970,6 +988,148 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
|
||||
---
|
||||
|
||||
### 5.11 asbuilt_drawings (NEW v1.7.0)
|
||||
|
||||
**Purpose**: Master table for AS Built drawings (final construction records)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| ---------------- | ------------ | ----------------------------------- | -------------------------- |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique drawing ID |
|
||||
| project_id | INT | NOT NULL, FK | Reference to projects |
|
||||
| drawing_number | VARCHAR(100) | NOT NULL, UNIQUE | AS Built drawing number |
|
||||
| main_category_id | INT | NOT NULL, FK | Reference to main category |
|
||||
| sub_category_id | INT | NOT NULL, FK | Reference to sub-category |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Record creation timestamp |
|
||||
| updated_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP ON UPDATE | Last update timestamp |
|
||||
| deleted_at | DATETIME | NULL | Soft delete timestamp |
|
||||
| updated_by | INT | NULL, FK | User who last updated |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (id)
|
||||
* UNIQUE (drawing_number)
|
||||
* FOREIGN KEY (project_id) REFERENCES projects(id)
|
||||
* FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories(id)
|
||||
* FOREIGN KEY (sub_category_id) REFERENCES shop_drawing_sub_categories(id)
|
||||
* FOREIGN KEY (updated_by) REFERENCES users(user_id)
|
||||
* INDEX (project_id)
|
||||
* INDEX (main_category_id)
|
||||
* INDEX (sub_category_id)
|
||||
* INDEX (deleted_at)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Parent: projects, shop_drawing_main_categories, shop_drawing_sub_categories, users
|
||||
* Children: asbuilt_drawing_revisions
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Drawing numbers are globally unique across all projects
|
||||
* Represents final as-built construction drawings
|
||||
* Can have multiple revisions
|
||||
* Soft delete preserves history
|
||||
* Uses same category structure as shop drawings
|
||||
|
||||
---
|
||||
|
||||
### 5.12 asbuilt_drawing_revisions (NEW v1.7.0)
|
||||
|
||||
**Purpose**: Child table storing revision history of AS Built drawings (1:N)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| --------------------- | ------------ | --------------------------- | ------------------------------ |
|
||||
| id | INT | PRIMARY KEY, AUTO_INCREMENT | Unique revision ID |
|
||||
| asbuilt_drawing_id | INT | NOT NULL, FK | Master AS Built drawing ID |
|
||||
| revision_number | INT | NOT NULL | Revision sequence (0, 1, 2...) |
|
||||
| revision_label | VARCHAR(10) | NULL | Display revision (A, B, C...) |
|
||||
| revision_date | DATE | NULL | Revision date |
|
||||
| title | VARCHAR(500) | NOT NULL | Drawing title |
|
||||
| description | TEXT | NULL | Revision description/changes |
|
||||
| legacy_drawing_number | VARCHAR(100) | NULL | Original/legacy drawing number |
|
||||
| created_at | TIMESTAMP | DEFAULT CURRENT_TIMESTAMP | Revision creation timestamp |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (id)
|
||||
* FOREIGN KEY (asbuilt_drawing_id) REFERENCES asbuilt_drawings(id) ON DELETE CASCADE
|
||||
* UNIQUE KEY (asbuilt_drawing_id, revision_number)
|
||||
* INDEX (revision_date)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Parent: asbuilt_drawings
|
||||
* Referenced by: asbuilt_revision_shop_revisions_refs, asbuilt_drawing_revision_attachments
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Revision numbers are sequential starting from 0
|
||||
* Each revision can reference multiple shop drawing revisions
|
||||
* Each revision can have multiple file attachments
|
||||
* Title stored at revision level for version-specific naming
|
||||
* legacy_drawing_number supports data migration from old systems
|
||||
|
||||
---
|
||||
|
||||
### 5.13 asbuilt_revision_shop_revisions_refs (NEW v1.7.0)
|
||||
|
||||
**Purpose**: Junction table linking AS Built drawing revisions to shop drawing revisions (M:N)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| --------------------------- | --------- | --------------- | ---------------------------------- |
|
||||
| asbuilt_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to AS Built revision |
|
||||
| shop_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to shop drawing revision |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (asbuilt_drawing_revision_id, shop_drawing_revision_id)
|
||||
* FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions(id) ON DELETE CASCADE
|
||||
* FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions(id) ON DELETE CASCADE
|
||||
* INDEX (shop_drawing_revision_id)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Parent: asbuilt_drawing_revisions, shop_drawing_revisions
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Tracks which shop drawings each AS Built drawing revision is based on
|
||||
* Maintains construction document lineage
|
||||
* One AS Built revision can reference multiple shop drawing revisions
|
||||
* Supports traceability from final construction to approved shop drawings
|
||||
|
||||
---
|
||||
|
||||
### 5.14 asbuilt_drawing_revision_attachments (NEW v1.7.0)
|
||||
|
||||
**Purpose**: Junction table linking AS Built drawing revisions to file attachments (M:N)
|
||||
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| --------------------------- | ------------------------------------- | --------------- | ------------------------------------- |
|
||||
| asbuilt_drawing_revision_id | INT | PRIMARY KEY, FK | Reference to AS Built revision |
|
||||
| attachment_id | INT | PRIMARY KEY, FK | Reference to attachment file |
|
||||
| file_type | ENUM('PDF', 'DWG', 'SOURCE', 'OTHER') | NULL | File type classification |
|
||||
| is_main_document | BOOLEAN | DEFAULT FALSE | Main document flag (1 = primary file) |
|
||||
|
||||
**Indexes**:
|
||||
|
||||
* PRIMARY KEY (asbuilt_drawing_revision_id, attachment_id)
|
||||
* FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions(id) ON DELETE CASCADE
|
||||
* FOREIGN KEY (attachment_id) REFERENCES attachments(id) ON DELETE CASCADE
|
||||
* INDEX (attachment_id)
|
||||
|
||||
**Relationships**:
|
||||
|
||||
* Parent: asbuilt_drawing_revisions, attachments
|
||||
|
||||
**Business Rules**:
|
||||
|
||||
* Each AS Built revision can have multiple file attachments
|
||||
* File types: PDF (documents), DWG (CAD files), SOURCE (source files), OTHER (miscellaneous)
|
||||
* One attachment can be marked as main document per revision
|
||||
* Cascade delete when revision is deleted
|
||||
|
||||
---
|
||||
|
||||
## **6. 🔄 Circulations Tables (ใบเวียนภายใน)**
|
||||
|
||||
### 6.1 circulation_status_codes
|
||||
@@ -1281,6 +1441,7 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
| correspondence_type_id | INT | NOT NULL, FK | Reference to correspondence_types |
|
||||
| format_string | VARCHAR(100) | NOT NULL | Format pattern (e.g., {ORG}-{TYPE}-{YYYY}-#) |
|
||||
| description | TEXT | NULL | Format description |
|
||||
| reset_annually | BOOLEAN | DEFAULT TRUE | Start sequence new every year |
|
||||
| is_active | TINYINT(1) | DEFAULT 1 | Active status |
|
||||
|
||||
**Indexes**:
|
||||
@@ -1341,17 +1502,20 @@ SET NULL - INDEX (is_active) - INDEX (email) ** Relationships **: - Parent: orga
|
||||
| Column Name | Data Type | Constraints | Description |
|
||||
| :------------------------- | :----------- | :----------------- | :-------------------------------------- |
|
||||
| id | INT | PK, AI | ID ของ audit record |
|
||||
| document_id | INT | NOT NULL, FK | ID ของเอกสารที่สร้างเลขที่ |
|
||||
| document_id | INT | NULL, FK | ID ของเอกสารที่สร้างเลขที่ (NULL if failed) |
|
||||
| document_type | VARCHAR(50) | NULL | ประเภทเอกสาร |
|
||||
| document_number | VARCHAR(100) | NOT NULL | เลขที่เอกสารที่สร้าง (ผลลัพธ์) |
|
||||
| operation | ENUM | DEFAULT 'CONFIRM' | RESERVE, CONFIRM, MANUAL_OVERRIDE, etc. |
|
||||
| status | ENUM | DEFAULT 'RESERVED' | RESERVED, CONFIRMED, CANCELLED, VOID |
|
||||
| counter_key | JSON | NOT NULL | Counter key ที่ใช้ (JSON 8 fields) |
|
||||
| reservation_token | VARCHAR(36) | NULL | Token การจอง |
|
||||
| idempotency_key | VARCHAR(128) | NULL | Idempotency Key from request |
|
||||
| originator_organization_id | INT | NULL | องค์กรผู้ส่ง |
|
||||
| recipient_organization_id | INT | NULL | องค์กรผู้รับ |
|
||||
| template_used | VARCHAR(200) | NOT NULL | Template ที่ใช้ในการสร้าง |
|
||||
| user_id | INT | NOT NULL, FK | ผู้ขอสร้างเลขที่ |
|
||||
| old_value | TEXT | NULL | Previous value |
|
||||
| new_value | TEXT | NULL | New value |
|
||||
| user_id | INT | NULL, FK | ผู้ขอสร้างเลขที่ |
|
||||
| is_success | BOOLEAN | DEFAULT TRUE | สถานะความสำเร็จ |
|
||||
| created_at | TIMESTAMP | DEFAULT NOW | วันที่/เวลาที่สร้าง |
|
||||
| total_duration_ms | INT | NULL | เวลารวมทั้งหมดในการสร้าง (ms) |
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
-- ==========================================================
|
||||
-- DMS v1.6.0 Document Management System Database
|
||||
-- DMS v1.7.0 Document Management System Database
|
||||
-- Deploy Script Schema
|
||||
-- Server: Container Station on QNAP TS-473A
|
||||
-- Database service: MariaDB 11.8
|
||||
@@ -10,11 +10,22 @@
|
||||
-- reverse proxy: jc21/nginx-proxy-manager:latest
|
||||
-- cron service: n8n
|
||||
-- ==========================================================
|
||||
-- [v1.6.0 UPDATE] Refactor Schema
|
||||
-- Update: Upgraded from v1.5.1
|
||||
-- Last Updated: 2025-12-13
|
||||
-- [v1.7.0 UPDATE] Refactor Schema
|
||||
-- Update: Upgraded from v1.6.0
|
||||
-- Last Updated: 2025-12-18
|
||||
-- Major Changes:
|
||||
-- 1. ปรับปรุง: corespondences, correspondence_revisions, correspondence_recipients, rfas, rfa_revisions
|
||||
-- 1. ปรับปรุง:
|
||||
-- 1.1 TABLE contract_drawings
|
||||
-- 1.2 TABLE contract_drawing_subcat_cat_maps
|
||||
-- 1.3 TABLE shop_drawing_sub_categories
|
||||
-- 1.4 TABLE shop_drawing_main_categories
|
||||
-- 1.5 TABLE shop_drawings
|
||||
-- 1.6 TABLE shop_drawing_revisions
|
||||
-- 2. เพิ่ม:
|
||||
-- 2.1 TABLE asbuilt_drawings
|
||||
-- 2.2 TABLE asbuilt_drawing_revisions
|
||||
-- 2.3 TABLE asbuilt_revision_shop_revisions_refs
|
||||
-- 2.4 TABLE asbuilt_drawing_revision_attachments
|
||||
-- ==========================================================
|
||||
SET NAMES utf8mb4;
|
||||
|
||||
@@ -73,6 +84,8 @@ DROP TABLE IF EXISTS document_number_reservations;
|
||||
-- ============================================================
|
||||
DROP TABLE IF EXISTS correspondence_tags;
|
||||
|
||||
DROP TABLE IF EXISTS asbuilt_revision_shop_revisions_refs;
|
||||
|
||||
DROP TABLE IF EXISTS shop_drawing_revision_contract_refs;
|
||||
|
||||
DROP TABLE IF EXISTS contract_drawing_subcat_cat_maps;
|
||||
@@ -86,6 +99,8 @@ DROP TABLE IF EXISTS circulation_attachments;
|
||||
|
||||
DROP TABLE IF EXISTS shop_drawing_revision_attachments;
|
||||
|
||||
DROP TABLE IF EXISTS asbuilt_drawing_revision_attachments;
|
||||
|
||||
DROP TABLE IF EXISTS correspondence_attachments;
|
||||
|
||||
DROP TABLE IF EXISTS attachments;
|
||||
@@ -113,6 +128,8 @@ DROP TABLE IF EXISTS transmittal_items;
|
||||
|
||||
DROP TABLE IF EXISTS shop_drawing_revisions;
|
||||
|
||||
DROP TABLE IF EXISTS asbuilt_drawing_revisions;
|
||||
|
||||
DROP TABLE IF EXISTS rfa_items;
|
||||
|
||||
DROP TABLE IF EXISTS rfa_revisions;
|
||||
@@ -135,6 +152,8 @@ DROP TABLE IF EXISTS contract_drawings;
|
||||
|
||||
DROP TABLE IF EXISTS shop_drawings;
|
||||
|
||||
DROP TABLE IF EXISTS asbuilt_drawings;
|
||||
|
||||
DROP TABLE IF EXISTS rfas;
|
||||
|
||||
DROP TABLE IF EXISTS correspondences;
|
||||
@@ -720,12 +739,7 @@ CREATE TABLE contract_drawing_subcat_cat_maps (
|
||||
project_id INT COMMENT 'ID ของโครงการ',
|
||||
sub_cat_id INT COMMENT 'ID ของหมวดหมู่ย่อย',
|
||||
cat_id INT COMMENT 'ID ของหมวดหมู่หลัก',
|
||||
PRIMARY KEY (
|
||||
id,
|
||||
project_id,
|
||||
sub_cat_id,
|
||||
cat_id
|
||||
),
|
||||
UNIQUE KEY ux_map_unique (project_id, sub_cat_id, cat_id),
|
||||
FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (sub_cat_id) REFERENCES contract_drawing_sub_cats (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (cat_id) REFERENCES contract_drawing_cats (id) ON DELETE CASCADE
|
||||
@@ -821,6 +835,49 @@ CREATE TABLE shop_drawing_revision_contract_refs (
|
||||
FOREIGN KEY (contract_drawing_id) REFERENCES contract_drawings (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมระหว่าง shop_drawing_revisions กับ contract_drawings (M :N)';
|
||||
|
||||
-- ตาราง Master เก็บข้อมูล "AS Built"
|
||||
CREATE TABLE asbuilt_drawings (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของตาราง',
|
||||
project_id INT NOT NULL COMMENT 'โครงการ',
|
||||
drawing_number VARCHAR(100) NOT NULL UNIQUE COMMENT 'เลขที่ AS Built Drawing',
|
||||
main_category_id INT NOT NULL COMMENT 'หมวดหมู่หลัก',
|
||||
sub_category_id INT NOT NULL COMMENT 'หมวดหมู่ย่อย',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
deleted_at DATETIME NULL COMMENT 'วันที่ลบ',
|
||||
updated_by INT COMMENT 'ผู้แก้ไขล่าสุด',
|
||||
FOREIGN KEY (project_id) REFERENCES projects (id),
|
||||
FOREIGN KEY (main_category_id) REFERENCES shop_drawing_main_categories (id),
|
||||
FOREIGN KEY (sub_category_id) REFERENCES shop_drawing_sub_categories (id)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง Master เก็บข้อมูล "แบบก่อสร้าง"';
|
||||
|
||||
-- ตาราง "ลูก" เก็บประวัติ (Revisions) ของ shop_drawings (1:N)
|
||||
CREATE TABLE asbuilt_drawing_revisions (
|
||||
id INT PRIMARY KEY AUTO_INCREMENT COMMENT 'ID ของ Revision',
|
||||
asbuilt_drawing_id INT NOT NULL COMMENT 'Master ID',
|
||||
revision_number INT NOT NULL COMMENT 'หมายเลข Revision (เช่น 0, 1, 2...)',
|
||||
revision_label VARCHAR(10) COMMENT 'Revision ที่แสดง (เช่น A, B, 1.1)',
|
||||
revision_date DATE COMMENT 'วันที่ของ Revision',
|
||||
title VARCHAR(500) NOT NULL COMMENT 'ชื่อแบบ',
|
||||
description TEXT COMMENT 'คำอธิบายการแก้ไข',
|
||||
legacy_drawing_number VARCHAR(100) NULL COMMENT 'เลขที่เดิมของ AS Built Drawing',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
FOREIGN KEY (asbuilt_drawing_id) REFERENCES asbuilt_drawings (id) ON DELETE CASCADE,
|
||||
UNIQUE KEY ux_sd_rev_drawing_revision (asbuilt_drawing_id, revision_number)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตาราง "ลูก" เก็บประวัติ (Revisions) ของ asbuilt_drawings (1 :N)';
|
||||
|
||||
-- ตารางเชื่อมระหว่าง asbuilt_drawing_revisions กับ shop_drawings (M:N)
|
||||
CREATE TABLE asbuilt_revision_shop_revisions_refs (
|
||||
asbuilt_drawing_revision_id INT COMMENT 'ID ของ AS Built Drawing Revision',
|
||||
shop_drawing_revision_id INT COMMENT 'ID ของ Shop Drawing Revision',
|
||||
PRIMARY KEY (
|
||||
asbuilt_drawing_revision_id,
|
||||
shop_drawing_revision_id
|
||||
),
|
||||
FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (shop_drawing_revision_id) REFERENCES shop_drawing_revisions (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อมระหว่าง asbuilt_drawing_revisions กับ shop_drawing_revisions (M :N)';
|
||||
|
||||
-- =====================================================
|
||||
-- 6. 🔄 Circulations (ใบเวียนภายใน)
|
||||
-- =====================================================
|
||||
@@ -926,6 +983,25 @@ CREATE TABLE circulation_attachments (
|
||||
FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม circulations กับ attachments (M :N)';
|
||||
|
||||
-- ตารางเชื่อม shop_drawing_revisions กับ attachments (M:N)
|
||||
CREATE TABLE asbuilt_drawing_revision_attachments (
|
||||
asbuilt_drawing_revision_id INT COMMENT 'ID ของ asbuilt Drawing Revision',
|
||||
attachment_id INT COMMENT 'ID ของไฟล์แนบ',
|
||||
file_type ENUM(
|
||||
'PDF',
|
||||
'DWG',
|
||||
'SOURCE',
|
||||
'OTHER '
|
||||
) COMMENT 'ประเภทไฟล์',
|
||||
is_main_document BOOLEAN DEFAULT FALSE COMMENT '(1 = ไฟล์หลัก)',
|
||||
PRIMARY KEY (
|
||||
asbuilt_drawing_revision_id,
|
||||
attachment_id
|
||||
),
|
||||
FOREIGN KEY (asbuilt_drawing_revision_id) REFERENCES asbuilt_drawing_revisions (id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (attachment_id) REFERENCES attachments (id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเชื่อม asbuilt_drawing_revisions กับ attachments (M :N)';
|
||||
|
||||
-- ตารางเชื่อม shop_drawing_revisions กับ attachments (M:N)
|
||||
CREATE TABLE shop_drawing_revision_attachments (
|
||||
shop_drawing_revision_id INT COMMENT 'ID ของ Shop Drawing Revision',
|
||||
@@ -973,13 +1049,10 @@ CREATE TABLE document_number_formats (
|
||||
project_id INT NOT NULL COMMENT 'โครงการ',
|
||||
correspondence_type_id INT NULL COMMENT 'ประเภทเอกสาร',
|
||||
discipline_id INT DEFAULT 0 COMMENT 'สาขางาน (0 = ทุกสาขา/ไม่ระบุ)',
|
||||
format_template VARCHAR(255) NOT NULL COMMENT 'รูปแบบ Template (เช่น {ORG}-{RECIPIENT}-{SEQ:4}-{YEAR:BE})',
|
||||
reset_sequence_yearly TINYINT(1) DEFAULT 1,
|
||||
example_number VARCHAR(100) COMMENT 'ตัวอย่างเลขที่ได้จาก Template',
|
||||
padding_length INT DEFAULT 4 COMMENT 'ความยาวของลำดับเลข (Padding)',
|
||||
format_string VARCHAR(100) NOT NULL COMMENT 'Format pattern (e.g., {ORG}-{TYPE}-{YYYY}-#)',
|
||||
description TEXT COMMENT 'Format description',
|
||||
reset_annually BOOLEAN DEFAULT TRUE COMMENT 'เริ่มนับใหม่ทุกปี',
|
||||
is_active BOOLEAN DEFAULT TRUE COMMENT 'สถานะการใช้งาน',
|
||||
description TEXT COMMENT 'คำอธิบายรูปแบบนี้',
|
||||
is_active TINYINT(1) DEFAULT 1 COMMENT 'สถานะการใช้งาน',
|
||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP COMMENT 'วันที่สร้าง',
|
||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT 'วันที่แก้ไขล่าสุด',
|
||||
FOREIGN KEY (project_id) REFERENCES projects (id) ON DELETE CASCADE,
|
||||
@@ -1038,10 +1111,11 @@ CREATE TABLE document_number_counters (
|
||||
-- Constraints
|
||||
CONSTRAINT chk_last_number_positive CHECK (last_number >= 0),
|
||||
CONSTRAINT chk_reset_scope_format CHECK (
|
||||
reset_scope IN ('NONE')
|
||||
OR reset_scope LIKE 'YEAR_%'
|
||||
OR reset_scope LIKE 'MONTH_%'
|
||||
OR reset_scope LIKE 'CONTRACT_%')
|
||||
reset_scope IN ('NONE')
|
||||
OR reset_scope LIKE 'YEAR_%'
|
||||
OR reset_scope LIKE 'MONTH_%'
|
||||
OR reset_scope LIKE 'CONTRACT_%'
|
||||
)
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'ตารางเก็บ Running Number Counters - รองรับ 8-column composite PK';
|
||||
|
||||
-- ==========================================================
|
||||
@@ -1052,7 +1126,7 @@ CREATE TABLE document_number_counters (
|
||||
CREATE TABLE document_number_audit (
|
||||
id INT AUTO_INCREMENT PRIMARY KEY COMMENT 'ID ของ audit record',
|
||||
-- Document Info
|
||||
document_id INT NOT NULL COMMENT 'ID ของเอกสารที่สร้างเลขที่ (correspondences.id)',
|
||||
document_id INT NULL COMMENT 'ID ของเอกสารที่สร้างเลขที่ (correspondences.id) - NULL if failed/reserved',
|
||||
document_type VARCHAR(50),
|
||||
document_number VARCHAR(100) NOT NULL COMMENT 'เลขที่เอกสารที่สร้าง (ผลลัพธ์)',
|
||||
operation ENUM(
|
||||
@@ -1062,23 +1136,23 @@ CREATE TABLE document_number_audit (
|
||||
'VOID_REPLACE',
|
||||
'CANCEL'
|
||||
) NOT NULL DEFAULT 'CONFIRM' COMMENT 'ประเภทการดำเนินการ',
|
||||
status ENUM(
|
||||
STATUS ENUM(
|
||||
'RESERVED',
|
||||
'CONFIRMED',
|
||||
'CANCELLED',
|
||||
'CANCELLED',
|
||||
'VOID',
|
||||
'MANUAL'
|
||||
) NOT NULL DEFAULT 'RESERVED' COMMENT 'สถานะเลขที่เอกสาร',
|
||||
counter_key JSON NOT NULL COMMENT 'Counter key ที่ใช้ (JSON format) - 8 fields',
|
||||
reservation_token VARCHAR(36) NULL,
|
||||
idempotency_key VARCHAR(128) NULL COMMENT 'Idempotency Key from request',
|
||||
originator_organization_id INT NULL,
|
||||
recipient_organization_id INT NULL,
|
||||
|
||||
template_used VARCHAR(200) NOT NULL COMMENT 'Template ที่ใช้ในการสร้าง',
|
||||
old_value TEXT NULL,
|
||||
new_value TEXT NULL,
|
||||
old_value TEXT NULL COMMENT 'Previous value for audit',
|
||||
new_value TEXT NULL COMMENT 'New value for audit',
|
||||
-- User Info
|
||||
user_id INT NOT NULL COMMENT 'ผู้ขอสร้างเลขที่',
|
||||
user_id INT NULL COMMENT 'ผู้ขอสร้างเลขที่',
|
||||
ip_address VARCHAR(45) COMMENT 'IP address ของผู้ขอ (IPv4/IPv6)',
|
||||
user_agent TEXT COMMENT 'User agent string (browser info)',
|
||||
is_success BOOLEAN DEFAULT TRUE,
|
||||
@@ -1089,14 +1163,14 @@ CREATE TABLE document_number_audit (
|
||||
total_duration_ms INT COMMENT 'เวลารวมทั้งหมดในการสร้าง (milliseconds)',
|
||||
fallback_used ENUM('NONE', 'DB_LOCK', 'RETRY') DEFAULT 'NONE' COMMENT 'Fallback strategy ที่ถูกใช้ (NONE=normal, DB_LOCK=Redis down, RETRY=conflict)',
|
||||
metadata JSON COMMENT 'Additional context data',
|
||||
|
||||
-- Indexes for performance
|
||||
INDEX idx_document_id (document_id),
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_status (status),
|
||||
INDEX idx_status (STATUS),
|
||||
INDEX idx_operation (operation),
|
||||
INDEX idx_document_number (document_number),
|
||||
INDEX idx_reservation_token (reservation_token),
|
||||
INDEX idx_idempotency_key (idempotency_key),
|
||||
INDEX idx_created_at (created_at),
|
||||
-- Foreign Keys
|
||||
FOREIGN KEY (document_id) REFERENCES correspondences (id) ON DELETE CASCADE,
|
||||
@@ -1172,11 +1246,13 @@ CREATE TABLE document_number_reservations (
|
||||
INDEX idx_user_id (user_id),
|
||||
INDEX idx_reserved_at (reserved_at),
|
||||
-- Foreign Keys
|
||||
FOREIGN KEY (document_id) REFERENCES correspondence_revisions(id) ON DELETE SET NULL,
|
||||
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
|
||||
FOREIGN KEY (document_id) REFERENCES correspondence_revisions(id) ON DELETE
|
||||
SET NULL,
|
||||
FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (correspondence_type_id) REFERENCES correspondence_types(id) ON DELETE CASCADE,
|
||||
FOREIGN KEY (user_id) REFERENCES users(user_id) ON DELETE CASCADE
|
||||
) ENGINE = InnoDB DEFAULT CHARSET = utf8mb4 COLLATE = utf8mb4_general_ci COMMENT = 'Document Number Reservations - Two-Phase Commit';
|
||||
|
||||
-- =====================================================
|
||||
-- 10. ⚙️ System & Logs (ระบบและ Log)
|
||||
-- =====================================================
|
||||
@@ -1488,7 +1564,6 @@ CREATE INDEX idx_backup_logs_completed_at ON backup_logs (completed_at);
|
||||
-- Additional Composite Indexes for Performance
|
||||
-- =====================================================
|
||||
-- Composite index for document_number_counters for faster lookups
|
||||
|
||||
-- Composite index for notifications for user-specific queries
|
||||
CREATE INDEX idx_notifications_user_unread ON notifications (user_id, is_read, created_at);
|
||||
|
||||
@@ -1902,4 +1977,8 @@ CREATE INDEX idx_correspondences_project_type ON correspondences (project_id, co
|
||||
|
||||
CREATE INDEX idx_corr_revisions_status_current ON correspondence_revisions (correspondence_status_id, is_current);
|
||||
|
||||
CREATE INDEX IDX_AUDIT_DOC_ID ON document_number_audit (document_id);
|
||||
CREATE INDEX IDX_AUDIT_STATUS ON document_number_audit (status);
|
||||
CREATE INDEX IDX_AUDIT_OPERATION ON document_number_audit (operation);
|
||||
|
||||
SET FOREIGN_KEY_CHECKS = 1;
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -13,3 +13,6 @@
|
||||
## TABLE shop_drawing_revisions
|
||||
- add title
|
||||
- add legacy_drawing_number VARCHAR(100) NULL COMMENT 'เลขที่เดิมของ Shop Drawing',
|
||||
## TABLE asbuilt_drawings
|
||||
## TABLE asbuilt_drawing_revisions
|
||||
## TABLE asbuilt_revision_shop_revisions_refs
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
# Session History - 2025-12-23: Document Numbering Form Refactoring
|
||||
|
||||
## Objective
|
||||
Refactor and debug the "Test Number Generation" (Template Tester) form to support real API validation and master data integration.
|
||||
|
||||
## Key Changes
|
||||
|
||||
### 1. Frontend Refactoring (`template-tester.tsx`)
|
||||
- **Master Data Integration**: Replaced manual text inputs with `Select` components for Originator, Recipient, Document Type, and Discipline.
|
||||
- **Dynamic Data Hook**:
|
||||
- Integrated `useOrganizations`, `useCorrespondenceTypes`, and `useDisciplines`.
|
||||
- Fixed empty Discipline list by adding `useContracts` to fetch active contracts for the project and deriving `contractId` dynamically.
|
||||
- **API Integration**: Switched from mock `generateTestNumber` to backend `previewNumber` endpoint.
|
||||
- **UI Enhancements**:
|
||||
- Added "Default (All Types)" and "None" options to dropdowns.
|
||||
- Improved error feedback with a visible error card if generation fails.
|
||||
- **Type Safety**:
|
||||
- Resolved multiple lint errors (`Unexpected any`, missing properties).
|
||||
- Updated `SearchOrganizationDto` in `organization.dto.ts` to include `isActive`.
|
||||
|
||||
### 2. Backend API Harmonization
|
||||
- **DTO Updates**:
|
||||
- Refactored `PreviewNumberDto` to use `originatorId` and `typeId` (aligned with frontend naming).
|
||||
- Added `@Type(() => Number)` and `@IsInt()` to ensure proper payload transformation.
|
||||
- **Service Logic**:
|
||||
- Fixed `CounterService` mapping to correctly use the entity property `originatorId` instead of the DTO naming `originatorOrganizationId` in WHERE clauses and creation logic.
|
||||
- Updated `DocumentNumberingController` to map the new DTO properties.
|
||||
|
||||
### 3. Troubleshooting & Reversion
|
||||
- **Issue**: "Format Preview" was reported as missing.
|
||||
- **Action**: Attempted a property rename from `formatTemplate` to `formatString` across the frontend based on database column naming.
|
||||
- **Result**: This caused the entire Document Numbering page to fail (UI became empty) because the backend entity still uses the property name `formatTemplate`.
|
||||
- **Resolution**: Reverted all renaming changes back to `formatTemplate`. The initial "missing" issue was resolved by ensuring proper prop passing and data loading.
|
||||
|
||||
## Status
|
||||
- **Test Generation Form**: Fully functional and integrated with real master data.
|
||||
- **Preview API**: Validated and working with correct database mapping.
|
||||
- **Next Steps**: Monitor for any further data-specific generation errors (e.g., Template format parsing).
|
||||
|
||||
---
|
||||
**Reference Task**: [TASK-FE-017-document-numbering-refactor.md](../06-tasks/TASK-FE-017-document-numbering-refactor.md)
|
||||
38
specs/09-history/2025-12-23-frontend-refactor-v170.md
Normal file
38
specs/09-history/2025-12-23-frontend-refactor-v170.md
Normal file
@@ -0,0 +1,38 @@
|
||||
# Session History: Frontend Refactoring for v1.7.0 Schema
|
||||
|
||||
**Date:** 2025-12-23
|
||||
**Objective:** Refactor frontend components and services to align with the v1.7.0 database schema and document numbering requirements.
|
||||
|
||||
## 1. Summary of Changes
|
||||
|
||||
### Frontend Refactoring
|
||||
- **`DrawingUploadForm` Refactor:**
|
||||
- Implemented dynamic validation validation schemas using Zod discriminated unions.
|
||||
- Added support for Contract Drawing fields: `mapCatId`, `volumePage`.
|
||||
- Added support for Shop/AsBuilt fields: `legacyDrawingNumber`, `revisionTitle`.
|
||||
- Added full support for `AS_BUILT` drawing type.
|
||||
- Dynamically passes `projectId` to context hooks.
|
||||
- **`DrawingList` & `DrawingCard`:**
|
||||
- Added `AS_BUILT` tab support.
|
||||
- Implemented conditional rendering for new columns (`Volume Page`, `Legacy No.`, `Rev. Title`).
|
||||
- **Service Layer Updates:**
|
||||
- Migrated `ContractDrawingService`, `ShopDrawingService`, and `AsbuiltDrawingService` to use `FormData` for all creation/upload methods to ensure correct binary file handling.
|
||||
- Updated Types to fully match backend DTOs.
|
||||
- **Documentation:**
|
||||
- Updated `task.md` and `walkthrough.md`.
|
||||
|
||||
## 2. Issues Encountered & Status
|
||||
|
||||
### Resolved
|
||||
- Fixed `Unexpected any` lint errors in `DrawingUploadForm` (mostly).
|
||||
- Resolved type mismatches in state identifiers.
|
||||
|
||||
### Known Issues (Pending Fix)
|
||||
- **Build Failure**: `pnpm build` failed in `frontend/app/(admin)/admin/numbering/[id]/page.tsx`.
|
||||
- **Error**: `Object literal may only specify known properties, and 'templateId' does not exist in type 'Partial<NumberingTemplate>'.`
|
||||
- **Location**: `numberingApi.saveTemplate({ ...data, templateId: parseInt(params.id) });`
|
||||
- **Cause**: The `saveTemplate` method likely expects a specific DTO that conflicts with the spread `...data` or the explicit `templateId` property assignment. This needs to be addressed in the next session.
|
||||
|
||||
## 3. Next Steps
|
||||
- Fix the build error in `admin/numbering/[id]/page.tsx`.
|
||||
- Proceed with full end-to-end testing of the drawing upload flows.
|
||||
Reference in New Issue
Block a user