移除验证码解析功能,简化为纯短信转发

- 删除 VerificationCodeParser 及相关测试,短信捕获和推送不再解析验证码
- 飞书推送改为只发送短信原文,时间戳格式化为可读日期
- 移除主界面"只推送验证码"开关和"调试时上传完整短信正文"选项
- 移除"保存轮询间隔"按钮,开启轮询时自动保存间隔(未输入默认1秒)
- 按钮文字从"开始1秒轮询验证码"改为"开始短信轮询"
- 删除"打印最近30条短信"功能及相关 SmsInboxReader.logRecentMessages
- SmsInboxReader 用 RecentSmsResult 替换 RecentCodeResult
- FeishuWebhookConfigStore.Config 移除 filterVerificationCode/sendFullBodyDebug
- 修复代码缩进不一致问题
This commit is contained in:
2026-05-18 22:38:06 +08:00
parent 95a3c6d8c4
commit c5ef726134
27 changed files with 273 additions and 697 deletions
@@ -11,46 +11,42 @@ The app SHALL use Android's new SMS received broadcast path as the primary mecha
- **WHEN** the app does not have `RECEIVE_SMS` permission
- **THEN** the app MUST report that the primary SMS capture path is blocked by missing permission
### Requirement: Parse complete SMS message bodies
The app SHALL parse SMS bodies using Android SMS message APIs rather than ad hoc PDU handling in business logic.
### Requirement: Preserve complete SMS message bodies
The app SHALL preserve SMS bodies using Android SMS message APIs rather than ad hoc PDU handling in business logic.
#### Scenario: Multi-part SMS is received
- **WHEN** the received intent contains multiple SMS message segments
- **THEN** the app MUST combine the message bodies in received order before verification code extraction
- **THEN** the app MUST combine the message bodies in received order before saving or displaying the capture result
#### Scenario: Sender and timestamp are available
- **WHEN** Android exposes sender address or timestamp for the SMS message
- **THEN** the app MUST attach those values to the capture result for diagnostics and display
### Requirement: Extract verification code candidates
The app SHALL extract verification code candidates from SMS bodies with a conservative parser optimized for common Chinese and English verification messages.
### Requirement: Surface the original SMS content as the primary result
The app SHALL use the original SMS body as the primary display and diagnostic result.
#### Scenario: Chinese verification keyword is present
- **WHEN** the SMS body contains a keyword such as `验证码``校验码` or `动态码` near a 4-8 character code
- **THEN** the app MUST extract the nearby code as the preferred verification code candidate
#### Scenario: SMS body is available
- **WHEN** the app reads an SMS body successfully
- **THEN** the app MUST retain the original SMS body for local display and diagnostics
#### Scenario: English verification keyword is present
- **WHEN** the SMS body contains a keyword such as `code`, `verification` or `OTP` near a 4-8 character code
- **THEN** the app MUST extract the nearby code as the preferred verification code candidate
#### Scenario: SMS body is empty
- **WHEN** the app reads an SMS message but the body is empty
- **THEN** the app MUST return a structured failure instead of inventing a display value
#### Scenario: Code contains spaces or hyphens
- **WHEN** the SMS body contains a verification code formatted with spaces or hyphens
- **THEN** the app MUST normalize the code before displaying it
#### Scenario: No reliable code candidate exists
- **WHEN** the SMS body does not contain a reliable verification code candidate
- **THEN** the app MUST return a structured parse failure instead of displaying a guessed code
#### Scenario: Capture result is displayed
- **WHEN** the app shows the latest SMS capture result
- **THEN** it MUST display the original SMS content, sender summary, source, timestamp, and any structured failure reason
### Requirement: Support optional Google SMS verification APIs
The app SHALL support Google SMS verification APIs only as optional paths and MUST NOT depend on them for the primary capture behavior.
#### Scenario: SMS User Consent path is available
- **WHEN** Google Play services supports SMS User Consent and the user authorizes reading a single SMS
- **THEN** the app MUST parse that SMS body through the same verification code parser used by the primary path
- **THEN** the app MUST feed that SMS body through the same body-preservation path used by the primary path
#### Scenario: SMS Retriever path is used with app hash
- **WHEN** a controlled test SMS includes the app hash required by SMS Retriever
- **THEN** the app MUST accept the retrieved message and parse the verification code
- **THEN** the app MUST accept the retrieved message and preserve the original SMS body
#### Scenario: Google SMS API is unavailable
- **WHEN** Google Play services is missing, disabled, incompatible, times out, or the user declines consent
@@ -4,27 +4,27 @@
The app SHALL be validated on the user's Xiaomi 12S running HyperOS 3 and Android 15 before the SMS capture behavior is considered complete.
#### Scenario: Foreground validation
- **WHEN** the app is open in the foreground and a test SMS containing `验证码 123456` is received
- **THEN** the app MUST show `123456` as the latest parsed verification code
- **WHEN** the app is open in the foreground and a test SMS containing `这是一条短信原文样本` is received
- **THEN** the app MUST show that SMS body as the latest received SMS content
#### Scenario: Background validation
- **WHEN** the app has been moved to the background and a test SMS containing a new verification code is received
- **THEN** the app MUST either show the new code after returning to the app or report that background delivery was blocked
- **WHEN** the app has been moved to the background and a test SMS containing new SMS content is received
- **THEN** the app MUST either show that new SMS body after returning to the app or report that background delivery was blocked
#### Scenario: Lock screen validation
- **WHEN** the device is locked and a test SMS is received
- **THEN** the app MUST show the received result after unlock or report that delivery was blocked under lock screen conditions
### Requirement: Validate parser behavior with representative samples
The verification parser SHALL be validated with representative verification SMS examples and negative examples.
### Requirement: Validate SMS body handling with representative samples
The SMS body handling logic SHALL be validated with representative SMS examples and failure examples.
#### Scenario: Common valid samples
- **WHEN** parser tests include Chinese verification codes, English OTP messages, space-separated codes, hyphen-separated codes, and multiple candidates
- **THEN** all expected verification codes MUST be extracted with the correct normalized value
- **WHEN** tests include Chinese notices, English notification-like messages, multi-part messages, and regular promotional text
- **THEN** all expected SMS bodies MUST be preserved with the correct original content
#### Scenario: Negative samples
- **WHEN** parser tests include messages with phone numbers, dates, money amounts, tracking numbers, or no verification code
- **THEN** the parser MUST avoid returning a false verification code unless a stronger keyword-nearby rule applies
#### Scenario: Failure samples
- **WHEN** tests include empty bodies, unreadable message input, or missing permission states
- **THEN** the app MUST return a structured failure instead of a fabricated SMS result
### Requirement: Validate optional API assumptions separately
The app SHALL validate Google SMS APIs independently from the primary system broadcast path.
@@ -15,12 +15,12 @@ The app SHALL display whether the SMS receive permission is granted, denied, or
The app SHALL expose diagnostic state for each supported SMS capture path.
#### Scenario: Primary path receives an SMS
- **WHEN** the system broadcast path receives and parses an SMS
- **THEN** the app MUST show the latest receive time, source path, sender summary, parsed code, and parse strategy
- **WHEN** the system broadcast path receives and processes an SMS
- **THEN** the app MUST show the latest receive time, source path, sender summary, and SMS body or body summary
#### Scenario: Primary path fails before parsing
- **WHEN** the app cannot receive or parse an SMS through the primary path
- **THEN** the app MUST show a specific reason such as missing permission, no broadcast received, empty body, or parser failure
#### Scenario: Primary path fails before body capture completes
- **WHEN** the app cannot receive or process an SMS through the primary path
- **THEN** the app MUST show a specific reason such as missing permission, no broadcast received, empty body, or body-read failure
#### Scenario: Optional Google API path fails
- **WHEN** SMS User Consent or SMS Retriever cannot complete
@@ -29,13 +29,13 @@ The app SHALL expose diagnostic state for each supported SMS capture path.
### Requirement: Avoid unnecessary SMS content retention
The app SHALL minimize retention and logging of full SMS content.
#### Scenario: Verification code is parsed successfully
- **WHEN** the app extracts a verification code from an SMS
- **THEN** the app MUST display or retain the code, sender summary, timestamp, and parse metadata without requiring persistent storage of the full SMS body
#### Scenario: Recent SMS result is stored for display
- **WHEN** the app stores the latest SMS capture result
- **THEN** the app MUST keep retention limited to the recent result, sender summary, timestamp, source, and the SMS body needed for local display or diagnostics
#### Scenario: Debug body visibility is enabled
- **WHEN** a debug-only setting enables full body visibility
- **THEN** the app MUST keep that behavior local to the device and clearly separate it from normal display state
#### Scenario: Full body visibility is shown in diagnostics
- **WHEN** the app shows full SMS content for local diagnostics
- **THEN** the app MUST keep that behavior local to the device and clearly separate it from broader logging or export behavior
### Requirement: Provide recovery actions for permission problems
The app SHALL provide a clear recovery path when Android or HyperOS blocks SMS capture permissions.