Skip to content

Add premium subscriptions and casual server orchestration#62

Draft
NicholasBottone wants to merge 5 commits into
mainfrom
polar-subscriptions
Draft

Add premium subscriptions and casual server orchestration#62
NicholasBottone wants to merge 5 commits into
mainfrom
polar-subscriptions

Conversation

@NicholasBottone
Copy link
Copy Markdown
Member

@NicholasBottone NicholasBottone commented May 28, 2026

Summary

Adds premium subscriptions for casual server hosting, with Polar as the billing provider and SecondWebsite as the entitlement/usage authority. Ranked server flows remain free and separate.

Subscriptions and casual servers

  • Adds the new subscriptions Django app.
  • Adds Polar checkout/customer portal support and signed Polar webhook handling.
  • Adds website pages for viewing the current plan, remaining casual server minutes, recent sessions, and launching/stopping casual servers.
  • Adds orchestrator integration so SecondWebsite authorizes casual launches, creates a website session, calls the orchestrator, and records lifecycle callbacks/usage.

API endpoints added

  • GET /api/subscriptions/me/entitlement/
  • GET /api/subscriptions/casual-games/
  • GET /api/subscriptions/users/{discord_user_id}/entitlement/
  • POST /api/subscriptions/server-sessions/start/
  • POST /api/subscriptions/server-sessions/{session_id}/stop/
  • POST /api/subscriptions/server-sessions/{session_id}/orchestrator-event/
  • POST /subscriptions/polar/webhook/

DB tables/models added

  • SubscriptionPlan: configurable tiers, pricing, server-minute limits, max session length, concurrency, Polar product mapping.
  • SubscriptionEntitlement: provider-neutral active subscription/comp entitlement records.
  • ServerSession: casual server reservation/lifecycle state, orchestrator session details, connection info, callbacks, failures.
  • UsageLedgerEntry: billing-period usage ledger, rounded to 5-minute increments.
  • WebhookEvent: idempotency/audit record for Polar and orchestrator events.

Inter-service contracts

  • Discord bot -> SecondWebsite:

    • Casual server launches must go through SecondWebsite.
    • Uses the existing shared API_KEY via X-API-KEY.
    • Sends owner_discord_id; SecondWebsite handles entitlement, remaining minutes, max session length, and concurrency.
    • Ranked flows are unchanged and do not consult subscriptions.
  • SecondWebsite -> orchestrator:

    • Uses ORCHESTRATOR_API_BASE_URL and ORCHESTRATOR_API_TOKEN.
    • Fetches casual game metadata, launches casual sessions, and requests stops.
    • The orchestrator owns actual server lifecycle; SecondWebsite owns authorization and usage accounting.
  • Orchestrator -> SecondWebsite:

    • Sends all casual lifecycle callbacks to orchestrator-event/ with X-API-KEY.
    • Supported events include launch_accepted, ready, heartbeat, stopping, stopped, launch_failed, exited, and killed.
    • Callback event_id is used for idempotency.

Migration baseline repair

  • Removes migrations/ from .gitignore.
  • Adds baseline migrations for existing first-party apps.
  • Production deployment needs this one-time command:
    • .venv/bin/python manage.py migrate --fake-initial
  • After the baseline is established, future deploys should use normal committed migrations:
    • .venv/bin/python manage.py migrate

CI

  • Updates GitHub Actions to check for missing migrations.
  • Verifies a fresh DB can run migrations.
  • Runs Django checks and pytest before deploy.

Validation

  • manage.py makemigrations --check --dry-run
  • manage.py migrate --plan
  • manage.py check
  • pytest

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant