chore: merge main into notifications branch

Resolve conflicts in app/auth.py and app/api/admin_users.py:

- auth.py: combine admin-aware profile creation (from main, adding
  is_complimentary/highest-tier defaults for admins) with signup
  notification/webhook (from our branch). Admin users skip the
  signup notification since they are the ones being notified.

- admin_users.py: combine is_complimentary assignment (from main)
  with tier_changed/new_tier tracking variables (from our branch)
  to fire plan-change notifications when an admin updates a user.
This commit is contained in:
copilot-swe-agent[bot]
2026-03-07 20:52:44 +00:00
28 changed files with 1267 additions and 108 deletions
+12 -2
View File
@@ -19,14 +19,14 @@ This guide covers how to configure Stripe billing and local user sign-up in Docu
By default, user accounts are created by an administrator. To allow users to self-register with an email address and password, set `ALLOW_LOCAL_SIGNUP=true`.
> **Note:** SMTP must be configured before enabling local sign-up. New accounts require email verification before they can log in.
> **Note:** SMTP is **optional** for local sign-up. When SMTP is configured, new accounts require email verification before they can log in. Without SMTP, accounts are activated immediately upon registration — useful for self-hosted deployments without email infrastructure.
### Configuration
```bash
ALLOW_LOCAL_SIGNUP=true
# SMTP (required for verification emails)
# SMTP (optional — enables email verification and password reset)
EMAIL_HOST=smtp.example.com
EMAIL_PORT=587
EMAIL_USERNAME=noreply@example.com
@@ -37,11 +37,21 @@ EMAIL_SENDER=DocuElevate <noreply@example.com>
### Sign-up Flow
**With SMTP configured (recommended):**
1. User visits `/signup` and fills out the registration form.
2. DocuElevate sends a verification email with a 24-hour token link.
3. User clicks the link — their account is activated and they are signed in.
4. First-time users are redirected to the onboarding wizard.
**Without SMTP:**
1. User visits `/signup` and fills out the registration form.
2. Account is activated immediately — no email verification required.
3. User is redirected to the login page to sign in straight away.
### Admin-Created Accounts
Administrators can create local user accounts directly from the **Admin → User Management** page without requiring self-registration. Admin-created accounts are immediately active regardless of SMTP configuration.
### Password Reset Flow
1. User clicks "Forgot password?" on the login page.
+41 -1
View File
@@ -2,6 +2,8 @@
DocuElevate uses database-backed subscription plans that are fully configurable by admins via the **Plan Designer** at `/admin/plans`. Four default tiers are seeded automatically on first startup.
All plans are priced **per user, per month** (or per year with ~20 % discount). There are no team, business, or enterprise tiers — every plan is a single-user subscription.
## Default Plans
| Plan | Monthly | Yearly | Docs/Month | Lifetime Docs | OCR Pages/Mo | Max File | Mailboxes | Destinations |
@@ -9,12 +11,21 @@ DocuElevate uses database-backed subscription plans that are fully configurable
| **Free** | $0 | $0 | — | 50 total | 150 total | 5 MB | 0 | 1 |
| **Starter** | $2.99 | $28.99 | 50 | — | 300 | 25 MB | 1 | 2 |
| **Professional** | $5.99 | $57.99 | 150 | — | 750 | 100 MB | 3 | 5 |
| **Business** | $7.99 | $76.99 | 300 | — | 1,500 | Unlimited | Unlimited | 10 |
| **Power** | $7.99 | $76.99 | 300 | — | 1,500 | Unlimited | Unlimited | 10 |
> Prices ex-VAT. German customers add 19% MwSt.
All paid plans include a **30-day free trial**.
### Intended Use Cases
- **Free** — Try DocuElevate with no commitment. Good for one-off experiments or evaluating the service.
- **Starter** — Freelancers and side-project owners sending ~50 invoices, contracts, or scanned receipts a month.
- **Professional** — Knowledge workers (consultants, paralegals, accountants) handling ~150 multi-page documents a month across several cloud destinations.
- **Power** — Power users with heavy daily workloads: real estate agents, bookkeepers, or researchers processing ~10 documents a day (≈ 300/month) with no file-size restrictions.
> The **plan_id** in the database remains `"business"` for the Power tier to preserve backwards compatibility. The display name shown to users is "Power".
## How Plans Are Stored
Plans are stored in the `subscription_plans` database table. On application startup, `seed_default_plans()` is called automatically — if the table is empty, the four built-in defaults are inserted. If plans already exist, the seed is a no-op.
@@ -55,6 +66,35 @@ When a user's `subscription_billing_cycle` is set to `yearly`:
Setting `UserProfile.allow_overage = True` bypasses monthly quota checks entirely for that user. Usage is still tracked so future billing integrations can charge retroactively. This field is not yet exposed in the admin UI.
## is_complimentary Flag (Complimentary Plans)
Setting `UserProfile.is_complimentary = True` marks a user as being on a **complimentary (uncharged) plan**. The user retains all quota benefits of their assigned subscription tier but is **never billed via Stripe**. This is useful for:
- **Admin accounts** — automatically set on every admin user profile at login time.
- **Gifted access** — granting full plan benefits to partners, testers, or sponsored users.
### Admin Auto-Provisioning
When an admin user logs in for the first time (via OAuth, local account, or the built-in admin credentials), DocuElevate automatically:
1. Creates a `UserProfile` row if one does not already exist.
2. Assigns the **highest available subscription tier** (currently `business`).
3. Sets `is_complimentary = True` so the account is never billed.
4. Sets `onboarding_completed = True` so admins skip the first-time setup wizard.
On subsequent logins for existing admin profiles:
- `is_complimentary` is ensured to be `True`.
- If the profile was still on the `free` tier it is upgraded to the highest tier.
- All other admin-managed settings (custom limits, notes, etc.) are preserved.
### Managing via Admin UI
The **User Management** page (`/admin/users`) shows a green gift icon (🎁) next to the plan badge for any user with `is_complimentary = True`. The toggle is available in the user edit modal under **Billing**.
### API Field
`is_complimentary` is exposed in the `PUT /api/admin/users/{user_id}` body and in all user detail responses.
## Plan Designer
Navigate to `/admin/plans` (admin only) to: