Some checks failed
Deploy Waitlist / Deploy to VPS (push) Failing after 2m26s
Adds Django waitlist app to serve the launch-gating endpoints: - GET /training/django-cohort/waitlist → HTML cohort waitlist page - POST /v1/waitlist/django-cohort → JSON signup with attribution Changes: - waitlist/ app: WaitlistSignup model, views, urls, admin, template - config/settings/waitlist.py: minimal prod settings for waitlist-only deploy - config/urls_waitlist.py: slimmed URL conf (waitlist + healthz + admin) - config/urls.py: registers waitlist routes on full project - config/settings/base.py: adds waitlist to INSTALLED_APPS - docker-compose.waitlist.yml: Traefik-labelled deploy for VPS - requirements/waitlist.txt: minimal dependency set for waitlist build - .gitea/workflows/deploy-waitlist.yml: CI deploy job using Docker socket - Dockerfile: parameterise DJANGO_SETTINGS_FOR_COLLECTSTATIC DNS action required after deploy (board): api.usepaperclip.app → 76.13.129.223 (VPS) usepaperclip.app → 76.13.129.223 (VPS) OR Vercel creds for Next.js fix Co-Authored-By: Paperclip <noreply@paperclip.ing>
75 lines
2.3 KiB
Python
75 lines
2.3 KiB
Python
import json
|
|
|
|
from django.core.exceptions import ValidationError
|
|
from django.core.validators import validate_email
|
|
from django.http import JsonResponse
|
|
from django.shortcuts import render
|
|
from django.views.decorators.csrf import csrf_exempt
|
|
from django.views.decorators.http import require_POST
|
|
|
|
from .models import WaitlistSignup
|
|
|
|
ATTRIBUTION_KEYS = [
|
|
"utm_source",
|
|
"utm_medium",
|
|
"utm_campaign",
|
|
"utm_content",
|
|
"utm_term",
|
|
"utm_id",
|
|
"campaign_id",
|
|
"channel",
|
|
"variant",
|
|
"audience_segment",
|
|
"cta",
|
|
]
|
|
|
|
|
|
def cohort_waitlist(request):
|
|
return render(request, "waitlist/cohort_waitlist.html")
|
|
|
|
|
|
@csrf_exempt
|
|
@require_POST
|
|
def submit_cohort_waitlist(request):
|
|
payload = {}
|
|
try:
|
|
if request.content_type and "application/json" in request.content_type:
|
|
payload = json.loads((request.body or b"{}").decode("utf-8"))
|
|
else:
|
|
payload = request.POST.dict()
|
|
except (json.JSONDecodeError, UnicodeDecodeError):
|
|
return JsonResponse({"ok": False, "error": "invalid_json"}, status=400)
|
|
|
|
email = str(payload.get("email", "")).strip().lower()
|
|
name = str(payload.get("name", "")).strip()
|
|
source = str(payload.get("source", "cohort_waitlist_page")).strip()
|
|
|
|
if not email:
|
|
return JsonResponse({"ok": False, "error": "email_required"}, status=400)
|
|
try:
|
|
validate_email(email)
|
|
except ValidationError:
|
|
return JsonResponse({"ok": False, "error": "invalid_email"}, status=400)
|
|
|
|
attribution = {k: str(payload.get(k, "") or "").strip() for k in ATTRIBUTION_KEYS}
|
|
|
|
signup, created = WaitlistSignup.objects.get_or_create(
|
|
email=email,
|
|
defaults={"name": name, "source": source[:80], "attribution": attribution},
|
|
)
|
|
if not created:
|
|
fields_to_update = []
|
|
if name and signup.name != name:
|
|
signup.name = name
|
|
fields_to_update.append("name")
|
|
if source and signup.source != source[:80]:
|
|
signup.source = source[:80]
|
|
fields_to_update.append("source")
|
|
if signup.attribution != attribution:
|
|
signup.attribution = attribution
|
|
fields_to_update.append("attribution")
|
|
if fields_to_update:
|
|
signup.save(update_fields=fields_to_update)
|
|
|
|
return JsonResponse({"ok": True, "created": created})
|