Files
Jacky 1f98f7152d
CI / test (push) Failing after 1m31s
v0.2 Preview: Construction Plan.
2026-08-08 21:25:27 +08:00

105 lines
3.4 KiB
Python

from django.db import transaction
from django.utils import timezone
from content.models import ContentInteraction, ContentItem
from math_life.models import (
MathBTIAssessment,
MathBTIResult,
MathIdentity,
Story,
StoryRun,
StoryVersion,
)
from math_life.services import score_mathbti
from progression.models import Card, UserCard
from progression.services import initialize_math_identity
from .models import VisitorMigration
def migration_summary(payload):
mathbti = 1 if isinstance(payload.get("mathbti"), dict) else 0
return {
"mathbti_results": mathbti,
"story_saves": min(len(payload.get("story_saves", [])), 20),
"favorites": min(len(payload.get("favorites", [])), 200),
"cards": min(len(payload.get("cards", [])), 100),
}
@transaction.atomic
def apply_visitor_migration(user):
migration = VisitorMigration.objects.select_for_update().get(user=user)
if migration.status == VisitorMigration.Status.APPLIED:
return migration
payload = migration.payload
mathbti = payload.get("mathbti")
if isinstance(mathbti, dict):
assessment = MathBTIAssessment.objects.filter(
version=mathbti.get("version"),
is_published=True,
).first()
if assessment:
code, scores = score_mathbti(assessment.definition, mathbti.get("answers", []))
identity = MathIdentity.objects.get(code=code)
MathBTIResult.objects.create(
user=user,
assessment=assessment,
identity=identity,
answers=mathbti["answers"],
axis_scores=scores,
)
initialize_math_identity(user, identity)
for item in payload.get("story_saves", [])[:20]:
if not isinstance(item, dict):
continue
story = Story.objects.filter(slug=item.get("story_slug")).first()
if story is None:
continue
version = StoryVersion.objects.filter(
story=story,
version=item.get("version"),
is_published=True,
).first()
node_id = item.get("current_node")
if version is None or node_id not in version.content.get("nodes", {}):
continue
StoryRun.objects.get_or_create(
user=user,
story_version=version,
status=StoryRun.Status.ACTIVE,
defaults={
"current_node": node_id,
"state": item.get("state", {}) if isinstance(item.get("state"), dict) else {},
},
)
favorites = ContentItem.objects.filter(
slug__in=payload.get("favorites", [])[:200],
is_published=True,
)
ContentInteraction.objects.bulk_create(
[
ContentInteraction(
user=user,
content=item,
action=ContentInteraction.Action.FAVORITE,
)
for item in favorites
],
ignore_conflicts=True,
)
cards = Card.objects.filter(slug__in=payload.get("cards", [])[:100])
UserCard.objects.bulk_create(
[UserCard(user=user, card=card, source="visitor_migration") for card in cards],
ignore_conflicts=True,
)
migration.status = VisitorMigration.Status.APPLIED
migration.applied_at = timezone.now()
migration.save(update_fields=["status", "applied_at"])
return migration