- Control centre (QUORLA_CONTROL=true on app.quorlasocial.com): public /signup → Stripe Checkout,
verified Stripe webhook (paid, updated, cancelled, payment failed), Admin → Agencies
(approve without Stripe, suspend, resume, billing portal, resend welcome, remove)
- deploy/provision-tenants.sh (cron): one container per agency with its own .env and data,
nginx map for <agency>.quorlasocial.com, upgrades agencies after a rebuild, archives removed data
- New workspaces: first admin only via the emailed one-time setup link (SETUP_TOKEN)
- Meta system user token can be saved in Settings (encrypted) for workspaces that can't edit .env
- docs/multi-tenant.md: DNS, wildcard cert, nginx, sudoers, cron, Stripe setup; tests for the control centre
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- quota.js: per-platform limits (YouTube 10,000 units/day Pacific per project,
Instagram 100 / Threads 250 / TikTok 15 posts per 24 h per account, ...),
usage log, .env overrides (QUOTA_<PLATFORM>)
- Publishing checks the budget first and records usage; when a platform is
out of quota (or answers quota exceeded / 429) the post stays approved and
the queue retries after the reset, without re-posting finished platforms
- Drafts that exceed a day's limit get a warning
- Connections page shows used/limit and when it frees up
- Tests for windows (incl. DST), shared vs per-account limits and the
wait-and-retry queue flow; docs for quotas and the Google app setup
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Connections page: admins set up each platform's developer app (keys stored
encrypted), connect a client's account via OAuth, choose company Page /
business location, check or disconnect
- Adapters per platform with sign-in, identity, targets and publishing;
token refresh with "reconnect needed" when a sign-in expires
- Publishing and Content library: "Post to" lists the client's connected
platforms with their own fields and optional per-platform caption
- Queue validates drafts per platform and publishes through the adapters;
Facebook/Instagram unchanged
- Signed, expiring media links (/m/...) for platforms that fetch media by URL
- Agent: list_connections tool; schedule tools accept all platforms + options
- Offline test suite with simulated platform APIs (15 tests)
- docs/platforms.md: setup, approvals per platform, what is and isn't tested
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- docs/hosting.html: step-by-step setup of app.quorlasocial.com with Docker
- env.js: trim spaces/tabs Docker keeps after "=" (broke the Meta token)
- Dockerfile: chown only writable folders (build step 55s -> 2s)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Dashboard (content library, publishing queue with approvals, inbox, team
management, AI runs), Meta connector, branded PDF reports, agent skills,
and Docker packaging (Dockerfile, docker-compose with Caddy HTTPS,
backup and path-relocation scripts).
Client data, live data and secrets are excluded via .gitignore.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>