Skip to content

Latest commit

 

History

History
101 lines (82 loc) · 6.04 KB

File metadata and controls

101 lines (82 loc) · 6.04 KB

Chapel — Wedding Management Monorepo

Generated: 2026-04-30 (initial knowledge base)

OVERVIEW

Three-tier wedding management system: Spring Boot REST API + Vue web app + uni-app mobile (H5 / WeChat Mini Program). Multi-wedding tenancy enforced at the SQL layer via a custom MyBatis interceptor.

STRUCTURE

.
├── chapel-backend/      # Spring Boot 3.2.5 + Java 21 + MyBatis Plus + ULID — see ./chapel-backend/AGENTS.md
├── chapel-frontend/     # Vue 3 + TypeScript + TDesign + Pinia    — see ./chapel-frontend/AGENTS.md
├── doc/                 # Personal/project notes; doc/note.md is user-maintained, do not edit unless asked
├── README.md            # Human-facing structure, development, deployment, migration, maintenance guide
├── docker-compose.yml   # MySQL 8 + backend + frontend
└── .env.example         # Docker compose env (MYSQL_*, JWT_*, OSS_*)

WHERE TO LOOK

Task Location
Add a new business module All three: backend entity/+mapper/+service/+controller/, frontend api/+store/modules/+pages/+router/modules/chapel.ts, mobile api/+store/modules/+pages/+pages.json
Change wedding-data isolation chapel-backend/.../interceptor/WeddingDataInterceptor.java
Auth flow chapel-backend/.../common/Jwt*.java + chapel-frontend/src/permission.ts + chapel-frontend/src/store/modules/user.ts
Database schema chapel-backend/src/main/resources/db/migration/V1__init_schema.sql (only one Flyway file so far)
Theme / design tokens chapel-frontend/src/style/chapel-theme.less (Klein blue #002fa7)
Docker / nginx chapel-backend/Dockerfile, chapel-frontend/Dockerfile, chapel-frontend/nginx*.conf, docker-compose.yml

CROSS-PROJECT CONVENTIONS

Database — physical delete only

No @TableLogic. No deleted column. Hard delete throughout. This contradicts older notes that mentioned soft delete — the actual V1__init_schema.sql has no deleted column on any table.

Primary keys — ULID strings, not auto-increment

All entities use @TableId(type = IdType.ASSIGN_UUID) + custom UlidIdentifierGenerator. Columns are CHAR(26). Never use IdType.ASSIGN_ID (will throw UnsupportedOperationException).

Multi-wedding isolation — happens at MyBatis layer

Backend WeddingDataInterceptor auto-injects WHERE wedding_id = ? into SELECTs against whitelisted tables (chapel_task, chapel_budget_*, chapel_guest, chapel_seating_event, chapel_hotel, chapel_collaboration). To opt out, annotate the mapper method with @ManualWeddingId. The current wedding ID lives in UserContext (ThreadLocal), populated by @RequireWedding aspect.

All table names prefixed chapel_

Database tables: chapel_user, chapel_wedding, chapel_user_wedding, chapel_guest, chapel_guest_group, chapel_seating_*, chapel_hotel*, chapel_room_assignment, chapel_budget_*, chapel_task*, chapel_collaboration. 17 entities total.

Time / locale

  • Jackson yyyy-MM-dd HH:mm:ss, time zone Asia/Shanghai (set in application.yml).
  • All comments / Javadoc / log messages / user-facing error messages in Chinese.
  • Frontend i18n: zh_CN (default) + en_US.

Auth

  • JWT, Bearer token. Subject is the ULID userId (String, not Long).
  • /auth/** routes bypass /api prefix. Other endpoints under /api/**.
  • Frontend stores token in localStorage via Pinia persist (user.token only).

COMMANDS

Whole stack

cp .env.example .env
docker compose up -d                      # MySQL + backend + frontend (HTTP, port 80)
docker compose logs -f backend

Per-project

# Backend (chapel-backend/)
mvn spring-boot:run                              # Uses application.yml + env vars
mvn clean package -DskipTests                    # Build JAR

# Frontend (chapel-frontend/)
npm run dev                # Vite dev, port 3002, proxies /api+/auth → :8080
npm run dev:mock           # Same, with mock mode (mock/ dir is currently empty)
npm run build              # Typecheck (vue-tsc) + build
npm run lint               # ESLint --max-warnings 0
npm run stylelint          # Stylelint for CSS/Less

# Mobile (chapel-mobile/)
npm run dev:h5             # uni-app H5 dev
npm run dev:mp-weixin      # WeChat Mini Program dev
npm run typecheck          # vue-tsc --noEmit

GIT COMMIT FORMAT

Angular Conventional Commits via commitlint (frontend has the .husky hook):

feat|fix|docs|style|refactor|perf|test|build|ci|chore|revert|types|perf: <subject>

ANTI-PATTERNS (THIS PROJECT)

  • Don't add @TableLogic or deleted columns — physical delete is intentional.
  • Don't use IdType.ASSIGN_ID on entities — must be IdType.ASSIGN_UUID (ULID).
  • Don't refactor tabs-router.ts:56 keepAlive !== false condition — explicit comment forbids it. Subtle keep-alive default semantics.
  • Don't bypass WeddingDataInterceptor without @ManualWeddingId. Silent data leak if wedding_id is missing from context.
  • Don't commit OSS credentials — backend config is env-var driven; keep real keys in local/server .env only.
  • Don't write English Javadoc — backend convention is Chinese.

NOTES

  • Root is the canonical git repo for open-source work. chapel-backend/ and chapel-frontend/ are no longer nested git repos; their previous .git directories are backed up under .git-backups/ and ignored.
  • chapel-mobile/, design/, and icon/ are intentionally ignored for now because they are not part of the initial open-source scope.
  • mock/ directory under chapel-frontend/ is configured (vite-plugin-mock) but currently empty — backend is the source of truth.
  • No frontend test framework. Backend uses spring-boot-starter-test (JUnit 5 + Mockito).
  • Backend uses a single application.yml; local and production differences come from env vars such as MYSQL_*, OSS_*, JWT_*, and log levels.
  • Production HTTPS is expected to be handled by host nginx or another edge proxy. The Compose stack only exposes HTTP from chapel-frontend plus the backend and MySQL ports configured in .env.