6.7 KiB
CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
Session Startup
Read these files in order before planning, coding, reviewing, or deploying:
memory.md— current project state and handoff contextdocs/architecture.md— authoritative system-level source of truthdocs/api-reference.md— backend endpoint and auth boundary referenceAGENTS.md— role routing rules and hard guardrails
Project Overview
yoyuzh.xyz — full-stack personal site with four functional areas:
- Personal cloud drive (netdisk)
- P2P browser-to-browser file transfer (快传 / quick-transfer)
- Account system with invite-code registration
- Admin console
Frontend is hosted on Aliyun OSS (static). Backend runs as my-site-api.service on a Linux server at 1.14.49.201, jar at /opt/yoyuzh/yoyuzh-portal-backend.jar.
Commands
Do not run npm at the repo root. The root has no real package.json.
Frontend (cd front)
npm run dev # Vite dev server on port 3000
npm run build # Production build
npm run preview # Preview built output
npm run lint # tsc --noEmit (this IS the type-check; no ESLint)
npm run test # node --import tsx --test src/**/*.test.ts
npm run clean # rm -rf dist
Backend (cd backend)
mvn spring-boot:run # Default profile (MySQL)
mvn spring-boot:run -Dspring-boot.run.profiles=dev # Dev profile (H2, mock data)
mvn test
mvn package # Produces backend/target/yoyuzh-portal-backend-0.0.1-SNAPSHOT.jar
There is no backend lint or typecheck command.
Deploy
node scripts/deploy-front-oss.mjs # Build + upload frontend to Aliyun OSS
node scripts/deploy-front-oss.mjs --dry-run # Preview without uploading
node scripts/deploy-front-oss.mjs --skip-build # Upload only
Requires OSS credentials from env vars or .env.oss.local.
Backend deploy: mvn package, then SCP the jar to /opt/yoyuzh/yoyuzh-portal-backend.jar on the server and restart my-site-api.service. No checked-in backend deploy script exists.
Architecture
Tech Stack
| Layer | Technology |
|---|---|
| Frontend | React 19, TypeScript, Vite 6, Tailwind CSS v4, react-router-dom v7 |
| Admin UI | react-admin v5 (lazy-loaded at /admin/*) |
| Backend | Spring Boot 3.3.8, Java 17, Maven, Spring Security + JWT |
| ORM | Spring Data JPA / Hibernate |
| DB (prod) | MySQL 8 |
| DB (dev) | H2 (in-file, MySQL compat mode via application-dev.yml) |
| File storage | Aliyun OSS (yoyuzh-files2, Chengdu region) |
Frontend Structure (front/src/)
App.tsx— router entrypointlib/— pure logic modules, each with a co-located*.test.tsapi.ts— all backend API callssession.ts— JWT session managementtransfer-runtime.ts,transfer-protocol.ts— WebRTC logicfiles-upload.ts— upload orchestration
pages/— page-level components (Files.tsx,Transfer.tsx,TransferReceive.tsx,Login.tsx,Overview.tsx,FileShare.tsx)admin/— react-admin console with customdata-provider.tscomponents/layout/,components/ui/— shared UI primitivesauth/AuthProvider.tsx— auth context
Frontend API proxy: all /api/* calls during dev proxy to VITE_BACKEND_URL (default http://localhost:8080) via front/vite.config.ts. Production hardcodes https://api.yoyuzh.xyz/api in front/.env.production.
Backend Package Structure (com.yoyuzh)
auth— JWT, login, register, refresh token, single-device session enforcementfiles— file metadata CRUD, upload/download, share links;files/storage/abstracts local vs OSStransfer— quick-transfer signaling API only (no file content relay)admin— admin-only user/file management APIsconfig—SecurityConfig, CORS,JwtAuthenticationFiltercommon— shared exceptions and utilities
Key Design Decisions
- Single-device login:
activeSessionIdin user DB record matched againstsidJWT claim on every request. New login invalidates old device's access token immediately. - Quick-transfer: backend is signaling-only. File bytes travel via WebRTC
DataChannelbetween browsers — no server bandwidth consumed. Offline mode uploads to OSS for 7-day retention. - File storage abstraction:
FileContentStorageinterface decouples metadata logic from disk/OSS. Upload flow:initiate→ direct OSS upload →complete. Falls back to proxy upload on failure. - Invite-code registration: single-use codes auto-rotate after consumption; current code displayed in admin console.
Security Boundaries (SecurityConfig)
- Public:
/api/auth/**,/api/transfer/**,GET /api/files/share-links/{token} - Requires auth:
/api/files/**,/api/user/**,/api/admin/**
Testing
Frontend tests live next to the module they test (src/lib/api.test.ts beside src/lib/api.ts). Run a single test file:
cd front && node --import tsx --test src/lib/api.test.ts
Backend tests mirror the main package structure under backend/src/test/java/com/yoyuzh/. Run a single test class:
cd backend && mvn test -Dtest=ClassName
Dev profile (-Dspring-boot.run.profiles=dev) uses H2; H2 console available at http://localhost:8080/h2-console.
Codex Agent Roles
Agents are defined in .codex/agents/ and configured in .codex/config.toml. Use the workflow from AGENTS.md:
| Agent | Role | Mode |
|---|---|---|
orchestrator |
Default coordinator, routes to specialists | read-only |
planner |
File-level and command plans before code changes | read-only |
explorer |
Maps code paths and existing behavior | read-only |
implementer |
Owns code edits and nearby test updates | read-write |
tester |
Runs repo-backed commands, reports failures | read-only |
reviewer |
Reviews diffs for bugs, regressions, test gaps | read-only |
deployer |
Builds and publishes frontend to OSS; packages backend jar for SSH delivery | read-write |
Default workflow: orchestrator → planner (if multi-file) → explorer (if behavior unclear) → implementer → tester → reviewer → deployer.
Known Constraints
- VS Code "final field not initialized" errors on backend are Lombok/Java LS false positives — check Lombok extension and annotation processor, not source code.
- Frontend chunk size warnings from Vite do not block builds or deploys.
api.yoyuzh.xyzhas TLS/SNI instability on some networks; this is not a backend code issue.- Production frontend bundle hardcodes the API base URL — API subdomain issues surface as "network error" or "login failed" on the frontend.
- Server credentials are in local file
账号密码.txt; never commit or output their contents.