chore: initialize WiseGrade project
This commit is contained in:
@@ -0,0 +1,13 @@
|
|||||||
|
WISEGRADE_DATA_DIR=./data/inbox
|
||||||
|
DATABASE_URL=postgresql+psycopg://wisegrade:wisegrade@db:5432/wisegrade
|
||||||
|
REDIS_URL=redis://redis:6379/0
|
||||||
|
DEEPSEEK_BASE_URL=https://api.deepseek.com
|
||||||
|
DEEPSEEK_MODEL=deepseek-flash
|
||||||
|
DEEPSEEK_API_KEY=
|
||||||
|
WISEGRADE_SECRET_KEY=replace-with-a-random-32-character-secret
|
||||||
|
EMBEDDING_MODEL_NAME=BAAI/bge-m3
|
||||||
|
EMBEDDING_MODEL_PATH=/models/bge-m3
|
||||||
|
EMBEDDING_MODEL_VERSION=local
|
||||||
|
MODEL_TIMEOUT_SECONDS=120
|
||||||
|
MODEL_CONCURRENCY=2
|
||||||
|
MODEL_RETRIES=2
|
||||||
@@ -16,7 +16,11 @@ coverage/
|
|||||||
data/processed/
|
data/processed/
|
||||||
data/exports/
|
data/exports/
|
||||||
data/runtime/
|
data/runtime/
|
||||||
|
data/inbox/
|
||||||
|
data/test-fixtures/
|
||||||
models/
|
models/
|
||||||
|
*.tar.zst
|
||||||
|
*.tar
|
||||||
*.log
|
*.log
|
||||||
*.sqlite3
|
*.sqlite3
|
||||||
*.db
|
*.db
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
WiseGrade 是面向《自动化专业综合实践》课程的教师端自动评分系统。
|
WiseGrade 是面向《自动化专业综合实践》课程的教师端自动评分系统。
|
||||||
|
|
||||||
当前项目处于技术方案固化和系统开发准备阶段。完整技术规格见:
|
教师端系统包含课程版本、挂载目录导入、文档解析、知识库检索、独立评分批次、教师复核及导出。完整技术规格见:
|
||||||
|
|
||||||
- [技术方案与开发规格](docs/WISEGRADE_TECHNICAL_SPEC.md)
|
- [技术方案与开发规格](docs/WISEGRADE_TECHNICAL_SPEC.md)
|
||||||
- [Codex Goal 模式开发提示词](docs/CODEX_GOAL_PROMPT.md)
|
- [Codex Goal 模式开发提示词](docs/CODEX_GOAL_PROMPT.md)
|
||||||
@@ -20,3 +20,11 @@ WiseGrade 是面向《自动化专业综合实践》课程的教师端自动评
|
|||||||
## 资料
|
## 资料
|
||||||
|
|
||||||
课程原始资料位于 `docs/` 目录。
|
课程原始资料位于 `docs/` 目录。
|
||||||
|
|
||||||
|
## 快速启动
|
||||||
|
|
||||||
|
1. 复制 `.env.example` 为 `.env`,设置 `WISEGRADE_DATA_DIR`、`DEEPSEEK_API_KEY` 和 `WISEGRADE_SECRET_KEY`。
|
||||||
|
2. 将离线嵌入模型放在 `models/bge-m3/`(或修改 `EMBEDDING_MODEL_PATH`)。
|
||||||
|
3. 运行 `docker compose up --build -d`,访问 <http://127.0.0.1:8080>。
|
||||||
|
|
||||||
|
学生材料只从只读挂载的 `/data/inbox` 读取。没有本地嵌入模型或 API 密钥时,系统仍可启动和完成导入;评分会显示明确错误。详细部署和使用步骤见 [部署与使用指南](docs/DEPLOYMENT.md)。
|
||||||
|
|||||||
@@ -0,0 +1,8 @@
|
|||||||
|
.venv/
|
||||||
|
.pytest_cache/
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
tests/
|
||||||
|
*.db
|
||||||
|
*.sqlite3
|
||||||
|
.env
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3.11-slim
|
||||||
|
ENV PYTHONDONTWRITEBYTECODE=1 PYTHONUNBUFFERED=1 HF_HUB_OFFLINE=1 TRANSFORMERS_OFFLINE=1
|
||||||
|
RUN apt-get update && apt-get install -y --no-install-recommends libreoffice poppler-utils fonts-noto-cjk libpango-1.0-0 libpangoft2-1.0-0 libgl1 libglib2.0-0 && rm -rf /var/lib/apt/lists/*
|
||||||
|
WORKDIR /app
|
||||||
|
COPY --from=ghcr.io/astral-sh/uv:0.11.0 /uv /uvx /bin/
|
||||||
|
COPY pyproject.toml uv.lock ./
|
||||||
|
RUN uv sync --frozen --no-dev --extra ocr
|
||||||
|
COPY . .
|
||||||
|
ENV PATH=/app/.venv/bin:$PATH PYTHONPATH=/app
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
[project]
|
||||||
|
name = "wisegrade-backend"
|
||||||
|
version = "0.1.0"
|
||||||
|
description = "WiseGrade teacher-only scoring backend"
|
||||||
|
requires-python = ">=3.10,<3.13"
|
||||||
|
dependencies = [
|
||||||
|
"fastapi>=0.115,<0.125", "starlette>=0.40,<0.50", "uvicorn[standard]>=0.34,<1", "sqlalchemy>=2,<3",
|
||||||
|
"alembic>=1.14,<2", "psycopg[binary]>=3.2,<4", "pgvector>=0.4,<1",
|
||||||
|
"pydantic-settings>=2,<3", "redis>=5,<7", "rq>=2,<3",
|
||||||
|
"pymupdf>=1.25,<2", "python-docx>=1.1,<2", "python-pptx>=1,<2",
|
||||||
|
"pillow>=11,<13", "sentence-transformers>=4,<6", "torch>=2.3,<3", "httpx>=0.28,<1",
|
||||||
|
"cryptography>=44,<48", "openpyxl>=3.1,<4", "weasyprint>=64,<70",
|
||||||
|
]
|
||||||
|
[dependency-groups]
|
||||||
|
dev = ["pytest>=8,<10"]
|
||||||
|
[project.optional-dependencies]
|
||||||
|
ocr = ["paddleocr>=2.9,<4", "paddlepaddle>=2.6,<4"]
|
||||||
|
[tool.uv.sources]
|
||||||
|
torch = { index = "pytorch-cpu" }
|
||||||
|
[[tool.uv.index]]
|
||||||
|
name = "pytorch-cpu"
|
||||||
|
url = "https://download.pytorch.org/whl/cpu"
|
||||||
|
explicit = true
|
||||||
|
[tool.pytest.ini_options]
|
||||||
|
testpaths = ["tests"]
|
||||||
|
pythonpath = ["."]
|
||||||
|
markers = ["integration: tests using bundled course examples"]
|
||||||
Generated
+3501
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,51 @@
|
|||||||
|
services:
|
||||||
|
db:
|
||||||
|
image: pgvector/pgvector:pg16
|
||||||
|
environment:
|
||||||
|
POSTGRES_DB: wisegrade
|
||||||
|
POSTGRES_USER: wisegrade
|
||||||
|
POSTGRES_PASSWORD: wisegrade
|
||||||
|
volumes:
|
||||||
|
- pgdata:/var/lib/postgresql/data
|
||||||
|
healthcheck:
|
||||||
|
test: [CMD-SHELL, "pg_isready -U wisegrade"]
|
||||||
|
interval: 5s
|
||||||
|
retries: 12
|
||||||
|
redis:
|
||||||
|
image: redis:7-alpine
|
||||||
|
api:
|
||||||
|
build: ./backend
|
||||||
|
env_file: .env
|
||||||
|
volumes: &api-volumes
|
||||||
|
- ${WISEGRADE_DATA_DIR}:/data/inbox:ro
|
||||||
|
- ./data/processed:/data/processed
|
||||||
|
- ./data/exports:/data/exports
|
||||||
|
- ./models:/models:ro
|
||||||
|
- ./docs:/app/course-docs:ro
|
||||||
|
depends_on:
|
||||||
|
db: {condition: service_healthy}
|
||||||
|
redis: {condition: service_started}
|
||||||
|
command: ["sh", "-c", "alembic upgrade head && uvicorn wisegrade.main:app --host 0.0.0.0 --port 8000"]
|
||||||
|
healthcheck:
|
||||||
|
test: [CMD, python, -c, "import urllib.request; urllib.request.urlopen('http://127.0.0.1:8000/api/health')"]
|
||||||
|
interval: 10s
|
||||||
|
retries: 12
|
||||||
|
worker:
|
||||||
|
build: ./backend
|
||||||
|
env_file: .env
|
||||||
|
volumes: *api-volumes
|
||||||
|
depends_on:
|
||||||
|
db: {condition: service_healthy}
|
||||||
|
redis: {condition: service_started}
|
||||||
|
command: ["sh", "-c", "rq worker wisegrade --url \"$$REDIS_URL\""]
|
||||||
|
web:
|
||||||
|
build: ./frontend
|
||||||
|
ports:
|
||||||
|
- "127.0.0.1:8080:80"
|
||||||
|
depends_on: [api]
|
||||||
|
healthcheck:
|
||||||
|
test: [CMD, wget, -q, -O, /dev/null, "http://127.0.0.1/health"]
|
||||||
|
interval: 10s
|
||||||
|
retries: 6
|
||||||
|
volumes:
|
||||||
|
pgdata:
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
node_modules/
|
||||||
|
dist/
|
||||||
|
.env
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
FROM node:22-alpine AS build
|
||||||
|
WORKDIR /app
|
||||||
|
COPY package.json package-lock.json ./
|
||||||
|
RUN npm ci
|
||||||
|
COPY . .
|
||||||
|
RUN npm run build
|
||||||
|
FROM nginx:alpine
|
||||||
|
COPY nginx.conf /etc/nginx/conf.d/default.conf
|
||||||
|
COPY --from=build /app/dist /usr/share/nginx/html
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
<!doctype html><html lang="zh-CN"><head><meta charset="UTF-8"/><meta name="viewport" content="width=device-width, initial-scale=1.0"/><title>WiseGrade 智评</title></head><body><div id="root"></div><script type="module" src="/src/main.tsx"></script></body></html>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
server {
|
||||||
|
listen 80;
|
||||||
|
location = /health { add_header Content-Type text/plain; return 200 'ok'; }
|
||||||
|
location /api/ { proxy_pass http://api:8000; proxy_set_header Host $host; client_max_body_size 1m; }
|
||||||
|
location / { try_files $uri /index.html; }
|
||||||
|
}
|
||||||
Generated
+2946
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"name": "wisegrade-frontend",
|
||||||
|
"private": true,
|
||||||
|
"version": "0.1.0",
|
||||||
|
"type": "module",
|
||||||
|
"scripts": {"dev": "vite --host 0.0.0.0", "build": "tsc -b && vite build"},
|
||||||
|
"dependencies": {"antd": "^5.27.0", "@ant-design/icons": "^6.0.0", "react": "^19.1.0", "react-dom": "^19.1.0"},
|
||||||
|
"devDependencies": {"@types/react": "^19.1.0", "@types/react-dom": "^19.1.0", "@vitejs/plugin-react": "^5.0.0", "typescript": "^5.9.0", "vite": "^7.1.0"}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {"target": "ES2022", "useDefineForClassFields": true, "lib": ["ES2022", "DOM", "DOM.Iterable"], "module": "ESNext", "skipLibCheck": true, "moduleResolution": "Bundler", "allowImportingTsExtensions": true, "resolveJsonModule": true, "isolatedModules": true, "noEmit": true, "jsx": "react-jsx", "strict": false},
|
||||||
|
"include": ["src"]
|
||||||
|
}
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
import { defineConfig } from 'vite';
|
||||||
|
import react from '@vitejs/plugin-react';
|
||||||
|
export default defineConfig({ plugins: [react()], server: { proxy: { '/api': 'http://localhost:8000' } } });
|
||||||
Reference in New Issue
Block a user