Browse Source

docs: apply surgical corrections for correctness and clarity

Analysis doc improvements:
- Add accuracy note for Capacitor vs Cordova runtime naming
- Declare 5 required Status Matrix fields verbatim in Bridge Surface
- Add Manifest Hygiene checklist to Build Configuration section

Implementation plan improvements:
- Fix BOOT_COMPLETED permission wiring (top-level permissions, not receiver attribute)
- Add user-visible Exact-Alarm Decision Rule for QA/ops reasoning
- Add 2 ops-grade error cases: E_CHANNEL_MISSING, E_BAD_CONFIG
- Add Preflight Golden Path (Demo) to Runbooks for 30-second sanity checks
- Clamp text lengths at JS boundary with unknown field rejection
- Declare minimal Event IDs for deterministic grep operations

All changes maintain existing structure with surgical precision edits.
master
Matthew Raymer 2 days ago
parent
commit
0313aacfd4
  1. 12
      docs/android-app-analysis.md
  2. 41
      docs/android-app-improvement-plan.md

12
docs/android-app-analysis.md

@ -184,6 +184,8 @@ assets/public/
├── index.html # Main test interface (549 lines)
├── capacitor.js # Capacitor runtime
├── capacitor_plugins.js # Plugin JavaScript bridge
> **Note:** On pure Capacitor builds, the runtime is `capacitor.js`. Only include `cordova.js/cordova_plugins.js` if Cordova-compat is enabled; otherwise remove those references for accuracy.
└── plugins/ # Plugin JavaScript files
```
@ -363,6 +365,14 @@ android {
**Purpose**: Auto-generated Capacitor configuration
**Note**: Regenerated on each `npx cap sync` - should not be manually edited
**Manifest Hygiene (Quick Scan)**
- [ ] `<uses-permission android:name="android.permission.POST_NOTIFICATIONS"/>`
- [ ] `<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM"/>` (if you truly need exact)
- [ ] `<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED"/>`
- [ ] BootReceiver: `exported="true"` + BOOT_COMPLETED filter
- [ ] Other receivers exported=false unless needed
- [ ] No stray `android:permission=` on BootReceiver
## Runtime Behavior
### App Startup Sequence
@ -533,6 +543,8 @@ This architecture serves as both a practical testing tool and a reference implem
- `requestNotificationPermissions() -> {granted: boolean, permissions: {...}}`
- `getNotificationStatus() -> {isEnabled, isScheduled, nextNotificationTime, ...}`
**Status Matrix MUST include:** `postNotificationsGranted`, `exactAlarmGranted`, `channelEnabled`, `batteryOptimizationsIgnored`, `canScheduleNow`.
## Permission & Settings Truth Table
| Symptom | Likely Cause | Action |

41
docs/android-app-improvement-plan.md

@ -230,6 +230,10 @@ public class ScheduleDaily {
- **Error Handling**: Standardized error responses
- **Validation**: Input validation before processing
### Exact-Alarm Decision Rule (User-Visible)
If `SCHEDULE_EXACT_ALARM` is **granted** → schedule with `setExactAndAllowWhileIdle`.
If **denied or quota-limited** → schedule via WorkManager (exp backoff + jitter) and surface `E_EXACT_ALARM_DENIED` (with "Degraded timing — Doze may delay" hint).
### 3. Service Locator
**Purpose**: Dependency injection for testability
@ -413,12 +417,12 @@ export class SchemaValidator {
errors.push('Time must be in HH:mm format');
}
// Validate title length
// Validate title length (enforce exactly: title ≤ 100 chars)
if (request.title && request.title.length > 100) {
errors.push('Title must be 100 characters or less');
}
// Validate body length
// Validate body length (enforce exactly: body ≤ 500 chars)
if (request.body && request.body.length > 500) {
errors.push('Body must be 500 characters or less');
}
@ -433,9 +437,17 @@ export class SchemaValidator {
errors.push('Priority must be low, default, or high');
}
// Reject unknown fields
const allowedFields = ['time', 'title', 'body', 'sound', 'priority'];
const unknownFields = Object.keys(request).filter(key => !allowedFields.includes(key));
if (unknownFields.length > 0) {
errors.push(`Unknown fields: ${unknownFields.join(', ')}`);
}
return {
isValid: errors.length === 0,
errors
errors,
message: errors.join('; ') // Single joined message for UI display
};
}
}
@ -495,6 +507,11 @@ public class SecureNetworkClient {
#### Implementation Plan
```xml
<!-- AndroidManifest.xml -->
<!-- Top-level permissions -->
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
<uses-permission android:name="android.permission.SCHEDULE_EXACT_ALARM" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<receiver
android:name="com.timesafari.dailynotification.DailyNotificationReceiver"
android:enabled="true"
@ -507,8 +524,7 @@ public class SecureNetworkClient {
<receiver
android:name="com.timesafari.dailynotification.BootReceiver"
android:enabled="true"
android:exported="true"
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
android:exported="true">
<intent-filter android:priority="1000">
<action android:name="android.intent.action.BOOT_COMPLETED" />
</intent-filter>
@ -809,6 +825,12 @@ interface ScheduleResponse {
- Implement progress logging
- Create log export functionality
**Event IDs (minimum set)**
- EVT_SCHEDULE_REQUEST / EVT_SCHEDULE_OK / EVT_SCHEDULE_FAIL
- EVT_BOOT_REHYDRATE_START / EVT_BOOT_REHYDRATE_DONE
- EVT_CHANNEL_STATUS / EVT_PERM_STATUS / EVT_EXACT_ALARM_STATUS
- EVT_DOZE_FALLBACK_TAKEN / EVT_WORKER_RETRY
### Phase 3: Security & Performance
- [ ] **Security Hardening**
- Add network security measures
@ -941,6 +963,8 @@ By following this plan, the test app will become more maintainable, reliable, an
| E_CHANNEL_DISABLED | Channel blocked/low importance | Open channel settings |
| E_EXACT_ALARM_DENIED | No exact alarm | Open exact alarm settings / fallback |
| E_DOZE_LIMIT | Throttled by Doze | Expect delays; fallback taken |
| E_CHANNEL_MISSING | Channel ID not found at runtime | Recreate channel; verify ID & importance |
| E_BAD_CONFIG | Missing/invalid plugin config at startup | Check `capacitor.config.json` and diagnostics dump |
## Runbooks
@ -952,3 +976,10 @@ Check storage for orphan schedule rows; verify idempotent rescheduler logs.
### Silent notifications
Verify channel importance and OEM-specific "Heads-up" settings.
### Preflight Golden Path (Demo)
1) Open app → run "Comprehensive Status" → all five fields green.
2) Tap "Open Channel Settings" → ensure importance = High.
3) Tap "Open Exact Alarm Settings" → grant if available.
4) Run "Immediate Notification" → toast & notif appear within 5s.
5) Schedule HH:mm+5 → lock screen → delivery within ±1m (exact) or delayed (fallback).

Loading…
Cancel
Save