docs: add Sub2API monitor design
This commit is contained in:
118
docs/plans/2026-06-23-sub2api-monitor-design.md
Normal file
118
docs/plans/2026-06-23-sub2api-monitor-design.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# 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.
|
||||
|
||||
Reference in New Issue
Block a user