Со вчерашнего дня в Сети активно обсуждается ситуация со скруткой голосов по инициативе Навального «5 шагов для России». В качестве косвенного доказательства скрутки приводится частичное несоответствие падежей числу голосов:

На утреннем созвоне команды кто-то поднял этот вопрос во время ежедневной «политинформации». В нашей команде как и везде есть сторонники и противники Навального, поэтому естественно разгорелась бурная дискуссия, которая от «теории заговора» довольно быстро перешла в техническую плоскость. Возникло вот такое обсуждение в Слаке:

Итак, разбираемся

Вот главная страница РОИ  https://www.roi.ru/
Открываем инициативы из блока «Инициативы на голосовании» до тех пор, пока не увидим неправильный падеж. В нашем случае такой страницей оказывается https://www.roi.ru/64726/

Видим ошибку: 12494 голосов

Исследуем исходный html код страницы, находим оригинальную разметку блока

В оригинальной разметке другое значение счетчика – 12 499, которое

  1. отличается от значения 12494 по номиналу
  2. соответствует падежу голосов
  3. отличается от значения 12494 по формату – содержит разделитель групп разрядов

Так же на странице находим блок со значением 12494 и 12 494:

 

Это разметка индикатора прогресса голосования, в котором видим 12 494:

Гипотеза

Гипотеза, что после отображения страницы, значение из индикатора 12494 переносится в блок счетчика голосов javascript ом. Соответствующее падежу значение «12 499 голосов» в счетчике голосов (исходный код страницы) превращается в «12494 голосов»
Зачем так может быть сделано:

  1. Данные счетчика голосов и индикатора получаются из разных источников и могут оказаться рассинхронизированными на несколько голосов.
  2. В косметических целях, чтобы номиналы совпали, на странице делается перенос значения индикатора в значение счетчика, без изменения падежа слова голосов (UI баг)

Поискали и нашли этот скрипт переноса в https://js.roi.ru/themes/frontend/custom.js?v=199

 

Баг с неправильным склонением может воспроизвестись на странице просмотра любой инициативы. Достаточно 2 условий:

  1. Счетчики разошлись
  2. Падеж значения счетчика 1 отличается от падежа значения счетчика 2

Выводы и рекоммендации

Описанный механизм копирования похож на классическую «заплатку» — просто реализуется, сделан архитектурно в неправильном месте (на фронтенде вместо бекенда), делает поверхностную логику замены (только значение без падежа слова «голос»)
Правильное решение – организовывать код на бекенде так, чтобы интенсивно меняющиеся данные получались один раз из одного источника в одном экземпляре и использовались всюду при подготовке html кода страницы. Если сделать так, то значения во всех счетчиках на фронтенде окажутся одинаковыми в исходном html, javascript корректировок не потребуется.

Важно также отметить, что этот баг не объясняет другие замеченные активистами подозрительные ситуации во время голосования по инициативе, но по крайней мере проясняет ситуацию с падежами.