huskies: merge 671_refactor_migrate_pipeline_state_consumers_from_string_comparisons_to_typed_pipelinestage_enum

This commit is contained in:
dave
2026-04-27 16:35:25 +00:00
parent 39a9766d7d
commit 4a0f57478c
15 changed files with 161 additions and 103 deletions
+37 -6
View File
@@ -12,17 +12,15 @@
//! event bus are fully defined and tested here. Consumers will be migrated to
//! the typed API incrementally in follow-up stories.
// Foundation module — all items are exercised by tests but not yet called from
// non-test code. The dead_code lint is suppressed until consumer migration.
#![allow(unused_imports, dead_code)]
// Some items are exercised by tests or used only in non-active code paths;
// the dead_code lint is suppressed for the module.
#![allow(dead_code)]
use chrono::{DateTime, Utc};
use serde::{Deserialize, Serialize};
use std::fmt;
use std::num::NonZeroU32;
use crate::crdt_state::PipelineItemView;
// ── Newtypes ────────────────────────────────────────────────────────────────
#[derive(Debug, Clone, PartialEq, Eq, Hash, Serialize, Deserialize)]
@@ -134,6 +132,35 @@ impl Stage {
}
)
}
/// Parse a stage from its filesystem directory name.
///
/// This is the single canonical conversion boundary for turning a loose
/// stage-directory string (from CRDT fields or watcher events) into a
/// typed `Stage`. Rich variants (`Done`, `Archived`, `Merge`) are
/// synthesised with zero-value fields — callers should use this only for
/// stage *classification* (e.g. `is_active()`, `matches!`), not for
/// accessing the rich metadata fields.
pub fn from_dir(s: &str) -> Option<Self> {
match s {
"1_backlog" => Some(Stage::Backlog),
"2_current" => Some(Stage::Coding),
"3_qa" => Some(Stage::Qa),
"4_merge" => Some(Stage::Merge {
feature_branch: BranchName(String::new()),
commits_ahead: NonZeroU32::new(1).expect("1 is non-zero"),
}),
"5_done" => Some(Stage::Done {
merged_at: DateTime::<Utc>::UNIX_EPOCH,
merge_commit: GitSha(String::new()),
}),
"6_archived" => Some(Stage::Archived {
archived_at: DateTime::<Utc>::UNIX_EPOCH,
reason: ArchiveReason::Completed,
}),
_ => None,
}
}
}
// ── Per-node execution state ────────────────────────────────────────────────
@@ -464,8 +491,12 @@ mod events;
mod projection;
mod subscribers;
#[allow(unused_imports)]
pub use events::{EventBus, TransitionFired, TransitionSubscriber};
pub use projection::{ProjectionError, project_stage, read_all_typed, read_typed};
#[allow(unused_imports)]
pub use projection::{ProjectionError, project_stage};
pub use projection::{read_all_typed, read_typed};
#[allow(unused_imports)]
pub use subscribers::{
AutoAssignSubscriber, FileRendererSubscriber, MatrixBotSubscriber, PipelineItemsSubscriber,
WebUiBroadcastSubscriber,
+1
View File
@@ -2,6 +2,7 @@
use super::Stage;
use super::events::{TransitionFired, TransitionSubscriber};
#[allow(unused_imports)]
use super::{event_label, stage_dir_name, stage_label};
// ── Subscriber stubs (real dispatch uses these as the interface) ─────────────