Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/contracts/program-solutions-v1/README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
<!-- @format -->

Изменение 1.22.0: optional weight_percent у критериев, scoring_mode у результатов и contributions у строки решения. Режим weighted_percent нормализует каждый числовой критерий по его шкале и процентному весу, максимум равен 100; legacy сохраняет прежнюю сумму. Старые payload оценок, required поля, URL и примеры совместимы. Веса и режим входят в revision и фиксируются первой оценкой; правила Project и ProgramSolution используют общую формулу. Для внедрения нужны добавочные миграции программы/критерия и backend до Angular.

# C00 Контракт решения в программе

Изменение 1.21.0: публичные GET охватывают уже сданные конкурсные решения КЧ/хакатона после окончания программы и установки marker существующим publisher. Неконкурсные сохраненные материалы остаются без сдачи. DTO/156 schemas/59 operations сохраняются;6 новых независимых сценариев, итого305. Временный сценарий published_solution_list_competitive_pending_rule намеренно меняется404→200 с пустой страницей: весь конкурсный список больше не закрыт из-за отдельного вопроса о draft. Остальные298 старых сценариев структурно неизменны. Несданные конкурсные работы и архивы не выдаются, окончательная eligibility draft все еще ожидает ответа. Нового Angular UI, схемы БД или Project нет.
Expand Down
389 changes: 388 additions & 1 deletion docs/contracts/program-solutions-v1/examples.json

Large diffs are not rendered by default.

