feat(docs): P3.4-A/B Documentation polish - JSDoc and troubleshooting

P3.4-A: Enhanced public API JSDoc
- Enhanced createSchedule() with detailed parameter docs and examples
- Enhanced updateSchedule() with examples and error documentation
- Enhanced deleteSchedule() with error documentation
- Enhanced enableSchedule() with examples

P3.4-B: Created troubleshooting guide
- docs/TROUBLESHOOTING.md with common issues and solutions
- Covers CI failures, packaging, platform tests, build, permissions, recovery, performance
- Linked in docs/00-INDEX.md

Verification:
- TypeScript compiles 
- JSDoc generates in .d.ts files 
- Documentation created and linked 
This commit is contained in:
Matthew Raymer
2025-12-23 07:20:58 +00:00
parent 3a0b9b5692
commit bdd2a5d7ac
3 changed files with 211 additions and 6 deletions

View File

@@ -19,6 +19,7 @@ These are **policy-as-code**. Any gate (push, release, publish) MUST call `./ci/
- **Verification / Invariants:** `./scripts/verify.sh` — Encodes packaging, core-purity, and build invariants
- **CI Usage & Setup:** `ci/README.md` — Local CI documentation
- **Performance Characteristics:** `docs/PERFORMANCE.md` — Performance characteristics and benchmarks
- **Troubleshooting Guide:** `docs/TROUBLESHOOTING.md` — Common issues and solutions
---

151
docs/TROUBLESHOOTING.md Normal file
View File

@@ -0,0 +1,151 @@
# Troubleshooting Guide
**Purpose:** Common issues, symptoms, causes, and solutions.
**Owner:** Development Team
**Last Updated:** 2025-12-22
**Status:** active
---
## CI Failures
### Symptom: `./ci/run.sh` fails
**Causes:**
- Forbidden files in package
- Core module imports platform deps
- Export paths don't match artifacts
**Solutions:**
1. Check forbidden files: `npm pack --dry-run | grep -E "xcuserdata|xcuserstate|DerivedData|ios/App/"`
2. Check core purity: `grep -r "@capacitor\|react\|fs\|path\|os" src/core/`
3. Check exports: `node -e "const p=require('./package.json'); console.log(JSON.stringify(p.exports, null, 2))"`
---
## Packaging Failures
### Symptom: `npm pack` includes forbidden files
**Causes:**
- `package.json` `files` field is too permissive
- `.npmignore` is missing or incomplete
**Solutions:**
1. Review `package.json` `files` field (should be whitelist)
2. Add to `.npmignore`: `**/xcuserdata/`, `**/*.xcuserstate`, `**/DerivedData/`, `ios/App/`, `.DS_Store`
3. Run `npm pack --dry-run` to verify
---
## Platform Test Failures
### Symptom: Android tests fail in CI
**Causes:**
- Robolectric SDK version mismatch
- Missing test dependencies
- Test database setup issues
**Solutions:**
1. Check `@Config(sdk = [34])` matches Robolectric version
2. Verify `android/build.gradle` has test dependencies
3. Check `TestDBFactory` creates in-memory database correctly
### Symptom: iOS tests not running in CI
**Causes:**
- macOS runner not available
- xcodebuild not found
- Test app not configured
**Solutions:**
1. Use scheduled/manual workflows for iOS tests
2. Verify `xcodebuild` is available: `xcodebuild -version`
3. Check test app configuration in `test-apps/ios-test-app/`
---
## Build Failures
### Symptom: TypeScript compilation fails
**Causes:**
- Type errors in source code
- Missing type definitions
- Incorrect import paths
**Solutions:**
1. Run `npx tsc --noEmit` to see all type errors
2. Check import paths match `package.json` exports
3. Verify all dependencies are installed: `npm install`
### Symptom: Build succeeds but runtime errors occur
**Causes:**
- Missing runtime dependencies
- Incorrect module resolution
- Platform-specific code not available
**Solutions:**
1. Check `dist/` directory contains expected files
2. Verify `package.json` exports match build artifacts
3. Test on actual platform (not just build)
---
## Permission Issues
### Symptom: Notifications not appearing
**Causes:**
- Permission not granted
- Battery optimization killing background tasks
- Platform-specific permission issues
**Solutions:**
1. Check permission status: `await DailyNotification.checkPermission()`
2. Request permission: `await DailyNotification.requestPermission()`
3. Check battery optimization settings (Android)
4. Verify Info.plist/AndroidManifest.xml permissions
---
## Recovery Issues
### Symptom: Missed notifications after app restart
**Causes:**
- Recovery not running on app launch
- Database corruption
- Platform-specific recovery limitations
**Solutions:**
1. Check recovery logs in history: `await DailyNotification.getHistory({ kind: 'recovery' })`
2. Verify recovery is called on app launch
3. Check database integrity
4. Review platform-specific recovery constraints
---
## Performance Issues
### Symptom: Slow database queries
**Causes:**
- Large number of schedules
- Missing database indexes
- Database corruption
**Solutions:**
1. Check query performance in logs (warnings if > 100ms)
2. Review database schema for missing indexes
3. Consider database cleanup/migration
---
**See also:**
- [SYSTEM_INVARIANTS.md](./SYSTEM_INVARIANTS.md) — Enforced system invariants
- [PERFORMANCE.md](./PERFORMANCE.md) — Performance characteristics
- [docs/progress/03-TEST-RUNS.md](./progress/03-TEST-RUNS.md) — Test run history

View File

@@ -610,13 +610,33 @@ export interface DailyNotificationPlugin {
* Create a new recurring schedule
*
* @param schedule Schedule configuration
* @param schedule.id - Unique schedule identifier (required, must be unique)
* @param schedule.kind - Schedule type: 'notify' for notifications, 'fetch' for content fetching
* @param schedule.cron - Cron expression (e.g., '0 9 * * *' for daily at 9 AM). Mutually exclusive with clockTime
* @param schedule.clockTime - Time of day in HH:mm format (e.g., '09:00'). Mutually exclusive with cron
* @param schedule.enabled - Whether schedule is active (default: true)
* @param schedule.jitterMs - Random jitter in milliseconds (default: 0)
* @param schedule.backoffPolicy - Backoff policy for retries (default: 'exp')
* @returns Promise resolving to created Schedule object
* @throws {DailyNotificationError} If schedule creation fails (e.g., invalid cron, duplicate ID, permission denied)
*
* @example
* ```typescript
* const schedule = await DailyNotification.createSchedule({
* id: 'morning-notification',
* kind: 'notify',
* cron: '0 9 * * *', // Daily at 9 AM
* clockTime: '09:00',
* enabled: true
* });
* ```
*
* @example
* ```typescript
* // Using cron expression
* const schedule = await DailyNotification.createSchedule({
* id: 'daily-fetch',
* kind: 'fetch',
* cron: '0 */6 * * *', // Every 6 hours
* enabled: true
* });
* ```
@@ -626,26 +646,59 @@ export interface DailyNotificationPlugin {
/**
* Update an existing schedule
*
* @param id Schedule ID
* @param updates Partial schedule updates
* @param id Schedule ID (required)
* @param updates Partial schedule updates. Only provided fields will be updated.
* @returns Promise resolving to updated Schedule object
* @throws {DailyNotificationError} If schedule not found, invalid updates, or permission denied
*
* @example
* ```typescript
* // Update schedule time
* const updated = await DailyNotification.updateSchedule('morning-notification', {
* clockTime: '10:00'
* });
* ```
*
* @example
* ```typescript
* // Disable a schedule
* await DailyNotification.updateSchedule('morning-notification', {
* enabled: false
* });
* ```
*/
updateSchedule(id: string, updates: Partial<Schedule>): Promise<Schedule>;
/**
* Delete a schedule
*
* @param id Schedule ID
* @param id Schedule ID (required)
* @returns Promise resolving when deletion completes
* @throws {DailyNotificationError} If schedule not found or deletion fails
*
* @example
* ```typescript
* await DailyNotification.deleteSchedule('morning-notification');
* ```
*/
deleteSchedule(id: string): Promise<void>;
/**
* Enable or disable a schedule
*
* @param id Schedule ID
* @param enabled Enable state
* @param id Schedule ID (required)
* @param enabled Enable state (true to enable, false to disable)
* @returns Promise resolving when update completes
* @throws {DailyNotificationError} If schedule not found or update fails
*
* @example
* ```typescript
* // Enable a schedule
* await DailyNotification.enableSchedule('morning-notification', true);
*
* // Disable a schedule
* await DailyNotification.enableSchedule('morning-notification', false);
* ```
*/
enableSchedule(id: string, enabled: boolean): Promise<void>;