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:
2026-08-26 07:55:26 -05:00
co-authored by Cursor
parent 45d0888d33
commit 787f0e48fb
297 changed files with 32534 additions and 3 deletions
+49
View File
@@ -0,0 +1,49 @@
"""Register portal nav, dashboard widgets, and due-work dispatch."""
from django.utils import timezone
from core.registry import (
register_dashboard_collector,
register_dispatcher,
register_feature,
register_portal_nav,
)
def register() -> None:
register_feature("email_sms")
register_portal_nav(
section="campaigns",
label="Campaigns",
url_name="email_sms:campaign_list",
group="Outreach",
order=20,
)
register_dashboard_collector(_dashboard)
register_dispatcher(_dispatch_due)
def _dashboard(request) -> dict:
from email_sms.models import Campaign
upcoming = Campaign.objects.exclude(
status__in=[Campaign.Status.COMPLETED, Campaign.Status.CANCELLED]
).order_by("scheduled_for", "-created_at")[:5]
return {"upcoming_campaigns": upcoming}
def _dispatch_due() -> int:
from email_sms.models import Message
from email_sms.tasks import send_campaign_message
now = timezone.now()
enqueued = 0
for message in Message.objects.filter(
status=Message.Status.SCHEDULED,
scheduled_for__lte=now,
).iterator():
message.status = Message.Status.QUEUED
message.save(update_fields=["status", "updated_at"])
send_campaign_message.enqueue(message_id=str(message.pk))
enqueued += 1
return enqueued