101 lines
3.2 KiB
Python
101 lines
3.2 KiB
Python
# apps/skills/models.py
|
|
|
|
import uuid
|
|
from django.db import models
|
|
|
|
|
|
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",
|
|
)
|
|
]
|