diff --git a/.claude/ignore b/.claude/ignore new file mode 100644 index 0000000..d0b7a9b --- /dev/null +++ b/.claude/ignore @@ -0,0 +1,26 @@ +# IDE +.idea/ +.vscode/ + +# Java / Maven build output +target/ +*/target/ + +# Frontend dependencies +jog-frontend/node/ +jog-frontend/node_modules/ + +# Frontend build output +jog-frontend/dist/ +jog-admin/src/main/resources/static/ + +# Logs +*.log + +# OS files +.DS_Store +Thumbs.db + +# Git / Claude internal +.git/ +.claude/worktrees/ diff --git a/.claude/launch.json b/.claude/launch.json new file mode 100644 index 0000000..405f82f --- /dev/null +++ b/.claude/launch.json @@ -0,0 +1,12 @@ +{ + "version": "0.0.1", + "configurations": [ + { + "name": "frontend", + "runtimeExecutable": "npm", + "runtimeArgs": ["run", "dev"], + "cwd": "${workspaceFolder}/jog-frontend", + "port": 5173 + } + ] +} diff --git a/.claude/settings.json b/.claude/settings.json new file mode 100644 index 0000000..63eb776 --- /dev/null +++ b/.claude/settings.json @@ -0,0 +1,10 @@ +{ + "permissions": { + "allow": [ + "Bash(mvn test *)", + "Bash(mvn package *)", + "Bash(mvn compile *)", + "Bash(curl -s http://localhost:8080/*)" + ] + } +} diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..a26ae06 --- /dev/null +++ b/CLAUDE.md @@ -0,0 +1,96 @@ +# CLAUDE.md + +This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository. + +## Project Overview + +Jog System — a modern blog CMS with Spring Boot 3 + Vue 3 (Java 21), JWT auth, MySQL + Redis + Flyway. + +## Build & Run + +**Important:** `jog-admin/pom.xml` bundles `frontend-maven-plugin` that downloads Node.js, runs `npm ci`, and `npm run build` during Maven's `generate-resources` phase. This means `mvn compile` / `mvn spring-boot:run` also trigger a full frontend build — heavyweight and slow. For daily development, run the backend from IDE instead. + +```bash +# Backend — compile all modules (triggers frontend build via plugin, slow) +mvn clean compile -DskipTests + +# Backend — run all tests (uses Mockito, tagged p0/p1) +mvn test + +# Backend — run a single test class +mvn test -Dtest=AuthServiceImplP0P1Test + +# Backend — run tests by tag +mvn test -Dgroups="p0" + +# Backend — start dev server (port 8080) +# NOTE: triggers frontend-maven-plugin (slow). Recommended: run +# JogApplication.main() from IDE instead to skip frontend build. +mvn spring-boot:run -pl jog-admin + +# Frontend — start dev server (port 5173, proxies /api → 8080) +cd jog-frontend && npm run dev + +# Frontend — build (outputs to jog-admin/src/main/resources/static) +cd jog-frontend && npm run build + +# Full production build (installs Node + npm ci + build via frontend-maven-plugin) +mvn clean package -DskipTests +``` + +## Project Structure + +``` +jog-admin/ # Spring Boot entry point (depends on all modules) +jog-common/ # Shared: annotations, enums, exceptions, models (ApiResult, PageResult) +jog-framework/ # Cross-cutting: security (JWT), config, AOP (logging, rate-limit), XSS filter +jog-module-system/ # Auth (login/register/refresh), user management +jog-module-blog/ # Articles, categories, tags, AI summary (DashScope), tag recommendation +jog-module-comment/ # Comments (nested, audit, like) +jog-frontend/ # Vue 3 + Vite + Element Plus + Pinia + Tiptap +``` + +Module dependency chain (top to bottom): +``` +jog-admin → jog-module-{system,blog,comment} → jog-framework → jog-common +``` + +## Architecture Conventions + +### Backend +- **Controller → Service (interface) → ServiceImpl → Mapper (MyBatis-Plus)** +- Controllers use `@RequiredArgsConstructor` + `final` field injection, no `@Autowired` +- Service implementations are `@Transactional` on mutation methods +- All controllers return `ApiResult` (code/message/data/timestamp) +- Error codes via `ErrorCode` enum, thrown as `BusinessException` +- Three API tiers: `/api/public/**` (no auth), `/api/app/**` (USER/ADMIN), `/api/admin/**` (ADMIN only) +- Pagination: `PageResult` wrapping MyBatis-Plus `Page` +- JWT: access token (2h) + refresh token (24h / 14d with "remember me") +- DTOs use `jakarta.validation` annotations +- Lombok: `@Data`, `@Builder`, `@RequiredArgsConstructor` throughout + +### Frontend +- `src/utils/request.js` — axios instance with auto Bearer token, 401 auto-refresh +- `src/api/*.js` — per-domain API functions, no direct axios calls in views +- `src/stores/user.js` — Pinia store for auth state (token, userInfo, isLoggedIn, isAdmin) +- `src/router/index.js` — route guards: `requiresAuth` redirects to login, `requiresAdmin` redirects to home +- Views: 3 layout groups — BlogLayout (public), AppLayout (user), AdminLayout (admin) + +### Database +- Flyway migrations in `jog-admin/src/main/resources/db/migration/` +- MyBatis-Plus: camelCase mapping, `@TableLogic` for soft delete (deleted=1) +- Redis: used for rate limiting (AI summary), token blacklist + +### Testing +- `@ExtendWith(MockitoExtension.class)` for unit tests — mock all mappers +- Test classes suffixed with `P0P1Test` or `Test`; live IT classes suffixed with `LiveIT` +- Test tags: `@Tag("p0")` (critical), `@Tag("p1")` (important) + +### AI Features +- DashScope (阿里云百炼) via OpenAI-compatible API in `AiSummaryServiceImpl` +- Tag recommendation via `TagRecommendServiceImpl` +- Both rate-limited per-user via Redis +- Configurable via `dashscope.*` properties in `application.yml` + +## Git Rules +- Only the user performs `git commit`, `git push`, or `git push -u` — Claude must not auto-execute these