Invites and suggestions are cases; the responsible follow the content
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:
Bendik Aagaard Lynghaug
2026-09-29 21:00:10 +02:00
co-authored by Claude Fable 5.1
parent 7a50ce77b2
commit ef4789f9b2
14 changed files with 1025 additions and 88 deletions
+15
View File
@@ -38,6 +38,11 @@ fn lookup(lang: &str, key: &str) -> Option<&'static str> {
("en", "suggest_edit_help") => "You are listed as responsible for this question. Say what should change, and it goes to the people who keep the site.",
("en", "suggest_edit_send") => "Send the suggestion",
("en", "suggest_edit_sent") => "Thank you - your suggestion is sent.",
("en", "suggestions_yours") => "What you have suggested here",
("en", "suggestion_open") => "Sent",
("en", "suggestion_discussed") => "Being looked at",
("en", "suggestion_done") => "Done",
("en", "suggestion_declined") => "Not done",
("en", "the_start") => "the start",
("no", "also_worth_asking") => "Også verdt å spørre",
@@ -62,6 +67,11 @@ fn lookup(lang: &str, key: &str) -> Option<&'static str> {
("no", "suggest_edit_help") => "Du står oppført som ansvarlig for dette spørsmålet. Skriv hva som bør endres, så går det til dem som har siden.",
("no", "suggest_edit_send") => "Send forslaget",
("no", "suggest_edit_sent") => "Takk - forslaget er sendt.",
("no", "suggestions_yours") => "Det du har foreslått her",
("no", "suggestion_open") => "Sendt",
("no", "suggestion_discussed") => "Blir sett på",
("no", "suggestion_done") => "Gjort",
("no", "suggestion_declined") => "Ikke gjort",
("no", "the_start") => "starten",
_ => return None,
@@ -101,6 +111,11 @@ mod tests {
"suggest_edit_help",
"suggest_edit_send",
"suggest_edit_sent",
"suggestions_yours",
"suggestion_open",
"suggestion_discussed",
"suggestion_done",
"suggestion_declined",
] {
assert!(lookup("en", key).is_some(), "en missing {key}");
assert!(lookup("no", key).is_some(), "no missing {key}");