From 7091bccdb4f709161fa3d874204240c3e3e619b5 Mon Sep 17 00:00:00 2001 From: isaacclad Date: Sun, 7 Jun 2026 09:56:23 +0000 Subject: [PATCH] Fix deploy pipeline and add missing event registrations migration. Correct CI workflow for events.ladill.com, default deploy paths, nginx provisioning step, and qr_event_registrations table migration. Co-authored-by: Cursor --- .gitea/workflows/deploy.yml | 26 ++- ...01_create_qr_event_registrations_table.php | 39 +++++ deploy/deploy.sh | 4 +- deployment/setup-service-subdomain-nginx.sh | 153 ++++++++++++++++++ 4 files changed, 214 insertions(+), 8 deletions(-) create mode 100644 database/migrations/2026_06_01_000001_create_qr_event_registrations_table.php create mode 100755 deployment/setup-service-subdomain-nginx.sh diff --git a/.gitea/workflows/deploy.yml b/.gitea/workflows/deploy.yml index 3779644..6877b3f 100644 --- a/.gitea/workflows/deploy.yml +++ b/.gitea/workflows/deploy.yml @@ -1,4 +1,4 @@ -name: Deploy Ladill QR Plus +name: Deploy Ladill Events on: push: @@ -10,7 +10,7 @@ permissions: contents: read concurrency: - group: deploy-qr-plus + group: deploy-events cancel-in-progress: true jobs: @@ -19,9 +19,9 @@ jobs: env: NODE_ROOT: /tmp/ladill-node-22-r1 NODE_VERSION: "22.14.0" - RELEASE_ARCHIVE: /tmp/ladill-qr-plus-release-${{ gitea.run_id }}-${{ gitea.run_attempt }}.tgz - WORKSPACE: /tmp/${{ gitea.repository_owner }}-qr-plus-${{ gitea.run_id }}-${{ gitea.run_attempt }} - LADILL_APP_ROOT: /var/www/ladill-qr-plus + RELEASE_ARCHIVE: /tmp/ladill-events-release-${{ gitea.run_id }}-${{ gitea.run_attempt }}.tgz + WORKSPACE: /tmp/${{ gitea.repository_owner }}-events-${{ gitea.run_id }}-${{ gitea.run_attempt }} + LADILL_APP_ROOT: /var/www/ladill-events steps: - name: Checkout shell: bash {0} @@ -78,12 +78,26 @@ jobs: - name: Deploy release shell: bash {0} env: - LADILL_RELEASE_ARCHIVE: /tmp/ladill-qr-plus-release-${{ gitea.run_id }}-${{ gitea.run_attempt }}.tgz + LADILL_RELEASE_ARCHIVE: /tmp/ladill-events-release-${{ gitea.run_id }}-${{ gitea.run_attempt }}.tgz run: | set -Eeuo pipefail : "${LADILL_APP_ROOT:?Set LADILL_APP_ROOT}" bash "$WORKSPACE/deploy/deploy.sh" + - name: Ensure nginx vhost + shell: bash {0} + run: | + set -Eeuo pipefail + NGINX_SCRIPT="$WORKSPACE/deployment/setup-service-subdomain-nginx.sh" + if [ ! -f "$NGINX_SCRIPT" ]; then + NGINX_SCRIPT="/var/www/ladill.com/current/deployment/setup-service-subdomain-nginx.sh" + fi + if [ -f "$NGINX_SCRIPT" ]; then + sudo bash "$NGINX_SCRIPT" events --app /var/www/ladill-events/current + else + echo "WARN: setup-service-subdomain-nginx.sh not found — configure events.ladill.com vhost manually" + fi + - name: Cleanup if: always() shell: bash {0} diff --git a/database/migrations/2026_06_01_000001_create_qr_event_registrations_table.php b/database/migrations/2026_06_01_000001_create_qr_event_registrations_table.php new file mode 100644 index 0000000..c58200d --- /dev/null +++ b/database/migrations/2026_06_01_000001_create_qr_event_registrations_table.php @@ -0,0 +1,39 @@ +id(); + $table->foreignId('qr_code_id')->constrained('qr_codes')->cascadeOnDelete(); + $table->foreignId('user_id')->constrained('users')->cascadeOnDelete(); // organizer + $table->string('reference', 40)->unique(); + $table->string('badge_code', 16)->unique(); + $table->string('tier_name', 80); + $table->unsignedInteger('amount_minor')->default(0); + $table->string('currency', 3)->default('GHS'); + $table->string('attendee_name', 120); + $table->string('attendee_email', 200)->nullable(); + $table->string('attendee_phone', 30)->nullable(); + $table->json('badge_fields')->nullable(); + $table->string('status', 20)->default('pending'); // pending | confirmed | failed | cancelled + $table->string('payment_reference', 60)->nullable(); + $table->timestamp('paid_at')->nullable(); + $table->timestamp('checked_in_at')->nullable(); + $table->json('metadata')->nullable(); + $table->timestamps(); + + $table->index(['qr_code_id', 'status']); + }); + } + + public function down(): void + { + Schema::dropIfExists('qr_event_registrations'); + } +}; diff --git a/deploy/deploy.sh b/deploy/deploy.sh index dc477e2..02fa494 100755 --- a/deploy/deploy.sh +++ b/deploy/deploy.sh @@ -2,7 +2,7 @@ # Fast on-host release deploy (same model as climpme/web/deploy/deploy.sh). set -Eeuo pipefail -APP_ROOT="${LADILL_APP_ROOT:-/var/www/ladill-qr-plus}" +APP_ROOT="${LADILL_APP_ROOT:-/var/www/ladill-events}" RELEASES_DIR="$APP_ROOT/releases" SHARED_DIR="$APP_ROOT/shared" CURRENT_LINK="$APP_ROOT/current" @@ -230,7 +230,7 @@ if [ -L "$CURRENT_LINK" ] && [ -f "$CURRENT_LINK/artisan" ]; then (cd "$CURRENT_LINK" && php artisan queue:restart) || true fi if command -v supervisorctl >/dev/null 2>&1; then - supervisorctl restart ladill-qr-plus-worker:* 2>/dev/null || true + supervisorctl restart ladill-events-worker:* 2>/dev/null || true fi log "Cleaning old releases" diff --git a/deployment/setup-service-subdomain-nginx.sh b/deployment/setup-service-subdomain-nginx.sh new file mode 100755 index 0000000..afde633 --- /dev/null +++ b/deployment/setup-service-subdomain-nginx.sh @@ -0,0 +1,153 @@ +#!/usr/bin/env bash +# +# Provision an nginx vhost for one of Ladill's own service subdomains +# (auth./account./pay./qr./... .ladill.com), reusing the existing +# *.ladill.com wildcard TLS certificate. +# +# The monolith phase needs nothing here — the ladill.com vhost already +# serves *.ladill.com over the wildcard cert. Use this when a service gets +# its OWN app (separate Laravel app dir, or a backend on another host/port), +# so its subdomain stops falling through to the catch-all and routes to the +# real service instead. +# +# Idempotent + safe: writes to sites-available, validates with `nginx -t`, +# and only reloads on success (restores the previous config on failure). +# +# Usage: +# setup-service-subdomain-nginx.sh --app [--fpm ] +# setup-service-subdomain-nginx.sh --proxy +# +# Options: +# --app DIR Serve a Laravel app from DIR/public via PHP-FPM. +# --fpm SOCK PHP-FPM socket for --app (default: /run/php/php8.4-fpm-ladill.sock). +# --proxy URL Reverse-proxy the subdomain to URL (e.g. http://127.0.0.1:9001). +# --zone ZONE Apex zone (default: ladill.com). +# --cert NAME Let's Encrypt lineage under /etc/letsencrypt/live (default: ladill-wildcard). +# --dry-run Print the rendered vhost and exit without writing anything. +# +# Examples: +# setup-service-subdomain-nginx.sh auth --app /var/www/auth.ladill.com/current +# setup-service-subdomain-nginx.sh pay --proxy http://127.0.0.1:9002 +set -euo pipefail + +SUB="${1:-}"; shift || true +[ -n "$SUB" ] || { echo "ERROR: missing (e.g. 'auth')"; exit 2; } + +MODE=""; APP_DIR=""; PROXY_URL="" +FPM_SOCK="/run/php/php8.4-fpm-ladill.sock" +ZONE="ladill.com" +CERT="ladill-wildcard" +DRY_RUN=0 + +while [ $# -gt 0 ]; do + case "$1" in + --app) MODE="app"; APP_DIR="${2:?--app needs a dir}"; shift 2;; + --proxy) MODE="proxy"; PROXY_URL="${2:?--proxy needs a url}"; shift 2;; + --fpm) FPM_SOCK="${2:?}"; shift 2;; + --zone) ZONE="${2:?}"; shift 2;; + --cert) CERT="${2:?}"; shift 2;; + --dry-run) DRY_RUN=1; shift;; + *) echo "ERROR: unknown arg '$1'"; exit 2;; + esac +done + +[ -n "$MODE" ] || { echo "ERROR: choose a backend: --app or --proxy "; exit 2; } + +FQDN="${SUB}.${ZONE}" +CERT_DIR="/etc/letsencrypt/live/${CERT}" +WEBROOT="${APP_DIR:-/var/www/${ZONE}/current}/public" + +if [ "$MODE" = "app" ]; then + BODY=$(cat <> Backed up existing vhost to $BK" +fi + +printf '%s\n' "$VHOST" > "$AVAIL" +ln -sfn "$AVAIL" "$ENABLED" + +if nginx -t; then + systemctl reload nginx + echo ">> ${FQDN} vhost active (${MODE})." +else + echo "ERROR: nginx config test failed — rolling back." + if [ -n "${BK:-}" ] && [ -f "${BK:-}" ]; then + cp -a "$BK" "$AVAIL" + else + rm -f "$AVAIL" "$ENABLED" + fi + nginx -t && systemctl reload nginx || true + exit 1 +fi