Партия: правка истории и кнопка «Редактировать» у игрока
Правка завершённой партии проверяла состав теми же правилами, что и создание: участник обязан состоять в группе сейчас, фракция — быть доступной сейчас. После отключения дополнения партию, сыгранную на Тау, было уже не исправить, а после удаления игрока из группы — любую партию с ним. Теперь то, что уже записано в партии, проходит всегда, а новые игроки и фракции по-прежнему берутся только из текущего состава: чинить историю можно, занести в неё постороннего — нет. Создание партии не ослабло. Править завершённую партию умел любой участник группы, но только через API — кнопки не было, и на практике это мог сделать лишь админ через админку. Теперь у блока «Результаты» есть «Редактировать», и правка идёт тем же перетаскиванием, что и завершение: раскладка восстанавливается из сохранённых мест (одинаковое место — ничья, выбывшие отдельно), рядом — фракции, причина победы и комментарии. Сохранение шлёт версию партии, так что устаревшая правка отклоняется как раньше. Фракции вынесены отдельным блоком, а не в PlaceEditor: он занят перетаскиванием, и селекты внутри него — лишний риск. В списке доступных фракций к набору группы добавляются те, что уже стоят в партии, — иначе фракцию из отключённого дополнения нельзя было бы даже оставить как есть. #29 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BoiJK9ux8peeyjLb8TYjFf
This commit is contained in:
@@ -168,16 +168,28 @@ def _validate_roster_basics(
|
||||
group_id: int,
|
||||
user_ids: list[int],
|
||||
faction_ids: list[int],
|
||||
*,
|
||||
keep_user_ids: set[int] | None = None,
|
||||
keep_faction_ids: set[int] | None = None,
|
||||
) -> None:
|
||||
"""Состав партии: размер, отсутствие дублей, принадлежность группе.
|
||||
|
||||
keep_* — то, что уже записано в правимой партии: такие игроки и фракции проходят
|
||||
независимо от текущего состава группы. Иначе отключённое дополнение или ушедший из
|
||||
группы игрок делали бы старую партию неисправимой навсегда."""
|
||||
if len(user_ids) < 2:
|
||||
raise ValidationError("В партии должно быть не менее 2 участников.")
|
||||
if len(user_ids) > MAX_MATCH_PLAYERS:
|
||||
raise ValidationError(f"В партии не может быть больше {MAX_MATCH_PLAYERS} игроков.")
|
||||
if len(set(user_ids)) != len(user_ids) or len(set(faction_ids)) != len(faction_ids):
|
||||
raise DuplicateParticipantError()
|
||||
if not set(user_ids).issubset(_group_member_ids(session, group_id)):
|
||||
allowed_users = _group_member_ids(session, group_id) | (keep_user_ids or set())
|
||||
if not set(user_ids).issubset(allowed_users):
|
||||
raise ValidationError("Все участники должны состоять в группе.")
|
||||
if not set(faction_ids).issubset(group_service.available_faction_ids(session, group_id)):
|
||||
allowed_factions = group_service.available_faction_ids(session, group_id) | (
|
||||
keep_faction_ids or set()
|
||||
)
|
||||
if not set(faction_ids).issubset(allowed_factions):
|
||||
raise FactionNotAvailableError()
|
||||
|
||||
|
||||
@@ -423,18 +435,23 @@ def update_match(
|
||||
match.win_reason = win_reason
|
||||
|
||||
if participants is not None:
|
||||
saved = session.exec(
|
||||
select(MatchParticipant).where(MatchParticipant.match_id == match.id)
|
||||
).all()
|
||||
# Что уже записано в партии, остаётся допустимым: состав группы и набор
|
||||
# дополнений с тех пор могли поменяться, но историю это чинить не мешает.
|
||||
_validate_roster_basics(
|
||||
session,
|
||||
match.group_id,
|
||||
[p.user_id for p in participants],
|
||||
[p.faction_id for p in participants],
|
||||
keep_user_ids={p.user_id for p in saved},
|
||||
keep_faction_ids={p.faction_id for p in saved},
|
||||
)
|
||||
places = _resolve_finish_places(
|
||||
[(p.user_id, p.place, p.eliminated) for p in participants]
|
||||
)
|
||||
for old in session.exec(
|
||||
select(MatchParticipant).where(MatchParticipant.match_id == match.id)
|
||||
).all():
|
||||
for old in saved:
|
||||
session.delete(old)
|
||||
session.flush()
|
||||
for p in participants:
|
||||
|
||||
Reference in New Issue
Block a user