Same move as the watches, and the config's last piece of integration state goes with it: - `rhema-calendar-integration` owns the calendar table now (`store.rs`): SQLite in the shared dispatch database, the pattern the claw's watch table established. `CalendarWatch` gains the `validate` the config's boot check used to run — per-kind URL and credential rules, plus the lead-under-horizon check — so an invalid calendar is loud at the one door every writer shares. - `CalendarSource::from_store` reads the table fresh on every detect pass (the forge source's pattern): a calendar added over the route is live next tick, a removed one stops polling, no restart in the story. The static constructor stays for tests. - `POST/DELETE/GET /v1/calendars` on the daemon: the POST body is the integration's `CalendarWatch` shape, validated at the table; DELETE takes `?name=`; the api listing names the door. - `ClawConfig.calendars` is gone. A config still carrying it is refused at parse time, like the retired `watches:` seed. The config-side validation and its tests moved with the type. The config file now carries only what boot needs: credentials, the surface, paths, the poll cadence. Everything the daemon reconfigures at runtime lives in its tables, behind its HTTP doors.
45 lines
1.8 KiB
TOML
45 lines
1.8 KiB
TOML
[package]
|
|
name = "rhema-calendar-integration"
|
|
description = "The calendar integration: ICS/webcal feeds, CalDAV collections, and the Google Calendar API normalized into one occurrence vocabulary for reminder-style dispatch"
|
|
version.workspace = true
|
|
edition.workspace = true
|
|
rust-version.workspace = true
|
|
license.workspace = true
|
|
repository.workspace = true
|
|
authors.workspace = true
|
|
# The resident tier is still indev: `cargo publish --workspace` skips
|
|
# it until the claw ships.
|
|
publish = false
|
|
|
|
[dependencies]
|
|
rusqlite = { version = "0.40", features = ["bundled"] }
|
|
# The reminder source: one `Source` over the feeds, detect-pass shaped
|
|
# like the task scheduler's
|
|
rhema-autonomous-agent = { path = "../../crates/rhema-autonomous-agent", version = "0.1.0" }
|
|
# The reminder source ingests its slots into a `Dispatcher`; the event
|
|
# and key-function shapes are the dispatcher's
|
|
rhema-rsd = { path = "../../crates/rhema-rsd", version = "0.1.0" }
|
|
serde = { workspace = true }
|
|
serde_json = { workspace = true }
|
|
thiserror = { workspace = true }
|
|
async-trait = { workspace = true }
|
|
# HTTP against the three feed kinds: one bounded request per poll, no
|
|
# streaming
|
|
reqwest = { version = "0.12", features = ["json"] }
|
|
# The CalDAV adapter reads 207 multistatus bodies; the element set it
|
|
# cares about is small enough that a pull parser beats a DOM
|
|
quick-xml = "0.41"
|
|
# Every wire time (RFC 3339, iCalendar's compact `YYYYMMDDTHHMMSS[Z]`,
|
|
# `VALUE=DATE` all-days) normalizes to an OffsetDateTime, and the
|
|
# vocabulary's instants round-trip as RFC 3339.
|
|
time = { version = "0.3", default-features = false, features = [
|
|
"parsing",
|
|
"formatting",
|
|
"serde-well-known",
|
|
] }
|
|
|
|
[dev-dependencies]
|
|
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "sync", "time"] }
|
|
# In-process HTTP mocks for offline tests
|
|
wiremock = "0.6"
|