feat(channel): add auto-schedule feature to channels with background scheduler

This commit is contained in:
2026-03-13 02:27:27 +01:00
parent dfd8f52a53
commit 1fc473342d
14 changed files with 161 additions and 6 deletions

View File

@@ -13,6 +13,7 @@ pub(super) struct ChannelRow {
pub timezone: String,
pub schedule_config: String,
pub recycle_policy: String,
pub auto_schedule: i64,
pub created_at: String,
pub updated_at: String,
}
@@ -51,6 +52,7 @@ impl TryFrom<ChannelRow> for Channel {
timezone: row.timezone,
schedule_config,
recycle_policy,
auto_schedule: row.auto_schedule != 0,
created_at: parse_dt(&row.created_at)?,
updated_at: parse_dt(&row.updated_at)?,
})
@@ -58,4 +60,4 @@ impl TryFrom<ChannelRow> for Channel {
}
pub(super) const SELECT_COLS: &str =
"id, owner_id, name, description, timezone, schedule_config, recycle_policy, created_at, updated_at";
"id, owner_id, name, description, timezone, schedule_config, recycle_policy, auto_schedule, created_at, updated_at";

View File

@@ -61,14 +61,15 @@ impl ChannelRepository for PostgresChannelRepository {
sqlx::query(
r#"
INSERT INTO channels
(id, owner_id, name, description, timezone, schedule_config, recycle_policy, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9)
(id, owner_id, name, description, timezone, schedule_config, recycle_policy, auto_schedule, created_at, updated_at)
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)
ON CONFLICT(id) DO UPDATE SET
name = EXCLUDED.name,
description = EXCLUDED.description,
timezone = EXCLUDED.timezone,
schedule_config = EXCLUDED.schedule_config,
recycle_policy = EXCLUDED.recycle_policy,
auto_schedule = EXCLUDED.auto_schedule,
updated_at = EXCLUDED.updated_at
"#,
)
@@ -79,6 +80,7 @@ impl ChannelRepository for PostgresChannelRepository {
.bind(&channel.timezone)
.bind(&schedule_config)
.bind(&recycle_policy)
.bind(channel.auto_schedule as i64)
.bind(channel.created_at.to_rfc3339())
.bind(channel.updated_at.to_rfc3339())
.execute(&self.pool)
@@ -88,6 +90,18 @@ impl ChannelRepository for PostgresChannelRepository {
Ok(())
}
async fn find_auto_schedule_enabled(&self) -> DomainResult<Vec<Channel>> {
let sql = format!(
"SELECT {SELECT_COLS} FROM channels WHERE auto_schedule = 1 ORDER BY created_at ASC"
);
let rows: Vec<ChannelRow> = sqlx::query_as(&sql)
.fetch_all(&self.pool)
.await
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
rows.into_iter().map(Channel::try_from).collect()
}
async fn delete(&self, id: ChannelId) -> DomainResult<()> {
sqlx::query("DELETE FROM channels WHERE id = $1")
.bind(id.to_string())

View File

@@ -61,14 +61,15 @@ impl ChannelRepository for SqliteChannelRepository {
sqlx::query(
r#"
INSERT INTO channels
(id, owner_id, name, description, timezone, schedule_config, recycle_policy, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
(id, owner_id, name, description, timezone, schedule_config, recycle_policy, auto_schedule, created_at, updated_at)
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
ON CONFLICT(id) DO UPDATE SET
name = excluded.name,
description = excluded.description,
timezone = excluded.timezone,
schedule_config = excluded.schedule_config,
recycle_policy = excluded.recycle_policy,
auto_schedule = excluded.auto_schedule,
updated_at = excluded.updated_at
"#,
)
@@ -79,6 +80,7 @@ impl ChannelRepository for SqliteChannelRepository {
.bind(&channel.timezone)
.bind(&schedule_config)
.bind(&recycle_policy)
.bind(channel.auto_schedule as i64)
.bind(channel.created_at.to_rfc3339())
.bind(channel.updated_at.to_rfc3339())
.execute(&self.pool)
@@ -88,6 +90,18 @@ impl ChannelRepository for SqliteChannelRepository {
Ok(())
}
async fn find_auto_schedule_enabled(&self) -> DomainResult<Vec<Channel>> {
let sql = format!(
"SELECT {SELECT_COLS} FROM channels WHERE auto_schedule = 1 ORDER BY created_at ASC"
);
let rows: Vec<ChannelRow> = sqlx::query_as(&sql)
.fetch_all(&self.pool)
.await
.map_err(|e| DomainError::RepositoryError(e.to_string()))?;
rows.into_iter().map(Channel::try_from).collect()
}
async fn delete(&self, id: ChannelId) -> DomainResult<()> {
sqlx::query("DELETE FROM channels WHERE id = ?")
.bind(id.to_string())