HoneyNotify - implementation plan
Repository status
The production release covers the control plane, versioned API, strict payload validation, priority queue contract, acknowledged worker delivery, atomic retry promotion, recipient claim locking, retries/DLQ, dashboard workflow, team invitations and role management, iOS and Android SDK clients, usage metering, owner TOTP MFA, cancellable privacy workflows, legal documents, encrypted backups, restore verification, Stripe integration and scale-out configuration described below. The current production worker processes are co-located on the cPanel host under Supervisor with separate Redis and database identities; moving them to a dedicated Ubuntu push-01 remains an infrastructure scaling step. Live APNs, FCM and Stripe acceptance tests require operator-owned provider credentials. Cloudflare onboarding requires access to that vendor account; see DEPLOYMENT.md and OPERATIONS.md.
Phase 0 - foundations
- Choose product name/domain.
- Create Git repositories or a monorepo for webapp, worker, SDKs and docs.
- Provision
push-01with Ubuntu 24.04. - Create WireGuard tunnel between WHM and push-01.
- Put web/API behind Cloudflare; keep database and Redis private.
- Establish dev, staging and production environment variables and secrets.
Phase 1 - control plane on WHM
Build the customer-facing SaaS application in PHP 8.3. The control plane owns identity and persistent business data:
- organisations and team users
- apps/projects
- API keys and scopes
- encrypted Apple/Firebase credentials
- devices/subscribers
- tags
- notifications/campaigns
- delivery reports
- usage totals
Initial UI pages:
- login / forgotten password / owner TOTP MFA
- dashboard
- Apps
- App -> Setup -> iOS
- App -> Setup -> Android
- App -> API keys
- App -> Audience / Devices
- App -> Notifications -> New
- App -> Notifications -> History / report
- Organisation -> Team
- Organisation -> Billing
Do not allow provider private keys to be redisplayed after upload. Allow replacement/revocation instead.
Phase 2 - public developer API
Implement versioned JSON endpoints under /v1:
POST /v1/devices/registerDELETE /v1/devices/{id}POST /v1/notificationsGET /v1/notifications/{id}POST /v1/events- users and tags are represented through external user IDs and device tags; reusable segments, templates and outbound webhooks remain post-v1 extensions
Requirements:
- bearer API-key authentication
- API keys stored hashed, never plain text
- per-key scopes
- per-organisation rate limits
- request IDs
- JSON error format
- input size limits
- audit logging for dashboard actions
- idempotency key on notification creation before public release
Phase 3 - queue contract
The web server must not send APNs/FCM requests itself. It creates a notification row and publishes an expand_notification job.
Job contract:
{"type":"expand_notification","notification_id":123}
The worker resolves the target and splits it into fixed-size batches. Each batch becomes:
{"type":"deliver_batch","notification_id":123,"batch_id":456,"device_ids":[1,2,3]}
Use separate priority queues:
push-transactionalpush-highpush-normalpush-bulk
Never let a huge marketing blast share all capacity with transactional sends.
Phase 4 - worker node
push-01 owns transient processing infrastructure:
- Redis
- worker processes
- APNs HTTP/2 sender
- FCM HTTP v1 sender
- scheduler, retry promotion and privacy/retention processes
- logs and monitoring agents
Worker rules:
- a job contains IDs, not provider secrets
- retrieve secrets from the database only when required
- decrypt only in worker memory
- hard timeout all provider calls
- disable tokens APNs/FCM report as permanently invalid
- retry only transient failures
- use exponential backoff plus jitter
- cap retries
- never retry obvious permanent 4xx failures
Phase 5 - dashboard MVP
Build the customer workflow:
- Sign up.
- Create organisation.
- Create application.
- Configure iOS/Android credentials.
- Generate API key.
- Follow SDK/API setup instructions.
- Device appears in Audience.
- Send test notification.
- Create broadcast.
- View accepted/failed counts.
This workflow is the real MVP milestone.
Phase 6 - SDKs
Start with thin SDKs rather than recreating every OneSignal feature.
iOS
- request notification permission
- obtain APNs device token
- call
/v1/devices/register - update token when APNs rotates it
- identify/log out external user
- submit opened/clicked events
Android
- obtain FCM registration token
- call
/v1/devices/register - handle token refresh
- identify/log out external user
- submit opened/clicked events
Do not embed a server/REST API secret in apps. Issue a separate public app identifier/client key with limited device-registration permissions before shipping SDKs publicly.
Phase 7 - reliability hardening before paying customers
The queue, retry, idempotency, request-rate, audit and production recovery foundations are included:
- reliable queue acknowledgement using Redis Streams
- dead-letter queue
- retry queue/backoff
- idempotency for sends
- graceful shutdown/draining
- locking so the same notification cannot be expanded twice
- queue age metrics
- rate limiting per customer/app
- abuse/spam controls
- audit logs
- MFA for account owners
- encrypted backups and isolated-database restore testing
- credential rotation
- GDPR retention/deletion processes
- Terms / Acceptable Use / Privacy / DPA
Phase 8 - billing
Record usage independently from Stripe:
- monthly active subscribed devices
- attempted notifications
- accepted provider sends
- API requests if billable
Create a usage_daily aggregate table rather than calculating monthly bills by scanning every delivery row.
Stripe handles plan/subscription/payment state; your own database remains authoritative for measured usage.
Phase 9 - scale-out
When push-01 becomes constrained:
- Add
push-02with the same worker code and.env. - Point it at the same private DB and Redis service.
- Start worker services.
- It immediately shares queue load.
Next separation should be Redis/message broker from workers:
queue-01: Redis/message brokerpush-01: worker nodepush-02: worker node
Later add DB replication/dedicated DB and ClickHouse/event pipeline when analytics volume justifies it.
Suggested v1 release gates
Alpha
- one app
- one iOS and Android test device
- send by device and external user
- provider failures recorded
Private beta
- multi-tenant organisations/apps
- bulk/all targeting
- scheduled notification
- dashboard delivery counts
- API rate limiting
- monitoring/backups
Paid v1
- reliable queue / retries / DLQ
- Stripe
- usage metering
- team access
- security/audit controls
- SDK docs
- GDPR tooling
- status page and operational runbook