Adds a new "procedural" tree type for linear step-by-step project workflows (domain controller setup, M365 onboarding, VPN config, etc). Includes intake form builder, two-panel step navigation, variable resolution, procedural exports, 3 seed templates, and UI rename from "Trees" to "Flows". Also archives 19 implemented plan docs and creates deferred features backlog. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2.7 KiB
2.7 KiB
Resend Invite Codes — Design
Date: 2026-02-12
Summary
Add a "Resend" capability to both invite systems (platform invite codes and account invites). Resending revokes the old code and generates a fresh one, then emails it to the recipient.
Backend
Platform Invite Codes
New endpoint: POST /api/v1/invites/{code}/resend (admin-only)
- Look up existing invite by code
- Reject if already used (409 Conflict)
- Delete the old invite
- Create a new invite with the same properties (email, plan, trial_days, note, expiration recalculated from now)
- Send email via
EmailService.send_invite_email() - Log audit event
- Return the new invite
Account Invites
New endpoint: POST /api/v1/accounts/me/invites/{invite_id}/resend (owner-only)
- Look up existing invite by ID
- Reject if already used (409 Conflict)
- Delete the old invite
- Create a new invite with the same email, role, and fresh expiration
- Send email via new
EmailService.send_account_invite_email() - Log audit event
- Return the new invite
New Email Method: send_account_invite_email()
Added to EmailService in backend/app/core/email.py.
- Parameters:
to_email,code,account_name,role,signup_url - Subject: "You've been invited to join [Account Name] on ResolutionFlow"
- Body: Same dark monochrome HTML template as platform invites, with:
- "You've been invited to join [Account Name] as an Engineer/Viewer"
- Prominent invite code display (same style)
- No plan/trial section
- "Create Your Account" CTA button
- Returns
bool— best-effort, never raises
Frontend
Platform Invite Codes (InviteCodesPage.tsx)
- Resend button in actions column (next to copy/delete)
- Only visible for unused, non-expired codes with an email address
- Calls
POST /api/v1/invites/{code}/resend - Shows success toast with new code, refreshes list
- Loading state on button during API call
Account Invites (AccountSettingsPage.tsx)
- Resend button next to each pending invite
- Only visible for unused, non-expired invites
- Calls
POST /api/v1/accounts/me/invites/{invite_id}/resend - Shows success toast, refreshes list
- Loading state on button during API call
Files to Modify
backend/app/core/email.py— addsend_account_invite_email()+ HTML templatebackend/app/api/endpoints/invite.py— add resend endpoint for platform codesbackend/app/api/endpoints/accounts.py— add resend endpoint for account invitesfrontend/src/pages/admin/InviteCodesPage.tsx— add resend buttonfrontend/src/pages/AccountSettingsPage.tsx— add resend buttonfrontend/src/api/admin.ts— add resend API callfrontend/src/api/accounts.ts— add resend API call