Template
Populate the client website template with catalog feature flags.
Extract always-on public/portal/UTM plus optional email_sms, directmail, blog, payments, social, and social_ai so new client sites can be bootstrapped from this seed. Refs #1 Refs #2 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Executable
+60
@@ -0,0 +1,60 @@
|
||||
#!/usr/bin/env bash
|
||||
# Seed a client repo from this template.
|
||||
# Usage: scripts/bootstrap-client.sh <slug> "<Site Name>" <domain>
|
||||
# Example: scripts/bootstrap-client.sh acme_site "Acme HVAC" acmehvac.com
|
||||
set -euo pipefail
|
||||
|
||||
SLUG="${1:?Usage: $0 <slug> \"<Site Name>\" <domain>}"
|
||||
SITE_NAME="${2:?Usage: $0 <slug> \"<Site Name>\" <domain>}"
|
||||
DOMAIN="${3:?Usage: $0 <slug> \"<Site Name>\" <domain>}"
|
||||
|
||||
if [[ ! "$SLUG" =~ ^[a-z][a-z0-9_]*$ ]]; then
|
||||
echo "slug must be snake_case starting with a letter (e.g. acme_site)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
ROOT="$(cd "$(dirname "$0")/.." && pwd)"
|
||||
cd "$ROOT"
|
||||
|
||||
if [[ "$SLUG" == "client_site" ]]; then
|
||||
echo "slug is already client_site — branding defaults only."
|
||||
else
|
||||
echo "Renaming package client_site → $SLUG"
|
||||
if [[ -d site/client_site ]]; then
|
||||
mv site/client_site "site/$SLUG"
|
||||
fi
|
||||
grep -rl 'client_site' \
|
||||
--exclude-dir=.git --exclude-dir=.venv --exclude-dir=__pycache__ \
|
||||
--exclude='*.png' --exclude='*.jpg' --exclude='*.woff*' --exclude='*.eot' \
|
||||
--exclude='uv.lock' . \
|
||||
| while read -r f; do
|
||||
sed -i "s/client_site/${SLUG}/g" "$f"
|
||||
done
|
||||
fi
|
||||
|
||||
python3 -c "
|
||||
from pathlib import Path
|
||||
name, domain = '''${SITE_NAME}''', '''${DOMAIN}'''
|
||||
for rel in ('.env.example', '.env.prod.example'):
|
||||
p = Path(rel)
|
||||
if not p.exists():
|
||||
continue
|
||||
text = p.read_text()
|
||||
text = text.replace('SITE_NAME=Your Company', f'SITE_NAME={name}')
|
||||
text = text.replace('hello@example.com', f'hello@{domain}')
|
||||
text = text.replace('noreply@example.com', f'noreply@{domain}')
|
||||
text = text.replace('PUBLIC_SITE_URL=https://example.com', f'PUBLIC_SITE_URL=https://{domain}')
|
||||
text = text.replace('DJANGO_ALLOWED_HOSTS=example.com,www.example.com',
|
||||
f'DJANGO_ALLOWED_HOSTS={domain},www.{domain}')
|
||||
p.write_text(text)
|
||||
"
|
||||
|
||||
echo
|
||||
echo "Next:"
|
||||
echo " 1. Brand public templates + static/brand/ (logo, colors, copy)."
|
||||
echo " 2. Copy .env.prod.example → ~/Documents/secrets/${SLUG}/${SLUG}_prod.env"
|
||||
echo " Flip only the FEATURE_* flags they bought. Fill provider secrets."
|
||||
echo " 3. Validate: ./scripts/validate-env.sh ~/Documents/secrets/${SLUG}/${SLUG}_prod.env"
|
||||
echo " 4. Infra: Postgres on 10.0.0.230, server-infra app_catalog, NPM vhost, CI deploy."
|
||||
echo " 5. Deploy. Smoke public home/contact, portal login, leads, UTM."
|
||||
echo " Disabled feature URLs must 404 and must not appear in portal nav."
|
||||
Reference in New Issue
Block a user