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
+5 -1
View File
@@ -108,8 +108,12 @@ async fn main() -> anyhow::Result<()> {
// windows (see announce.rs).
tokio::spawn(portal::announce::run(state.clone()));
tokio::spawn(portal::deadlines::run(state.clone()));
// The first person in, when SEED_ADMIN_EMAIL names one (seed.rs).
// The accounts the content mandates: the first person in, and
// everyone a page names as responsible, at start and whenever the
// content changes (seed.rs).
tokio::spawn(portal::seed::run(state.clone()));
// Invites whose link ran out, or whose person is in (people.rs).
tokio::spawn(portal::people::run(state.clone()));
// Replies to case mail, matched to their record by whatever reads
// the mailbox (uhhm/gdo over JMAP) and turned into notes here. A