Ship Print Forge shop site (colors, photos, 3D viewer) (#2)
Deploy Beta / unit-tests (push) Successful in 31s
Deploy Beta / docker (push) Failing after 34s
Deploy Beta / deploy-beta (push) Skipped

## Summary

- Rebrand the Django client template as Print Forge (`client_site` → `print_forge`) with shop + shipping enabled.
- Product listings support multiple photos, color variants (shared price/description/STL, per-color stock and photos), and a photo-first / 3D-second gallery.
- Public pages use 3D printer / printed-toy photography instead of leftover t-shirt mockups; beta CI deploys on `master`.

Closes #1
Infra: [server-infra#27](ai_ml_operations/server-infra#27) (easy deploy beta).

## Test plan

- [ ] Product page shows photo first, 3D model second; color swatches swap photos and stock
- [ ] Portal can upload multiple photos and per-color qty/images; STL stays shared
- [ ] Public home/about/gallery have no t-shirt mockups
- [ ] `manage.py test` passes
- [ ] After server-infra#27: beta deploy to `print-forge-preview.aimloperations.com`

Reviewed-on: #2
This commit was merged in pull request #2.
This commit is contained in:
2026-09-06 18:40:42 -07:00
parent 8a97e3fbe2
commit 1ca5a757d9
339 changed files with 9761 additions and 2541 deletions
+41 -22
View File
@@ -1,7 +1,7 @@
# Secret env files for server-infra deploy. Never commit.
# Copy on the control node:
# ~/Documents/secrets/<slug>_site/<slug>_site_prod.env
# ~/Documents/secrets/<slug>_site/<slug>_site_beta.env
# ~/Documents/secrets/print_forge/print_forge_prod.env
# ~/Documents/secrets/print_forge/print_forge_beta.env
#
# Docker Compose: if a secret contains $ (e.g. DATABASE_URL password), escape
# each $ as $$ or compose will treat $word as a variable.
@@ -9,34 +9,38 @@
DJANGO_ENV=prod
DJANGO_DEBUG=false
DJANGO_SECRET_KEY=replace-with-a-long-random-secret
DJANGO_ALLOWED_HOSTS=example.com,www.example.com
DJANGO_ALLOWED_HOSTS=printforgeprints.com,www.printforgeprints.com
SITE_UNDER_CONSTRUCTION=true
SITE_NAME=Your Company
SITE_TAGLINE=A tagline for the public site
PUBLIC_SITE_URL=https://example.com
DEFAULT_FROM_EMAIL=noreply@example.com
CONTACT_PHONE=
CONTACT_EMAIL=
SITE_NAME="Print Forge"
SITE_TAGLINE="Handcrafted 3D printed toys"
PUBLIC_SITE_URL=https://printforgeprints.com
DEFAULT_FROM_EMAIL=Printforgeprints@gmail.com
CONTACT_PHONE=630-632-0202
CONTACT_EMAIL=Printforgeprints@gmail.com
CONTACT_ADDRESS=
CONTACT_SERVICE_AREA=
CREDIT_NAME=AI ML Operations, LLC
CONTACT_SERVICE_AREA=Chicagoland
CREDIT_NAME="AI ML Operations, LLC"
CREDIT_URL=https://aimloperations.com
# Optional catalog features — false unless purchased.
# Turning a flag on later: set true, redeploy, migrate. Do not auto-drop tables.
FEATURE_EMAIL_SMS=false
FEATURE_EMAIL_SMS=true
FEATURE_DIRECT_MAIL=false
FEATURE_BLOG=false
FEATURE_PAYMENTS=false
FEATURE_PAYMENTS=true
FEATURE_SOCIAL=false
FEATURE_SOCIAL_AI=false
FEATURE_SHOP=true
FEATURE_POS_SYNC=false
FEATURE_EVENTS=false
FEATURE_SHIPPING=true
# Shared external Postgres (10.0.0.230)
DATABASE_URL=postgres://westfarn:replace-db-password@10.0.0.230:5432/client_site
DATABASE_URL=postgres://westfarn:replace-db-password@10.0.0.230:5432/print_forge
WEB_PORT=8004
WEB_PORT=8007
RECAPTCHA_PUBLIC_KEY=replace-me
RECAPTCHA_PRIVATE_KEY=replace-me
@@ -63,6 +67,21 @@ STRIPE_PUBLISHABLE_KEY=
STRIPE_WEBHOOK_SECRET=
STRIPE_CURRENCY=usd
# Required when FEATURE_SHOP=true (also requires FEATURE_EMAIL_SMS + FEATURE_PAYMENTS)
# SHOP_PRINT_QUEUE_LIMIT_MINUTES=0
# Required when FEATURE_POS_SYNC=true in beta/prod (also requires FEATURE_SHOP)
POS_WEBHOOK_SECRET=
POS_API_BASE_URL=
POS_API_TOKEN=
# Optional when FEATURE_SHIPPING=true (also requires FEATURE_SHOP)
EASYPOST_API_KEY=
SHIP_FROM_LINE1=
SHIP_FROM_CITY=
SHIP_FROM_STATE=
SHIP_FROM_ZIP=
# Required when FEATURE_SOCIAL=true
META_APP_ID=
META_APP_SECRET=
@@ -78,8 +97,8 @@ OLLAMA_TIMEOUT_SECONDS=120
# Token must match SHORTENER_API_TOKENS on url_shortening_service (name:secret).
# Generate: python -c "import secrets; print(secrets.token_urlsafe(32))"
SHORTENER_BASE_URL=https://shortener.aimloperations.com
SHORTENER_API_TOKEN=acme:replace-me
# UTM_SOURCE=acme # optional; default is a slug of SITE_NAME
SHORTENER_API_TOKEN=print_forge:replace-me
# UTM_SOURCE=print-forge # optional; default is a slug of SITE_NAME
NOMINATIM_BASE_URL=http://10.0.0.128:8089
NOMINATIM_TIMEOUT_SECONDS=8
@@ -92,11 +111,11 @@ TIANJI_WEBSITE_ID=
GUNICORN_WORKERS=2
GUNICORN_BIND=0.0.0.0:8000
# BETA overrides — <slug>-preview.aimloperations.com
# BETA overrides — print-forge-preview.aimloperations.com
# DJANGO_ENV=beta
# SITE_UNDER_CONSTRUCTION=false
# PUBLIC_SITE_URL=https://example-preview.aimloperations.com
# DATABASE_URL=postgres://westfarn:replace-db-password@10.0.0.230:5432/client_site_beta
# WEB_PORT=8014
# PUBLIC_SITE_URL=https://print-forge-preview.aimloperations.com
# DATABASE_URL=postgres://westfarn:replace-db-password@10.0.0.230:5432/print_forge_beta
# WEB_PORT=8019
# SHORTENER_BASE_URL=https://shortener-beta.aimloperations.com
# SHORTENER_API_TOKEN=acme:replace-with-a-different-token
# SHORTENER_API_TOKEN=print_forge:replace-with-a-different-token