Invites and suggestions are cases; the responsible follow the content
Test / test (pull_request) Successful in 56s
Test / test (pull_request) Successful in 56s
Five things the first cut of accounts-from-content left open. The first person and the responsible people are set up side by side, and both try again a minute apart: a seed that waited twenty minutes on Kanidm used to hold everyone else up, and a responsible person who failed waited for the next restart. The responsible are gone over again whenever the content changes. watch_for_reload publishes portal.content.reloaded once new content is in place, and seed.rs listens. Being responsible ends when the content stops saying so: someone no page names any more leaves RESPONSIBLE_GROUP in the same pass, if portal is who put them there (Invited.already_member). The account stays. An invite keeps itself current. portal_invites has an expired state; signing in closes a person's invites, a sweep moves the ones whose link ran out, and a desk's move from expired back to open makes a fresh link and mails it. Invites made at start are on file with the desks'. A suggested edit is a case in the built-in portal_edit_suggestions bucket, the person who made it is mailed at each move, and the card lists what they sent and where it stands. Found on the way, against Kanidm 1.11.2: a link's end comes as seconds since the epoch, which portal did not read, so invite mails said "until" and nothing; and a mail search answered with a 5xx was taken for a refusal. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GT37Z1Xtfd9pUuQtMTg6Yt
This commit is contained in:
co-authored by
Claude Fable 5.1
parent
7a50ce77b2
commit
ef4789f9b2
@@ -171,6 +171,13 @@ pub async fn load_questions_from_gitea(
|
||||
#[cfg(feature = "ssr")]
|
||||
pub const CONTENT_RELOAD_SUBJECT: &str = "portal.content.reload";
|
||||
|
||||
/// Published by `watch_for_reload` once new content is in place, for
|
||||
/// whatever acts on what the content says rather than serving it: the
|
||||
/// accounts it mandates (`seed.rs`). No payload; the content is read
|
||||
/// from where it always is.
|
||||
#[cfg(feature = "ssr")]
|
||||
pub const CONTENT_RELOADED_SUBJECT: &str = "portal.content.reloaded";
|
||||
|
||||
/// Runs for the life of the process: re-fetches `repo_url`/`branch` and
|
||||
/// atomically swaps both `questions` and `aggregates` on every
|
||||
/// `CONTENT_RELOAD_SUBJECT` message - the two only ever swap together,
|
||||
@@ -233,6 +240,7 @@ pub async fn watch_for_reload(
|
||||
aggregates.store(std::sync::Arc::new(loaded_aggregates));
|
||||
site.store(std::sync::Arc::new(loaded_site));
|
||||
tracing::info!(count, "reloaded content");
|
||||
let _ = nats.publish(CONTENT_RELOADED_SUBJECT, "".into()).await;
|
||||
}
|
||||
Err(e) => {
|
||||
tracing::error!(error = %e, "content reload failed, keeping last-good content");
|
||||
|
||||
Reference in New Issue
Block a user