Architecture
How the software works
A paced, system-level explanation — the mental model first, then the parts, the request lifecycle, and how it ships.
The simplest mental model
Hold this picture in your head
``
Visitor → register/verify/login
↓
Generator form (band, song, lyrics, style, portraits, aspect)
↓
arcana_queue (pending)
↓
Cron worker claims row (processing)
↓
Gemini text → Song DNA JSON → cinematic prompt (+ style/portraits)
↓
Gemini image → WebP + thumb → local uploads/dble + B2
↓
arcana_renders insert → consume image credit → queue completed
↓
Gallery / notifications / optional email share
``
The nouns that matter
- Queue job — a pending generation request (
arcana_queue) - Song DNA — structured analysis JSON from Gemini text
- Render — finished image metadata + URLs (
arcana_renders) - Credits — counters on
usersthat pay for successful renders - Plan — feature flags derived from
users.plan_type - Style — reusable prompt fragment (
arcana_styles) or dynamic StyleMap
The rule that explains cost control
Credits are checked before enqueue and consumed after a successful render insert. Failed generations should not silently bill — though races between concurrent submits remain a risk.
Components
Browser-facing PHP pages
- Public:
index.php(+ variants), legal/FAQ/feedback - Auth: register/login/logout/verify/password reset/account
- App: dashboard, image generator, gallery, pricing, subscription, notifications
- Admin:
arcana.admin/*
Shared includes / libraries
auth_lib.php/auth_check.php— sessions, schema helpers, credits, maintenancearcana.helpers.php— render/job helpers, B2 URL helpersarcana.plan_tiers.php— plan normalizationincludes/b2_helpers.php— Backblaze APIstripe_lib.php— Stripe SDK integration (mysqli)config/load_env.php,config/smtp.php,config/backblaze.php
Background workers
Multiple arcana.queue.processor*.php scripts. Best-evidence current: arcana.queue.processor.cron.parallel.v3.dynamicstyle.php.
External providers
Gemini, Stripe, SMTP, Turnstile, B2.
Request flow
Typical authenticated page
- Include
auth_check.php→ maintenance check → require login - Load user via
auth_user() - Render HTML or handle POST with CSRF
Generation submit
- POST
action=generatetoarcana.image.generator.php - Validate plan/credits/inputs
- INSERT
arcana_queue - JSON response; client polls status
Worker (out of HTTP request)
- Cron executes processor script
- Lock pending rows
- Gemini calls + storage + DB updates
Payments
- Pricing POST → Stripe Checkout redirect
- Stripe webhook POST → credit/subscription updates
- Optional success page retrieval of session
Deployment
Assumed production shape
- Document root serves this repository (or a sync of it)
- PHP 8.2 + MySQL/MariaDB
- Cron invokes one
arcana.queue.processor.cron*.phpperiodically .envpresent but not web-readable (.htaccess)- Composer
vendor/installed for Stripe/PHPMailer
VibeKB static guide (GitHub Pages)
GitHub Pages is configured to publish from the /docs folder on main.
Regenerate after model changes:
``bash
php tools/validate.php
php tools/generate-static.php
``
Entry point: docs/index.html. The snapshot does not update itself. No PHP is required to read the published guide.
Uncertain
Exact Hostinger paths, cron command, and which Stripe endpoint URL is registered are not fully specified in-repo (path.php exists to help discover paths).