ab9e4147a7833c95478a1a375fae1828579d0a36
Plesk Agency Management Portal (MVP)
Next.js + Tailwind + Supabase + Stripe multi-tenant SaaS starter for agencies managing one or more Plesk instances.
Included MVP Features
- Supabase Postgres schema + RLS (
supabase/schema.sql) - Supabase Auth (magic-link login)
- Agency tenancy context (
agency_membersbased) - Dashboard with:
- Plesk instance connect + validation
- Plesk sync (subscriptions + domains)
- Subscription suspend / unsuspend actions
- Stripe checkout + billing portal launch
- Stripe webhook endpoint to sync billing state
1) Setup
- Install dependencies:
npm install
- Create local env:
cp .env.example .env.local
-
Fill
.env.localwith your Supabase + Stripe values. -
In Supabase SQL Editor, run:
-- contents of supabase/schema.sql
- In Supabase Auth settings, set site URL and redirect URL(s), e.g.:
http://localhost:3000http://localhost:3000/dashboard
- Run dev server:
npm run dev
2) Seed Minimum Data
After first login user is created in auth.users, then add membership rows (via SQL) so tenant context resolves:
insert into agencies (name) values ('My Agency') returning id;
-- replace values
insert into agency_members (agency_id, user_id, role)
values ('<agency_uuid>', '<auth_user_uuid>', 'owner');
3) API Endpoints
POST /api/plesk/instances— create + validate Plesk connectionPOST /api/plesk/instances/:id/sync— pull/sync subscriptions + domains from one Plesk instancePOST /api/plesk/instances/:id/autosync— update auto-sync enabled/frequency for one Plesk instancePOST /api/jobs/plesk-sync-all— background sync job for all connected instances (requiresX-JOB-SECRET)POST /api/cron/autosync— scheduled auto-sync tick (requiresX-CRON-SECRET)POST /api/plesk/subscriptions/:id/action— suspend or unsuspendPOST /api/stripe/checkout— create Stripe Checkout sessionPOST /api/stripe/portal— create Stripe Customer Portal sessionPOST /api/stripe/webhook— Stripe webhook receiver
4) Important Notes
- Set a strong
ENCRYPTION_KEY; it encrypts stored Plesk auth secrets. - Set a strong
PLESK_CRED_ENC_KEY(32-byte base64 or 64-char hex) for Plesk credential encryption. - Set
JOB_SECRETfor internal cron-triggered job auth. - Set
CRON_SECRETfor/api/cron/autosyncauth. /api/stripe/webhookis excluded from auth middleware for Stripe signature verification.- Current implementation is intentionally MVP-focused; add stronger validation, retries, idempotency keys, and richer error observability for production.
5) Automatic Plesk Auto-Sync (CL3.5)
Background auto-sync endpoint:
curl -sS -X POST http://localhost:3000/api/jobs/plesk-sync-all \
-H "X-JOB-SECRET: <JOB_SECRET>"
Recommended cron (every 5 minutes):
*/5 * * * * curl -sS -X POST http://localhost:3000/api/jobs/plesk-sync-all -H "X-JOB-SECRET: ${JOB_SECRET}"
Notes:
- Job uses DB lock (
job_locks) to avoid overlapping runs. - Job processes at most 10 connected instances per run.
- Instances synced in the last 3 minutes are skipped.
6) Auto Sync Worker (CL6)
New scheduler fields live on plesk_instances:
auto_sync_enabledauto_sync_frequency_minuteslast_auto_sync_atnext_auto_sync_atauto_sync_lock_untilauto_sync_lock_token
Endpoint for periodic worker ticks:
curl -sS -X POST http://localhost:3000/api/cron/autosync \
-H "X-CRON-SECRET: <CRON_SECRET>"
Recommended system cron (every 5 minutes):
*/5 * * * * curl -sS -X POST https://<your-host>/api/cron/autosync -H "X-CRON-SECRET: ${CRON_SECRET}"
Or schedule the same call from Jenkins.
Worker safety behavior:
- processes at most 5 instances per tick
- concurrency limited to 2 at a time
- per-instance lock lease 15 minutes
- per-instance timeout guard 14 minutes
- per-instance failures are isolated and logged to
actions_log
Description
Languages
TypeScript
86.9%
PLpgSQL
11.2%
Shell
1.1%
Dockerfile
0.6%
JavaScript
0.1%