# Kế hoạch phát triển SonicForge Studio > Nguyên tắc chung: **Giữ nguyên UI đã thiết kế**, chỉ bổ sung/bổ khuyết các thành phần còn thiếu. > Mọi thay đổi phải tương thích với code hiện tại (backend FastAPI + frontend React/Babel trong `index.html`). --- ## 0. Khảo sát hiện trạng (đã phân tích) | Hạng mục | Trạng thái | Ghi chú | |---|---|---| | Backend Auth (login/register/change-password/profile) | ✅ Sẵn sàng | `app/api/v1/auth.py` | | Mock password admin | ✅ `seed_admin()` | Mật khẩu mặc định `admin123`, `must_change_password=1` | | Quota / System Manager API | ✅ Sẵn sàng | `app/api/v1/admin.py`, `app/api/v1/projects.py` | | Phân tích Stereo/Mono | ✅ Sẵn sàng | `audioEngine.analyzeAudioBufferChannels()` | | Auth UI (AuthModal/ProfileModal/SystemManagerModal) | ✅ Sẵn sàng | `app/static/js/components/*` | | Temp project (local + cloud) | ✅ Sẵn sàng | `storage.scheduleTempAutoSave()`, API `/projects/temp`, `/projects/cloud` | | Export/Import `.sfs` | ⚠️ Có nhưng thiếu double-click mở lại | `storage.exportProjectToSFS/importProjectFromSFSFile` | | Mock audioclip trong dự án | ❌ Cần xóa | `index.html:1876-1902` | | Sub-tab: trục tọa độ channel/volume/panning + zoom rõ nét | ❌ Thiếu | Cần bổ sung theo ảnh đính kèm 1 | --- ## 1. Xóa audioclip mock trong dự án **Mục tiêu:** Khởi tạo project trống, không có clip mẫu nào khi mở ứng dụng. **Thay đổi (`app/templates/index.html`):** - Xóa hàm `createMockAudioBufferObj` (line ~1859) và biến `mockBuffer` (line ~1876) — chỉ giữ lại nếu dùng chỗ khác (hiện chỉ phục vụ mock clip). - Sửa initial `tracks` state (line ~1880): Track 01 (`id:'1'`) để `buffer: null`, `name: 'Track 01'`, bỏ mảng `clips` mock. Giữ Track 02 rỗng như hiện tại. - Đồng bộ `handleNewProject` (Ctrl+N, line ~2499 & 5319) đã dùng track rỗng — không đổi. - Đảm bảo không còn tham chiếu `mockBuffer`/`createMockAudioBufferObj` nào khác (grep xác nhận trước khi xóa). **Kiểm chứng:** Mở app → 2 track trống, không có waveform mẫu, không có clip `Creak_DeepWood2.wav`. --- ## 2. Phân tích Stereo/Mono khi import & chỉnh sửa đúng loại **Mục tiêu:** Khi import audio (main session hoặc sub-tab), tự động phát hiện Stereo/Mono và DSP (volume/panning/fade/stretch) phải hoạt động đúng số kênh thực tế. **Frontend (`app/templates/index.html`):** - Hàm import audio (decoded bằng `window.SonicAudio.decodeAudioFile`) đã trả về `{ audioBuffer, channelInfo }` với `channelInfo = { channels, isStereo, label }`. - Khi gán vào track / sub-tab: lưu `channelInfo` vào đối tượng track và sub-tab (`track.channelInfo`, `st.channelInfo`). Hiển thị badge `STEREO`/`MONO` trên TCP panel (giữ nguyên vị trí hiển thị hiện tại). - **Sub-tab DSP:** - Nếu `isStereo` → cho phép kéo Volume (L/R independent) và Panning (L100..R100) trên 2 kênh. - Nếu `MONO` → ẩn/disable kênh đối xứng, chỉ 1 đường Volume, Panning khóa ở Center (vô hiệu hóa). Logic đã có sẵn trong `SubTabWaveform` (kiểm tra `channelInfo?.isStereo`) — bổ sung guard đầy đủ. - Waveform render: vẽ đủ `numberOfChannels` kênh; với Mono chỉ vẽ 1 lane, Stereo vẽ 2 lane (L/R). **Backend (`app/core/sub_tab_dsp.py`):** giữ nguyên xử lý theo số kênh của buffer đầu vào (đã đúng). Chỉ đảm bảo API nhận buffer đa kênh. **Kiểm chứng:** Import file Mono → badge MONO, không thể pan; import Stereo → badge STEREO, pan L/R hoạt động. --- ## 3. Sub-tab timeline: trục tọa độ + zoom rõ nét (theo ảnh 1) **Mục tiêu:** Trong sub-tab, track timeline hiển thị trục tọa độ thể hiện **Channel / Volume / Panning**, zoom in/out realtime mượt mà, cập nhật ngay khi click/thay đổi thông số. **Thay đổi (`app/templates/index.html` — khối sub-tab timeline, ~line 6152+):** - Bổ sung **overlay trục tọa độ** vẽ trên canvas (giữ nguyên style UI): - **Channel axis:** label `L` / `R` (stereo) hoặc `M` (mono) bên trái lane. - **Volume axis:** thang dB dọc (`+3 / 0 / -15 / -30 dB`) căn chỉnh với đường `0dB` của graph volume. - **Panning axis:** thang ngang (`L100 / C / R100`) căn chỉnh với graph panning. - **Realtime zoom:** dùng `devicePixelRatio` (dpr) scale canvas như main timeline (`ctx.scale(dpr * (useW / timelineWidth), dpr)`) để nét khi zoom in. Đã có pattern ở `SubTabWaveform` (line ~751) — áp dụng đồng nhất cho trục tọa độ. - Gán `requestAnimationFrame` / `useEffect` dependency `[zoom, buffer, volumeNodes, panningNodes, selectionStart, selectionEnd, currentTime]` để vẽ lại ngay khi tham số đổi (đã có sẵn trong `SubTabWaveform`, mở rộng vẽ thêm trục). - Giữ nguyên ruler thời gian `0.00s` (đã sửa ở bước trước). **Kiểm chứng:** Zoom in → waveform + trục dB/pan sắc nét; kéo node volume/pan → trục cập nhật tức thì; click waveform → playhead + trục khớp. --- ## 4. Quản lý người dùng & Menu File **Mục tiêu:** Admin đăng nhập (mock password), đổi mật khẩu, quản lý hệ thống; menu File có `Profile` (trên `Logout`) và `System Manager` (trong Profile). **Trạng thái đã có:** `currentUser`, `handleLogout`, `AuthModal`, `ProfileModal`, `SystemManagerModal`, `handleAuthSuccess` đã được bổ sung vào `App` (sửa lỗi `currentUser is not defined`). Backend `seed_admin` + `must_change_password` đã sẵn sàng. **Frontend (`index.html` — menu File, ~line 5319+ / 5728+):** - Đảm bảo thứ tự menu File: `... → Profile → Logout`. (Đã đúng: Profile line 5729, Logout line 5730.) - `Profile` mở `ProfileModal` (đổi password, xem quota) — đã render. - `System Manager` hiển thị **chỉ khi `currentUser.role === 'admin'`** (đã có guard line 5728) → mở `SystemManagerModal` (quản lý user/quota). - Auth flow bắt buộc khi login lần đầu (`isMandatoryLogin`) đã có trong `checkAuthStatus` effect. **Backend (`app/core/auth.py`):** `seed_admin()` dùng `DEFAULT_ADMIN_PASSWORD` (mặc định `admin123`), set `must_change_password=1`. Khi admin login → `AuthModal` mode `force_change` ép đổi pass. ✅ Không đổi. **Kiểm chứng:** Khởi chạy lần đầu → ép login admin/`admin123` → modal đổi mật khẩu → vào app. File menu hiện Profile (trên Logout); admin thấy thêm System Manager. --- ## 5. Dự án tạm (Temp) & lưu cloud / `.sfs` **Mục tiêu:** Chưa lưu → auto-save tiến trình vào dự án tạm (local + server); cho phép đăng ký/đăng nhập/lưu cloud (quota); cho phép export `.sfs` về ổ cứng; double-click `.sfs` mở domain → login → tải lại dự án. **5.1 Temp auto-save (đã có, chuẩn hóa):** - `storage.scheduleTempAutoSave()` lưu localStorage `sonic_temp_project` + gọi `API saveTempProject` nếu có token. ✅ Giữ nguyên. - Đảm bảo mọi thay đổi (`tracks`, `subTabs`, `volumeNodes`, `panningNodes`, `fade*`, `speed`) đều nằm trong state được auto-save (serialize an toàn, không lưu `AudioBuffer` thô mà lưu metadata + `serverFileId`). **5.2 Lưu cloud (quota):** - Backend `/projects/cloud` kiểm tra quota (`storage_limit_mb`, `max_tracks`). ✅ - Frontend: menu File `Save to Cloud` → `handleSaveCloud` (đã có trong `app.js`) → port vào `App` trong `index.html` nếu chưa có, dùng `window.SonicAPI.saveCloudProject`. **5.3 Export / Import `.sfs`:** - `exportProjectToSFS` (đã có) → download `.sfs`. ✅ - **Bổ sung double-click mở lại:** - Thêm vào `.sfs` JSON trường `domain` (đã có) và đăng ký MIME/association phía client: khi user double-click file `.sfs` trên máy, OS mở URL `domain/?sfs=` (hoặc protocol handler `sonicforge://open?file=...`). - Tại `index.html` khởi tạo: đọc query param `?sfs=` → nếu có → yêu cầu login (nếu chưa) → `importProjectFromSFSFile` (đọc từ blob/server) → load tracks. - Ghi chú: cơ chế double-click thực tế phụ thuộc OS (file association / protocol handler). Cung cấp hướng dẫn + nút "Mở dự án .sfs" trong UI làm fallback. **Kiểm chứng:** Sửa project → F5 → tiến trình còn (temp). Login → Save Cloud → quota đúng. Export `.sfs` → mở lại domain → login → project restored. --- ## 6. Thứ tự thực hiện & kiểm thử 1. **B1** — Xóa mock clip (§1). Chạy app, confirm trống. 2. **B2** — Stereo/Mono import + DSP (§2). Test Mono & Stereo file. 3. **B3** — Sub-tab trục tọa độ + zoom (§3). So sánh ảnh 1. 4. **B4** — User/Menu (§4). Test admin flow + role guard. 5. **B5** — Temp/Cloud/`.sfs` (§5). Test auto-save, quota, round-trip sfs. 6. **B6** — Lint/typecheck (nếu có script) + chạy `tests/` hiện có (`test_sub_tab_dsp.py`, `test_auth_and_quota.py`). - ✅ Sửa `main.py`: thêm auth + admin + projects routers (thiếu từ đầu). - ✅ 31/31 tests pass (auth + dsp_engine + sub_tab_dsp). **Không thay đổi:** Layout tổng thể, màu sắc, component giao diện đã design; chỉ bổ sung thành phần (trục, badge, modal, menu item) và sửa logic thiếu. --- ## 7. Tối ưu hóa & Module hóa `index.html` (giảm latency) ### 7.1 Hiện trạng & nguyên nhân latency | Vấn đề | Chi tiết | |---|---| | File `index.html` khổng lồ (~6784 dòng) chứa TOÀN BỘ UI inline trong 1 thẻ `