progression 50% pour evolution des joueurs
CI - Security, Lint & Tests / validate (push) Failing after 1m13s

This commit is contained in:
cedrick2711
2026-09-05 11:30:13 -04:00
parent cf551867c9
commit f468217745
22 changed files with 2235 additions and 8 deletions
+143 -1
View File
@@ -23,7 +23,15 @@ from marshmallow import (
validates_schema,
)
from app.models import ESPORT_GAMES, GAME_PLATFORMS, USER_TYPES
from app.models import (
ESPORT_GAMES,
GAME_PLATFORMS,
OBJECTIVE_CHECK_FREQUENCIES,
OBJECTIVE_PRIORITIES,
OBJECTIVE_STATUSES,
OBJECTIVE_TYPES,
USER_TYPES,
)
# =============================================================================
# Custom Validators
@@ -1049,3 +1057,137 @@ class EvaluationSchema(StripMixin):
allow_none=True,
load_default=None,
)
# =============================================================================
# Player Evolution — Objective / Plan Schema
# =============================================================================
class ObjectiveSchema(StripMixin):
"""A player-evolution objective — individual or team KPI goal.
Validates the form payload from the create / edit modal on the
objectives management page.
"""
title = fields.String(
required=True,
validate=validate.Length(min=1, max=200, error=_l('Le titre est obligatoire.')),
error_messages={'required': _l('Le titre est obligatoire.')},
)
description = fields.String(
allow_none=True,
load_default=None,
validate=validate.Length(max=5000),
)
type = fields.String(
validate=validate.OneOf(
[v for v, _ in OBJECTIVE_TYPES],
error=_l("Type d'objectif invalide."),
),
load_default='individual',
)
status = fields.String(
validate=validate.OneOf(
[v for v, _ in OBJECTIVE_STATUSES],
error=_l('Statut invalide.'),
),
load_default='active',
)
priority = fields.String(
validate=validate.OneOf(
[v for v, _ in OBJECTIVE_PRIORITIES],
error=_l('Priorité invalide.'),
),
load_default='medium',
)
category = fields.String(
allow_none=True,
load_default=None,
validate=validate.Length(max=50),
)
is_template = fields.Boolean(load_default=False)
player_id = fields.Integer(
allow_none=True,
load_default=None,
validate=validate.Range(min=1),
error_messages={'invalid': _l('Joueur invalide.')},
)
team_id = fields.Integer(
allow_none=True,
load_default=None,
validate=validate.Range(min=1),
error_messages={'invalid': _l('Équipe invalide.')},
)
kpi_metric = fields.String(
allow_none=True,
load_default=None,
validate=validate.Length(max=120),
)
kpi_target = fields.Decimal(
allow_none=True,
load_default=None,
places=2,
error_messages={'invalid': _l('Cible KPI invalide.')},
)
kpi_unit = fields.String(
allow_none=True,
load_default=None,
validate=validate.Length(max=20),
)
kpi_precision = fields.Integer(
allow_none=True,
load_default=None,
validate=validate.Range(min=0, max=10),
)
start_date = fields.Date(
allow_none=True,
load_default=None,
format='%Y-%m-%d',
error_messages={'invalid': _l('Date de début invalide (AAAA-MM-JJ).')},
)
due_date = fields.Date(
required=True,
format='%Y-%m-%d',
error_messages={
'required': _l('La date d\'échéance est obligatoire.'),
'invalid': _l('Date d\'échéance invalide (AAAA-MM-JJ).'),
},
)
check_frequency = fields.String(
allow_none=True,
load_default=None,
validate=validate.OneOf(
[''] + [v for v, _ in OBJECTIVE_CHECK_FREQUENCIES],
error=_l('Fréquence de vérification invalide.'),
),
)
progress = fields.Integer(
load_default=0,
validate=validate.Range(
min=0, max=100, error=_l('La progression doit être entre 0 et 100.')
),
)
tags = fields.String(
allow_none=True,
load_default=None,
validate=validate.Length(max=255),
)
@validates_schema
def validate_assignment(self, data, **kwargs):
"""Type-aware assignment: coerce to a clean state.
- Templates → no player or team.
- Team objectives → clear player_id.
- Individual objectives → clear team_id.
"""
if data.get('is_template'):
data['player_id'] = None
data['team_id'] = None
return
if data.get('type') == 'team':
data['player_id'] = None
else:
data['team_id'] = None