package main import ( "context" "encoding/json" "fmt" "atlas9.dev/c/core" "atlas9.dev/c/core/outbox" "atlas9.dev/c/core/tokens" ) type TenantInvitationEvent struct { TenantID core.ID Email string } const TenantInvitationEventType = "tenant.member.invited" type InvitationData struct { TenantID core.ID Email string } func EmitTenantInvitation(ctx context.Context, emitter outbox.Emitter, tenantID core.ID, email string) error { payload, err := json.Marshal(TenantInvitationEvent{ TenantID: tenantID, Email: email, }) if err != nil { return fmt.Errorf("marshaling invitation event: %w", err) } return emitter.Emit(ctx, TenantInvitationEventType, tenantID.String(), payload, nil) } func SendTenantInvitationEmail(ctx context.Context, baseURL string, invitationTokens tokens.Store[InvitationData], mailer Mailer, event outbox.Event) error { var dat TenantInvitationEvent err := json.Unmarshal(event.Payload, &dat) if err != nil { return err } tok, err := invitationTokens.Put(ctx, dat.Email, InvitationData{ TenantID: dat.TenantID, Email: dat.Email, }) if err != nil { return fmt.Errorf("creating invitation token: %w", err) } acceptURL := baseURL + "/accept-invitation?token=" + tok.Key err = mailer.Send(ctx, dat.Email, "You've been invited", "You've been invited to join a team. Click here to accept: "+acceptURL) if err != nil { return err } return nil }