Files
sub2api-monitor/docs/plans/2026-06-23-sub2api-monitor-design.md
2026-06-23 10:16:28 +08:00

119 lines
3.7 KiB
Markdown

# Sub2API Monitor Android Widget Design
Date: 2026-06-23
## Goal
Build a runnable Android prototype for monitoring Sub2API from a home-screen widget.
The first version focuses on the full user flow, visual layout, local-only
configuration, simulated monitoring data, and a data layer that can later be
replaced by real Sub2API admin APIs.
## Recommended Approach
Use native Android with Kotlin:
- Jetpack Compose for the in-app configuration screen.
- Jetpack Glance for the Android home-screen widget.
- DataStore for local configuration and cached widget state.
- A repository interface with a mock data source for the first version.
This keeps the widget integration native, makes the UI fast to iterate on, and
leaves a clean replacement point for the real network integration.
## App Configuration
The app provides one configuration screen with:
- Sub2API base URL input.
- Admin key input, hidden as a password field.
- Automatic refresh interval setting.
- Test connection action.
- Save configuration action.
The admin key is stored only on the device and is never rendered in the widget.
For the prototype, test connection uses the mock data source and reports a
success or failure result.
## Widget Experience
When no configuration exists, the widget shows:
> 请先配置 Sub2API
When configured, the widget renders as a phone home-screen monitoring dashboard:
- White translucent rounded card.
- Sub2API title.
- Last update time.
- Manual refresh button.
- Highlighted blocks for today's tokens, today's cost, today's request count,
and service status.
- Secondary metrics for average latency, RPM, TPM, active keys, and users.
- Recent 5 call records.
- Model cost TOP4.
- Lifetime tokens and lifetime cost.
The visual hierarchy emphasizes today's usage, today's cost, recent calls, and
model ranking.
## Data Model
The UI consumes a `Sub2ApiSnapshot` style state object containing:
- `lastUpdatedAt`
- `todayTokens`
- `todayCost`
- `todayRequests`
- `averageLatencyMs`
- `rpm`
- `tpm`
- `serviceStatus`
- `activeKeyCount`
- `userCount`
- `recentCalls`
- `modelTop`
- `totalTokens`
- `totalCost`
- optional error state
The widget should not bind directly to the mock implementation. It should depend
on repository-level state so a future real API client can provide the same
snapshot contract.
## Data Flow
1. The user opens the app and saves URL, admin key, and refresh interval.
2. Configuration is stored locally in DataStore.
3. The widget reads configuration and cached snapshot state.
4. Manual refresh invokes a widget action that asks the repository to fetch data.
5. Automatic refresh is represented through a scheduler boundary and can be
backed by WorkManager.
6. On success, the latest snapshot becomes the last known good snapshot.
7. On failure, the widget records the error state but keeps showing the previous
successful snapshot.
## Error Handling
- No configuration: show the setup prompt.
- Fetch failure with previous data: show the previous data plus an error status.
- Fetch failure without previous data: show a concise error state.
- Admin key is never shown in widget text or logs.
## Testing Plan
Focus tests on behavior that should survive the later real API integration:
- Missing configuration maps to the unconfigured widget state.
- Saved configuration can be loaded.
- Mock repository returns complete monitoring data.
- Failed refresh preserves the last successful snapshot.
- Formatting functions render tokens, currency, latency, RPM, TPM, and time
consistently.
## Future Real API Integration
Add a real `Sub2ApiRemoteDataSource` behind the same repository contract. The
widget, Compose screen, and cached state should not need structural changes.