pulse/interfaces/storage.interface.ts
Edo Limburg 78a2b27f6d feat: implement orchestrator module with feed source management
Add FeedOrchestrator that coordinates fetch→parse→dedup→store pipeline:
- FeedSource type for managing RSS/Atom feed configurations
- Feed source CRUD operations in IStorage interface
- Database schema migration for feed_sources table
- Exponential backoff retry with configurable delays
- Per-feed poll intervals with health tracking
- Concurrency-limited parallel feed processing
- ProcessResult and FeedHealth interfaces for status monitoring

Files added:
- orchestrator/orchestrator.ts - main orchestrator class
- orchestrator/scheduler.ts - backoff calculation utilities
- orchestrator/index.ts - module exports
- orchestrator/orchestrator.test.ts - comprehensive test suite

Files modified:
- interfaces/feed.types.ts - add FeedSource type
- interfaces/storage.interface.ts - extend with feed source methods
- infrastructure/db/database.ts - add FeedSourceTable interface
- infrastructure/db/schema.ts - add feed_sources table migration
- modules/storage/storage.ts - implement feed source CRUD
- modules/storage/storage.test.ts - add feed source tests
2026-05-05 22:17:16 +02:00

62 lines
1.4 KiB
TypeScript

import type { FeedItem, FeedSource } from './feed.types.js';
export interface StorageError {
code: 'DB_ERROR' | 'CONSTRAINT_ERROR' | 'UNKNOWN';
message: string;
}
export interface IStorage {
/**
* Persist items to storage. Should handle duplicates gracefully (upsert).
*/
save(items: FeedItem[]): Promise<void>;
/**
* Get most recent items across all sources.
*/
getRecent(limit: number): Promise<FeedItem[]>;
/**
* Get recent items from a specific source feed.
*/
getBySource(source: string, limit: number): Promise<FeedItem[]>;
/**
* Search items by title/content keywords.
*/
search(query: string): Promise<FeedItem[]>;
/**
* Get all feed sources, optionally filtering by active status.
*/
getFeedSources(activeOnly?: boolean): Promise<FeedSource[]>;
/**
* Get a single feed source by ID.
*/
getFeedSourceById(id: string): Promise<FeedSource | null>;
/**
* Save or update a feed source (upsert).
*/
saveFeedSource(source: FeedSource): Promise<void>;
/**
* Update feed source status fields (last fetched, success, failures, active).
*/
updateFeedSourceStatus(
id: string,
updates: {
lastFetchedAt?: Date;
lastSuccessAt?: Date;
consecutiveFailures?: number;
isActive?: boolean;
}
): Promise<void>;
/**
* Delete a feed source by ID.
*/
deleteFeedSource(id: string): Promise<void>;
}