Browse Source
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.master
1 changed files with 597 additions and 0 deletions
@ -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 |
|||
|
|||
Loading…
Reference in new issue