You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Apply comprehensive project context, architecture details, and coding style rules for all coding and debugging tasks in the repository.
3
+
applyTo: '**/*'
4
+
---
5
+
6
+
# Project Context
7
+
8
+
This project is a **Manifest V3 browser extension** (Chrome + Firefox) built with **WXT**, **React 19**, **TypeScript**, and **Tailwind CSS v4**. It helps students track grades, schedules, and info by scraping university portal pages.
9
+
10
+
## Key Technologies & Architecture
11
+
-**State Management**: Zustand stores persisted to `chrome.storage.sync` (global) and `chrome.storage.local` (per-user data).
12
+
-**Storage tiers**: `sync:` for cross-device global settings; `local:{MSSV}:{suffix}` for per-user data (scores, info, calendar, userSettings); `local:{MSSV}:avatar` for avatar separately.
13
+
-**Data Flow**: Side Panel UI -> Background Service Worker -> Content Scripts (DOM scraping).
14
+
-**DOM Scrapers**: Injected inline via `browser.scripting.executeScript()`.
15
+
16
+
## Parameter System
17
+
18
+
When adding new computed values, thresholds, or configurable numbers:
19
+
1.**Types first**: Define types in `types/point.ts` (or appropriate file under `types/`). NEVER put `export type` in `constants/`.
20
+
2.**Defaults in `constants/default.ts`**: Only `export const _DEFAULT_*` values. Import types from `@/types`.
21
+
3.**School-wide params** → `useGlobalStore` (sync storage, editable in Settings)
5.**Compute logic** → `utils/academic-compute.ts` (pure functions, no side effects). Re-export via `utils/score.ts` for backward compat.
24
+
6.**Update SettingsPage** with editable inputs for new params.
25
+
7.**Update `assets/docs/cach_tinh_toan.md`** with `{{VAR_NAME}}` placeholders.
26
+
8.**Update AboutUsPage**`calcParams` to pass current values to the markdown renderer.
27
+
28
+
## Specific Coding Standards
29
+
30
+
### General Rules
31
+
- Explain **WHY**, not **WHAT**. Avoid obvious/verbose comments.
32
+
- No `// ======` section dividers. Use brief `// ── section ──` with Unicode box-drawing chars only in large files.
33
+
- Minimal JSDoc: public API methods get one-liner `/** Brief. */`; private methods are self-documenting.
34
+
- Empty catch blocks: use an inline `/* reason */` block comment, never leave a bare `{}`.
35
+
- Use `Promise.all` for parallel independent async work.
36
+
- Use `Map` for in-memory caches with simple key patterns like `${a}:${b}`.
37
+
38
+
### Project-Specific Rules
39
+
-**Formatting & Linting**: Use **Biome** (avoid ESLint/Prettier).
40
+
-**Path Aliasing**: Use `@/*` to map to the repository root.
41
+
-**Constants**: Always check the `constants/` directory (e.g., `constants/default.ts`) to reuse existing values or define new ones centrally. Types go in `types/`, not in `constants/`.
42
+
-**Storage keys**: Use the builder functions from `constants/storage.ts` (`getPointKey`, `getCalendarKey`, etc.) — never hardcode `local:{MSSV}:*` strings.
43
+
-**Error Handling**: Follow project patterns, especially considering content-script-to-background messaging.
Copy file name to clipboardExpand all lines: CLAUDE.md
+34-6Lines changed: 34 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -43,13 +43,40 @@ Message type constants are defined in [constants/chrome.ts](constants/chrome.ts)
43
43
44
44
### State Management
45
45
46
-
Three Zustand stores, each persisted to `chrome.storage.local`:
46
+
Zustand stores with tiered persistence:
47
47
48
-
| Store | File | Manages |
49
-
|-------|------|---------|
50
-
| Global config |[store/use-global-store.ts](store/use-global-store.ts)| Active tab, site URL, ignored subjects, fixed points |
51
-
| Grade data |[entrypoints/sidepanel/PointTab/use-score-store.ts](entrypoints/sidepanel/PointTab/use-score-store.ts)| Semester scores, GPA calculations |
52
-
| Calendar data |[entrypoints/sidepanel/CalendarTab/use-calendar-store.ts](entrypoints/sidepanel/CalendarTab/use-calendar-store.ts)| Class schedules, exam events |
| Current user |[store/use-current-user-store.ts](store/use-current-user-store.ts)|`local:currentUser` + `local:{MSSV}:avatar`| studentId, displayName, avatar (avatar stored in separate key, not in JSON) |
52
+
| User settings |[store/use-user-settings-store.ts](store/use-user-settings-store.ts)|`local:{MSSV}:userSettings`| trainingSemesters, totalProgramCredits (per-MSSV, switches with effectiveStudentId) |
53
+
| Grade data |[store/use-score-store.ts](store/use-score-store.ts)|`local:{MSSV}:pointData`| Semester scores, GPA calculations |
54
+
| Info data |[store/use-info-store.ts](store/use-info-store.ts)|`local:{MSSV}:userData`| Student profile, course data |
55
+
| Calendar data |[store/use-calendar-store.ts](store/use-calendar-store.ts)|`local:{MSSV}:calendarData` / `local:{MSSV}:examData`| Class schedules, exam events |
56
+
57
+
**Key pattern**: All per-user data stores use `effectiveStudentId` from `useCurrentUserStore` — supports view-only account switching.
58
+
59
+
### Academic Compute Module
60
+
61
+
[utils/academic-compute.ts](utils/academic-compute.ts) — pure functions, no side effects:
6. Update `assets/docs/cach_tinh_toan.md` with `{{VAR}}` placeholders
79
+
7. Update `AboutUsPage``calcParams` for markdown rendering
53
80
54
81
### Content Scripts (DOM Scrapers)
55
82
@@ -76,5 +103,6 @@ Defined in [constants/default.ts](constants/default.ts) (`_DEFAULT_SITE_URL_MAPP
76
103
-**Linter/Formatter**: Biome (not ESLint/Prettier) — config in [biome.jsonc](biome.jsonc)
77
104
-**Commits**: Conventional Commits enforced by commitlint + husky (required for semantic-release versioning)
78
105
-**Path alias**: `@/*` maps to the repo root
106
+
-**Constants & Definitions**: When coding magic numbers, defining thresholds, or adding constant configuration functions, ALWAYS check the `constants/` directory (e.g., `constants/default.ts`) to reuse existing values or define them centrally.
79
107
-**Grade conversion**: 10-point → 4-point scale logic is in [utils/index.ts](utils/index.ts)
80
108
-**Release**: Automated via semantic-release on push to `main`; updates `package.json`, `wxt.config.ts`, `CHANGELOG.md`, and `assets/data/info.json`
# Set up the encryption key (used for local data encryption)
38
+
cp .env.example .env
39
+
# Edit .env to set your own MPC_KEY, or keep the default for local dev
40
+
37
41
pnpm install
38
42
39
43
pnpm build
40
44
pnpm build:firefox # For Firefox
41
45
```
42
46
47
+
The `MPC_KEY` environment variable is injected at build time and used to encrypt locally stored data. The default value `"MPC"` is fine for local development. In CI/CD, this key is set via GitHub Secrets.
48
+
43
49
After building, the **.output** folder will be created. Inside, there are folders corresponding to each browser. Use these folders to install manually as described above.
# Thiết lập khóa mã hóa (dùng để mã hóa dữ liệu local)
39
+
cp .env.example .env
40
+
# Sửa .env để đặt MPC_KEY riêng, hoặc giữ mặc định cho dev
41
+
38
42
pnpm install
39
43
40
44
pnpm build
41
45
pnpm build:firefox # Dành cho Firefox
42
46
```
43
47
48
+
Biến môi trường `MPC_KEY` được inject lúc build và dùng để mã hóa dữ liệu lưu cục bộ. Giá trị mặc định `"MPC"` dùng tốt cho môi trường phát triển. Trên CI/CD, khóa này được đặt qua GitHub Secrets.
49
+
44
50
Sau khi build, folder **.output** sẽ được tạo ra. Bên trong có các folder tương ứng cho từng trình duyệt. Sử dụng folder này để cài đặt thủ công như hướng dẫn ở trên.
0 commit comments