Commit Graph

2 Commits

Author SHA1 Message Date
Matthew Meszaros bc435747ea feat: expand admin management queries
Add richer backend models, handlers, services, and repository queries for admin campaigns, discounts, outreach, organizations, limit requests, and provisioning surfaces.
2026-06-02 15:54:29 +02:00
Matt e6753f7c24 feat(limits): limit-increase request workflow (backend)
Wire the customer self-serve path for asking "please give me more
mailboxes / campaigns / contacts." Migration 000046 adds
limit_increase_requests with a partial unique index ensuring only one
pending request per (org, field) so the queue can't be spammed, plus
a CHECK requiring requested > current_effective so no-op rows never
reach an admin.

Service layer:
  - SubmitLimitIncreaseRequest validates membership, rejects unknown
    fields, snapshots the user's current effective limit at submission
    time so the queue row carries the context the admin needs.
  - CancelLimitRequest lets the original submitter walk back a pending
    request; approved/rejected rows are immutable as the audit record.
  - ApproveLimitRequest stamps the row and writes the corresponding
    column on organization_limit_overrides via SetLimitOverrides —
    same write path direct admin overrides use, so granted_by and
    notes carry through and the audit log treats both flows uniformly.
  - RejectLimitRequest stamps the row with required review notes.

Routes:
  POST   /v1/organization/:orgId/limit-requests
  GET    /v1/organization/:orgId/limit-requests
  DELETE /v1/limit-requests/:id                 (submitter only)
  GET    /admin/limit-requests?status=pending
  POST   /admin/limit-requests/:id/approve
  POST   /admin/limit-requests/:id/reject

Admin approval and rejection both fire admin audit log entries with
field + requested + notes so the decision history survives any future
reorg of the request table.

UI (admin queue page + dashboard request form) plus the ToS clause
giving Warmbly the right to refuse any increase land in the next commit.
2026-05-28 12:05:32 +02:00