This document describes the technical implementation of platform admin functionality, including access controls, scope-aware operations, billing/reconciliation tooling, and operational safeguards.
Scope
This document focuses on platform admin implementation in:
- Views, forms, and templates used by superusers.
- Account provisioning and account-management operations.
- Promotion and billing actions exposed through platform admin.
- Security, rate limiting, and auditability requirements.
Entry Points and Structure
Primary implementation files:
checktick_app/core/views_platform_admin.pychecktick_app/core/urls.pychecktick_app/core/templates/core/platform_admin/*.html
Primary navigation surfaces include:
- Dashboard
- Organisations
- Statistics
- Logs
- Pricing
- Billing
- Promotions
Access Control Model
Platform admin endpoints are superuser-only and protected by explicit controls:
superuser_requireddecorator for route protection.require_http_methodsfor endpoint method constraints.django-ratelimiton sensitive actions.- CSRF protection for state-changing form posts.
Design intent: administrative workflows are explicit, auditable, and fail-closed when authorization fails.
Data access boundary: Platform Admins are deliberately excluded from survey response data. They cannot view, download, or export survey data, and can_export_survey_data returns False for platform admin status alone. Platform Admin capabilities are limited to account/billing/promotions operations and platform-level log review. A Platform Admin may only access survey data if they independently hold an in-survey role (survey owner, organisation owner/admin, or active data custodian). This boundary is enforced by the permission helpers in checktick_app/surveys/permissions.py and locked down by automated tests in checktick_app/surveys/tests/test_data_governance_views.py.
Encryption at rest: Survey responses are encrypted at submission time using a per-survey X25519 keypair (hybrid encryption: random per-response 32-byte DEK, AES-256-GCM payload, DEK wrapped via ephemeral X25519 ECDH + HKDF-SHA256). Only the survey's public key is stored server-side in plaintext form; the private key is stored wrapped and is only unwrapped into the owner's session via owner unlock (password / recovery phrase / OIDC auto-unlock / organisation key). The server can encrypt responses but cryptographically cannot decrypt them, so platform admins (and anyone with database access) cannot read response content โ including demographics, which are encrypted inside the same response payload โ without recovering the survey private key. Recovery flows (see Recovery Dashboard) use the same Vault escrow mechanisms and audit trails to recover the survey private key; recovering it grants the ability to decrypt all responses encrypted with the survey's public key, and is restricted to organisation owners and platform admins via the recovery dashboard's dual-authorization workflow.
Account and Billing Operations
Platform admin supports operational workflows across account types and tiers:
- Organization administration and status management.
- Pricing override management for supported tiers.
- Billing timeline/reconciliation views.
- Controlled refund actions linked to payment records.
- Manual tier upgrades with configurable renewal dates (see below).
Manual Tier Upgrades
Platform admins can create or update a tier-scoped account (Pro, Team, Organisation, Enterprise) via the organization_create view when create_target == 'account'. The form includes:
- Tier dropdown: overrides the
scopequery param, allowing any tier. - Renewal date: preset buttons (1 year, 2 years, 5 years) or a custom date picker. Sanity cap: max 5 years, must be in the future.
- Tier-specific rules: Free ignores expiry; Pro/Team require a renewal date; Organisation/Enterprise default to no expiry but allow optional renewal.
The view sets subscription_current_period_end on the profile so the existing process_expired_subscriptions cron auto-downgrades the account when the date passes. Pre-expiry warning tracking fields (last_expiry_warning_sent_at, last_expiry_warning_stage) are reset on each save so warnings restart for the new expiry date.
Manually upgraded accounts (no payment_subscription_id) receive a 7-day grace period before downgrade, matching the GoCardless past-due grace period. GoCardless subscriptions are downgraded immediately (the provider has already notified the user).
Manual tier changes are logged via AuditLog (recording the admin actor, target user, old/new tier, and valid_until date). A notification email is sent to the user via send_manual_upgrade_email when upgraded to a paid tier. The expiry date is shown on the profile page and in the subscription portal.
Downgrading to free via the form closes excess surveys immediately (via force_downgrade_tier). Upgrading re-opens surveys auto-closed by a previous downgrade (via reopen_surveys_on_upgrade).
The tier selected determines which survey layouts the user can access (see tier_limits.py allowed_layouts). Free tier: linear only. All paid tiers: all 7 layouts (section menu, RCT, guided, staged, matrix, Delphi).
See docs/billing-and-subscriptions.md ยง Manual Tier Upgrades and Expiry for the user-facing behaviour.
Refund action constraints (hosted reference flow):
- Full refund automation only.
- Mandatory reason code.
- Required free-text explanation for
otherreason. - Idempotent handling for repeated operator attempts.
Promotions Operations
Platform admin promotions implementation supports:
- Promotion creation and edit workflows.
- Activate/deactivate/toggle operations.
- Duplicate/revoke workflows for reuse and controlled shutdown.
- Post-start immutability of billing-impacting terms.
- Lifecycle processing and reconciliation alignment.
Audit and Observability
Administrative actions and lifecycle outcomes are auditable using structured metadata.
Coverage includes:
- Promotion lifecycle events.
- Refund request and webhook-reconciled state transitions.
- Operator attribution and references required for finance/audit traceability.
- Manual tier changes (actor, target user, old/new tier, valid_until date).
See also: Audit Logging and Notifications.
Security and Abuse Controls
Relevant protections include:
- Role-constrained admin actions.
- Endpoint rate limiting on refund/billing operations.
- Strict webhook signature verification and required webhook secret.
- Defensive validation on refund amount/policy paths.
See also: Security Overview.
Testing Strategy (Platform Admin Slice)
Primary coverage areas:
- Permissions and authorization boundaries.
- Method restrictions and malformed request handling.
- Promotion operation regressions.
- Billing/refund policy enforcement and idempotency.
- Webhook-reconciled billing state transitions.
Representative suites:
tests/test_platform_admin_permissions.pytests/test_platform_admin_regressions.pytests/test_platform_admin_tier_validity.pytests/test_manual_upgrade_lifecycle.pytests/test_billing.pytests/test_layout_gating.pytests/test_organisation_checkout.py
Self-Hosted Considerations
For SELF_HOSTED=true environments:
- Billing is disabled by default.
- Platform admin billing/refund flows depend on optional external provider integration.
- Operators must configure webhook signing and provider-specific credentials before enabling billing actions.