Why WordPress remains
Decision
Use a dedicated WordPress installation for editorial content, presentation and an independently packaged HSLG API-host plugin. Keep the WordPress presenter and the API as different plugins. The mobile runtime never imports WordPress PHP or the presenter.
Benefits
- Virtualmin already hosts PHP, MariaDB, HTTPS and site-level permissions; using that infrastructure avoids provisioning a separate always-on service for the MVP.
- WordPress provides administrative editing and content REST endpoints for events, terms and editorial pages.
wp_mail()respects active WordPress mail-transport plugins, reducing custom SMTP configuration.- WordPress page APIs retain edit history when revisions are enabled; HSLG documentation can use them rather than overwrite database rows directly.
Cost and risks
- Plugins and themes must be patched; a vulnerable WordPress install can expose the host site.
- WordPress requests are not a substitute for transaction workers, durable queue processing or low-latency native device APIs.
- WordPress user IDs and post IDs must never become permanent HSLG customer/order identities.
- HSLG API and presentation packages require separate lifecycle checks, backups and rollback.
Alternative rejected for MVP
Running a second custom API host immediately adds operations, monitoring, TLS, release scripts and backup responsibilities. A migration is viable once the app is working; the domain repository ports deliberately isolate that later change.
The actual deployment role of WordPress
WordPress is the already-operated PHP application on the media.hslg.uk Virtualmin virtual server. It provides editorial administration, HTTPS routing, plugin lifecycle hooks, a MariaDB connection and familiar content management. HSLG uses that installation as a host for three independently released plugin roles: the visual presenter, the HSLG REST API and the documentation publisher. The presence of a shared host is not permission to merge these responsibilities or to read and modify other hosted sites.
The presenter owns demonstration routes, iframe/phone presentation layout, and its own plugin assets. The API owns namespaced REST endpoints, HSLG database schema installation and its PHP service adapters. The documentation publisher owns a versioned collection of WordPress pages under /app/ and /devlog/. The mobile APK is built from the shared application packages; it is not the WordPress presenter and does not embed WordPress PHP.
Why separate plugins are worth the administration overhead
A presentation update can be staged by uploading a single ZIP and visually verifying it without migrating customer tables. A documentation release can add and revise WordPress pages without changing registration, password handling, business logic or menu prices. API updates can be tested against database migrations and endpoint authorization without affecting the visual presenter package. The cost is three independently versioned installables, each with its own rollback and compatibility notes. That cost is significantly smaller than untangling an accidental schema change from a styling-only release.
One domain also needs namespace discipline. HSLG documentation pages are owned under /app with a stable document key, and the chronological page is /devlog. A future unrelated plugin must have its own navigation root and page metadata. The documentation publisher must never take over an unrelated page simply because the slug matches. Ownership, edit conflicts and a missing parent are blocking conditions, not reasons to rewrite the database directly.
What the API can and cannot rely on
The API controller registers REST endpoints using WordPress's route registration and permission callbacks. The account layer deliberately does not use wp_users as the authoritative customer identity. It accepts HSLG bearer tokens for protected routes and uses its own customer ID. Some anonymous account actions return deliberately noncommittal responses so callers cannot learn whether an email exists. HTTP transport, rate limits and input validation are security requirements; a properly installed WordPress site alone does not satisfy them.
The API uses WordPress's database interface and prefixed custom tables. Every migration needs a real MariaDB test because schema creation functions and DB defaults can behave differently from mocks. Customer-field history and order state are separate data models. A change to an editorial post must not mutate a customer's identity history. Schema release and WordPress plugin version numbers require compatibility checks before deployment.
For email delivery the explicit design is to call wp_mail() through one dedicated verification module when that module extraction is completed. wp_mail() uses active WordPress transport integrations; HSLG should not embed SMTP passwords or initialize a second mail stack per feature. Authentication must still log and handle delivery failure, resend throttling and challenge expiry. A successful return from the mail transport does not prove inbox delivery. Deliverability and message templates must be tested against the configured mail provider.
Revision-safe documentation is a separate product feature
Documentation is generated from canonical project Markdown and reviewed release metadata. The publisher loads a checksummed bundle and creates pages using wp_insert_post(). When the document changes, it finds the existing owned page and uses wp_update_post() to retain the WordPress page ID and create its normal post revision. Unchanged pages are skipped. Manual edits that diverge from the last applied content block automated updates rather than being silently lost. Deleted source pages are not treated as permission to delete WordPress pages.
The automatic publisher currently hooks activation, plugin upgrades and later admin/cron checks. It therefore does not require the operator to execute WP-CLI on every release. The release gate checks that these mechanisms remain present and that destructive post/table operations have not been introduced. Live server evidence must still confirm that all pages were published and that revisions are enabled; local tests only exercise simulated WordPress behaviour.
A full project restoration cannot rely solely on WordPress revisions. The canonical Markdown, JSON page manifest, history, source ZIP and scripts must be kept outside the failed server. When all copies are lost, no command can recreate actual original editor changes or customer data.
Security and operational constraints
WordPress executes on a multi-site Virtualmin host. A change to /etc/php/*, global Apache configuration, MariaDB server-wide settings or Virtualmin templates may affect unrelated virtual servers. HSLG changes should be applied through the media virtual user and its site-specific PHP-FPM configuration where possible, with snapshots, syntax validation and service-specific health checks. Build tools live in /home/media/.hslg-build, outside the public webroot; they must not be mixed with serving the site.
Reduce attack surface by keeping WordPress core and plugins patched, restricting administrator accounts, protecting REST secrets, limiting plugin write permissions and ensuring HTTPS. API routes must enforce capability checks independently of WordPress's ability to route requests. Never treat a browser Origin header or a QR code as proof of authorization. Logs should exclude passwords, bearer tokens, email verification codes, card numbers and other secrets.
When this architecture should be reconsidered
A dedicated API service may become appropriate when load, independent release frequency, queue processing, contractual uptime or security isolation make a WordPress-hosted endpoint operationally expensive. Migration is viable because business repositories and service ports are intended to be independent of the current WordPress adapter. Trigger the decision with actual latency, CPU, DB locking, outage or release evidence—not technology preference alone.
Do not move hosting merely because a demo works. The first useful measures are successful account signup, a real verified session, controlled venue/catalogue data, order idempotency and a reliable signed native build. Confirm site-level backups and restore operations before onboarding paying customers. Any later migration must preserve stable customer UUIDs, originating write timestamps, audit records and legitimate deletion requirements.
Review path
Inspect wordpress/hslg-app-api/src/Plugin.php and the controllers/repositories for real endpoints; inspect wordpress/hslg-presentation/ for browser-only features; inspect wordpress/hslg-docs-publisher/src/Publisher.php and AutoSync.php for revision and ownership rules. Then compare live plugin versions and WordPress admin page IDs against the published manifest. Record discrepancies in the development chronology instead of silently changing WordPress tables.