CTA login attribution implementation skill for Django4Lyfe: guides adding new CTA sources, button/tab attribution, enum registration, and tests.
Implements Django login CTA attribution for Slack, Teams, and Email with proper enum registration, URL wiring, and tests.
/plugin marketplace add diversioteam/agent-skills-marketplace/plugin install login-cta-attribution-skill@diversiotechThis skill is limited to using the following tools:
references/architecture-and-signatures.mdUse this Skill in Django4Lyfe backend repos when implementing or updating login CTA attribution for Slack, Teams, or Email.
Primary command:
/login-cta-attribution-skill:implement - add or update a CTA source with
correct enum registration, attribution plumbing, and tests./login-cta-attribution-skill:implement slack survey_complete."High-level flow:
CTA URL (?source=...) ->
CTA view parses source ->
magic link stores attribution metadata ->
auth exchange copies attribution to token ->
Mixpanel receives attribution fields
Button attribution has two valid layers:
Use exactly one layer per CTA path to avoid double-attribution.
For concrete signatures and deeper architecture notes, read:
references/architecture-and-signatures.mdBefore coding:
git branch --show-current
git status --porcelain
Read these files first:
optimo_core/models/login_attribution.pyoptimo_core/auth/magic_link.pyoptimo_integrations/utils/platform_magic_links.pyAlso read local policy docs when present:
AGENTS.mddocs/python-typing-3.14-best-practices.mdTY_MIGRATION_GUIDE.mdThis is a Python code-touching skill. Use this precedence unless target repo docs/CI define a different order:
typyrightmypyDetect active checker:
ty is active if any of:
[tool.ty] in pyproject.tomlty.toml.bin/tytypyright is active if any of:
pyrightconfig.json[tool.pyright] in pyproject.tomlpyrightmypy is active if any of:
mypy.ini or .mypy.ini[tool.mypy] in pyproject.tomlmypyCommand resolution order:
.bin/<tool>uv run <tool><tool>Examples:
# ty
.bin/ty check <changed python files>
uv run ty check <changed python files>
# pyright
.bin/pyright <changed python files>
uv run pyright <changed python files>
# mypy
.bin/mypy <changed python files>
uv run mypy <changed python files>
Strictness:
Run on changed files (or stricter if repo policy requires):
.bin/ruff check --fix <changed files>.bin/ruff format <changed files>ty or pyright or mypy).bin/django check if available, else python manage.py check)From user request, resolve:
slack, teams, or emailweekly_digest, survey_complete, dashboard_ctaAsk for clarification if either is ambiguous.
File: optimo_core/models/login_attribution.py
If action is new, add it to LoginSourceDetailChoices and keep the project's
existing enum conversion pattern consistent.
File: optimo_core/models/login_attribution.py
Use enum composition and Final[str]:
CTA_SOURCE_{PLATFORM}_{ACTION}: Final[str] = (
f"{LoginSourceChoices.{PLATFORM}.value}_{LoginSourceDetailChoices.{ACTION}.value}"
)
File: optimo_core/models/login_attribution.py
Register in both:
ALLOWED_CTA_SOURCESVALID_DETAILS_BY_SOURCEMissing either commonly causes parse_cta_source() fallbacks.
Enum labels must match actual UI button text.
update_slack_cta_url_with_button_info() /
update_teams_cta_url_with_button_info().Never apply both layers on the same CTA path.
Use typed enums for source and detail where required, and keep button/tab value types aligned with the function signature you are calling.
Example (Slack, Layer 1):
from optimo_core.models.login_attribution import CTA_SOURCE_{PLATFORM}_{ACTION}
from optimo_core.models import SlackButtonChoices, SlackTabChoices
from optimo_integrations.utils.platform_magic_links import build_stable_slack_cta_url
url = build_stable_slack_cta_url(
slack_user_uuid=user_uuid,
source=CTA_SOURCE_{PLATFORM}_{ACTION},
slack_tab=SlackTabChoices.HOME,
slack_button=SlackButtonChoices.VIEW_ALL_ALERTS,
)
Example (Teams, Layer 1):
from optimo_core.models.login_attribution import CTA_SOURCE_{PLATFORM}_{ACTION}
from optimo_core.models import TeamsButtonChoices
from optimo_integrations.utils.platform_magic_links import build_stable_teams_cta_url
url = build_stable_teams_cta_url(
teams_user_uuid=user_uuid,
source=CTA_SOURCE_{PLATFORM}_{ACTION},
teams_button=TeamsButtonChoices.GO_TO_DASHBOARD,
)
Example (direct magic-link builder):
from optimo_core.models.login_attribution import (
LoginSourceChoices,
LoginSourceDetailChoices,
)
from optimo_core.models import SlackButtonChoices, SlackTabChoices
from optimo_integrations.utils.platform_magic_links import build_login_magic_link_for_user
url = build_login_magic_link_for_user(
user=user,
login_cta_source=LoginSourceChoices.SLACK,
login_cta_source_detail=LoginSourceDetailChoices.WEEKLY_DIGEST,
slack_button=str(SlackButtonChoices.OPEN_IN_OPTIMO.value),
slack_tab=str(SlackTabChoices.HOME.value),
)
Add or update tests to cover:
parse_cta_source)Use enum values in tests, not raw magic strings.
Update local docs/guides in the target repo if new attribution behavior was introduced.
Before completion:
CTA_SOURCE_* constant added with enum composition.ALLOWED_CTA_SOURCES.VALID_DETAILS_BY_SOURCE for the right platform.When reporting work, include:
If blocked, explicitly report the blocker with file-level context and exact failing command output summary.
For detailed signatures, metadata schema notes, parser behavior, and extended file map:
references/architecture-and-signatures.mdThis Skill is designed to work with both Claude Code and OpenAI Codex.
/login-cta-attribution-skill:implement.name: login-cta-attribution-skill.Expert guidance for Next.js Cache Components and Partial Prerendering (PPR). **PROACTIVE ACTIVATION**: Use this skill automatically when working in Next.js projects that have `cacheComponents: true` in their next.config.ts/next.config.js. When this config is detected, proactively apply Cache Components patterns and best practices to all React Server Component implementations. **DETECTION**: At the start of a session in a Next.js project, check for `cacheComponents: true` in next.config. If enabled, this skill's patterns should guide all component authoring, data fetching, and caching decisions. **USE CASES**: Implementing 'use cache' directive, configuring cache lifetimes with cacheLife(), tagging cached data with cacheTag(), invalidating caches with updateTag()/revalidateTag(), optimizing static vs dynamic content boundaries, debugging cache issues, and reviewing Cache Component implementations.
Creating algorithmic art using p5.js with seeded randomness and interactive parameter exploration. Use this when users request creating art using code, generative art, algorithmic art, flow fields, or particle systems. Create original algorithmic art rather than copying existing artists' work to avoid copyright violations.