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
62 lines
1.4 KiB
TypeScript
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>;
|
|
}
|