docs(refactor): add integration point refactor context mapping
Add INTEGRATION_REFACTOR_CONTEXT.md that maps current codebase to the Integration Point Refactor plan, including: - Current state analysis and what needs to be created/modified - Dependency mapping and implementation checklists - Testing strategy and open questions Also update AndroidManifest.xml files to register Application classes.
This commit is contained in:
597
docs/INTEGRATION_REFACTOR_CONTEXT.md
Normal file
597
docs/INTEGRATION_REFACTOR_CONTEXT.md
Normal file
@@ -0,0 +1,597 @@
|
||||
# Integration Point Refactor - Implementation Context
|
||||
|
||||
**Author**: Matthew Raymer
|
||||
**Date**: 2025-10-29
|
||||
**Status**: 🎯 **CONTEXT** - Pre-implementation analysis and mapping
|
||||
|
||||
## Purpose
|
||||
|
||||
This document maps the current codebase to the Integration Point Refactor plan, identifies what exists, what needs to be created, and where gaps exist before starting implementation (PR1).
|
||||
|
||||
---
|
||||
|
||||
## Current State Analysis
|
||||
|
||||
### ✅ What Already Exists
|
||||
|
||||
#### 1. TypeScript Type Definitions (`src/types/content-fetcher.ts`)
|
||||
- ✅ `NotificationContent` interface (matches directive spec)
|
||||
- ✅ `FetchContext` interface (matches directive spec)
|
||||
- ✅ `JsNotificationContentFetcher` interface (matches directive spec)
|
||||
- ✅ `FetchTrigger` type (matches directive spec)
|
||||
- ✅ `SchedulingPolicy` interface (matches directive spec)
|
||||
|
||||
**Status**: Complete and ready for PR1. No changes needed.
|
||||
|
||||
#### 2. Example Implementations
|
||||
- ✅ `examples/native-fetcher-android.kt` - Kotlin native fetcher skeleton
|
||||
- ✅ `examples/js-fetcher-typescript.ts` - TypeScript JS fetcher skeleton
|
||||
|
||||
**Status**: Examples exist as reference. These are for host app, not plugin.
|
||||
|
||||
#### 3. Test Contract (`tests/fixtures/test-contract.json`)
|
||||
- ✅ Golden contract fixture with expected outputs
|
||||
- ✅ Failure scenarios defined
|
||||
|
||||
**Status**: Ready for contract tests. Will be used in PR2+ for validation.
|
||||
|
||||
#### 4. Current TimeSafari Integration (To Be Replaced)
|
||||
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/`
|
||||
|
||||
- ✅ `TimeSafariIntegrationManager.java` - Current TimeSafari orchestration
|
||||
- ✅ `EnhancedDailyNotificationFetcher.java` - TimeSafari API client
|
||||
- ✅ `DailyNotificationJWTManager.java` - JWT generation for TimeSafari
|
||||
- ✅ `DailyNotificationETagManager.java` - ETag caching for TimeSafari
|
||||
|
||||
**Status**: These will be moved to host app OR deprecated behind feature flag (PR7).
|
||||
|
||||
**Current Integration Flow**:
|
||||
```
|
||||
DailyNotificationPlugin.load()
|
||||
→ TimeSafariIntegrationManager (created in plugin)
|
||||
→ EnhancedDailyNotificationFetcher
|
||||
→ JWTManager + ETagManager
|
||||
→ TimeSafari API endpoints
|
||||
```
|
||||
|
||||
**Target Flow** (after refactor):
|
||||
```
|
||||
DailyNotificationPlugin.load()
|
||||
→ NativeNotificationContentFetcher (registered by host app)
|
||||
→ Host app's TimeSafari integration
|
||||
→ TimeSafari API endpoints
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## What Needs to Be Created
|
||||
|
||||
### PR1: SPI Shell (First Implementation)
|
||||
|
||||
#### 1. Android Native SPI Interface
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/`
|
||||
|
||||
**File to Create**: `NativeNotificationContentFetcher.java`
|
||||
|
||||
```java
|
||||
package com.timesafari.dailynotification;
|
||||
|
||||
public interface NativeNotificationContentFetcher {
|
||||
java.util.concurrent.CompletableFuture<java.util.List<NotificationContent>>
|
||||
fetchContent(FetchContext context);
|
||||
}
|
||||
|
||||
public class FetchContext {
|
||||
public final String trigger; // "background_work" | "prefetch" | "manual" | "scheduled"
|
||||
public final Long scheduledTime; // Optional: epoch ms
|
||||
public final long fetchTime; // Required: epoch ms
|
||||
public final Map<String, Object> metadata; // Optional
|
||||
|
||||
// Constructor, getters...
|
||||
}
|
||||
```
|
||||
|
||||
**Status**: ❌ Not created yet - PR1 task
|
||||
|
||||
#### 2. Fetcher Registry in Plugin
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java`
|
||||
|
||||
**What to Add**:
|
||||
- Field: `private NativeNotificationContentFetcher nativeFetcher;`
|
||||
- Method: `public void setNativeFetcher(NativeNotificationContentFetcher fetcher)`
|
||||
- Storage: Store in static registry or application-level singleton
|
||||
|
||||
**Status**: ❌ Not implemented yet - PR1 task
|
||||
|
||||
#### 3. SchedulingPolicy Implementation (Android)
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/`
|
||||
|
||||
**File to Create**: `SchedulingPolicy.java`
|
||||
|
||||
```java
|
||||
public class SchedulingPolicy {
|
||||
public Long prefetchWindowMs;
|
||||
public RetryBackoff retryBackoff;
|
||||
public Integer maxBatchSize;
|
||||
public Long dedupeHorizonMs;
|
||||
public Integer cacheTtlSeconds;
|
||||
public Boolean exactAlarmsAllowed;
|
||||
|
||||
public static class RetryBackoff {
|
||||
public long minMs;
|
||||
public long maxMs;
|
||||
public double factor;
|
||||
public int jitterPct;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Status**: ❌ Not created yet - PR1 task
|
||||
|
||||
**Where Used**:
|
||||
- `DailyNotificationFetchWorker` - backoff policy
|
||||
- `DailyNotificationScheduler` - prefetch timing
|
||||
- Deduplication logic (new, PR4)
|
||||
- TTL enforcement (existing `DailyNotificationTTLEnforcer`)
|
||||
|
||||
#### 4. Plugin API Methods (TypeScript Bridge)
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java`
|
||||
|
||||
**Methods to Add**:
|
||||
```java
|
||||
@PluginMethod
|
||||
public void setJsContentFetcher(PluginCall call) {
|
||||
// Store JS fetcher for foreground use
|
||||
// Will be called from TypeScript
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
public void enableNativeFetcher(PluginCall call) {
|
||||
// Toggle native fetcher on/off
|
||||
// Default: true (native required for background)
|
||||
}
|
||||
|
||||
@PluginMethod
|
||||
public void setPolicy(PluginCall call) {
|
||||
// Update SchedulingPolicy
|
||||
// Parse JSON from call, create SchedulingPolicy instance
|
||||
}
|
||||
```
|
||||
|
||||
**Status**: ❌ Not implemented yet - PR1 task
|
||||
|
||||
#### 5. TypeScript Plugin Interface Extensions
|
||||
**Location**: `src/definitions.ts`
|
||||
|
||||
**What to Add**:
|
||||
```typescript
|
||||
export interface DailyNotificationPlugin {
|
||||
// ... existing methods ...
|
||||
|
||||
setJsContentFetcher(fetcher: JsNotificationContentFetcher): void;
|
||||
enableNativeFetcher(enable: boolean): Promise<void>;
|
||||
setPolicy(policy: SchedulingPolicy): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
**Status**: ❌ Partially exists in `src/types/content-fetcher.ts` but not wired to `DailyNotificationPlugin` interface in `src/definitions.ts` - PR1 task
|
||||
|
||||
---
|
||||
|
||||
### PR2: Background Workers
|
||||
|
||||
#### Current Worker: `DailyNotificationFetchWorker.java`
|
||||
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationFetchWorker.java`
|
||||
|
||||
**Current Behavior**:
|
||||
- Uses `DailyNotificationFetcher` (generic, no TimeSafari)
|
||||
- Called from `DailyNotificationFetcher.scheduleFetch()`
|
||||
- Runs via WorkManager
|
||||
|
||||
**What Needs to Change**:
|
||||
|
||||
1. **Remove TimeSafari-Specific Coordination**:
|
||||
```java
|
||||
// Remove these lines (79-92):
|
||||
boolean timesafariCoordination = inputData.getBoolean("timesafari_coordination", false);
|
||||
// ... coordination checks ...
|
||||
```
|
||||
|
||||
2. **Add Native Fetcher Call**:
|
||||
```java
|
||||
private NotificationContent fetchContentWithTimeout() {
|
||||
if (nativeFetcher == null) {
|
||||
Log.w(TAG, "Native fetcher not registered, falling back to cache");
|
||||
return getCachedContent();
|
||||
}
|
||||
|
||||
FetchContext context = new FetchContext(
|
||||
"background_work",
|
||||
scheduledTime,
|
||||
System.currentTimeMillis(),
|
||||
metadata
|
||||
);
|
||||
|
||||
try {
|
||||
List<NotificationContent> results =
|
||||
nativeFetcher.fetchContent(context)
|
||||
.get(30, TimeUnit.SECONDS);
|
||||
return results.isEmpty() ? null : results.get(0);
|
||||
} catch (Exception e) {
|
||||
// Handle timeout, errors
|
||||
return null;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
3. **Add SchedulingPolicy Backoff**:
|
||||
- Use `SchedulingPolicy.retryBackoff` for retry delays
|
||||
- Replace hardcoded retry logic
|
||||
|
||||
**Status**: ❌ Not modified yet - PR2 task
|
||||
|
||||
---
|
||||
|
||||
### PR3: JS Fetcher Path
|
||||
|
||||
#### Plugin Side: Bridge JS Fetcher to Workers
|
||||
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/DailyNotificationPlugin.java`
|
||||
|
||||
**What Needs to Change**:
|
||||
|
||||
1. **Store JS Fetcher Reference**:
|
||||
```java
|
||||
private JsNotificationContentFetcher jsFetcher; // Wrapper object needed
|
||||
|
||||
@PluginMethod
|
||||
public void setJsContentFetcher(PluginCall call) {
|
||||
// Extract callback from JS
|
||||
// Store for foreground use only
|
||||
// Log warning if used in background worker
|
||||
}
|
||||
```
|
||||
|
||||
2. **Foreground Fetch Method**:
|
||||
```java
|
||||
@PluginMethod
|
||||
public void refreshNow(PluginCall call) {
|
||||
if (jsFetcher != null) {
|
||||
// Call JS fetcher (foreground only)
|
||||
// Must bridge JS callback to Java
|
||||
} else if (nativeFetcher != null) {
|
||||
// Fall back to native fetcher
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Challenge**: JavaScript → Java callback bridge. Options:
|
||||
- Option A: Use Capacitor's bridge to call JS function
|
||||
- Option B: Use event system (plugin emits event, JS responds)
|
||||
- Option C: Store fetcher config, not callback (requires HTTP endpoint)
|
||||
|
||||
**Status**: ❌ Not implemented yet - PR3 task
|
||||
|
||||
---
|
||||
|
||||
### PR4: Deduplication
|
||||
|
||||
#### New Component: Deduplication Store
|
||||
|
||||
**Location**: `android/plugin/src/main/java/com/timesafari/dailynotification/`
|
||||
|
||||
**File to Create**: `NotificationDeduplicationStore.java`
|
||||
|
||||
**Responsibilities**:
|
||||
- Maintain bloom filter or LRU cache of recent `dedupeKey` values
|
||||
- Check `dedupeHorizonMs` window
|
||||
- Prevent duplicate notifications within horizon
|
||||
- Use `dedupeKey` (fallback to `id`)
|
||||
|
||||
**Integration Points**:
|
||||
- `DailyNotificationScheduler.scheduleNotification()` - check before scheduling
|
||||
- `DailyNotificationFetchWorker.doWork()` - check after fetch
|
||||
|
||||
**Status**: ❌ Not created yet - PR4 task
|
||||
|
||||
---
|
||||
|
||||
### PR5: Failure Policy
|
||||
|
||||
#### Enhance Existing Components
|
||||
|
||||
**Location**: Multiple files
|
||||
|
||||
**1. Retry Logic** (`DailyNotificationFetchWorker.java`):
|
||||
- Replace hardcoded retry with `SchedulingPolicy.retryBackoff`
|
||||
- Implement exponential backoff with jitter
|
||||
- Distinguish retryable vs unretryable errors
|
||||
|
||||
**2. Cache Fallback** (new or enhance `DailyNotificationStorage.java`):
|
||||
- Check TTL using `SchedulingPolicy.cacheTtlSeconds` or item `ttlSeconds`
|
||||
- Fallback to cached content if fetch fails and cache valid
|
||||
|
||||
**3. Error Classification**:
|
||||
```java
|
||||
public enum FetchErrorType {
|
||||
RETRYABLE, // 5xx, network, timeout
|
||||
UNRETRYABLE, // 4xx auth, schema error
|
||||
PARTIAL, // Some items bad
|
||||
OVER_QUOTA // 429 with Retry-After
|
||||
}
|
||||
```
|
||||
|
||||
**Status**: ❌ Partially implemented (basic retry exists), needs enhancement - PR5 task
|
||||
|
||||
---
|
||||
|
||||
## Component Dependency Map
|
||||
|
||||
### Current Dependencies
|
||||
|
||||
```
|
||||
DailyNotificationPlugin
|
||||
├── TimeSafariIntegrationManager (TO BE REMOVED in PR7)
|
||||
│ ├── EnhancedDailyNotificationFetcher (TO BE MOVED to host app)
|
||||
│ ├── DailyNotificationJWTManager (TO BE MOVED to host app)
|
||||
│ └── DailyNotificationETagManager (TO BE MOVED to host app)
|
||||
├── DailyNotificationScheduler
|
||||
│ ├── DailyNotificationTTLEnforcer
|
||||
│ └── PendingIntentManager
|
||||
├── DailyNotificationFetchWorker
|
||||
│ └── DailyNotificationFetcher (generic, keep)
|
||||
└── DailyNotificationStorage
|
||||
```
|
||||
|
||||
### Target Dependencies (After Refactor)
|
||||
|
||||
```
|
||||
DailyNotificationPlugin
|
||||
├── NativeNotificationContentFetcher (REGISTERED by host app)
|
||||
├── JsNotificationContentFetcher (REGISTERED by host app, foreground only)
|
||||
├── SchedulingPolicy (CONFIGURED by host app)
|
||||
├── DailyNotificationScheduler
|
||||
│ ├── DailyNotificationTTLEnforcer
|
||||
│ ├── PendingIntentManager
|
||||
│ └── NotificationDeduplicationStore (NEW in PR4)
|
||||
├── DailyNotificationFetchWorker
|
||||
│ ├── Calls NativeNotificationContentFetcher (native path)
|
||||
│ └── Uses SchedulingPolicy (backoff, TTL)
|
||||
└── DailyNotificationStorage
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Integration Points to Identify
|
||||
|
||||
### 1. Worker Enqueue Points
|
||||
|
||||
**Where Workers Are Scheduled**:
|
||||
|
||||
1. **`DailyNotificationFetcher.scheduleFetch()`** (line ~77-116):
|
||||
- Enqueues `DailyNotificationFetchWorker`
|
||||
- Currently generic (no TimeSafari coupling)
|
||||
|
||||
2. **`TimeSafariIntegrationManager.fetchAndScheduleFromServer()`** (line ~258):
|
||||
- May enqueue workers with TimeSafari coordination flags
|
||||
- Needs to switch to native fetcher path
|
||||
|
||||
3. **`DailyNotificationPlugin.scheduleCoordinatedBackgroundJobs()`**:
|
||||
- Phase 3 coordination code
|
||||
- Adds TimeSafari-specific flags to WorkManager Data
|
||||
- Needs refactor to remove TimeSafari flags
|
||||
|
||||
**Action for PR2**: Modify worker enqueue to use native fetcher, remove TimeSafari coordination flags.
|
||||
|
||||
---
|
||||
|
||||
### 2. Notification Content Flow
|
||||
|
||||
**Current Flow**:
|
||||
```
|
||||
EnhancedDailyNotificationFetcher.fetch()
|
||||
→ Returns TimeSafariNotificationBundle
|
||||
→ TimeSafariIntegrationManager.convertBundleToNotificationContent()
|
||||
→ Returns List<NotificationContent>
|
||||
→ DailyNotificationScheduler.scheduleNotification()
|
||||
```
|
||||
|
||||
**Target Flow**:
|
||||
```
|
||||
NativeNotificationContentFetcher.fetchContent(context)
|
||||
→ Returns List<NotificationContent> (already generic)
|
||||
→ DailyNotificationScheduler.scheduleNotification()
|
||||
```
|
||||
|
||||
**Gap**: `convertBundleToNotificationContent()` logic must move to host app (PR7).
|
||||
|
||||
---
|
||||
|
||||
### 3. TTL Enforcement Points
|
||||
|
||||
**Current TTL Flow**:
|
||||
1. **Hard-Fail at Arming**: `->DailyNotificationScheduler.scheduleNotification()`
|
||||
- Calls `ttlEnforcer.validateBeforeArming(content)`
|
||||
- ✅ Already generic (works with any `NotificationContent`)
|
||||
|
||||
2. **Soft-Check at Fire**: `DailyNotificationReceiver.onReceive()`
|
||||
- Checks freshness, may trigger refresh
|
||||
- ✅ Already generic
|
||||
|
||||
**Status**: ✅ TTL enforcement is already generic - no changes needed for SPI.
|
||||
|
||||
---
|
||||
|
||||
### 4. Metrics Collection Points
|
||||
|
||||
**Current Metrics**:
|
||||
- `src/observability.ts` - TypeScript observability
|
||||
- `packages/polling-contracts/src/telemetry.ts` - Telemetry manager
|
||||
|
||||
**What to Add**:
|
||||
- `fetch_duration_ms` - Time for native fetcher to complete
|
||||
- `fetch_success` - Boolean success/failure
|
||||
- `fetch_fail_class` - Error classification (retryable/unretryable/partial/over-quota)
|
||||
- `items_fetched` - Number of items from fetcher
|
||||
- `items_enqueued` - Number successfully scheduled
|
||||
- `deduped_count` - Items filtered by deduplication (PR4)
|
||||
- `cache_hits` - Cached content used when fetch fails (PR5)
|
||||
|
||||
**Action for PR2**: Add metrics calls in `DailyNotificationFetchWorker.doWork()`.
|
||||
|
||||
---
|
||||
|
||||
## Migration Path Mapping
|
||||
|
||||
### Feature Flag Implementation (PR7)
|
||||
|
||||
**Location**: `DailyNotificationPlugin.java`
|
||||
|
||||
**What to Add**:
|
||||
```java
|
||||
private static final boolean USE_LEGACY_INTEGRATION = false; // Default false in new minor
|
||||
|
||||
private void fetchContent() {
|
||||
if (USE_LEGACY_INTEGRATION && timeSafariIntegration != null) {
|
||||
// Legacy path
|
||||
timeSafariIntegration.fetchAndScheduleFromServer(false);
|
||||
} else if (nativeFetcher != null) {
|
||||
// New SPI path
|
||||
// Call native fetcher
|
||||
} else {
|
||||
Log.w(TAG, "No fetcher available");
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Files to Guard**:
|
||||
- `TimeSafariIntegrationManager.java` - Keep for one minor release
|
||||
- `EnhancedDailyNotificationFetcher.java` - Keep for one minor release
|
||||
- Legacy `@PluginMethod` wrappers - Deprecate, keep for compatibility
|
||||
|
||||
---
|
||||
|
||||
## File Creation Checklist
|
||||
|
||||
### PR1: SPI Shell
|
||||
- [ ] `android/plugin/src/main/java/com/timesafari/dailynotification/NativeNotificationContentFetcher.java`
|
||||
- [ ] `android/plugin/src/main/java/com/timesafari/dailynotification/FetchContext.java` (or inner class)
|
||||
- [ ] `android/plugin/src/main/java/com/timesafari/dailynotification/SchedulingPolicy.java`
|
||||
- [ ] Update `DailyNotificationPlugin.java`:
|
||||
- [ ] Add `setNativeFetcher()` method
|
||||
- [ ] Add `setJsContentFetcher()` method (stub, full in PR3)
|
||||
- [ ] Add `enableNativeFetcher()` method
|
||||
- [ ] Add `setPolicy()` method
|
||||
- [ ] Update `src/definitions.ts`:
|
||||
- [ ] Wire `SchedulingPolicy` from `content-fetcher.ts`
|
||||
- [ ] Add new methods to `DailyNotificationPlugin` interface
|
||||
|
||||
### PR2: Background Workers
|
||||
- [ ] Modify `DailyNotificationFetchWorker.java`:
|
||||
- [ ] Remove TimeSafari coordination checks
|
||||
- [ ] Add native fetcher call
|
||||
- [ ] Add SchedulingPolicy backoff
|
||||
- [ ] Add metrics recording
|
||||
|
||||
### PR3: JS Fetcher Path
|
||||
- [ ] Modify `DailyNotificationPlugin.java`:
|
||||
- [ ] Implement `setJsContentFetcher()` (JS bridge)
|
||||
- [ ] Add foreground refresh method
|
||||
- [ ] Add event bus for JS communication
|
||||
- [ ] Create TypeScript bridge utilities
|
||||
|
||||
### PR4: Deduplication
|
||||
- [ ] `android/plugin/src/main/java/com/timesafari/dailynotification/NotificationDeduplicationStore.java`
|
||||
- [ ] Integrate into `DailyNotificationScheduler`
|
||||
- [ ] Add metrics for deduped count
|
||||
|
||||
### PR5: Failure Policy
|
||||
- [ ] Create `FetchErrorType` enum
|
||||
- [ ] Enhance retry logic with SchedulingPolicy
|
||||
- [ ] Add cache fallback mechanism
|
||||
- [ ] Add error classification helpers
|
||||
|
||||
### PR6: Docs & Samples
|
||||
- [ ] `INTEGRATION_GUIDE.md` - When to use native vs JS fetcher
|
||||
- [ ] `SCHEDULING_POLICY.md` - All configuration knobs
|
||||
- [ ] Update examples with real registration code
|
||||
|
||||
### PR7: Feature Flag Legacy
|
||||
- [ ] Add `USE_LEGACY_INTEGRATION` flag
|
||||
- [ ] Guard all TimeSafari code paths
|
||||
- [ ] Update migration guide
|
||||
- [ ] Regression tests
|
||||
|
||||
---
|
||||
|
||||
## Open Questions to Resolve
|
||||
|
||||
### Before PR1
|
||||
1. **Fetcher Registration Pattern**:
|
||||
- Should `setNativeFetcher()` be called from host app's `Application.onCreate()`?
|
||||
- Or should it be a static registry accessible from host app's native code?
|
||||
- **Recommendation**: Static registry in plugin, host app registers in `Application.onCreate()`
|
||||
|
||||
2. **FetchContext Metadata**:
|
||||
- What should plugin populate in `metadata` map?
|
||||
- Current activeDid? App state? Network state?
|
||||
- **Recommendation**: Start minimal (empty map), extend later
|
||||
|
||||
### Before PR2
|
||||
3. **Background Worker Timeout**:
|
||||
- Current: 30 seconds for fetch
|
||||
- Should this be configurable in `SchedulingPolicy`?
|
||||
- **Recommendation**: Add `fetchTimeoutMs` to `SchedulingPolicy` in PR1
|
||||
|
||||
4. **Multiple NotificationContent Handling**:
|
||||
- If native fetcher returns multiple items, should all be scheduled?
|
||||
- Should `maxBatchSize` apply here?
|
||||
- **Recommendation**: Schedule all valid items, `maxBatchSize` limits fetcher input/API calls
|
||||
|
||||
### Before PR3
|
||||
5. **JS Fetcher Bridge Mechanism**:
|
||||
- Which approach: Capacitor bridge callback, event system, or HTTP endpoint?
|
||||
- **Recommendation**: Start with event system (plugin emits `fetch_needed`, JS responds via `setJsContentFetcher` callback)
|
||||
|
||||
6. **Foreground-Only Enforcement**:
|
||||
- How to prevent JS fetcher from being called in background worker?
|
||||
- **Recommendation**: Runtime guard + lint rule (document in PR3)
|
||||
|
||||
---
|
||||
|
||||
## Testing Strategy
|
||||
|
||||
### Contract Tests (After PR2)
|
||||
- Use `tests/fixtures/test-contract.json`
|
||||
- Run native fetcher with fixture context
|
||||
- Compare normalized output to expected output
|
||||
- **Location**: Create `android/plugin/src/test/java/com/timesafari/dailynotification/NativeFetcherContractTest.java`
|
||||
|
||||
### Integration Tests (After PR3)
|
||||
- Test JS fetcher in foreground
|
||||
- Test native fetcher in background worker
|
||||
- Verify both produce identical results for same input
|
||||
|
||||
### Regression Tests (Before PR7)
|
||||
- Ensure legacy TimeSafari path still works behind feature flag
|
||||
- Verify new SPI path works independently
|
||||
- Test migration from legacy to SPI path
|
||||
|
||||
---
|
||||
|
||||
## Next Steps
|
||||
|
||||
1. **Review this context document** - Verify completeness
|
||||
2. **Resolve open questions** - Make decisions before PR1
|
||||
3. **Create PR1 branch** - Start with SPI shell implementation
|
||||
4. **Reference examples** - Use `examples/native-fetcher-android.kt` as pattern
|
||||
5. **Follow 7-PR plan** - Sequential implementation with tests after each PR
|
||||
|
||||
---
|
||||
|
||||
**Status**: Context building complete - ready for PR1 implementation
|
||||
**Last Updated**: 2025-10-29
|
||||
**Maintainer**: Plugin development team
|
||||
|
||||
Reference in New Issue
Block a user