ceres_core/lib.rs
1//! Ceres Core - Domain types, business logic, and services.
2//!
3//! This crate provides the core functionality for Ceres, including:
4//!
5//! - **Domain models**: [`Dataset`], [`SearchResult`], [`Portal`], etc.
6//! - **Business logic**: Delta detection, statistics tracking
7//! - **Services**: [`HarvestService`] for portal synchronization, [`SearchService`] for semantic search, [`ExportService`] for streaming exports
8//! - **Traits**: [`EmbeddingProvider`], [`DatasetStore`], [`PortalClient`] for dependency injection
9//! - **Progress reporting**: [`ProgressReporter`] trait for decoupled logging/UI
10//!
11//! # Architecture
12//!
13//! This crate is designed to be reusable by different frontends (CLI, server, etc.).
14//! Business logic is decoupled from I/O concerns through traits:
15//!
16//! # Server Development Notes (ceres-server)
17//!
18//! TODO(server): Use utoipa for automatic OpenAPI documentation
19//! When creating ceres-server, use the `utoipa` crate (compatible with Axum/Actix)
20//! to auto-generate OpenAPI specs from Rust types and handlers via derive macros.
21//! Expose `/swagger-ui` endpoint for interactive API documentation.
22//! This makes the API immediately usable by frontend developers without reading code.
23//!
24//! - [`EmbeddingProvider`] - abstracts embedding generation (e.g., Gemini API)
25//! - [`DatasetStore`] - abstracts database operations (e.g., PostgreSQL)
26//! - [`PortalClient`] - abstracts portal access (e.g., CKAN API)
27//!
28//! # Example
29//!
30//! ```ignore
31//! use ceres_core::{HarvestService, SearchService};
32//! use ceres_core::progress::TracingReporter;
33//!
34//! // Create services with your implementations
35//! let harvest = HarvestService::new(store, embedding, portal_factory);
36//! let reporter = TracingReporter;
37//! let stats = harvest.sync_portal_with_progress("https://data.gov/api/3", &reporter).await?;
38//!
39//! // Semantic search
40//! let search = SearchService::new(store, embedding);
41//! let results = search.search("climate data", 10).await?;
42//! ```
43
44pub mod circuit_breaker;
45pub mod config;
46pub mod error;
47pub mod export;
48pub mod harvest;
49pub mod job;
50pub mod job_queue;
51pub mod models;
52pub mod progress;
53pub mod search;
54pub mod sync;
55pub mod traits;
56pub mod worker;
57
58// Circuit breaker
59pub use circuit_breaker::{
60 CircuitBreaker, CircuitBreakerConfig, CircuitBreakerError, CircuitBreakerStats, CircuitState,
61};
62
63// Configuration
64pub use config::{
65 DbConfig, HttpConfig, PortalEntry, PortalsConfig, SyncConfig, default_config_path,
66 load_portals_config,
67};
68
69// Error handling
70pub use error::AppError;
71
72// Domain models
73pub use models::{DatabaseStats, Dataset, NewDataset, Portal, SearchResult};
74
75// Sync types and business logic
76pub use sync::{
77 AtomicSyncStats, BatchHarvestSummary, PortalHarvestResult, ReprocessingDecision, SyncOutcome,
78 SyncResult, SyncStats, SyncStatus, needs_reprocessing,
79};
80
81// Progress reporting
82pub use progress::{HarvestEvent, ProgressReporter, SilentReporter, TracingReporter};
83
84// Traits for dependency injection
85pub use traits::{DatasetStore, EmbeddingProvider, PortalClient, PortalClientFactory};
86
87// Services (generic over trait implementations)
88pub use export::{ExportFormat, ExportService};
89pub use harvest::HarvestService;
90pub use search::SearchService;
91
92// Job queue types
93pub use job::{CreateJobRequest, HarvestJob, JobStatus, RetryConfig, WorkerConfig};
94pub use job_queue::JobQueue;
95
96// Worker service
97pub use worker::{
98 SilentWorkerReporter, TracingWorkerReporter, WorkerEvent, WorkerReporter, WorkerService,
99};