huskies: merge 945
This commit is contained in:
@@ -212,8 +212,8 @@ fn legacy_stage_to_clean(s: &str) -> Option<&'static str> {
|
||||
/// vocabulary (`"coding"`, `"merge"`, etc.).
|
||||
///
|
||||
/// Items that were at `"7_frozen"` additionally get the new `frozen` flag set
|
||||
/// — the stage variant `Frozen` was dropped in story 934 stage 4 in favour of
|
||||
/// an orthogonal CRDT register.
|
||||
/// Story 945: the `Frozen` variant returns as `Stage::Frozen { resume_to }`,
|
||||
/// replacing the orthogonal CRDT register that briefly existed in 934 stage 4.
|
||||
///
|
||||
/// One-time startup migration: items that have transitioned at least once
|
||||
/// since story 934 stage 1 (which made writes emit clean form) are no-ops.
|
||||
@@ -222,8 +222,10 @@ pub fn migrate_legacy_stage_strings() {
|
||||
return;
|
||||
};
|
||||
|
||||
// First pass: collect (index, clean_stage, set_frozen) for items that
|
||||
// still carry legacy stage strings.
|
||||
// First pass: collect (index, clean_stage, was_frozen) for items that
|
||||
// still carry legacy stage strings. `was_frozen` triggers writing
|
||||
// `resume_to = "backlog"` so the post-945 typed projection reads back as
|
||||
// `Stage::Frozen { resume_to: Stage::Backlog }`.
|
||||
let migrations: Vec<(usize, &'static str, bool)> = {
|
||||
let Ok(state) = state_mutex.lock() else {
|
||||
return;
|
||||
@@ -239,7 +241,11 @@ pub fn migrate_legacy_stage_strings() {
|
||||
};
|
||||
let clean = legacy_stage_to_clean(¤t)?;
|
||||
let was_frozen = current == "7_frozen";
|
||||
Some((idx, clean, was_frozen))
|
||||
// For legacy frozen items, store the post-945 stage as
|
||||
// "frozen" rather than "backlog" so the typed projection
|
||||
// produces `Stage::Frozen` again.
|
||||
let stage_out = if was_frozen { "frozen" } else { clean };
|
||||
Some((idx, stage_out, was_frozen))
|
||||
})
|
||||
.collect()
|
||||
};
|
||||
@@ -258,12 +264,14 @@ pub fn migrate_legacy_stage_strings() {
|
||||
s.crdt.doc.items[idx].stage.set(clean.to_string())
|
||||
});
|
||||
if was_frozen {
|
||||
apply_and_persist(&mut state, |s| s.crdt.doc.items[idx].frozen.set(true));
|
||||
apply_and_persist(&mut state, |s| {
|
||||
s.crdt.doc.items[idx].resume_to.set("backlog".to_string())
|
||||
});
|
||||
}
|
||||
}
|
||||
slog!(
|
||||
"[crdt] Migrated {count} legacy stage strings to clean wire form \
|
||||
({frozen_count} of which were '7_frozen' → backlog + frozen=true)"
|
||||
({frozen_count} of which were '7_frozen' → frozen + resume_to=backlog)"
|
||||
);
|
||||
}
|
||||
|
||||
@@ -292,7 +300,6 @@ mod stage_migration_tests {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
// Then overwrite the stage register with the raw legacy string,
|
||||
// bypassing `db::normalise_stage_str` / `write_item_str`'s mapping.
|
||||
@@ -353,27 +360,33 @@ mod stage_migration_tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn migrate_collapses_7_frozen_to_backlog_and_sets_frozen_flag() {
|
||||
fn migrate_promotes_7_frozen_to_typed_frozen_variant() {
|
||||
init_for_test();
|
||||
let story_id = "9510_legacy_frozen";
|
||||
seed_with_raw_stage(story_id, "7_frozen");
|
||||
|
||||
// Sanity: before migration, the frozen flag is false.
|
||||
let before = read_item(story_id).expect("seeded item exists");
|
||||
assert!(!before.frozen(), "frozen flag should start false");
|
||||
// Sanity: before migration, the projection's legacy fallback maps
|
||||
// raw `"7_frozen"` → `Stage::Backlog` (frozen state is lost without the
|
||||
// migration's resume_to write).
|
||||
let before = read_item(story_id).expect("legacy 7_frozen should still project");
|
||||
assert!(
|
||||
matches!(before.stage(), crate::pipeline_state::Stage::Backlog),
|
||||
"raw 7_frozen should fall back to Backlog before migration; got {:?}",
|
||||
before.stage()
|
||||
);
|
||||
|
||||
migrate_legacy_stage_strings();
|
||||
|
||||
let after = read_item(story_id).expect("item must still exist after migration");
|
||||
assert!(
|
||||
matches!(after.stage(), crate::pipeline_state::Stage::Backlog),
|
||||
"7_frozen should collapse to Backlog: got {:?}",
|
||||
after.stage()
|
||||
);
|
||||
assert!(
|
||||
after.frozen(),
|
||||
"frozen flag should be set after 7_frozen migration"
|
||||
);
|
||||
match after.stage() {
|
||||
crate::pipeline_state::Stage::Frozen { resume_to } => {
|
||||
assert!(
|
||||
matches!(**resume_to, crate::pipeline_state::Stage::Backlog),
|
||||
"resume_to should default to Backlog for migrated 7_frozen items"
|
||||
);
|
||||
}
|
||||
other => panic!("7_frozen should migrate to Stage::Frozen; got {other:?}"),
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
@@ -390,7 +403,6 @@ mod stage_migration_tests {
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
None,
|
||||
);
|
||||
seed_with_raw_stage("9521_needs_migration", "2_current");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user