# 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 ```