# Thiết kế VALIDATION SERVICE
[https://mermaid.live/](https://mermaid.live/)
## PROBLEM ANALYSIS
### Đầu vào
- 1 LargeAudio
- Danh sách CutAudio là các đoạn nhỏ cắt ra từ LargeAudio, có text
- Giới hạn start/end của CutAudio có thể gặp các vấn đề:
- Cắt vào giữa từ
- Cắt vào giữa câu (cắt vào đoạn ngập ngừng, ngắt nghỉ rất ngắn ở giữa câu)
- Đầu/cuối là các đoạn im lặng
- Text của CutAudio có thể gặp các vấn đề:
- Text không đúng
- Hậu xử lý không đúng
### Xử lý
#### Xác thực giới hạn của CutAudio
- Có 3 thao tác có thể thực hiện với 1 CutAudio
- Chỉnh start hoặc end
- KQ: 2-3 CutAudio
- Tất cả CutAudio đều có text là text của CutAudio ban đầu
- Gộp với CutAudio liền kề
- KQ: 1 CutAudio
- Text của CutAudio mới gộp là ghép từ tất cả các CutAudio ban đầu
- Tách ở giữa CutAudio
- KQ: 2 CutAudio
- Cả 2 CutAudio đều có text là text của CutAudio ban đầu
- **Trình tự xử lý với case: Cắt vào giữa câu/từ**
- Câu nằm gọn trong CutAudio:
- **B**: Chỉnh start/end của CutAudio vừa gộp
- **B**: Validate Text => Thêm/sửa/xóa text tương ứng cho các CutAudio vừa thu được
- Câu nằm ngoài CutAudio:
- **B**: Gộp với 1/nhiều CutAudio trước/sau CutAudio hiện tại
- **B**: Chỉnh start/end của CutAudio vừa gộp
- **B**: Validate Text => Thêm/sửa/xóa text tương ứng cho các CutAudio vừa thu được
- **Trình tự xử lý với case: Đầu cuối là các đoạn im lặng**
- **B**: Tách ở giữa, từ vị trí X phân tách của region có text và im lặng
- **B**: Validate Text => Đánh dấu Im lặng cho CutAudio tương ứng
- Ngoài ra, các CutAudio còn thể ở dạng mix giữa các case trên, ta vẫn sẽ dựa trên các bước cơ bản để xử lý từng vấn đề một. Trình tự ưu tiên xử lý:
- Cắt vào câu/từ
- Đầu cuối là các đoạn im lặng
#### Hậu xử lý kết quả xác thực giới hạn của CutAudio:
- Nhiều CutAudio đánh tag là Im lặng liền nhau => Gộp giới hạn của các CutAudio này lại thành 1 CutAudio duy nhất, có tag là im lặng
#### Xác thực text với CutAudio đã xác thực giới hạn
- Ghép/Tách text đối với giới hạn mới
- Nếu không thể tự động Ghép/Tách text thì phải nghe và điền thủ công.
### Đầu ra
- Danh sách CutAudio là các đoạn nhỏ cắt ra từ LargeAudio thỏa mãn:
- Giới hạn đúng
- Text đúng hoặc đánh dấu là Im lặng
## SEQUENCE DIAGRAMS
### Flow Tạo chiến dịch Xác thực Audio (Create AudioValidation Campaign)
```mermaid
sequenceDiagram
autoNumber
actor A as Admin
participant dcmAUI as DCM admin ui
participant dcmBB as DCM backend base
participant dcmVAL as DCM validation
participant dcmPSD as DCM publish speech data
participant dcmUUI as DCM user ui
actor U as Validation Contributor
A->>dcmAUI: Create validation campaign
dcmAUI-->>dcmAUI: Show validation campain page
A->>dcmAUI: Enter basic information
A->>dcmAUI: Select validation campaign type
A->>dcmAUI: Select branch validation campaign type
A->>+dcmAUI: Create campaign
dcmAUI->>+dcmBB: Create draft campaign
dcmBB-->>-dcmAUI: Return
dcmAUI->>+dcmVAL: Get validation data <br> (filter/input)
dcmVAL->>+dcmPSD: Get validation data <br> (filter/input)
dcmPSD-->>-dcmVAL: Return
dcmVAL-->>-dcmAUI: Return
dcmAUI-->>-dcmAUI: Show Audio List
A->>dcmAUI: Select Audio into Room <br>(Create campaign Assignment)
A->>+dcmAUI: Confirm campaign
dcmAUI->>+dcmBB: Confirm campaign
dcmBB->>+dcmVAL: Webhook create validation campaign
dcmVAL-->>-dcmBB: Return
dcmBB-->>-dcmAUI: Return
A->>dcmAUI: Edit Campaign detail
A->>dcmAUI: Divide audio (task) into room and assign room to contributor
dcmAUI->>+dcmVAL: Confirm assignment
dcmVAL-->>-dcmAUI: Return
U->>+dcmUUI: View campaigns
dcmUUI->>+dcmBB: Get campaigns
dcmBB-->>-dcmUUI: Send back campaigns
dcmUUI-->>-dcmUUI: Show user campaign page
U->>dcmUUI: Select campaign
dcmUUI->>dcmVAL: Get val data
dcmVAL-->>dcmUUI: Send back val data
dcmUUI-->>dcmUUI: Show validation room page
```
### Flow Chỉnh sửa start/end CutAudio (Modify CutAudio's Endpoints)
```mermaid
sequenceDiagram
autoNumber
actor C as Client
participant VUI as ValidateUI
participant VS as Validate Server
participant DB as Database
participant A as Audio Server
C->>VUI: Select Region
C->>+VUI: Click Modify
VUI->>+VS: ModifyCutAudioEndpoint<br>(OriginalCutAudio-OCA, LargeAudio, <br>modifiedStart, modifiedEnd)
VS->>A: GetCutAudio<br>(LargeAudio, modifiedStart, modifiedEnd)
A-->>VS: Return CutAudio = modifiedCutAudio
VS->>VS: leftCutAudio<br> = CreateCutAudio(LargeAudio, startOCA, modifiedStart)
VS->>VS: rightCutAudio<br> = CreateCutAudio(LargeAudio, endOCA, modifiedEnd)
VS->>DB: InsertCutAudios<br>(leftCutAudio, rightCutAudio)
Note right of VS: Set leftover CutAudios' text <br>= orginalCutAudio's text
VS->>DB: UpdateCutAudios<br>(OriginalCutAudio, modifiedStart, modifiedEnd)
VS->>DB: GetCutAudioList(LargeAudio)
VS-->>-VUI: Return modifiedCutAudios <br>and CutAudio List
VUI->>VUI: Show updated CutAudio List
VUI->>-VUI: Play modifiedCutAudio
```
### Flow Gộp CutAudio (Merge Audios)
```mermaid
sequenceDiagram
autoNumber
actor C as Client
participant VUI as ValidateUI
participant VS as ValidateServer
participant DB as Database
participant A as AudioServer
C->>VUI: Click Action button<br>on CutAudio Row
C->>+VUI: Select Merge Previous/<br>Merge Next CutAudio
VUI->>+VS: MergeCutAudio<br>(LargeAudio,<br>cutAudioLeft, cutAudioRight)
VS->>A: GetCutAudio(LargeAudio, start, end)<br>start = cutAudioLeft's start<br>end = cutAudioRight's end
A-->>VS: Return CutAudio = mergedCutAudio
VS->>DB: InsertCutAudios<br>(mergedCutAudio)
Note right of VS: Set mergedCutAudios' text <br>= concat(both CutAudio's text)
VS->>DB: DeleteCutAudios<br>(cutAudioLeft, cutAudioRight)
VS->>DB: GetCutAudioList(LargeAudio)
VS-->>-VUI: Return mergedCutAudio <br>and CutAudio List
VUI->>VUI: Show updated CutAudio List
VUI->>-VUI: Play mergedCutAudio
```
### Flow Tách ở giữa CutAudio (Split CutAudio)
```mermaid
sequenceDiagram
autoNumber
actor C as Client
participant VUI as ValidateUI
participant VS as ValidateServer
participant DB as ValidateDB
participant A as AudioServer
C->>VUI: Move cursor to the split point
C->>+VUI: Click Split
VUI->>+VS: SplitCutAudio<br>(OriginalCutAudio-OCA, LargeAudio, <br>startOCA, midOCA, endOCA)
VS->>A: Get2AdjacentCutAudios<br>(LargeAudio, startOCA, midOCA, endOCA)
A-->>VS: Return 2 CutAudios<br> = splitCutAudios
VS->>DB: InsertCutAudios<br>(splitCutAudios, originalCutAudioText)
Note right of VS: Set both splitCutAudios' text <br>= orginalCutAudio's text
VS->>DB: DeleteCutAudios<br>(OriginalCutAudio)
VS->>DB: GetCutAudioList(LargeAudio)
VS-->>-VUI: Return splitCutAudios <br>and CutAudio List
VUI->>VUI: Show updated CutAudio List
VUI->>-VUI: Play leftside CutAudio.
```
### Flow quản lý Audio trên AudioServer
```mermaid
sequenceDiagram
autoNumber
participant C as Client
participant AS as AudioServer
participant AC as AudioCache
participant AW as AudioWatcher
participant DB as AudioDB
C->>+AS: Request / Do Action<br>(AudioURL)
AS->>+AC: GetAudio(AudioURL)
alt If Audio doesn't exist
AC->>DB: Load Audio(AudioURL)
DB-->>AC: Return Audio
AC->>AC: Cache Audio with <br>Key = AudioURL
end
AC->>AC: setLastLoadAt(AudioURL, now)
AC-->>-AS: Return Audio
AS->>AS: do Something on Audio
AS-->>-C: Return Result
loop Every minute
AW->>+AC: Expired Cache
AC->>AC: Check lastLoadAt of all Audio in Cache
alt lastLoadAt > threshold
AC->>AC: Delete Cache (key=AudioURL)
end
AC-->>-AW: Void
end
C->>+AS: Finish(AudioURL)
AS->>AC: Release(AudioURL)
AC->>AC: Delete Cache (key=AudioURL)
AS-->>-C: Void
```