chore: 合并为单仓库,统一部署流程
- 根目录加入 docker-compose、Caddyfile、文档等原本不在仓库里的文件 - 前后端两份 GitHub Actions 合并成根目录的一个 deploy workflow: 构建前端上传到 build/,再在服务器上 git pull 并重建容器 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
70983a12a5
commit
47d4679984
40 files changed
+13723
-34
No files matched your search
@@ -0,0 +1,68 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
WebPreview is a web-based tutorial/challenge platform where users view tutorials and submit HTML/CSS/JS code for challenges. It has a Django API backend and a Vue 3 frontend, deployed via Docker Compose with Caddy as reverse proxy.
|
||||
|
||||
## Architecture
|
||||
|
||||
- **`api/`** — Django backend using **django-ninja** for REST APIs and **Django Channels** (Daphne/ASGI) for WebSocket support
|
||||
- `api/api/` — Django project config (settings, urls, asgi)
|
||||
- `api/account/` — User auth (login/logout, profiles, batch creation). Three roles: `super`, `admin`, `normal` — affects scoring weights
|
||||
- `api/task/` — Tutorial and Challenge models (single `Task` base model with `task_type`), with separate `tutorial.py` and `challenge.py` router files
|
||||
- `api/submission/` — Code submission + `Rating` model. Submission score is a weighted average of ratings by role: super×0.5, admin×0.3, normal×0.2. `Profile.recalculate_total_score()` uses best-score-per-challenge
|
||||
- `api/prompt/` — LLM chat feature: WebSocket consumer streams DeepSeek responses, `Conversation`/`Message` models store history, code blocks extracted from responses
|
||||
- `api/utils/upload.py` — Image upload endpoint
|
||||
- API routers are registered in `api/api/urls.py` under `/api/` prefix
|
||||
- Uses `AUTH_USER_MODEL = "account.User"` (custom user model)
|
||||
- Dev mode uses SQLite (`ENV != "production"`); production uses PostgreSQL + Redis (sessions, caching, channel layers)
|
||||
|
||||
- **`client/`** — Vue 3 + TypeScript SPA built with **Rsbuild**
|
||||
- UI framework: **Naive UI** (auto-imported via `unplugin-vue-components`)
|
||||
- `src/api.ts` — Axios-based API client with CSRF and auth interceptors; exports `Account`, `Tutorial`, `Challenge`, `Submission`, `Prompt`, `Helper` objects
|
||||
- `src/router.ts` — Vue Router with auth guards; routes under `/dashboard` require login
|
||||
- `src/store/` — Reactive state (plain Vue refs, not Vuex/Pinia)
|
||||
- `src/pages/` — Route-level views (Home, Dashboard, ChallengeHome, TutorialEditor, ChallengeEditor, Submissions, Leaderboard, MyScores)
|
||||
- `src/components/` — Shared components: `Task.vue`, `Tutorial.vue`, `Challenge.vue`, `Editors.vue` (CodeMirror), `Preview.vue` (live HTML preview), `Toolbar.vue`, `PromptPanel.vue` (LLM chat)
|
||||
|
||||
- **`Caddyfile`** — Routes `/api*`, `/admin*`, `/ws*` to backend; serves SPA and static/media files
|
||||
- **`docker-compose.yaml`** — Services: caddy, api, postgres, redis
|
||||
|
||||
## Development Commands
|
||||
|
||||
### Client (from `client/`)
|
||||
```bash
|
||||
npm run start # Dev server (Rsbuild)
|
||||
npm run build # Production build
|
||||
npm run fmt # Format with Prettier
|
||||
```
|
||||
|
||||
Frontend env vars used at build time: `PUBLIC_BASE_URL`, `PUBLIC_ADMIN_URL`, `PUBLIC_WS_URL`.
|
||||
|
||||
### API (from `api/`)
|
||||
```bash
|
||||
uv run manage.py runserver # Dev server
|
||||
uv run manage.py migrate # Run migrations
|
||||
uv run manage.py createsuperuser # Create admin user
|
||||
```
|
||||
Uses `uv` for Python dependency management (`pyproject.toml` + `uv.lock`). Set `ENV=dev` in `.env` (default) for SQLite.
|
||||
|
||||
### Docker (from project root)
|
||||
```bash
|
||||
docker compose up -d # Start all services
|
||||
docker compose up -d --build # Rebuild and start
|
||||
```
|
||||
|
||||
## Key Technical Details
|
||||
|
||||
- **Backend API pattern**: each Django app has `api.py` (or named router files like `task/tutorial.py`, `task/challenge.py`) with django-ninja routers, plus `schemas.py` for Pydantic models. Routers mount under `/api/<prefix>/`
|
||||
- **WebSocket**: `prompt/consumers.py` handles LLM chat at `ws://<host>/ws/prompt/<task_id>/`. Django Channels is configured; in dev, channel layer is in-memory (no Redis needed)
|
||||
- **LLM config**: `LLM_API_KEY`, `LLM_BASE_URL` (default: DeepSeek), `LLM_MODEL` set via `.env`
|
||||
- **Task `display` field**: integer used as URL slug for tutorials/challenges (unique per task type), not the DB `id`
|
||||
- **Submission IDs**: UUIDs (not integers)
|
||||
- Frontend dev server proxies `/media` to `PUBLIC_WEB_URL` env var; API calls go to `BASE_URL` defined in `src/utils/const.ts`
|
||||
- Environment config via `.env` file in `api/` (referenced by docker-compose and Django's `python-dotenv`)
|
||||
- Language/locale is Chinese (`zh-hans`, `Asia/Shanghai` timezone)
|
||||
- Client build output goes to `build/` directory, served by Caddy in production
|
||||
Reference in new issue
Block a user