Added a cron job processor so emails and notifications can get processed. Added super admin settings with a gui to edit.
This commit is contained in:
17 files changed
+645
-48
No files matched your search
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/bin/sh
|
||||
# Calls one of the app's CRON_SECRET-gated endpoints (see
|
||||
# src/app/api/cron/process-notifications/route.ts and
|
||||
# src/app/api/cron/sync-google-reviews/route.ts) for every business
|
||||
# currently provisioned under STACKS_DIR — so a single crontab entry on
|
||||
# the host covers every business automatically, including ones added
|
||||
# later, without a manual crontab line per business.
|
||||
#
|
||||
# Without something calling process-notifications on a schedule, queued
|
||||
# notifications (staff invitation emails, appointment reminders, loyalty
|
||||
# reward emails, etc.) are created in the database as PENDING and never
|
||||
# actually sent — see that route's own header for why this is a required
|
||||
# piece of infrastructure, not optional. This script is the reference
|
||||
# implementation for wiring that up; see the root README's "Notification
|
||||
# delivery" section for the crontab lines that call it.
|
||||
#
|
||||
# Usage:
|
||||
# process-cron.sh notifications # recommended every 1-2 minutes
|
||||
# process-cron.sh reviews # recommended once every 24 hours
|
||||
#
|
||||
# STACKS_DIR defaults to /opt/nextchair/stacks — override via env var if
|
||||
# this repo is cloned somewhere else (must match every other STACKS_DIR
|
||||
# use across this deployment — see .env.infra.example's own note on why).
|
||||
|
||||
set -eu
|
||||
|
||||
if [ $# -lt 1 ]; then
|
||||
echo "Usage: $0 notifications|reviews" >&2
|
||||
exit 1
|
||||
fi
|
||||
ENDPOINT="$1"
|
||||
STACKS_DIR="${STACKS_DIR:-/opt/nextchair/stacks}"
|
||||
|
||||
case "$ENDPOINT" in
|
||||
notifications) PATH_SUFFIX="process-notifications" ;;
|
||||
reviews) PATH_SUFFIX="sync-google-reviews" ;;
|
||||
*)
|
||||
echo "Unknown endpoint '$ENDPOINT' — expected 'notifications' or 'reviews'." >&2
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ ! -d "$STACKS_DIR" ]; then
|
||||
echo "STACKS_DIR '$STACKS_DIR' does not exist." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
for env_file in "$STACKS_DIR"/*/.env; do
|
||||
[ -f "$env_file" ] || continue
|
||||
|
||||
domain=$(grep -E '^DOMAIN=' "$env_file" | head -n1 | cut -d= -f2- | tr -d '"')
|
||||
cron_secret=$(grep -E '^CRON_SECRET=' "$env_file" | head -n1 | cut -d= -f2- | tr -d '"')
|
||||
slug=$(basename "$(dirname "$env_file")")
|
||||
|
||||
if [ -z "$domain" ] || [ -z "$cron_secret" ]; then
|
||||
echo "[$slug] skipped — no DOMAIN/CRON_SECRET in .env (not fully provisioned yet)." >&2
|
||||
continue
|
||||
fi
|
||||
|
||||
status=$(curl -sS -o /tmp/process-cron-response.$$ -w '%{http_code}' -X POST \
|
||||
"https://${domain}/api/cron/${PATH_SUFFIX}" \
|
||||
-H "Authorization: Bearer ${cron_secret}" || echo "curl_failed")
|
||||
|
||||
if [ "$status" = "200" ]; then
|
||||
echo "[$slug] $PATH_SUFFIX ok"
|
||||
else
|
||||
echo "[$slug] $PATH_SUFFIX FAILED (status=$status): $(cat /tmp/process-cron-response.$$ 2>/dev/null)" >&2
|
||||
fi
|
||||
rm -f /tmp/process-cron-response.$$
|
||||
done
|
||||
Reference in new issue
Block a user