Sơ đồ hệ thống
Trang này gom các sơ đồ nên mở khi cần trả lời nhanh trước hội đồng. Nếu cần nhìn cây thư mục hoặc luồng mở file để sửa code, mở Sơ đồ thư mục và luồng file. Nếu cần truy ngược file chi tiết, hãy mở song song Source map, API endpoint index và Full File CodeMap.
Runtime tổng quan
flowchart LR User["Student / Teacher / Admin"] Browser["Angular 20 PWA
Signals, routes, guards"] API["Spring Boot API
Clean Architecture / DDD"] DB["PostgreSQL 16
Flyway migrations"] R2["Cloudflare R2
files, video packages"] Worker["Dedicated video-worker
ingest/package"] Edge["Caddy + Cloudflare Worker
HTTPS, media auth"] Wiii["Wiii iframe/API
AI assistant + Pointy"] User --> Browser Browser --> API Browser -. postMessage .-> Wiii API --> DB API --> R2 API --> Worker Worker --> R2 Edge --> API Edge --> R2
Backend Clean Architecture
flowchart TB Controller["infrastructure/web
REST Controller"] UseCase["application/usecase
Business orchestration"] Domain["domain/model + valueobject
Pure domain, no JPA"] Port["domain/repository
Repository port"] Adapter["infrastructure/persistence
Adapter + Mapper"] JpaEntity["infrastructure/persistence/entity
*JpaEntity"] JpaRepo["Spring Data JpaRepository
JpaEntity only"] Postgres["PostgreSQL"] Controller --> UseCase UseCase --> Domain UseCase --> Port Port --> Adapter Adapter --> JpaEntity Adapter --> JpaRepo JpaRepo --> Postgres
Điểm phải nhớ: lỗi Not a managed type thường xảy ra khi JpaRepository dùng domain model thay vì *JpaEntity.
Database theo domain
Publication versioning
sequenceDiagram autonumber participant T as Teacher participant FE as Angular course editor participant API as CourseAuthoringControllerV3 participant PUB as CoursePublicationService participant ADM as Admin approval participant LD as Learning delivery T->>FE: Edit draft chapter/lesson/content block FE->>API: Save draft changes T->>FE: Submit for approval FE->>API: POST submit-for-approval API->>PUB: Build publication snapshot ADM->>API: Approve course API->>PUB: Mark approved publication version LD->>PUB: Read learner-facing snapshot
Wiii safe action contract
sequenceDiagram
autonumber
participant Host as LMS host page
participant Bridge as WiiiContextService
participant Wiii as Wiii iframe
participant UI as Safe DOM target
Host->>Bridge: Register route, user role, course/lesson context
Bridge->>Wiii: postMessage wiii:page-context
Wiii->>Bridge: Request action by data-wiii-id
Bridge->>UI: Verify data-wiii-click-safe=true
alt Safe navigation or preview action
Bridge->>UI: Click or open preview
Bridge->>Wiii: Return observed result
else Dangerous mutation
Bridge-->>Wiii: Reject with requires-human-review
end
Các hành động như submit quiz, delete, publish, enroll, grade, payment và mutate dữ liệu nguy hiểm không được tự động click.
Video, storage và offline
flowchart LR Teacher["Teacher upload video"] Upload["Presigned upload session"] R2Raw["R2 raw object"] Ingest["Video ingest job"] Shaka["Shaka Packager
HLS/DASH"] R2Pkg["R2 packaged manifests
segments"] Player["AdaptiveVideoPlayerComponent"] Offline["Dexie / IndexedDB
offline profile"] Progress["Progress sync queue"] Teacher --> Upload Upload --> R2Raw R2Raw --> Ingest Ingest --> Shaka Shaka --> R2Pkg R2Pkg --> Player Player --> Offline Offline --> Progress
Payment confirmation
sequenceDiagram autonumber participant S as Student participant FE as Angular payment UI participant API as PaymentControllerV3 participant Provider as VNPay / SePay participant Enroll as Enrollment use case S->>FE: Choose paid course FE->>API: Create payment request API->>Provider: Create redirect or QR Provider-->>FE: Return redirect/QR Provider->>API: Callback/webhook API->>API: Verify signature / transaction content API->>Enroll: Activate enrollment when paid FE->>API: Poll or reload payment status
Khi bị hỏi nên mở file nào
| Câu hỏi | Mở trang | Từ khóa search |
|---|---|---|
| Vì sao backend không trộn JPA vào domain? | Backend | Not a managed type, JpaEntity, CourseRepositoryAdapter |
| Khóa học sửa xong vì sao học viên chưa thấy? | Publication versioning | submit-for-approval, CoursePublicationService |
| AI Wiii có tự publish/xóa được không? | Wiii integration | data-wiii-click-safe, WiiiContextService |
| Video chạy adaptive/offline ra sao? | Video và offline | ShakaPackagerService, AdaptiveVideoPlayerComponent |
| Payment xác nhận thế nào? | Payment và revenue | PaymentControllerV3, sepay/webhook |