{
  "markdown": "# Project Tracker\n\nDashboard quản lý dự án & công việc nội bộ cho team IT WeCare. Kết nối trực tiếp Dataverse\n(Power Platform) để quản lý projects, tasks, tech resources và sinh weekly report bằng AI.\n\n**Stack**: React 19 · Vite 6 · TypeScript 5.8 · MSAL Azure AD · Dataverse Web API v9.2\n\n---\n\n## Trạng thái\n\nĐang chạy ổn định, tự động deploy lên GitHub Pages mỗi khi push `main`.\nXác thực bằng Azure AD thật (MSAL), phân quyền Edit qua whitelist email.\n\nCodebase theo cấu trúc **feature-based** (`app` → `features` → `shared`, 0 cross-feature import).\nTài liệu tách theo nguyên tắc:\n\n```\ndecisions/   BẤT BIẾN, append-only   -> vì sao chọn thế này\ndocs/        MUTABLE, cập nhật tự do -> hiện tại đang thế nào\n```\n\nRủi ro lớn nhất còn tồn: **không có test nào và CI không typecheck** —\nxem [docs/roadmap.md](./docs/roadmap.md) mục Chất lượng.\n\n---\n\n## Chạy locally\n\n**Yêu cầu**: Node.js 20+\n\n```bash\npnpm install                 # KHÔNG dùng npm — xem decisions/0008\ncp .env.example .env.local   # rồi điền giá trị thật\nlefthook install             # bật git hook; bỏ bước này thì KHÔNG cửa nào chặn bạn\npnpm run dev                 # http://localhost:3000\n```\n\n`.env.local` cần tối thiểu 3 biến sau, thiếu là **không đăng nhập được**:\n\n```bash\nVITE_MSAL_CLIENT_ID=<client-id cua App Registration tren Azure AD>\nVITE_MSAL_TENANT_ID=<tenant-id>\nVITE_DATAVERSE_URL=https://<org>.crm5.dynamics.com/api/data/v9.2/\n```\n\nBa biến tuỳ chọn cho tính năng AI Weekly Report: `GEMINI_API_KEY`,\n`OLLAMA_BASE_URL`, `OLLAMA_MODEL`.\n\nChi tiết từng biến, cơ chế inject và cấu hình redirect URI:\n[docs/tech-stack.md](./docs/tech-stack.md).\n\n### Commands\n\n```bash\npnpm run dev             # dev server, cong 3000\npnpm run build           # build production ra dist/\npnpm run preview         # xem truoc ban build\nsh scripts/verify.sh     # GATE — security · arch-boundaries · doc-paths · typecheck\nsh scripts/prove-gates.sh  # chung minh cac gate that su do duoc (2-4 phut)\n```\n\n> `pnpm run build` chỉ chạy `vite build`, **không typecheck**. `scripts/verify.sh` mới là cửa —\n> và pre-push tự chạy nó.\n\n---\n\n## Điều hướng tài liệu\n\n| Cần biết | Đọc |\n|---|---|\n| Hệ thống đang thế nào — phân tầng, thư mục, luồng auth, luồng dữ liệu, ERD | [docs/architecture.md](./docs/architecture.md) |\n| Stack, commands, biến môi trường, CI/CD | [docs/tech-stack.md](./docs/tech-stack.md) |\n| Đã xong gì, còn gì phải làm | [docs/roadmap.md](./docs/roadmap.md) |\n| Vì sao chọn cách này | [decisions/](./decisions/README.md) |\n| Harness: gate nào đang chạy, chặn ai, đã chứng minh chưa | [PROGRESS.md](./PROGRESS.md) · [docs/harness.md](./docs/harness.md) |\n| Bản đồ từng file | [index.md](./index.md) |\n| Lịch sử thay đổi | [log.md](./log.md) |\n| Yêu cầu nghiệp vụ · Hướng dẫn dùng · Test case | [docs/](./docs/) |\n\n---\n\n## Cấu trúc\n\n```text\nsrc/\n├── main.tsx           Entry — initializeMsal() TRUOC createRoot()\n├── app/               Tang ung dung: App.tsx + routes/{Dashboard, ProjectDetail}\n├── components/        UI dung chung, khong biet domain\n├── features/          project · task · report · auth  (KHONG import lan nhau)\n├── hooks/             useApiData — stale-while-revalidate\n├── lib/               dataverseService · aiService · apiCache\n├── config/            constants.ts\n└── types/             index.ts\n```\n\nAlias `@` trỏ `./src`, khai báo song song ở [vite.config.ts](./vite.config.ts) và\n[tsconfig.json](./tsconfig.json) — sửa một chỗ phải sửa cả hai.\n\nRanh giới kiến trúc và cách kiểm tra: [docs/architecture.md](./docs/architecture.md) ·\n[ADR 0002](./decisions/0002-feature-based-folder-architecture.md).\n",
  "bytes": 3595,
  "sha": "0cb19093fb45ab7eef6e0bf0ff480ca3c3f199791b137c5bdbbc803c79766249",
  "repo_slug": "hieu-le-hoang/project-tracker",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/okf_hieu_le_hoang_project_tracker_index_md_1d2e36d4/readme"
}