From c5fd0444f454adcd46974f1ea2991e159e6af752 Mon Sep 17 00:00:00 2001 From: Houmgaor Date: Tue, 24 Feb 2026 16:18:31 +0100 Subject: [PATCH] docs: update architecture docs to reflect 6-service layer The CLAUDE.md layered architecture section implied all handlers go through services. In practice, services handle cross-repo coordination while handlers call repos directly for simple CRUD. Updated the diagram, added a services table, and added an "Adding Business Logic" guide. Marked improvements.md item 4 as done. --- CLAUDE.md | 30 +++++++++++++++++++++++++++--- docs/improvements.md | 6 +++++- 2 files changed, 32 insertions(+), 4 deletions(-) diff --git a/CLAUDE.md b/CLAUDE.md index bd092d652..4fd3b6199 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -51,17 +51,30 @@ Handler signature: `func(s *Session, p mhfpacket.MHFPacket)` ``` handlers_*.go → svc_*.go (service layer) → repo_*.go (data access) - ↓ + (where needed) ↓ repo_interfaces.go (21 interfaces) ↓ repo_mocks_test.go (test doubles) ``` -- **Handlers**: Parse packets, call services/repos, build responses. Must always send ACK (see Error Handling below). -- **Services** (`svc_guild.go`, etc.): Business logic extracted from handlers. New domain logic should go here. +- **Handlers**: Parse packets, call services or repos, build responses. Must always send ACK (see Error Handling below). Simple CRUD operations call repos directly; multi-step or cross-repo logic goes through services. +- **Services**: Encapsulate business logic that spans multiple repos or requires orchestration beyond simple CRUD. Not a mandatory pass-through — handlers call repos directly for straightforward data access. - **Repositories**: All SQL lives in `repo_*.go` files behind interfaces in `repo_interfaces.go`. The `Server` struct holds interface types, not concrete implementations. Handler code must never contain inline SQL. - **Sign server** has its own repo pattern: 3 interfaces in `server/signserver/repo_interfaces.go`. +#### Services + +| Service | File | Methods | Purpose | +|---------|------|---------|---------| +| `GuildService` | `svc_guild.go` | 6 | Member operations, disband, resign, leave, scout — triggers cross-repo mail | +| `MailService` | `svc_mail.go` | 4 | Send/broadcast mail with message type routing | +| `GachaService` | `svc_gacha.go` | 6 | Gacha rolls (normal/stepup/box), point transactions, reward resolution | +| `AchievementService` | `svc_achievement.go` | 2 | Achievement fetch with score computation, increment | +| `TowerService` | `svc_tower.go` | 3 | Tower gem management, tenrourai progress capping, guild RP donation | +| `FestaService` | `svc_festa.go` | 2 | Event lifecycle (expiry/cleanup/creation), soul submission filtering | + +Each service takes repo interfaces + `*zap.Logger` in its constructor, making it testable with mocks. Tests live in `svc_*_test.go` files alongside the service. + ### Key Subsystems | File(s) | Purpose | @@ -124,6 +137,17 @@ The MHF client expects `MsgSysAck` for most requests. Missing ACKs cause client 2. Implement in the corresponding `repo_*.go` file 3. Add mock implementation in `repo_mocks_test.go` +## Adding Business Logic + +If the new logic involves multi-step orchestration, cross-repo coordination, or non-trivial data transformation: + +1. Add or extend a service in the appropriate `svc_*.go` file +2. Wire it in `sys_channel_server.go` (constructor + field on `Server` struct) +3. Add tests in `svc_*_test.go` using mock repos +4. Call the service from the handler instead of the repo directly + +Simple CRUD operations should stay as direct repo calls from handlers — not everything needs a service. + ## Known Issues See `docs/anti-patterns.md` for structural patterns and `docs/technical-debt.md` for specific fixable items with file paths and line numbers. diff --git a/docs/improvements.md b/docs/improvements.md index 541fec971..2fb2104cc 100644 --- a/docs/improvements.md +++ b/docs/improvements.md @@ -92,7 +92,11 @@ This isn't necessarily wrong — the services exist for multi-repo coordination, **Fix:** Update the architecture diagram in `CLAUDE.md` to reflect the actual pattern: services are used for cross-repo coordination, handlers call repos directly for simple CRUD. Remove the implication that all handlers go through services. Alternatively, expand service coverage to match the documented architecture, but that is a much larger effort with diminishing returns. -**Status:** Pending. +**Status:** **Done.** Updated three files: + +- `Erupe/CLAUDE.md` — Layered architecture diagram clarified ("where needed"), handler description updated to explain when to use services vs direct repo calls, added services table listing all 6 services with method counts and purpose, added "Adding Business Logic" section with guidelines +- `server/CLAUDE.md` — Repository Pattern section renamed to "Repository & Service Pattern", added service layer summary with the 6 services listed +- `docs/improvements.md` — This item marked as done ---