feat: add progression models and service structure

This commit is contained in:
2026-11-04 16:40:10 +01:00
parent 2e7b9e7ef3
commit a72066a62a
10 changed files with 354 additions and 6 deletions
+98 -1
View File
@@ -1,3 +1,100 @@
# apps/skills/models.py
import uuid
from django.db import models
# Create your models here.
class SkillTree(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
slug = models.SlugField(max_length=80, unique=True)
name = models.CharField(max_length=120)
description = models.TextField(blank=True)
icon = models.CharField(max_length=80, blank=True)
color = models.CharField(max_length=7, blank=True)
is_active = models.BooleanField(default=True)
sort_order = models.PositiveIntegerField(default=0)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class Skill(models.Model):
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
tree = models.ForeignKey(
SkillTree,
on_delete=models.CASCADE,
related_name="skills",
)
slug = models.SlugField(max_length=80)
name = models.CharField(max_length=120)
description = models.TextField(blank=True)
icon = models.CharField(max_length=80, blank=True)
# Utilisable pour afficher le graphe
position_x = models.IntegerField(default=0)
position_y = models.IntegerField(default=0)
sort_order = models.PositiveIntegerField(default=0)
is_active = models.BooleanField(default=True)
prerequisites = models.ManyToManyField(
"self",
symmetrical=False,
blank=True,
related_name="unlocks",
)
class Meta:
constraints = [
models.UniqueConstraint(
fields=("tree", "slug"),
name="unique_skill_slug_per_tree",
)
]
class Task(models.Model):
class ValidationMode(models.TextChoices):
SELF = "self", "Auto-validation"
PEER = "peer", "Validation par un tiers"
PROOF = "proof", "Preuve demandée"
id = models.UUIDField(primary_key=True, default=uuid.uuid4, editable=False)
slug = models.SlugField(max_length=100, unique=True)
name = models.CharField(max_length=160)
description = models.TextField(blank=True)
base_xp = models.PositiveIntegerField()
validation_mode = models.CharField(
max_length=16,
choices=ValidationMode.choices,
default=ValidationMode.SELF,
)
cooldown_seconds = models.PositiveIntegerField(default=0)
daily_limit = models.PositiveIntegerField(null=True, blank=True)
is_repeatable = models.BooleanField(default=True)
is_active = models.BooleanField(default=True)
skills = models.ManyToManyField(
Skill,
through="TaskSkillReward",
related_name="tasks",
)
created_at = models.DateTimeField(auto_now_add=True)
updated_at = models.DateTimeField(auto_now=True)
class TaskSkillReward(models.Model):
task = models.ForeignKey(Task, on_delete=models.CASCADE)
skill = models.ForeignKey(Skill, on_delete=models.CASCADE)
# Permet, par exemple, de répartir 10 XP entre maison et écologie.
xp = models.PositiveIntegerField()
class Meta:
constraints = [
models.UniqueConstraint(
fields=("task", "skill"),
name="unique_reward_per_task_skill",
)
]