{
  "schemaVersion": 1,
  "id": "P27-C03",
  "title": "Калькулятор доставки: от массы коробки к расчётному весу",
  "author": {
    "id": "P27",
    "name": "Филипп Нестеров"
  },
  "specialty": "Калькуляторы и подборщики для продаж",
  "projectStatus": "concept",
  "source": {
    "document": "catalogue_60_personas.md",
    "briefId": "P27-C03",
    "title": "Доставка груза",
    "kind": "editorial_concept",
    "data": "synthetic"
  },
  "context": "Коробка 60 × 40 × 40 см весит 8 кг, а расчёт по объёму даёт 19,2 кг. Если показать только итог, человек не поймёт, ошибся ли он при вводе или сработало другое правило. В этом прототипе я сделал основание расчёта видимым рядом с результатом.",
  "decision": "Разделил фактическую массу и объёмный вес и показал промежуточный объём в см³. В итог попадает большая из двух величин. Делитель оставил в форме: при тех же размерах изменение этого параметра должно быть видно и объяснимо. Формула выполняется в браузере при каждом корректном изменении поля.",
  "constraint": "Модель относится к одной прямоугольной упаковке и правилу max(объёмный вес, фактическая масса). Она не определяет стоимость доставки, округление или допустимость груза у конкретного перевозчика.",
  "steps": [
    "Задал пять независимых вводных: три размера в сантиметрах, массу в килограммах и делитель в см³/кг. Единицы указаны возле полей.",
    "Вывел промежуточные значения рядом с итогом: объём упаковки, деление на коэффициент и фактическую массу. Так можно проверить не только число, но и причину его выбора.",
    "Добавил проверку диапазонов и шага ввода. Ошибка относится к конкретному полю и блокирует расчёт до исправления; корректное изменение сразу пересчитывает результат."
  ],
  "inspection": [
    "Оставить размеры 60 × 40 × 40 см, массу 8 кг и делитель 5000: объём 96 000 см³, объёмный вес 19,2 кг, итог 19,2 кг.",
    "При тех же размерах и делителе изменить массу на 25 кг: объёмный вес остаётся 19,2 кг, итог становится 25 кг.",
    "Вернуть массу 8 кг и заменить делитель на 4000: объёмный и итоговый вес становятся 24 кг.",
    "При делителе 5000 указать массу 19,2 кг: обе величины равны, итог 19,2 кг.",
    "Ввести делитель 0: расчёт не выполняется, ошибка относится к полю делителя. После возврата 5000 корректный результат снова доступен."
  ],
  "sample": {
    "headers": [
      "Проверка",
      "Размеры / масса / делитель",
      "Объёмный вес",
      "Итог модели"
    ],
    "rows": [
      [
        "Лёгкая объёмная упаковка",
        "60 × 40 × 40 см / 8 кг / 5000 см³/кг",
        "96 000 / 5000 = 19,2 кг",
        "19,2 кг — больше фактической массы"
      ],
      [
        "Тяжёлое содержимое",
        "60 × 40 × 40 см / 25 кг / 5000 см³/кг",
        "19,2 кг",
        "25 кг — больше объёмного веса"
      ],
      [
        "Другой делитель",
        "60 × 40 × 40 см / 8 кг / 4000 см³/кг",
        "24 кг",
        "24 кг — правило тарифа меняет результат"
      ],
      [
        "Равные величины",
        "60 × 40 × 40 см / 19,2 кг / 5000 см³/кг",
        "19,2 кг",
        "19,2 кг"
      ],
      [
        "Недопустимый делитель",
        "60 × 40 × 40 см / 8 кг / 0 см³/кг",
        "Не вычисляется",
        "Ошибка, связанная с полем «Делитель по тарифу»"
      ]
    ]
  },
  "sampleNote": "Авторский прототип для одной упаковки. Значения заданы для проверки модели; цена, округление и ограничения конкретного перевозчика в расчёт не входят.",
  "caseStudy": {
    "role": "Проектирование интерфейса и разработка калькулятора",
    "contribution": "Спроектировал форму и разработал расчёт: пять связанных полей, промежуточные значения, явно заданные единицы и проверка допустимого ввода. Собрал контрольные примеры, в которых меняется основание результата.",
    "objective": "Объяснить разницу между массой коробки и расчётным весом через изменяемые исходные данные.",
    "problem": "Нужно показать, какое правило дало итог, и не смешать расчёт веса со стоимостью перевозки.",
    "deliverables": [
      "Форма с пересчётом веса и промежуточными вычислениями.",
      "Ошибки ввода, связанные с соответствующими полями.",
      "Пять контрольных примеров с порядком повторения."
    ],
    "result": "Готовый прототип пересчитывает вес при изменении вводных, показывает ход расчёта и останавливается на некорректном поле. На одной коробке можно проверить оба исхода: 19,2 кг по объёму и 25 кг по фактической массе.",
    "blocks": [
      {
        "type": "text",
        "title": "Показал основание рядом с итогом",
        "text": "У формы пять полей: длина, ширина, высота, масса и делитель. Рядом с итогом видны объём коробки, объёмный вес и фактическая масса. Поэтому проверку можно начать с конкретного места: неверный объём — проверить размеры; другой объёмный вес — проверить делитель.\n\nНа исходных данных получается 60 × 40 × 40 = 96 000 см³, затем 96 000 / 5000 = 19,2 кг. Масса 8 кг участвует в сравнении, но оказывается меньше. Если изменить только массу на 25 кг, объёмный вес останется прежним, а итог станет 25 кг."
      },
      {
        "type": "text",
        "title": "Оставил делитель в форме",
        "text": "Спрятать 5000 внутри формулы было бы проще, но тогда пользователь не увидел бы одно из условий расчёта. При делителе 4000 та же коробка даёт уже 24 кг. Поэтому коэффициент редактируется отдельно, с единицей см³/кг. Калькулятор применяет введённое правило; сам тариф он не подбирает."
      },
      {
        "type": "text",
        "title": "Связал ошибку с конкретным полем",
        "text": "Размеры вводятся в сантиметрах, масса — в килограммах. Пустое поле, нулевой делитель или значение вне допустимого диапазона убирают итог и показывают причину ошибки. После исправления расчёт возвращается без повторного заполнения формы.\n\nРазмеры в этой версии задаются целыми сантиметрами. Ввод 0,6 вместо 60 отклоняется: переключения единиц здесь нет. Сообщение об ошибке связано с полем и доступно при чтении интерфейса экранной программой."
      },
      {
        "type": "table",
        "title": "Что проверено на одной коробке",
        "lead": "Габариты во всех пяти примерах — 60 × 40 × 40 см. Изменяется только масса или делитель.",
        "table": {
          "headers": [
            "Что изменили",
            "Объёмный вес",
            "Итог модели"
          ],
          "rows": [
            [
              "Исходные: 8 кг, делитель 5000",
              "96 000 / 5000 = 19,2 кг",
              "19,2 кг — по объёму"
            ],
            [
              "Масса 25 кг; делитель прежний",
              "19,2 кг",
              "25 кг — фактическая масса больше"
            ],
            [
              "Масса 8 кг; делитель 4000",
              "24 кг",
              "24 кг — по объёму"
            ],
            [
              "Масса 19,2 кг; делитель 5000",
              "19,2 кг",
              "19,2 кг — величины равны"
            ],
            [
              "Делитель 0",
              "Не вычисляется",
              "Ошибка, связанная с полем делителя"
            ]
          ]
        }
      }
    ]
  },
  "calculator": {
    "kind": "cargo",
    "title": "Фактическая масса и объемный вес",
    "inputs": [
      {
        "id": "length",
        "label": "Длина",
        "type": "number",
        "value": 60,
        "unit": "см",
        "min": 1,
        "max": 500,
        "step": 1
      },
      {
        "id": "width",
        "label": "Ширина",
        "type": "number",
        "value": 40,
        "unit": "см",
        "min": 1,
        "max": 500,
        "step": 1
      },
      {
        "id": "height",
        "label": "Высота",
        "type": "number",
        "value": 40,
        "unit": "см",
        "min": 1,
        "max": 500,
        "step": 1
      },
      {
        "id": "mass",
        "label": "Фактическая масса",
        "type": "number",
        "value": 8,
        "unit": "кг",
        "min": 0.1,
        "max": 10000,
        "step": 0.1
      },
      {
        "id": "divisor",
        "label": "Делитель по тарифу",
        "type": "number",
        "value": 5000,
        "unit": "см³/кг",
        "min": 1000,
        "max": 10000,
        "step": 1
      }
    ],
    "formula": "Объемный вес = длина × ширина × высота / делитель. Тарифный вес = max(объемный вес, фактическая масса).",
    "assumptions": [
      "Делитель — пример тарифа, не универсальная константа.",
      "Габариты одной упаковки измеряются в сантиметрах.",
      "Цена, округление тарифа и предельные габариты перевозчика не рассчитаны."
    ],
    "tests": [
      {
        "values": {
          "length": 60,
          "width": 40,
          "height": 40,
          "mass": 8,
          "divisor": 5000
        },
        "expected": {
          "volumeWeight": 19.2,
          "billableWeight": 19.2
        }
      },
      {
        "values": {
          "length": 60,
          "width": 40,
          "height": 40,
          "mass": 25,
          "divisor": 5000
        },
        "expected": {
          "volumeWeight": 19.2,
          "billableWeight": 25
        }
      },
      {
        "values": {
          "divisor": 0
        },
        "expected": {
          "error": true
        }
      }
    ]
  },
  "takeaway": "Готовый прототип пересчитывает вес при изменении вводных, показывает ход расчёта и останавливается на некорректном поле. На одной коробке можно проверить оба исхода: 19,2 кг по объёму и 25 кг по фактической массе.",
  "capabilities": [
    "live_calculation",
    "input_validation"
  ],
  "externalConnections": []
}
