LMS Hàng Hải - Codebase Handbook và CodeMap
Tài liệu tra cứu nhanh để học sâu codebase, chuẩn bị bảo vệ, và xử lý tình huống thầy yêu cầu sửa code trực tiếp.
Nội dung dựa trên quét local tại E:\Sach\Sua\LMS_hohulili ngày 2026-06-13.
1. Cách Học Nhanh Trong 30 Phút
Nếu chỉ có ít thời gian, hãy học theo 4 lớp: nghiệp vụ, frontend, backend, và dữ liệu/runtime.
Câu giới thiệu dự án
Đây là hệ thống LMS cho đào tạo hàng hải, gồm quản lý khóa học, chương/bài học, lớp học, ghi danh, quiz, bài tập, chấm điểm, tiến độ, chứng chỉ, thanh toán, PWA offline, adaptive video và tích hợp AI/Wiii.
Câu giới thiệu kiến trúc
Frontend dùng Angular 20 theo Signals và lazy routes. Backend dùng Spring Boot theo Clean Architecture/DDD. PostgreSQL quản lý dữ liệu bằng Flyway migration. File/video dùng Cloudflare R2, Shaka Packager và worker riêng.
Lộ trình đọc code khi bị hỏi
*routes.ts2. Chạy Local Và Mở Công Cụ
Backend bằng Docker
cd E:\Sach\Sua\LMS_hohulili
copy .env.dev.example .env
docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d db backend
curl.exe -s http://localhost:8088/actuator/health
Frontend Angular
cd E:\Sach\Sua\LMS_hohulili\fe
npm install
npm start
| Bề mặt | URL | Ghi chú |
|---|---|---|
| Frontend | http://localhost:4200 | Angular dev server. |
| Backend API | http://localhost:8088/api/v3 | Spring Boot qua host port 8088. |
| Swagger | http://localhost:8088/swagger-ui | Xem endpoints và thử API. |
| Health | http://localhost:8088/actuator/health | Kỳ vọng {"status":"UP"}. |
Mở code và công cụ
| Công cụ | Cách mở | Dùng khi nào? |
|---|---|---|
| VS Code | cd E:\Sach\Sua\LMS_hohulilicode . | Mở toàn repo, sửa frontend, docs, scripts, tìm nhanh bằng rg. |
| IntelliJ IDEA | Mở thư mục E:\Sach\Sua\LMS_hohulili\backend | Đọc Spring Boot, Maven, Java use case, JPA entity, test backend. |
| DBeaver | Kết nối PostgreSQL local: host localhost, port 5432, DB lms, user lms | Xem schema, khóa ngoại, ERD, dữ liệu mẫu và kiểm bảng sau migration. |
Tài khoản test
| Role | Password | |
|---|---|---|
| ADMIN | admin@maritime.edu | redacted-local-seed |
| ORG_ADMIN | orgadmin@maritime.edu | redacted-local-seed |
| TEACHER | teacher@maritime.edu | redacted-local-seed |
| STUDENT | student@maritime.edu | redacted-local-seed |
3. Kiến Trúc Tổng Quan
4. CodeMap Tổng
4.0. Bản đồ file đầy đủ
Trang handbook này dùng để học kiến trúc và luồng nghiệp vụ. Khi cần tra nhanh một class, service, migration,
route hoặc file cụ thể, mở bản đồ file đầy đủ có search/filter tại
lms-full-file-codemap-2026-06-13.html.
Trang đó được sinh lại từ source hiện tại bằng node scripts/generate-codemap-report.mjs
và có cột symbol để tìm theo tên như WiiiContextService, QuizControllerV3,
CourseAuthoringUseCase.
4.1. Backend module map
| Module | Files | Controllers | Domain | Application | Infrastructure | Vai trò |
|---|---|---|---|---|---|---|
identity | 95 | 5 | 18 | 41 | 36 | Auth, user, role, org, invite, Google login. |
course_authoring | 104 | 8 | 20 | 37 | 42 | Course, chapter, lesson, publication, review. |
learning_delivery | 143 | 15 | 22 | 39 | 82 | Enrollment, class, progress, video, certificate. |
assessment | 107 | 8 | 28 | 31 | 48 | Quiz, assignment, submission, rubric, question bank. |
shared | 157 | 16 | 32 | 32 | 82 | Upload, payment, sync, audit, storage, Wiii integration. |
communication | 34 | 2 | 8 | 10 | 16 | Messages, announcements. |
ai_assistant | 19 | 2 | 4 | 6 | 9 | AI chat, Wiii adapter, token exchange. |
competency_mapping | 31 | 1 | 6 | 13 | 12 | STCW/competency map. |
config | 17 | 0 | 0 | 0 | 0 | Security, CORS, filters, app config. |
4.2. Frontend feature map
| Feature | TS | HTML | SCSS | Routes | Vai trò |
|---|---|---|---|---|---|
teacher | 146 | 38 | 15 | 5 | Course editor, dashboard, assignment hub, grading, revenue. |
ai-chat | 57 | 1 | 2 | 1 | AI widget, Wiii context, Pointy, preview dialog. |
admin | 36 | 23 | 25 | 1 | User/course management, review, analytics, settings. |
learning | 30 | 6 | 2 | 1 | Student course learning, adaptive video, notes, bookmarks. |
student | 27 | 10 | 7 | 2 | Dashboard, enrolled courses, tasks, grades, storage. |
auth | 17 | 1 | 0 | 1 | Login, Google callback, reset password, join org. |
courses | 13 | 3 | 0 | 0 | Public browse/detail/category pages. |
payment | 8 | 0 | 0 | 1 | Payment success/failed/callback/refund. |
4.3. Bản đồ module dễ nhớ
5. Frontend Angular
5.1. Thư mục chính
| Thư mục | Vai trò | Khi nào mở? |
|---|---|---|
fe/src/app/features | Màn hình theo nghiệp vụ. | Khi thầy chỉ một trang UI. |
fe/src/app/api | API client, endpoint constants, DTO types, interceptors. | Khi API sai URL, sai type hoặc cần thêm endpoint. |
fe/src/app/core | Auth, guards, services singleton, offline DB, upload, PWA. | Khi sửa auth, offline, upload, global behavior. |
fe/src/app/shared | Component dùng lại, block renderer, editor, upload UI. | Khi UI xuất hiện nhiều nơi. |
fe/src/app/state | State service toàn app. | Khi dữ liệu dùng xuyên nhiều feature. |
5.2. Teacher course editor
| File | Vai trò |
|---|---|
fe/src/app/features/teacher/teacher.routes.ts | Route teacher, preview, editor, assignment, student, revenue. |
fe/src/app/features/teacher/course-editor/course-editor.routes.ts | Route con info, curriculum, competency, settings, classes. |
course-editor/store/course-editor.store.ts | Course tree, readiness checklist, cache, optimistic reorder/move. |
course-editor/services/course-authoring.service.ts | DTO và HTTP calls tới teacher/course authoring backend. |
course-editor/pages/course-curriculum | Chỉnh chapter, lesson, section, upload material. |
course-editor/pages/course-info | Thông tin khóa học, category, pricing, thumbnail, intro video. |
5.3. Đổi màu và style
rg "#0056D2|--c-primary|--c-accent|bg-\[|text-\[" fe/src
- Theme global:
fe/src/styles.scss. - Design tokens Sass:
fe/src/styles/_variables.scss. - Critical layout/Fouc:
fe/src/styles/critical.scss. - Angular Material theme: tìm
mat.themetrongstyles.scss. - Component-specific Tailwind/arbitrary color: tìm trực tiếp trong template hoặc component.
6. Backend Spring Boot DDD
6.1. Quy tắc lớp
JpaRepository<SomethingJpaEntity, UUID>, rồi map qua adapter.
6.2. Controller quan trọng
| Nghiệp vụ | Controller/Endpoint | Ghi nhớ |
|---|---|---|
| Auth | AuthControllerV3 - /api/v3/auth | Login, refresh, me, Google, reset password. |
| Teacher course | TeacherCoursesControllerV3 - /api/v3/teacher/courses | My courses, draft, submit review, publications. |
| Course authoring | CourseAuthoringControllerV3 - /api/v3/courses | Chapter, lesson, section CRUD/reorder/move. |
| Admin course review | AdminCoursesControllerV3 - /api/v3/admin/courses | Approve, reject, revoke, analytics, delete. |
| Learning/progress | StudentEnrollmentControllerV3 - /api/v3/student | Enroll, progress, completed ids, next lesson. |
| Quiz/assignment | QuizControllerV3, AssignmentControllerV3, AssignmentSubmissionControllerV3 | Quiz attempts, assignment CRUD, submission, grading. |
| Upload | FileUploadControllerV3 - /api/v3/files | Multipart/direct upload, presigned init/confirm. |
| Video | VideoAssetControllerV3, AdaptiveVideoPlaybackController | Video asset, playback session, HLS/DASH manifest/object. |
| Payment | PaymentControllerV3, OrgPaymentConfigControllerV3 | Gateway, history, backend-truth access. |
| Wiii | WiiiDataControllerV3, WiiiCourseGenerationController | Integration APIs và course generation shell/chapter push. |
7. Database Và Migration
PostgreSQL là nguồn dữ liệu chính, schema do Flyway migration quản lý. Latest migration local là
V135__video_storage_governance.sql.
Catalog từ Flyway hiện có 78 application tables và 2 materialized views;
107 là số file migration SQL, không phải số bảng.
| Nhóm bảng | Bảng cần nhớ |
|---|---|
| Identity | users, organizations, organization_invites, user_external_identities |
| Course | courses, chapters, lessons, sections, course_publications (content_blocks là cột JSONB) |
| Learning | learning_classes, enrollments, student_lesson_progress, video_progress, certificates |
| Assessment | assignments, assignment_submissions, quizzes, quiz_attempts, packages, question_bank_categories |
| Upload/video | upload_sessions, file_attachments, video_assets, video_renditions, video_ingest_jobs |
| Payment | payment_transactions, teacher_bank_accounts, revenue_splits, payout_requests |
Khi thêm hoặc đổi dữ liệu
- Tạo migration mới trong
backend/src/main/resources/db/migration/, ví dụV136__add_xxx.sql. - Cập nhật JPA entity tương ứng trong
infrastructure/persistence/entity. - Cập nhật mapper, DTO, use case, controller nếu field đi ra/vào API.
- Cập nhật TypeScript DTO/service nếu frontend dùng field đó.
Tài liệu DB hữu ích: docs/database/SCHEMA_REFERENCE_2026-04-28.md,
docs/lms_schema.dbml, docs/lms_schema_a3.dbml.
lms,
mở schema public, tab Diagram, rồi zoom/arrange layout trước khi chụp.
Ảnh này phù hợp để trình bày ERD tổng; còn chi tiết từng bảng nên xem schema reference hoặc DBML.
8. Luồng Chức Năng Cần Thuộc
8.1. Auth, JWT, phân quyền
features/authMở: AuthControllerV3, AuthService, auth.interceptor.ts, role.guard.ts, SecurityConfig.java.
8.2. Teacher tạo khóa học
/teacher/course-creationCourseEditorStoreCourseAuthoringServiceCourseAuthoringUseCaseĐiểm hỏi hay gặp: readiness checklist, chapter/lesson/section reorder, draft vs publication.
8.3. Duyệt và publication snapshot
Câu trả lời ngắn: publication snapshot giúp student học ổn định, teacher sửa draft không phá nội dung đã công bố.
8.4. Student học bài và progress
/student/courses/{id}/enrollCourseLearningComponent8.5. Quiz, assignment, grading
Teacher tạo quiz/assignment qua teacher assessment hub. Student làm bài qua student tasks/quiz route. Backend lưu attempts/submissions và teacher grade qua submission controller.
Mở: assessment/, assignment-hub.routes.ts, QuizControllerV3, AssignmentSubmissionControllerV3.
8.6. Payment và paid access
Payment là backend-truth: UI không tự quyết định user đã có quyền học chỉ vì callback nhìn có vẻ thành công. Instructor-led course có thể cần manual activation sau khi payment hoàn tất.
Mở: PaymentControllerV3, CreateSepayPaymentUseCase, PaymentCompletedEventHandler, payment.api.ts.
9. Video, Upload, Offline
9.1. Presigned upload
/api/v3/files/upload/init/upload/confirmMở: PresignedUploadService, PresignedUploadUseCase, FileUploadControllerV3, UploadCleanupScheduler.
9.2. Video adaptive, Shaka và ABR
ABR là adaptive bitrate, không phải ARB. Frontend dùng Shaka Player để load HLS/DASH và tự đổi chất lượng. Backend dùng FFmpeg tạo renditions, Shaka Packager đóng gói HLS/DASH, worker riêng xử lý ingest.
| Lớp | File cần mở | Ý nghĩa |
|---|---|---|
| Frontend player | adaptive-video-player.component.ts | Khởi tạo Shaka, cấu hình abr, fallback HLS/DASH, chọn quality. |
| Backend ingest | VideoAssetIngestService | Probe, transcode, chọn profiles SAVER/STANDARD/HIGH, package. |
| Packager | ShakaPackagerService | Gọi binary packager, kiểm manifest/output. |
| Playback API | AdaptiveVideoPlaybackController | Manifest/object endpoints có playback token. |
| Config | application.yml, docker-compose.video-worker.yml | Token TTL, segment duration, profiles, worker env. |
9.3. Offline/PWA
Offline dùng IndexedDB/Dexie, course package, queued sync và stale package detection. Quy tắc quan trọng: offline progress merge additive/forward-only, không ghi đè lùi tiến độ server.
Mở: lms-offline.db.ts, course-download.service.ts, offline-sync.service.ts, offline.interceptor.ts.
10. Wiii AI Integration
LMS có lớp AI/Wiii ở cả frontend và backend. Mục tiêu là nhúng Wiii vào teacher/course editor, cung cấp context trang, DOM target ổn định, safe click, preview/diff trước khi apply nội dung AI sinh.
| Phần | File | Ghi nhớ |
|---|---|---|
| Wiii embed/env | environment.ts, environment.prod.ts, index.html | URL embed/app và CSP frame/connect origin. |
| Context/Pointy | features/ai-chat/infrastructure/api/wiii-context.service.ts | Thu context, target DOM, safe click guard. |
| DOM target | data-wiii-id, data-wiii-click-safe, data-wiii-click-kind | Chỉ navigation/open panel/form step an toàn mới safe. |
| Preview/diff | operator-preview-dialog.component.html | Teacher xem trước trước khi apply. |
| Backend integration | shared/integration/Wiii*.java | Service auth, data APIs, course generation endpoints. |
data-wiii-click-safe="true".
11. Playbook Sửa Code Khi Bị Hỏi
11.1. Đổi chữ, đổi màu, đổi UI
- Tìm text đang thấy:
rg "Chữ cần sửa" fe/src backend/src. - Nếu là UI, mở component/template trong
fe/src/app/features. - Nếu là toast/message backend, mở controller/use case ném message đó.
- Đổi màu global ở
styles.scsshoặc_variables.scss; đổi màu riêng ở template/component. - Chạy
cd fe && npm run build.
11.2. Thêm field mới vào Course
- Migration:
backend/src/main/resources/db/migration/V136__.... - JPA entity:
course_authoring/infrastructure/persistence/entity. - Domain/mapper/DTO/use case:
course_authoring/domain,application,mapper. - Controller response/request nếu cần.
- Frontend DTO/service:
course-authoring.service.tshoặcapi/types. - UI form trong
course-editor/pages/course-infohoặc page liên quan.
11.3. Thêm API mới
- Thiết kế request/response DTO.
- Thêm method vào use case, không để controller xử lý business phức tạp.
- Thêm controller endpoint với
@Validvà@PreAuthorize. - Nếu dùng DB mới, thêm migration và repository adapter.
- Frontend thêm endpoint/client/service rồi gọi từ component/store.
11.4. Trước khi nói "done"
cd E:\Sach\Sua\LMS_hohulili\fe
npm run build
cd E:\Sach\Sua\LMS_hohulili\backend
mvn -DskipTests compile -B
cd E:\Sach\Sua\LMS_hohulili
docker compose -f docker-compose.yml -f docker-compose.dev.yml config -q
curl.exe -s http://localhost:8088/actuator/health
Với flow UI quan trọng, thêm ảnh chụp hoặc smoke manual. Với PR thật, không stage .env, cache, screenshot tạm, build output.
12. Debug Nhanh
Backend không lên
docker compose -f docker-compose.yml -f docker-compose.dev.yml logs backend --tail=100
docker compose -f docker-compose.yml -f docker-compose.dev.yml ps
Not a managed type: JPA repository đang dùng domain model thay vì*JpaEntity.- Flyway fail: xem migration mới nhất, default/constraint, dữ liệu legacy.
- DB fail: kiểm container
dbvà biến môi trường.
Frontend không gọi được API
curl.exe -s http://localhost:8088/actuator/health
Get-Content fe/proxy.conf.json
rg "apiUrl|baseUrl|localhost:8088" fe/src
Dev server proxy /api, /actuator, /ws về localhost:8088.
Video không phát
rg "Shaka Packager|VideoPipeline|adaptivePackagingStatus" backend/src/main/java backend/src/main/resources
rg "master.m3u8|manifest.mpd|defaultBandwidthEstimate" fe/src/app
Kiểm asset status, playback token, manifest HLS/DASH, R2/media-domain, console browser.
Port bị chiếm
netstat -ano | findstr :4200
netstat -ano | findstr :8088
13. Câu Hỏi Bảo Vệ Thường Gặp
Vì sao dùng Clean Architecture/DDD?
Vì LMS có nhiều nghiệp vụ độc lập. Tách domain, application, infrastructure giúp giữ rule nghiệp vụ sạch, dễ test, dễ thay đổi persistence/API mà không trộn controller/JPA vào domain.
Vì sao student đọc publication snapshot, không đọc draft?
Để học viên đang học không bị thay đổi nội dung đột ngột khi teacher đang sửa bản nháp. Draft chỉ ra learner sau khi submit và admin/ORG_ADMIN duyệt.
Vì sao upload dùng presigned URL?
File lớn không nên đi qua backend web request. Browser upload trực tiếp lên storage, backend chỉ quản lý quyền, session, metadata và xác nhận.
Vì sao có dedicated video worker?
Encode và packaging video tốn CPU/thời gian. Tách worker giúp web backend vẫn phục vụ request học tập, login, API bình thường khi có ingest video.
Vì sao Angular dùng Signals?
Signals giúp state UI rõ ràng, reactive, phù hợp Angular 20 và OnPush. Derived state dùng computed(), local state dùng signal(), dependency injection dùng inject().
Wiii có được tự click mọi thứ không?
Không. Wiii/Pointy chỉ được click target LMS đánh dấu safe như navigation/open panel/form step. Không được tự submit quiz, delete, publish, enroll, grade, payment hoặc mutate dữ liệu nguy hiểm.
14. Nguồn Kiểm Chứng Và File Nên Đọc
14.1. Nguồn chuẩn bên ngoài
| Chủ đề | Nguồn chính thức | Tài liệu này áp dụng thế nào? |
|---|---|---|
| Angular Signals | Angular Signals guide | Giải thích vì sao frontend dùng signal(), computed(), state mịn theo component. |
| Angular lazy routes | Angular route loading strategies | Giải thích cấu trúc lazy-loaded routes trong features/*/*.routes.ts. |
| Spring Boot | Spring Boot 3.2 reference | Khớp stack Java/Spring Boot, actuator, configuration và runtime app. |
| Spring Security | Spring Security Servlet architecture | Giải thích filter chain, JWT filter, authorization và @PreAuthorize. |
| PostgreSQL | PostgreSQL official docs | Database chính, SQL, index, constraints, transaction. |
| Flyway migration | Flyway migrations docs | Giải thích migration là thay đổi schema/data được version control và chạy lặp lại theo thứ tự. |
| Shaka Player | Shaka Player project docs | Giải thích adaptive media HLS/DASH trong browser bằng web standards. |
| Dexie / IndexedDB | Dexie.js docs | Giải thích offline-first storage trên IndexedDB. |
| Cloudflare R2 | Cloudflare R2 docs | Giải thích object storage cho file/video package. |
| Docker Compose | Docker Compose docs | Giải thích local stack nhiều service bằng YAML và docker compose up. |
| Caddy | Caddy reverse proxy docs | Giải thích reverse proxy và HTTPS tự động khi có hostname. |
14.2. Nguồn trong repo
| Nguồn | Dùng để kiểm chứng |
|---|---|
AGENTS.md | Runtime truth, stack, test account, quy tắc làm việc. |
README.md, backend/README.md, fe/FRONTEND_ARCHITECTURE.md | Quick start và kiến trúc chính. |
docs/testing/TEST_CHECKLIST.md | Local green baseline, smoke-first gate. |
docs/runbooks/CLOUDFLARE_R2_VIDEO_SETUP.md | R2 + Shaka + adaptive/offline video config. |
docs/runbooks/DEDICATED_VIDEO_WORKER_RUNBOOK.md | Video worker runtime. |
docs/database/SCHEMA_REFERENCE_2026-04-28.md | Schema reference. |
docs/reference/FRONTEND_OVERVIEW.md | Frontend overview và gotchas. |
Lưu ý: nếu docs mâu thuẫn code đang chạy, ưu tiên theo thứ tự: code hiện tại, runbook/reference, changelog, archive.