33 changes: 32 additions & 1 deletion docs/contracts/program-solutions-v1/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"jsonSchemaDialect": "https://json-schema.org/draft/2020-12/schema",
"info": {
"title": "PROCOLLAB Program Solutions C00",
"version": "1.21.0",
"version": "1.22.0",
"description": "Контракт решений в программах для реализации и моков BE01–BE09. API base URL задается окружением. snake_case на проводе. Старые API не меняются."
},
"servers": [
Expand Down Expand Up @@ -11549,6 +11549,15 @@
],
"maxLength": 1000,
"description": "Строка/null по прежнему типу критерия. Текстовый комментарий допускает до 1000 символов, как текущий ProjectScore; числовой диапазон и True/False продолжают проверяться отдельно."
},
"weight_percent": {
"type": [
"number",
"null"
],
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Процентный вес числового критерия; null, если вес не применяется."
}
},
"required": [
Expand Down Expand Up @@ -12279,6 +12288,15 @@
"number",
"null"
]
},
"weight_percent": {
"type": [
"number",
"null"
],
"exclusiveMinimum": 0,
"maximum": 100,
"description": "Процентный вес числового критерия; null, если вес не применяется."
}
},
"required": [
Expand Down Expand Up @@ -12396,6 +12414,12 @@
"items": {
"$ref": "#/components/schemas/ResultExpert"
}
},
"contributions": {
"type": "object",
"additionalProperties": {
"type": "number"
}
}
},
"required": [
Expand Down Expand Up @@ -12481,6 +12505,13 @@
"items": {
"$ref": "#/components/schemas/ResultCriterion"
}
},
"scoring_mode": {
"type": "string",
"enum": [
"legacy",
"weighted_percent"
]
}
},
"required": [
Expand Down
50 changes: 50 additions & 0 deletions docs/weighted-case-criteria.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
<!-- @format -->

# Процентные веса критериев кейса

Согласовано 11 ноября 2026: сумма весов числовых критериев — 100%, итог кейса —
0–100. [Требования, формула, API и полный AC audit](https://github.com/PROCOLLAB-github/api/blob/codex/weighted-case-criteria-20261111/docs/weighted-case-criteria.md)
находятся в API repo. Квиз и общий рейтинг квиза с кейсом в эту задачу не входят.

## Поведение

В существующем разделе «Оценивание → Критерии» организатор выбирает «Веса
критериев, 0–100», задает проценты в редакторах и сохраняет весь набор. Поле веса
есть у числовых критериев; сумма и валидность шкал проверяются до сохранения и на
сервере. Изменения при 409 остаются в черновике; первая сохраненная оценка
фиксирует критерии и режим. Для прежних программ остается «Сумма исходных баллов».

Эксперт видит вес и вводит исходные баллы. Расчет выполняет API:
`(балл − минимум) / (максимум − минимум) × вес`. Итог команды — среднее полных
оценок экспертов. В результатах видны максимум 100, объяснение и вклады критериев.
Общая форма работает для Project и ProgramSolution; смешивания их сущностей нет.

`scoringMode`, `weightPercent`, `contributions` — добавочные поля. Старый ответ API
без них читается как legacy. C00 1.22.0 и generated solution DTO/fixtures обновлены;
поля запроса оценки и маршруты сохраняются. Сначала устанавливаются API и его
добавочные миграции, затем Angular. Автоматического включения весов нет.

## Проверка

- Checked by tests: 57 тестов, 7 файлов — criteria, Project/Solution results,
shared expert form, management adapter, solution contract и solution evaluation.
TypeScript solution contract check прошел. В API прошли 235 тестов на отдельном
PostgreSQL; схемы C00 и 307 сценариев проверены валидатором.
- Checked by build: `ng build social_platform --configuration production` прошел.
Остаются прежние предупреждения Sass, budgets и CommonJS. Scoped ESLint и
Prettier проверяют только измененные файлы; глобальные автоисправления не нужны.
- Checked in browser: production build + настоящий локальный Django, синтетические
аккаунты, все внешние сервисы заблокированы. Организатор сохранил 40/35/25;
эксперт через UI отправил 8/7/6, второй через API — 10/8/8. Итоги 71,5 и 88,
рейтинг 79,75 из 100. Проверены блокировка после первой оценки, формула, выгрузка,
desktop 1440 px, mobile 390 px без горизонтального скролла, Enter/Escape и
доступное имя числового поля. Ошибок страницы нет. XLSX после пересчета
LibreOffice совпал с API.
- Checked by source/design review: расширены существующие controls, cards, modal
и shared rating form; Mont и текущие tokens сохраняются, нового CSS/анимаций нет.
Loading/error/disabled/409/old API покрыты компонентными тестами. После
визуальной проверки сокращено только название режима, которое обрезалось на
телефоне. Невыполненных требований к этому расширению формы не осталось.

Not checked: установка на pilot/dev/prod, реальная почта, нагрузка 100 участников
и приемка клиента. Скриншоты, логи и учетные данные QA остаются вне Git.
Original file line number Diff line number Diff line change
@@ -1,23 +1,27 @@
/** @format */

export type CriterionType = "int" | "bool" | "str" | "float";
export type EvaluationScoringMode = "legacy" | "weighted_percent";
export interface ManagementCriterion {
id: number;
name: string;
description: string | null;
type: CriterionType;
minValue: number | null;
maxValue: number | null;
weightPercent?: number | null;
}
export interface ManagementCriteria {
updatedAt: string;
revision: string;
locked: boolean;
supportedTypes: CriterionType[];
criteria: ManagementCriterion[];
scoringMode?: EvaluationScoringMode;
}
export interface ManagementCriteriaWrite {
expectedUpdatedAt: string;
expectedRevision: string;
scoringMode?: EvaluationScoringMode;
criteria: (Omit<ManagementCriterion, "id"> & { id: number | null })[];
}
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/** @format */
import { ManagementCriterion } from "./program-criteria.model";
import { EvaluationScoringMode, ManagementCriterion } from "./program-criteria.model";
import { SolutionRef } from "@domain/solution/solution-contract.model";

export interface ResultExpert {
Expand All @@ -23,6 +23,7 @@ export interface ResultProject {
score: number | null;
place: number | null;
averages: Record<string, number>;
contributions?: Record<string, number>;
experts: ResultExpert[];
}
export interface ResultsGroup {
Expand All @@ -38,6 +39,7 @@ export interface ProgramResults {
generatedAt: string;
requiredEvaluators: number;
maximum: number | null;
scoringMode?: EvaluationScoringMode;
hasNumericCriteria: boolean;
caseOptions: string[];
criteria: ManagementCriterion[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ export interface ProjectRatingCriterion {
type: ProjectRatingCriterionType;
minValue: number | null;
maxValue: number | null;
weightPercent?: number | null;
value: string | number;
expertId: number;
}
Loading