Skip to content

Commit 95eac00

Browse files
committed
docs: 规划验证码通知模板绑定
1 parent e336adb commit 95eac00

2 files changed

Lines changed: 178 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Captcha Notification Template Binding Implementation Plan
2+
3+
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
4+
5+
**Goal:** Bind captcha scenes directly to notification center templates so SMS and email captcha sends are fully database-managed.
6+
7+
**Architecture:** Add `notificationTemplateId` to the captcha scene persistence model and database scripts. Introduce a focused bridge service that validates the bound notification template and delegates send execution to `NotificationServiceManager`. Wire SMS and email captcha services through that bridge while keeping image captcha unchanged.
8+
9+
**Tech Stack:** Java 17, Spring Boot, MyBatis-Plus, Maven, JUnit 5, Mockito.
10+
11+
---
12+
13+
## File Structure
14+
15+
- Modify `src/main/java/io/github/opensabre/sysadmin/captcha/model/po/CaptchaScene.java`: add `notificationTemplateId`.
16+
- Create `src/main/java/io/github/opensabre/sysadmin/captcha/service/CaptchaNotificationSender.java`: bridge from captcha scenes to notification center templates.
17+
- Modify `src/main/java/io/github/opensabre/sysadmin/captcha/service/impl/SmsCaptchaService.java`: send SMS captcha through `CaptchaNotificationSender`.
18+
- Modify `src/main/java/io/github/opensabre/sysadmin/captcha/service/impl/EmailCaptchaService.java`: send email captcha through `CaptchaNotificationSender`.
19+
- Modify `src/main/resources/db/os-base-sysadmin-ddl.sql`: add `notification_template_id`.
20+
- Modify `src/main/resources/db/os-base-sysadmin-db.sql`: seed template bindings for login SMS and email captcha scenes.
21+
- Create `src/test/java/io/github/opensabre/sysadmin/captcha/service/CaptchaNotificationSenderTest.java`: validate bridge behavior.
22+
- Modify `src/test/java/io/github/opensabre/sysadmin/captcha/service/impl/CaptchaSceneServiceTest.java`: assert model includes the new binding.
23+
24+
### Task 1: Captcha Scene Binding Model
25+
26+
**Files:**
27+
- Modify: `src/main/java/io/github/opensabre/sysadmin/captcha/model/po/CaptchaScene.java`
28+
- Modify: `src/main/resources/db/os-base-sysadmin-ddl.sql`
29+
- Modify: `src/main/resources/db/os-base-sysadmin-db.sql`
30+
- Test: `src/test/java/io/github/opensabre/sysadmin/captcha/service/impl/CaptchaSceneServiceTest.java`
31+
32+
- [ ] Add `private String notificationTemplateId;` to `CaptchaScene`.
33+
- [ ] Add `notification_template_id varchar(64) DEFAULT NULL COMMENT '通知模板ID'` after `template_code` in `base_sys_captcha_scene`.
34+
- [ ] Seed `LOGIN_SMS` with `NOTIFY_TPL_LOGIN_SMS` and `LOGIN_EMAIL` with `NOTIFY_TPL_LOGIN_EMAIL`.
35+
- [ ] Update `CaptchaSceneServiceTest` to assert `notificationTemplateId`.
36+
37+
### Task 2: Captcha Notification Bridge
38+
39+
**Files:**
40+
- Create: `src/main/java/io/github/opensabre/sysadmin/captcha/service/CaptchaNotificationSender.java`
41+
- Test: `src/test/java/io/github/opensabre/sysadmin/captcha/service/CaptchaNotificationSenderTest.java`
42+
43+
- [ ] Create `CaptchaNotificationSender` as a Spring `@Service`.
44+
- [ ] Inject `INotificationTemplateConfigService` and `NotificationServiceManager`.
45+
- [ ] Add `sendCaptcha(CaptchaScene scene, String target, String code)` that:
46+
- rejects blank `notificationTemplateId`;
47+
- loads the notification template by ID;
48+
- rejects missing or disabled templates;
49+
- validates `SMS` scene uses `SMS` template and `EMAIL` scene uses `EMAIL` template;
50+
- sends `NotificationSendForm` with `code` and `minutes`.
51+
- [ ] Add tests for success, missing binding, and channel mismatch.
52+
53+
### Task 3: Wire SMS and Email Captcha Sends
54+
55+
**Files:**
56+
- Modify: `src/main/java/io/github/opensabre/sysadmin/captcha/service/impl/SmsCaptchaService.java`
57+
- Modify: `src/main/java/io/github/opensabre/sysadmin/captcha/service/impl/EmailCaptchaService.java`
58+
- Test: `src/test/java/io/github/opensabre/sysadmin/captcha/service/CaptchaNotificationSenderTest.java`
59+
60+
- [ ] Replace legacy enum-template send code in `SmsCaptchaService.afterGenerateCaptcha`.
61+
- [ ] Replace legacy enum-template send code in `EmailCaptchaService.afterGenerateCaptcha`.
62+
- [ ] Keep response body unchanged: `captchaId` and `expireTime`.
63+
64+
### Task 4: Verification
65+
66+
**Files:**
67+
- All changed files.
68+
69+
- [ ] Run `mvn -Dtest=CaptchaNotificationSenderTest,CaptchaSceneServiceTest test`.
70+
- [ ] Run `mvn clean package -DskipTests`.
71+
- [ ] Check `git status -sb`.
72+
- [ ] Commit with `feat: 动态绑定验证码通知模板`.
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
# Captcha Notification Template Binding Design
2+
3+
## Goal
4+
5+
Upgrade the captcha module so SMS and email captcha scenes can be managed dynamically through database records and can bind directly to a notification template managed by the notification center.
6+
7+
## Scope
8+
9+
The captcha module already has database-backed captcha scenes and management APIs under `/captcha/scenes`. This upgrade keeps that model and adds an explicit template binding from a captcha scene to one notification template.
10+
11+
In scope:
12+
13+
- Add `notification_template_id` to `base_sys_captcha_scene`.
14+
- Expose `notificationTemplateId` through existing captcha scene APIs.
15+
- Send SMS and email captcha messages through notification center dynamic templates.
16+
- Keep image captcha generation unchanged.
17+
- Keep legacy `template_code` for compatibility, but stop using it as the primary send path.
18+
19+
Out of scope:
20+
21+
- Multi-template routing inside one captcha scene.
22+
- New notification providers.
23+
- Removing `BusinessScenario` legacy endpoints.
24+
25+
## Data Model
26+
27+
`base_sys_captcha_scene.notification_template_id` stores the exact `base_sys_notification_template.id` to use when the scene sends a captcha notification.
28+
29+
Rules:
30+
31+
- `IMAGE` captcha scenes do not require `notification_template_id`.
32+
- `SMS` captcha scenes require a notification template whose `channel` is `SMS`.
33+
- `EMAIL` captcha scenes require a notification template whose `channel` is `EMAIL`.
34+
- The referenced template must exist and be enabled.
35+
- The referenced notification scene should be enabled, because notification send still validates scene state.
36+
37+
Seed data binds:
38+
39+
- `LOGIN_SMS` to `NOTIFY_TPL_LOGIN_SMS`.
40+
- `LOGIN_EMAIL` to `NOTIFY_TPL_LOGIN_EMAIL`.
41+
42+
## Runtime Flow
43+
44+
For SMS and email captcha generation:
45+
46+
1. `CaptchaController` resolves a `CaptchaScene` either from legacy `BusinessScenario` or from `/captcha/send/{sceneCode}`.
47+
2. `CaptchaService` runs existing rate-limit checks and generates the captcha code.
48+
3. The concrete SMS or email service resolves the scene's `notificationTemplateId`.
49+
4. The service validates the template channel matches the captcha type.
50+
5. The service calls notification center with:
51+
- target: captcha business key, such as phone number or email address
52+
- scene code: template's notification scene code
53+
- channel: template channel
54+
- args: `code` and `minutes`
55+
6. Notification center renders the template, sends through the configured provider, and records the send result.
56+
57+
Image captcha returns image data directly and does not call notification center.
58+
59+
## API Behavior
60+
61+
Existing captcha scene management APIs remain:
62+
63+
- `GET /captcha/scenes`
64+
- `GET /captcha/scenes/enabled`
65+
- `GET /captcha/scenes/{sceneCode}`
66+
- `POST /captcha/scenes`
67+
- `PUT /captcha/scenes/{sceneCode}`
68+
- `DELETE /captcha/scenes/{sceneCode}`
69+
70+
The request and response body includes `notificationTemplateId` for scenes that need notification delivery.
71+
72+
Existing send APIs remain compatible:
73+
74+
- `POST /captcha/send/sms`
75+
- `POST /captcha/send/email`
76+
- `POST /captcha/send/image`
77+
- `POST /captcha/send/{sceneCode}`
78+
79+
The SMS and email send paths use `notificationTemplateId` when present. Legacy enum template sending is not used by the dynamic scene path.
80+
81+
## Error Handling
82+
83+
SMS and email captcha generation fails before returning a captcha response when:
84+
85+
- `notificationTemplateId` is blank.
86+
- The referenced notification template does not exist.
87+
- The referenced template is disabled.
88+
- The template channel does not match the captcha type.
89+
- Notification sending fails.
90+
91+
Failures are surfaced as runtime exceptions, matching the current captcha service style for rate-limit failures and unsupported scenes.
92+
93+
## Testing
94+
95+
Add focused unit tests for the captcha notification bridge:
96+
97+
- SMS captcha sends through a bound SMS notification template.
98+
- Email captcha sends through a bound email notification template.
99+
- Missing template binding fails for SMS/email scenes.
100+
- Channel mismatch fails before sending.
101+
- Image captcha still does not require a notification template.
102+
103+
Run:
104+
105+
- `mvn -Dtest=CaptchaNotificationTemplateTest,CaptchaSceneServiceTest test`
106+
- `mvn clean package -DskipTests`

0 commit comments

Comments
 (0)