docs: add comprehensive Android app analysis and improvement plan
- Add android-app-analysis.md: detailed analysis of /android/app structure and /www integration - Add android-app-improvement-plan.md: phase-based implementation plan for architecture improvements - Add chatgpt-analysis-guide.md: structured prompts for AI analysis of Android test app - Update README.md: add links to new documentation files These documents provide comprehensive guidance for understanding and improving the DailyNotification Android test app architecture.
This commit is contained in:
888
docs/android-app-improvement-plan.md
Normal file
888
docs/android-app-improvement-plan.md
Normal file
@@ -0,0 +1,888 @@
|
||||
# DailyNotification Android Test App — Implementation Plan (v1)
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-10-24
|
||||
**Version**: 1.0.0
|
||||
|
||||
## Overview
|
||||
|
||||
This document provides a structured implementation plan for improving the DailyNotification Android test app based on the improvement directive. The plan focuses on architecture, code organization, testing, and maintainability improvements.
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Implementation Phases](#implementation-phases)
|
||||
- [Architecture Improvements](#architecture-improvements)
|
||||
- [Code Organization](#code-organization)
|
||||
- [Testing Strategy](#testing-strategy)
|
||||
- [Security Hardening](#security-hardening)
|
||||
- [Performance & Reliability](#performance--reliability)
|
||||
- [Documentation Updates](#documentation-updates)
|
||||
- [Task Breakdown](#task-breakdown)
|
||||
- [Acceptance Criteria](#acceptance-criteria)
|
||||
|
||||
## Implementation Phases
|
||||
|
||||
### Phase 1: Foundation
|
||||
**Focus**: Core architecture improvements and status matrix
|
||||
- [ ] Create status matrix module
|
||||
- [ ] Add input schema validation
|
||||
- [ ] Centralize exact-alarm gate
|
||||
- [ ] Make BootReceiver idempotent
|
||||
- [ ] Introduce use-case classes
|
||||
|
||||
### Phase 2: Testing & Reliability
|
||||
**Focus**: Testing infrastructure and reliability improvements
|
||||
- [ ] Refactor test UI into modular scenarios
|
||||
- [ ] Add instrumentation tests
|
||||
- [ ] Implement error handling improvements
|
||||
- [ ] Add structured logging
|
||||
|
||||
### Phase 3: Security & Performance
|
||||
**Focus**: Security hardening and performance optimization
|
||||
- [ ] Implement security hardening
|
||||
- [ ] Add performance optimizations
|
||||
- [ ] Create diagnostics system
|
||||
- [ ] Update documentation
|
||||
|
||||
## Architecture Improvements
|
||||
|
||||
### 1. Split Monolithic Test UI
|
||||
|
||||
**Current State**: 549-line `index.html` with all functionality
|
||||
**Target State**: Modular, maintainable UI components
|
||||
|
||||
#### Implementation Plan
|
||||
```javascript
|
||||
// New structure
|
||||
www/
|
||||
├── index.html (minimal entry point)
|
||||
├── ui/
|
||||
│ ├── status-matrix.js
|
||||
│ ├── test-buttons.js
|
||||
│ └── diagnostics.js
|
||||
├── lib/
|
||||
│ ├── bridge.ts
|
||||
│ ├── schema-validation.ts
|
||||
│ └── error-handling.ts
|
||||
├── scenarios/
|
||||
│ ├── plugin-testing.js
|
||||
│ ├── notification-testing.js
|
||||
│ ├── permission-testing.js
|
||||
│ └── channel-testing.js
|
||||
└── fixtures/
|
||||
├── test-data.json
|
||||
└── expected-results.json
|
||||
```
|
||||
|
||||
#### Key Changes
|
||||
- **Modular Components**: Split UI into focused modules
|
||||
- **Scenario Runners**: Named test scenarios with fixtures
|
||||
- **TypeScript Bridge**: Typed interface to native plugin
|
||||
- **Schema Validation**: Input/output validation at boundary
|
||||
|
||||
### 2. Native Plugin Layering
|
||||
|
||||
**Current State**: 34 supporting classes with mixed responsibilities
|
||||
**Target State**: Organized by capability with use-case classes
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// New organization
|
||||
com.timesafari.dailynotification/
|
||||
├── plugin/
|
||||
│ └── DailyNotificationPlugin.java (thin facade)
|
||||
├── usecases/
|
||||
│ ├── ScheduleDaily.java
|
||||
│ ├── CheckPermissions.java
|
||||
│ ├── OpenSettings.java
|
||||
│ └── CollectRuntimeStatus.java
|
||||
├── scheduling/
|
||||
│ ├── ExactAlarmManager.java
|
||||
│ ├── DozeFallbackManager.java
|
||||
│ └── BootRescheduleManager.java
|
||||
├── permissions/
|
||||
│ ├── PermissionManager.java
|
||||
│ └── ChannelManager.java
|
||||
├── storage/
|
||||
│ ├── NotificationStorage.java
|
||||
│ └── MigrationManager.java
|
||||
└── workers/
|
||||
├── FetchWorker.java
|
||||
├── ScheduleWorker.java
|
||||
└── MaintenanceWorker.java
|
||||
```
|
||||
|
||||
#### Key Changes
|
||||
- **Use-Case Classes**: Business logic separated from plugin facade
|
||||
- **Capability Grouping**: Related functionality grouped together
|
||||
- **Service Locator**: Dependency injection for testability
|
||||
- **Thin Plugin Facade**: @PluginMethod methods delegate to use cases
|
||||
|
||||
### 3. Bridge Contract (Typed)
|
||||
|
||||
**Current State**: Unvalidated JavaScript calls to native methods
|
||||
**Target State**: Typed, validated interface with schema enforcement
|
||||
|
||||
#### Implementation Plan
|
||||
```typescript
|
||||
// lib/bridge.ts
|
||||
interface DailyNotificationBridge {
|
||||
scheduleDailyNotification(request: ScheduleRequest): Promise<ScheduleResponse>;
|
||||
checkPermissions(): Promise<PermissionStatus>;
|
||||
collectRuntimeStatus(): Promise<RuntimeStatus>;
|
||||
// ... other methods
|
||||
}
|
||||
|
||||
interface ScheduleRequest {
|
||||
time: string; // HH:mm format
|
||||
title: string; // max 100 chars
|
||||
body: string; // max 500 chars
|
||||
sound: boolean;
|
||||
priority: 'low' | 'default' | 'high';
|
||||
}
|
||||
|
||||
interface ScheduleResponse {
|
||||
success: boolean;
|
||||
scheduledAt?: number;
|
||||
error?: {
|
||||
code: string;
|
||||
message: string;
|
||||
hint?: string;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Changes
|
||||
- **TypeScript Interface**: Typed bridge contract
|
||||
- **Schema Validation**: Input validation before native calls
|
||||
- **Error Standardization**: Canonical error model
|
||||
- **Documentation**: API reference with schemas
|
||||
|
||||
## Code Organization
|
||||
|
||||
### 1. Status Matrix Module
|
||||
|
||||
**Purpose**: Single source of truth for runtime capabilities
|
||||
**Implementation**: Centralized status collection and display
|
||||
|
||||
#### Implementation Plan
|
||||
```javascript
|
||||
// ui/status-matrix.js
|
||||
class StatusMatrix {
|
||||
async collectRuntimeStatus() {
|
||||
return {
|
||||
postNotificationsGranted: await this.checkPostNotifications(),
|
||||
exactAlarmGranted: await this.checkExactAlarm(),
|
||||
channelEnabled: await this.checkChannelStatus(),
|
||||
batteryOptimizationsIgnored: await this.checkBatteryOptimization(),
|
||||
canScheduleNow: await this.canScheduleNow(),
|
||||
lastError: await this.getLastError(),
|
||||
capabilities: await this.getCapabilityMatrix()
|
||||
};
|
||||
}
|
||||
|
||||
renderStatusMatrix(status) {
|
||||
// Render actionable status matrix with buttons
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Single Source of Truth**: Centralized status collection
|
||||
- **Actionable UI**: Buttons to fix issues
|
||||
- **Real-time Updates**: Live status monitoring
|
||||
- **Diagnostics Export**: JSON export for debugging
|
||||
|
||||
### 2. Use-Case Classes
|
||||
|
||||
**Purpose**: Business logic separation from plugin facade
|
||||
**Implementation**: Thin @PluginMethod methods delegate to use cases
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// usecases/ScheduleDaily.java
|
||||
public class ScheduleDaily {
|
||||
private final ExactAlarmManager exactAlarmManager;
|
||||
private final DozeFallbackManager dozeFallbackManager;
|
||||
private final NotificationStorage storage;
|
||||
|
||||
public ScheduleResponse execute(ScheduleRequest request) {
|
||||
// Validate input
|
||||
ValidationResult validation = validateRequest(request);
|
||||
if (!validation.isValid()) {
|
||||
return ScheduleResponse.error(validation.getError());
|
||||
}
|
||||
|
||||
// Check prerequisites
|
||||
if (!canScheduleNow()) {
|
||||
return ScheduleResponse.error("E_SCHEDULE_BLOCKED", "Cannot schedule now");
|
||||
}
|
||||
|
||||
// Execute scheduling logic
|
||||
return doSchedule(request);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Business Logic**: Core functionality separated from plugin
|
||||
- **Dependency Injection**: Testable with mock dependencies
|
||||
- **Error Handling**: Standardized error responses
|
||||
- **Validation**: Input validation before processing
|
||||
|
||||
### 3. Service Locator
|
||||
|
||||
**Purpose**: Dependency injection for testability
|
||||
**Implementation**: Lightweight DI container
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// core/ServiceLocator.java
|
||||
public class ServiceLocator {
|
||||
private static final Map<Class<?>, Object> services = new HashMap<>();
|
||||
|
||||
public static <T> void register(Class<T> type, T instance) {
|
||||
services.put(type, instance);
|
||||
}
|
||||
|
||||
public static <T> T get(Class<T> type) {
|
||||
return (T) services.get(type);
|
||||
}
|
||||
|
||||
public static void initialize(Context context) {
|
||||
// Register core services
|
||||
register(WorkManager.class, WorkManager.getInstance(context));
|
||||
register(AlarmManager.class, (AlarmManager) context.getSystemService(Context.ALARM_SERVICE));
|
||||
register(NotificationStorage.class, new NotificationStorage(context));
|
||||
// ... other services
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Dependency Injection**: Testable service wiring
|
||||
- **Service Registration**: Centralized service management
|
||||
- **Context Integration**: Android context integration
|
||||
- **Testing Support**: Easy mocking for tests
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### 1. Scenario-Based Testing
|
||||
|
||||
**Current State**: 12 test buttons with mixed functionality
|
||||
**Target State**: Named scenarios with expected results
|
||||
|
||||
#### Implementation Plan
|
||||
```javascript
|
||||
// scenarios/notification-testing.js
|
||||
class NotificationScenarios {
|
||||
async testImmediateNotification() {
|
||||
const scenario = {
|
||||
name: 'Immediate Notification Test',
|
||||
description: 'Test immediate notification display',
|
||||
expectedResult: 'SUCCESS',
|
||||
timeout: 5000
|
||||
};
|
||||
|
||||
try {
|
||||
const result = await window.Capacitor.Plugins.DailyNotification.scheduleDailyNotification({
|
||||
time: this.getTimeIn5Minutes(),
|
||||
title: 'Test Notification',
|
||||
body: 'This is a test notification',
|
||||
sound: true,
|
||||
priority: 'high'
|
||||
});
|
||||
|
||||
return this.validateResult(result, scenario);
|
||||
} catch (error) {
|
||||
return this.handleError(error, scenario);
|
||||
}
|
||||
}
|
||||
|
||||
async testScheduledNotification() {
|
||||
// Similar pattern for scheduled notifications
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Named Scenarios**: Clear test descriptions
|
||||
- **Expected Results**: Machine-readable outcomes
|
||||
- **Error Handling**: Standardized error responses
|
||||
- **Timeout Management**: Configurable timeouts
|
||||
|
||||
### 2. Instrumentation Tests
|
||||
|
||||
**Purpose**: Automated testing of critical paths
|
||||
**Implementation**: Android instrumentation tests
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// androidTest/NotificationInstrumentationTest.java
|
||||
@RunWith(AndroidJUnit4.class)
|
||||
public class NotificationInstrumentationTest {
|
||||
@Test
|
||||
public void testChannelDisabledPath() {
|
||||
// Test channel disabled scenario
|
||||
// Verify error handling
|
||||
// Check status matrix updates
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testExactAlarmDeniedPath() {
|
||||
// Test exact alarm denied scenario
|
||||
// Verify fallback behavior
|
||||
// Check graceful degradation
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBootReschedule() {
|
||||
// Test boot reschedule functionality
|
||||
// Verify idempotent behavior
|
||||
// Check migration handling
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Critical Path Testing**: Test important user journeys
|
||||
- **Error Scenario Testing**: Test error handling paths
|
||||
- **Integration Testing**: Test full plugin integration
|
||||
- **Automated Validation**: CI/CD integration
|
||||
|
||||
### 3. Unit Tests
|
||||
|
||||
**Purpose**: Test individual components
|
||||
**Implementation**: JUnit tests for use-case classes
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// test/ScheduleDailyTest.java
|
||||
@RunWith(MockitoJUnitRunner.class)
|
||||
public class ScheduleDailyTest {
|
||||
@Mock private ExactAlarmManager exactAlarmManager;
|
||||
@Mock private DozeFallbackManager dozeFallbackManager;
|
||||
@Mock private NotificationStorage storage;
|
||||
|
||||
private ScheduleDaily scheduleDaily;
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
scheduleDaily = new ScheduleDaily(exactAlarmManager, dozeFallbackManager, storage);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScheduleWithValidInput() {
|
||||
// Test successful scheduling
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScheduleWithInvalidInput() {
|
||||
// Test input validation
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testScheduleWhenBlocked() {
|
||||
// Test blocked scheduling
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Component Testing**: Test individual use cases
|
||||
- **Mock Dependencies**: Isolated testing
|
||||
- **Edge Case Testing**: Test error conditions
|
||||
- **Fast Execution**: Quick feedback loop
|
||||
|
||||
## Security Hardening
|
||||
|
||||
### 1. Bridge Input Validation
|
||||
|
||||
**Purpose**: Validate all inputs before native processing
|
||||
**Implementation**: Schema validation at JavaScript boundary
|
||||
|
||||
#### Implementation Plan
|
||||
```typescript
|
||||
// lib/schema-validation.ts
|
||||
export class SchemaValidator {
|
||||
validateScheduleRequest(request: any): ValidationResult {
|
||||
const errors: string[] = [];
|
||||
|
||||
// Validate time format
|
||||
if (!this.isValidTimeFormat(request.time)) {
|
||||
errors.push('Time must be in HH:mm format');
|
||||
}
|
||||
|
||||
// Validate title length
|
||||
if (request.title && request.title.length > 100) {
|
||||
errors.push('Title must be 100 characters or less');
|
||||
}
|
||||
|
||||
// Validate body length
|
||||
if (request.body && request.body.length > 500) {
|
||||
errors.push('Body must be 500 characters or less');
|
||||
}
|
||||
|
||||
// Validate boolean fields
|
||||
if (typeof request.sound !== 'boolean') {
|
||||
errors.push('Sound must be a boolean');
|
||||
}
|
||||
|
||||
// Validate priority
|
||||
if (!['low', 'default', 'high'].includes(request.priority)) {
|
||||
errors.push('Priority must be low, default, or high');
|
||||
}
|
||||
|
||||
return {
|
||||
isValid: errors.length === 0,
|
||||
errors
|
||||
};
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Input Validation**: Validate all inputs
|
||||
- **Length Limits**: Prevent oversized inputs
|
||||
- **Type Validation**: Ensure correct types
|
||||
- **Format Validation**: Validate time formats
|
||||
|
||||
### 2. Network Security
|
||||
|
||||
**Purpose**: Secure network communication
|
||||
**Implementation**: HTTPS enforcement and timeout limits
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// network/SecureNetworkClient.java
|
||||
public class SecureNetworkClient {
|
||||
private static final int TIMEOUT_SECONDS = 30;
|
||||
private static final int MAX_RESPONSE_SIZE = 1024 * 1024; // 1MB
|
||||
|
||||
public String fetchContent(String url) throws NetworkException {
|
||||
// Enforce HTTPS
|
||||
if (!url.startsWith("https://")) {
|
||||
throw new NetworkException("E_INSECURE_URL", "Only HTTPS URLs allowed");
|
||||
}
|
||||
|
||||
// Set timeouts
|
||||
HttpURLConnection connection = createConnection(url);
|
||||
connection.setConnectTimeout(TIMEOUT_SECONDS * 1000);
|
||||
connection.setReadTimeout(TIMEOUT_SECONDS * 1000);
|
||||
|
||||
// Limit response size
|
||||
long contentLength = connection.getContentLengthLong();
|
||||
if (contentLength > MAX_RESPONSE_SIZE) {
|
||||
throw new NetworkException("E_RESPONSE_TOO_LARGE", "Response too large");
|
||||
}
|
||||
|
||||
return readResponse(connection);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **HTTPS Enforcement**: Only secure connections
|
||||
- **Timeout Limits**: Prevent hanging requests
|
||||
- **Size Limits**: Prevent memory exhaustion
|
||||
- **Error Handling**: Standardized network errors
|
||||
|
||||
### 3. Intent Filter Security
|
||||
|
||||
**Purpose**: Secure intent handling
|
||||
**Implementation**: Review and secure intent filters
|
||||
|
||||
#### Implementation Plan
|
||||
```xml
|
||||
<!-- AndroidManifest.xml -->
|
||||
<receiver
|
||||
android:name="com.timesafari.dailynotification.DailyNotificationReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="false">
|
||||
<intent-filter>
|
||||
<action android:name="com.timesafari.daily.NOTIFICATION" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
|
||||
<receiver
|
||||
android:name="com.timesafari.dailynotification.BootReceiver"
|
||||
android:enabled="true"
|
||||
android:exported="true"
|
||||
android:permission="android.permission.RECEIVE_BOOT_COMPLETED">
|
||||
<intent-filter android:priority="1000">
|
||||
<action android:name="android.intent.action.BOOT_COMPLETED" />
|
||||
</intent-filter>
|
||||
</receiver>
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Export Control**: Minimize exported components
|
||||
- **Permission Requirements**: Require permissions for exported components
|
||||
- **Intent Validation**: Validate incoming intents
|
||||
- **Security Review**: Regular security audits
|
||||
|
||||
## Performance & Reliability
|
||||
|
||||
### 1. WebView Cold-Start Optimization
|
||||
|
||||
**Purpose**: Minimize WebView initialization time
|
||||
**Implementation**: Lazy loading and preloading strategies
|
||||
|
||||
#### Implementation Plan
|
||||
```javascript
|
||||
// lib/lazy-loader.js
|
||||
class LazyLoader {
|
||||
constructor() {
|
||||
this.loadedModules = new Set();
|
||||
this.loadingPromises = new Map();
|
||||
}
|
||||
|
||||
async loadModule(moduleName) {
|
||||
if (this.loadedModules.has(moduleName)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.loadingPromises.has(moduleName)) {
|
||||
return this.loadingPromises.get(moduleName);
|
||||
}
|
||||
|
||||
const loadPromise = this.doLoadModule(moduleName);
|
||||
this.loadingPromises.set(moduleName, loadPromise);
|
||||
|
||||
try {
|
||||
await loadPromise;
|
||||
this.loadedModules.add(moduleName);
|
||||
} finally {
|
||||
this.loadingPromises.delete(moduleName);
|
||||
}
|
||||
}
|
||||
|
||||
async doLoadModule(moduleName) {
|
||||
// Load module dynamically
|
||||
const module = await import(`./modules/${moduleName}.js`);
|
||||
return module;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Lazy Loading**: Load modules on demand
|
||||
- **Preloading**: Preload critical modules
|
||||
- **Caching**: Cache loaded modules
|
||||
- **Performance Monitoring**: Track load times
|
||||
|
||||
### 2. Worker Backoff Strategy
|
||||
|
||||
**Purpose**: Implement exponential backoff with jitter
|
||||
**Implementation**: Smart retry logic for background work
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// workers/BackoffStrategy.java
|
||||
public class BackoffStrategy {
|
||||
private static final long BASE_DELAY_MS = 1000;
|
||||
private static final long MAX_DELAY_MS = 300000; // 5 minutes
|
||||
private static final double BACKOFF_MULTIPLIER = 2.0;
|
||||
private static final double JITTER_FACTOR = 0.1;
|
||||
|
||||
public long calculateDelay(int attemptNumber) {
|
||||
long delay = (long) (BASE_DELAY_MS * Math.pow(BACKOFF_MULTIPLIER, attemptNumber));
|
||||
delay = Math.min(delay, MAX_DELAY_MS);
|
||||
|
||||
// Add jitter to prevent thundering herd
|
||||
double jitter = delay * JITTER_FACTOR * (Math.random() - 0.5);
|
||||
delay += (long) jitter;
|
||||
|
||||
return Math.max(delay, 0);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Exponential Backoff**: Increasing delay between retries
|
||||
- **Jitter**: Random variation to prevent thundering herd
|
||||
- **Maximum Delay**: Cap on maximum delay
|
||||
- **Configurable**: Adjustable parameters
|
||||
|
||||
### 3. Database Hygiene
|
||||
|
||||
**Purpose**: Maintain database performance
|
||||
**Implementation**: Indexing and periodic cleanup
|
||||
|
||||
#### Implementation Plan
|
||||
```java
|
||||
// storage/DatabaseMaintenance.java
|
||||
public class DatabaseMaintenance {
|
||||
private final NotificationStorage storage;
|
||||
|
||||
public void performMaintenance() {
|
||||
// Clean up expired notifications
|
||||
cleanupExpiredNotifications();
|
||||
|
||||
// Clean up delivered notifications older than 7 days
|
||||
cleanupDeliveredNotifications();
|
||||
|
||||
// Rebuild indexes if needed
|
||||
rebuildIndexesIfNeeded();
|
||||
|
||||
// Vacuum database
|
||||
vacuumDatabase();
|
||||
}
|
||||
|
||||
private void cleanupExpiredNotifications() {
|
||||
long cutoffTime = System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7);
|
||||
storage.deleteExpiredNotifications(cutoffTime);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Periodic Cleanup**: Regular maintenance tasks
|
||||
- **Index Optimization**: Maintain database performance
|
||||
- **Data Retention**: Configurable retention policies
|
||||
- **Performance Monitoring**: Track maintenance impact
|
||||
|
||||
## Documentation Updates
|
||||
|
||||
### 1. "How it Works" Documentation
|
||||
|
||||
**Purpose**: Explain the system architecture and flow
|
||||
**Implementation**: Comprehensive architecture documentation
|
||||
|
||||
#### Implementation Plan
|
||||
```markdown
|
||||
# How It Works
|
||||
|
||||
## System Architecture
|
||||
|
||||
### App Launch Flow
|
||||
1. Android launches MainActivity
|
||||
2. Capacitor initializes WebView
|
||||
3. Plugin discovery loads DailyNotificationPlugin
|
||||
4. JavaScript bridge establishes communication
|
||||
5. Web interface loads and initializes
|
||||
|
||||
### Notification Scheduling Flow
|
||||
1. User triggers schedule action
|
||||
2. JavaScript validates input schema
|
||||
3. Bridge calls native plugin method
|
||||
4. Use-case class processes request
|
||||
5. ExactAlarmManager schedules notification
|
||||
6. WorkManager handles background processing
|
||||
7. NotificationReceiver displays notification
|
||||
|
||||
### Error Handling Flow
|
||||
1. Error occurs in native code
|
||||
2. Error mapped to canonical error code
|
||||
3. Error returned through bridge
|
||||
4. JavaScript displays user-friendly message
|
||||
5. Status matrix updated with error state
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Architecture Diagrams**: Visual system overview
|
||||
- **Flow Documentation**: Step-by-step processes
|
||||
- **Error Handling**: Error flow documentation
|
||||
- **Troubleshooting**: Common issues and solutions
|
||||
|
||||
### 2. Runbooks
|
||||
|
||||
**Purpose**: Operational procedures for common issues
|
||||
**Implementation**: Step-by-step troubleshooting guides
|
||||
|
||||
#### Implementation Plan
|
||||
```markdown
|
||||
# Runbooks
|
||||
|
||||
## No Notifications Firing
|
||||
|
||||
### Checks
|
||||
1. Check status matrix for red indicators
|
||||
2. Verify POST_NOTIFICATIONS permission
|
||||
3. Check notification channel status
|
||||
4. Verify exact alarm permission
|
||||
5. Check battery optimization settings
|
||||
|
||||
### Fix
|
||||
1. Request missing permissions
|
||||
2. Enable notification channel
|
||||
3. Enable exact alarms in settings
|
||||
4. Disable battery optimization
|
||||
|
||||
### Verify
|
||||
1. Run comprehensive status check
|
||||
2. Test immediate notification
|
||||
3. Verify scheduled notification
|
||||
4. Check logs for errors
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Step-by-Step Procedures**: Clear troubleshooting steps
|
||||
- **Check-Fix-Verify**: Structured problem resolution
|
||||
- **Common Issues**: Frequent problems and solutions
|
||||
- **Escalation Paths**: When to escalate issues
|
||||
|
||||
### 3. API Reference
|
||||
|
||||
**Purpose**: Complete API documentation
|
||||
**Implementation**: Method-by-method documentation
|
||||
|
||||
#### Implementation Plan
|
||||
```markdown
|
||||
# API Reference
|
||||
|
||||
## scheduleDailyNotification
|
||||
|
||||
### Request Schema
|
||||
```typescript
|
||||
interface ScheduleRequest {
|
||||
time: string; // HH:mm format
|
||||
title: string; // max 100 chars
|
||||
body: string; // max 500 chars
|
||||
sound: boolean; // play sound
|
||||
priority: 'low' | 'default' | 'high';
|
||||
}
|
||||
```
|
||||
|
||||
### Response Schema
|
||||
```typescript
|
||||
interface ScheduleResponse {
|
||||
success: boolean;
|
||||
scheduledAt?: number;
|
||||
error?: {
|
||||
code: string;
|
||||
message: string;
|
||||
hint?: string;
|
||||
};
|
||||
}
|
||||
```
|
||||
|
||||
### Error Codes
|
||||
- `E_INVALID_TIME`: Time format invalid
|
||||
- `E_TITLE_TOO_LONG`: Title exceeds 100 characters
|
||||
- `E_BODY_TOO_LONG`: Body exceeds 500 characters
|
||||
- `E_PERMISSION_DENIED`: Required permission not granted
|
||||
- `E_CHANNEL_DISABLED`: Notification channel disabled
|
||||
```
|
||||
|
||||
#### Key Features
|
||||
- **Complete API Coverage**: All methods documented
|
||||
- **Schema Definitions**: Request/response schemas
|
||||
- **Error Codes**: Complete error code reference
|
||||
- **Examples**: Usage examples for each method
|
||||
|
||||
## Task Breakdown
|
||||
|
||||
### Phase 1: Foundation
|
||||
- [ ] **Status Matrix Module**
|
||||
- Implement `collectRuntimeStatus()` function
|
||||
- Create status matrix UI component
|
||||
- Add "Copy Diagnostics" functionality
|
||||
- [ ] **Input Schema Validation**
|
||||
- Create TypeScript schema definitions
|
||||
- Implement validation at bridge boundary
|
||||
- Add error handling for validation failures
|
||||
- [ ] **Exact-Alarm Gate**
|
||||
- Create `ExactAlarmManager` class
|
||||
- Implement graceful fallback logic
|
||||
- Update status matrix to show exact alarm status
|
||||
- [ ] **BootReceiver Idempotent**
|
||||
- Add migration fence for old schedules
|
||||
- Implement idempotent rescheduling
|
||||
- Add logging for boot recovery
|
||||
- [ ] **Use-Case Classes**
|
||||
- Create `ScheduleDaily` use case
|
||||
- Create `CheckPermissions` use case
|
||||
- Refactor plugin methods to use cases
|
||||
|
||||
### Phase 2: Testing & Reliability
|
||||
- [ ] **Test UI Refactoring**
|
||||
- Split 549-line HTML into modules
|
||||
- Create scenario runner framework
|
||||
- Implement named test scenarios
|
||||
- [ ] **Instrumentation Tests**
|
||||
- Test channel disabled path
|
||||
- Test exact alarm denied path
|
||||
- Test boot reschedule functionality
|
||||
- [ ] **Structured Logging**
|
||||
- Add event IDs for all operations
|
||||
- Implement progress logging
|
||||
- Create log export functionality
|
||||
|
||||
### Phase 3: Security & Performance
|
||||
- [ ] **Security Hardening**
|
||||
- Add network security measures
|
||||
- Review intent filter security
|
||||
- Implement channel policy enforcement
|
||||
- [ ] **Performance Optimizations**
|
||||
- Implement lazy loading for UI modules
|
||||
- Add worker backoff strategy
|
||||
- Optimize database operations
|
||||
- [ ] **Diagnostics System**
|
||||
- Implement comprehensive diagnostics
|
||||
- Add performance monitoring
|
||||
- Create health check endpoints
|
||||
- [ ] **Documentation Updates**
|
||||
- Create "How it Works" documentation
|
||||
- Write runbooks for common issues
|
||||
- Complete API reference
|
||||
|
||||
## Acceptance Criteria
|
||||
|
||||
### Status Matrix
|
||||
- [ ] Reports all relevant runtime capabilities
|
||||
- [ ] Shows live channel state
|
||||
- [ ] Provides actionable buttons for issues
|
||||
- [ ] Exports diagnostics as JSON
|
||||
|
||||
### Error Handling
|
||||
- [ ] All @PluginMethod calls validate inputs
|
||||
- [ ] Returns stable error codes with hints
|
||||
- [ ] Maps native exceptions to canonical errors
|
||||
- [ ] Provides user-friendly error messages
|
||||
|
||||
### Reliability
|
||||
- [ ] Reboot scenarios reliably deliver notifications
|
||||
- [ ] Doze scenarios degrade gracefully
|
||||
- [ ] Clear logs explain system behavior
|
||||
- [ ] User-visible reasoning for failures
|
||||
|
||||
### Testing
|
||||
- [ ] Test UI modularized into scenarios
|
||||
- [ ] At least 2 scenarios run as automated tests
|
||||
- [ ] Instrumentation tests cover critical paths
|
||||
- [ ] Unit tests cover use-case classes
|
||||
|
||||
### Documentation
|
||||
- [ ] "How it Works" page with lifecycle diagrams
|
||||
- [ ] Runbooks for common issues
|
||||
- [ ] Complete API reference with schemas
|
||||
- [ ] Error codes table with explanations
|
||||
|
||||
## Success Metrics
|
||||
|
||||
### Code Quality
|
||||
- **Maintainability**: Reduced complexity in test UI
|
||||
- **Testability**: Use-case classes with dependency injection
|
||||
- **Reliability**: Improved error handling and logging
|
||||
- **Security**: Input validation and network security
|
||||
|
||||
### User Experience
|
||||
- **Clarity**: Clear status matrix with actionable items
|
||||
- **Reliability**: Consistent notification delivery
|
||||
- **Debugging**: Comprehensive diagnostics and logging
|
||||
- **Performance**: Faster app startup and response
|
||||
|
||||
### Developer Experience
|
||||
- **Documentation**: Complete API reference and runbooks
|
||||
- **Testing**: Automated test coverage for critical paths
|
||||
- **Debugging**: Structured logging and diagnostics
|
||||
- **Maintenance**: Modular architecture for easy updates
|
||||
|
||||
## Conclusion
|
||||
|
||||
This implementation plan provides a structured approach to improving the DailyNotification Android test app. The plan focuses on architecture improvements, code organization, testing, and maintainability while maintaining the existing functionality.
|
||||
|
||||
The phased approach allows for incremental improvements while ensuring each phase delivers value. The acceptance criteria provide clear success metrics for each improvement area.
|
||||
|
||||
By following this plan, the test app will become more maintainable, reliable, and user-friendly while providing a solid foundation for future enhancements.
|
||||
Reference in New Issue
Block a user