4 Commits
Author SHA1 Message Date
Bendik Aagaard LynghaugandClaude Fable 5 d161677155 Release 0.3.16
Test / test (push) Successful in 25s
Publish release / publish (push) Successful in 1m33s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y42TyF8Zu7NGRR2893vNcZ
2026-08-30 23:13:33 +02:00
Bendik Aagaard LynghaugandClaude Fable 5 8229dbf4c2 Announce sweeper: refresh open records from content
A date or place corrected after first announce never reached the
portal_events record, so the followup fired on the stale schedule.
While a record is still in its initial state, content is the source
of truth: differing responses are written back on each sweep.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y42TyF8Zu7NGRR2893vNcZ
2026-08-30 23:13:29 +02:00
Bendik Aagaard LynghaugandClaude Fable 5 3de069f41d Release 0.3.15
Test / test (push) Successful in 24s
Publish release / publish (push) Successful in 1m33s
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y42TyF8Zu7NGRR2893vNcZ
2026-08-30 23:09:11 +02:00
Bendik Aagaard LynghaugandClaude Fable 5 ab3a649646 Hidden fields: carrier value without a label row
A type: hidden requirement rendered through the fallback branch, whose
label wrapper shows the field name — so a preset key listed as a second
visible field under the email. Bare hidden input, no row.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Y42TyF8Zu7NGRR2893vNcZ
2026-08-30 23:08:59 +02:00
4 changed files with 28 additions and 2 deletions
Generated
+1 -1
View File
@@ -2948,7 +2948,7 @@ dependencies = [
[[package]]
name = "portal"
version = "0.3.14"
version = "0.3.16"
dependencies = [
"anyhow",
"arc-swap",
+1 -1
View File
@@ -1,6 +1,6 @@
[package]
name = "portal"
version = "0.3.14"
version = "0.3.16"
edition = "2021"
[lib]
+12
View File
@@ -92,6 +92,18 @@ pub async fn sweep(state: &AppState) -> anyhow::Result<()> {
Some(a) => a,
};
// Content is the source of truth while the window is still
// open: a corrected date or place flows into the record, so the
// followup fires on the schedule the page actually announces.
if answer.state == schema.initial && answer.responses != responses {
let mut refreshed = answer.clone();
refreshed.responses = responses.clone();
if let Some(store) = &store {
store.put(&id, serde_json::to_vec(&refreshed)?.into()).await?;
tracing::info!(question = %q.id, "event record refreshed from content");
}
}
if answer.state == schema.initial && now_ms >= ends {
let target = "awaiting_summary";
let payload = serde_json::json!({ "to": target, "item": id, "by": "portal" });
+14
View File
@@ -1244,6 +1244,20 @@ fn AlternativeCard(
.into_any();
}
if req.kind == "hidden" {
// A carrier value only — no label row, or a
// preset key reads as a second visible field.
return view! {
<input
id=field_id
type="hidden"
prop:value=move || sig.get()
on:input=move |ev| sig.set(event_target_value(&ev))
/>
}
.into_any();
}
view! {
<label class="field" for=label_for>
{label_text}