[Unreleased]
Added
- Add a fail-fast Python production builder that creates a clean, upload-ready cPanel ZIP with compiled assets, production Composer dependencies, cron runners, and a SHA-256 checksum.
- Add GitHub Actions CI for dependency audits, frontend builds, PHP formatting, static analysis, Blade compilation, and isolated PHPUnit tests.
- Add a durable dispatch-attempt ledger with atomic claims, stable Discord nonces, lease recovery, and database-backed delivery jobs.
- Add daily chunked retention for Discord logs and completed dispatch attempts.
- Add full-administrator controls to copy and replace encrypted Discord tokens from a user's configuration page.
- Add an isolated graphite-violet design system for the landing, marketplace, product detail, about, changelog, privacy, terms, and refund pages.
- Add complete English and Indonesian public-page copy with persistent language and theme controls.
- Render
/changelogsafely from this canonical Markdown file. - Add regression tests for administrator boundaries, subscription and marketplace completion, Pakasir webhook verification, Discord autopost safety, token encryption, and partial configuration updates.
- Add PHPUnit configuration with an in-memory SQLite database for isolated tests.
- Add a safe
.env.examplefor the application, MySQL, email, Pakasir, and Discord configuration.
Changed
- Move Discord delivery and user webhook notifications out of cron into dedicated persistent queue workers.
- Derive Discord identity and Nitro capability from server-side Discord validation instead of browser metadata.
- Use subscription service data as the single source for public pricing and account limits.
- Centralize marketplace and subscription completion so webhook and status-check flows enforce the same rules.
- Include Composer, PDO SQLite, and DOM/XML extensions in the Docker image for development and testing.
- Update Laravel dependencies and align Symfony components with the PHP 8.2 runtime.
Fixed
- Restore detailed Discord delivery notifications with message previews, timing data, next schedules, and clickable links that use the destination guild, channel, and message IDs.
- Prevent duplicate delivery claims, recover expired sending leases with the same nonce, retry transient network failures, and reject config mutation while delivery is active.
- Validate partial random-delay ranges and run token, channel, message, and plan preflight checks before starting a configuration.
- Make the dashboard sidebar collapse to 64 pixels with matching content alignment, while keeping the mobile drawer fully expanded and labeled.
- Prevent repeated subscription completion with a database transaction, row locks, and an idempotent status check.
- Reuse an existing live subscription invoice when checkout is submitted repeatedly, preventing distinct duplicate orders from extending the same account multiple times.
- Prevent duplicate or incomplete marketplace allocation when callbacks run concurrently.
- Send marketplace notifications only after the database transaction is committed.
- Make Discord autopost
--dry-runavoid message delivery and database mutations. - Resume Discord configurations after their rate-limit backoff expires.
- Clear stale
invalid_tokenerrors after successful token revalidation and leave affected configurations safely stopped until the user restarts them. - Correct partial Discord configuration updates,
use_random_delaydefaults, and missing HTTP client imports. - Make the project linter fail when syntax, PHPStan, or Pint checks fail or are unavailable.
Security
- Keep token secrets out of initial page data, return them only for an explicit non-cacheable copy request, and deny copy or replacement access to staff accounts.
- Prevent staff accounts from modifying or deleting administrator accounts.
- Verify Pakasir payment status server-to-server before completing subscriptions, balance top-ups, or marketplace transactions; query-string webhook tokens are no longer trusted.
- Encrypt Discord credentials at rest with Laravel's encrypted cast and exclude them from serialization.
- Use a separate HMAC fingerprint for duplicate credential detection without comparing plaintext or randomized ciphertext.
- Add a migration that encrypts existing Discord credentials and expands the token column to
TEXT.
Operational Notes
- Production now requires
QUEUE_CONNECTION=database(or Redis), one scheduler process, and a persistent worker consumingdiscord,notifications,default. - Shared cPanel deployments without Supervisor can run
cron-runner.phpandqueue-runner.phponce per minute as separate scheduler and bounded-worker processes. - Do not rotate or lose
APP_KEYwithout a credential re-encryption procedure. Stored Discord credentials depend on this key for decryption.