# State graphs for event-sourced buckets - see portal's # src/aggregates/mod.rs. Bucket names are redoal_-prefixed because # both portal instances (uhhm.no and redoal.com) share one NATS # JetStream; a bare "subscribers" would collide with uhhm's. # # redoal_gestures (index.yaml's record_as for drawn paths) has no # entry on purpose: plain KV, no lifecycle - a drawn gesture is a # fact, not a process. aggregates: - bucket: redoal_subscribers initial: open states: open: { event: subscribed } unsubscribed: { event: unsubscribed } transitions: open: [unsubscribed] # Double opt-in: a watcher is pending until the address confirms from # the mail n8n sends (redoal: confirm watching); only open watchers # are told when something lands at their shape. - bucket: redoal_watchers initial: pending states: pending: { event: requested } open: { event: confirmed } unsubscribed: { event: unsubscribed } transitions: pending: [open, unsubscribed] open: [unsubscribed] # Reports on recordings. The relay watches this bucket: a record # moved to "removed" deletes the recording from its store, the varde # pin, and discovery. "kept" closes the report with the recording in # place. Decisions are human, never automatic. - bucket: redoal_reports initial: open states: open: { event: reported } removed: { event: removed } kept: { event: kept } transitions: open: [removed, kept] # TestFlight beta signups (index.yaml's "Test it on your iPhone"). # Attended by automation, not a human desk: a new "requested" signup # is handed to the App Store Connect API to invite the Apple ID to the # closed beta; "withdrawn" (the /joined-testers self-transition) drops # them from the invite list. - bucket: redoal_testers attended_by: > n8n TestFlight onboarding workflow — ops/n8n/testflight-onboarding in redoal/redoal. Consumes NATS events.redoal_testers.* and calls App Store Connect POST /v1/betaTesters. initial: open states: open: { event: requested } withdrawn: { event: withdrawn } transitions: open: [withdrawn]