Dev Specs

Вопросы заказчику — BetterPlace Staff App

Единый реестр открытых продуктовых/доменных вопросов к заказчику. Источник — sticky-notes автора Miro-прототипа + наблюдения при разборе спек/ревью. Заказчик отвечает пачкой по этому документу.

Главный принцип: прототип НЕ блокируется на этих вопросах. Для каждого зафиксирован fallback в коде (что показываем сейчас). Где нет блокера — продолжаем реализацию; ответ заказчика потом меняет поведение без переделки архитектуры.

Статусы: 🔵 OPEN · 🟢 ANSWERED · 🟡 PARTIAL (ответ есть, часть деталей открыта) · ⚪ N/A (снят). Не входит сюда: технический долг (proto-*, secret-DTO, next-intl v4, кэш метаданных) — он в memory/roadmaps/betterplace-staff-app-findings.md. Здесь только то, что решает ЗАКАЗЧИК (продукт/домен).

Процесс: любой новый sticky/🟡-вопрос при работе над эпиком → строкой сюда (Вопрос / Варианты / fallback в прототипе / влияет-на / ссылка на finding). При ответе заказчика → статус 🟢 + решение переносится в эпик-спеку и в findings (Resolved).

Сессия ответов: 🟢/🟡 ниже зафиксированы по встрече Akira × Sergey Korchagin от 2026-06-22 (транскрипт: ~/docs/StaffApp Akira.md). Каждое решение помечено **→ Решение (2026-06-22)**. Перенос решений в эпик-спеки и вёрстку — отдельными PDD-проходами (см. блок «Что дальше» внизу).


Кросс-решения встречи (2026-06-22)

Два решения охватывают несколько вопросов сразу — фиксируем отдельно, чтобы не дублировать:

  • K-1 · Assignment везде = конфигурируемая композиция людей. Во ВСЕХ HR-модулях (Schedules, Shifts, Public Holidays, Annual Leave) Assignment оперирует конкретными людьми, не ролью-абстракцией. Где назначается набор (Schedules, Public Holidays, Annual Leave) — это настраиваемая композиция: группа/ роль/кластер, ИЛИ отдельные люди, ИЛИ комбинация («Office + Иван Петров», «две группы», «группа + 2 чел.») — как в Lark. В UI сохраняется идентичность группы (отображается её название, а не разворот в плоский список); на бэкенде композиция резолвится в список людей (membership-expansion). Единичная замена (Shift, Q-21) — частный случай: один человек. Покрывает Q-19, Q-20, Q-21. → эпик E09.
  • K-2 · «Reports» → «Maintenance Reports», «Projects» — отдельная вкладка. Это две разные операционные сущности. Maintenance Reports — про деньги НЕ говорят: договор управления активом разрешает мелкий ремонт в пределах лимита (~1–2 млн IDR) без счёта/согласования, отчёт = факт работ + проблемы. Projects — воронка согласования крупного (ремонт/реновация/инновация), вот там costs/charges/handling fee. Покрывает Q-01, Q-02, Q-03. → эпики E06, E07.

Сводка (быстрый скан)

#ВопросЭпикВажн.Статус
Q-01Какие задачи попадают в месячный отчётE06IMPORTANT🟢 ANSWERED
Q-02Формула handling fee (авто % или ручной ввод)E07IMPORTANT🟢 ANSWERED
Q-03Total Costs = агрегат vs Σ позицийE07IMPORTANT🟢 ANSWERED
Q-04Связь Review→Employee для heat-gridE08IMPORTANT🟢 ANSWERED
Q-05Где авторинг Announcements (место в IA)E10IMPORTANT🟢 ANSWERED
Q-06Жизненный цикл Task: создание/завершение mobile↔desktopE04IMPORTANT🟢 ANSWERED
Q-07Иерархия каскадных фильтров назначенияE03NIT🟡 PARTIAL
Q-08Семантика issues «required / not required»E05/E02NIT🟢 ANSWERED
Q-09Шкала приоритетов Task/IssueE03/E05NIT🟢 ANSWERED
Q-10Терминология триггеров occupancy/vacancy/reservationE02NIT🟢 ANSWERED
Q-11Связь дат задач с датами бронейE02/E04NIT🟢 ANSWERED
Q-12Какие юниты показывать (только live?)E01NIT🟢 ANSWERED
Q-13История чек-инов + разрез «задачи на сотрудника»E09NIT🔵 OPEN (deferred)
Q-14Числовые фильтры (диапазоны) — где нужныcrossNIT🔵 OPEN (deferred)
Q-15Реальные подписи/копирайт vs placeholdercrossNIT🔵 OPEN (deferred)
Q-16Актуальна ли «Copy of Staff App» (vs оригинал доски)processNIT🔵 OPEN (deferred)
Q-17Квоты отпусков + формула Balance (S14)E09IMPORTANT🟡 PARTIAL
Q-18Источник агрегата Monthly/Yearly + таксономия LeaveE09IMPORTANT🟢 ANSWERED
Q-19Days Off: счётчик vs перечень дат + AssignmentE09NIT🟡 PARTIAL
Q-20Schedule: привязка per-role vs per-employeeE09NIT🟢 ANSWERED
Q-21Shift: Name/Assignment = лейбл+роль vs сотрудник+локацияE09NIT🟢 ANSWERED
Q-22Приоритет Exp Check In/Out (Holiday>Shift>Schedule)E09IMPORTANT🟢 ANSWERED
Q-23Leave: чип Attendance в фильтре заявокE09NIT🟢 ANSWERED
Q-24Leave: квота/баланс у Sick & OtherE09IMPORTANT🟢 ANSWERED
Q-25Убирать ли Tasks-вкладку из Projects (re-confirm)E07IMPORTANT🔵 OPEN

Отложено на следующую встречу: Q-13, Q-14, Q-15, Q-16 (закончилось время; не блокеры). Ждут внешнего входа: Q-17 (точная квота — у HR, action Akira), Q-07 (engineering edge-cases — обсудить с Соей; подход реализации ПРИНЯТ — ADR-001), Requests-модуль HR (attendance/day-off запросы — не задизайнен, следующий этап).


IMPORTANT

Q-01 · report-task-inclusion-rule — 🟢 ANSWERED

  • Эпик/экран: E06 Maintenance Reports (UC-4 компиляция отчёта).
  • Вопрос (sticky ×2): «only approved or approved and finished? tasks can be included?» + «what should be by default — tasks included or excluded». Какие задачи попадают в месячный отчёт и каков дефолт включения.
  • → Решение (2026-06-22): в отчёт автоматически постятся все завершённые задачи по этой вилле за этот год+месяц, со статусом «не включено» по умолчанию. Человек перед отправкой кликабельно переключает included/not-included (нужна кнопка «включить все» для удобства). Только включённые попадают в секцию completed task reporter. То же для issues — все зарепорченные за месяц/год по вилле, included/not-included кликабельно. Maintenance Report = веб-репрезентация сделанного (area report по комнатам + выбранные tasks/issues), про деньги НЕ говорит (см. K-2).
  • Дельта к fallback: дефолт меняется included → NOT included; статус включения становится интерактивным (клик прямо в отчёте). → верстка E06 (S35).
  • Finding: report-task-inclusion-rule.

Q-02 · handling-fee-calculation — 🟢 ANSWERED

  • Эпик/экран: E07 Projects (вкладка Costs). (NB: не E06 — в Maintenance Reports денег нет, см. K-2.)
  • Вопрос (sticky): «handling fee automatical» — handling fee считается автоматически (% от costs?) или вводится вручную?
  • → Решение (2026-06-22): ручной ввод, но с возможными пресетами. Handling fee — это тип charge (charges = группа, handling fee = подтип). В Costs проекта не хватает кнопки «добавить charge»; charges-секция мануальная, поверх автоматических items.
  • Дельта к fallback: добавить кнопку add-charge + handling fee как charge-тип (ручной + пресеты). → верстка E07.
  • Finding: handling-fee-calculation.

Q-03 · totalcosts-aggregate-vs-sum-of-positions — 🟢 ANSWERED

  • Эпик/экран: E07 Projects (вкладки Proposal / Costs).
  • Вопрос: Total Costs — отдельный агрегат или Σ позиций? Сейчас на prop-001 расходятся (2,5М vs 2,8М).
  • → Решение (2026-06-22): структура costs: (1) items добавляются на вкладке Proposal (wall paint, door…), у каждого item — раскрываемые под-позиции (new sink, installation, transport…), position_total. (2) На вкладке Costs эти items с под-позициями показываются с возможностью collapse/expand; их сумма = Total Costs (живой агрегат из позиций). (3) Ниже — мануальная секция Charges (incl. handling fee). (4) Финальный итог = Total Costs + Charges, переименовать в «Project Costs» (чтобы не «total total»). Tasks-вкладки в Projects быть НЕ должно (она тут ни при чём). Warranty/Duration — два свободных текстовых поля (не считается).
  • Дельта к fallback: Total Costs = Σ позиций (живой), под-позиции раскрываемы, убрать tasks-вкладку из Projects, переименовать итог. → верстка E07.
  • Finding: e07-totalcosts-aggregate-vs-sum-of-positions.

Q-04 · review-employee-attribution — 🟢 ANSWERED

  • Эпик/экран: E08 Reviews, S52 heat-grid (Employees × Units).
  • Вопрос: по какому правилу отзыв гостя (на бронь/виллу) приписывается сотруднику?
  • → Решение (2026-06-22): через цепочку отзыв → вилла → кластер → команда кластера. Отзыв получает вся команда, прикреплённая к кластеру этой виллы (вариант, близкий к A/B, но именно на уровне cluster-team). Контекст: запрос Mark & Alex — показывать хорошие отзывы сотрудникам по их объекту (мотивация). Нормализация шкал — на бэке: Booking.com 1–10 vs Airbnb 1–5 → привести к одной шкале (модификатор/transform). Метрика ячейки — как предложено (цвет = средняя нормализованная, число = count).
  • Дельта к fallback: атрибуция = cluster-team (бэкенд), attributedEmployees заполняется командой кластера; фронт heat-grid не меняется. → в основном бэкенд/модель, E08.
  • Finding: review-employee-attribution.

Q-05 · announcements-authoring-ia — 🟢 ANSWERED

  • Эпик/экран: E10 Communications (Announcements) + IA (00-overview §2).
  • Вопрос: где живёт авторинг объявлений (видны на mobile Home, в desktop места нет)?
  • → Решение (2026-06-22): отдельная top-level вкладка «Announcements» в десктопе — как админка блога, где ответственные пишут анонсы на разном уровне; питает ленту анонсов в мобильном приложении. (Вариант B.)
  • Дельта к fallback: новый top-level пункт навигации + экран-авторинг. → верстка E10 desktop (новый экран).
  • Finding: announcements-authoring-ia.

Q-06 · task-create-complete-flow — 🟢 ANSWERED

  • Эпик/экран: E04 Mobile Execution (UC-2 жизненный цикл Task).
  • Вопрос: создаётся ли задача отдельно от экрана исполнения; где завершается (desktop/mobile)?
  • → Решение (2026-06-22): Task всегда создаётся на desktop, из 4 источников: (1) новая бронь → движок создаёт таски из брони; (2) ежедневный движок авто-тасков по графикам; (3) менеджер вручную; (4) авто из зарепорченного issue. Исполнение — desktop И mobile (в основном mobile; часть manager-report тасков — desktop). Апрув — на desktop. На mobile нет создания тасков, только исполнение.
  • Дельта к fallback: подтверждает mobile = только execution; create/approve = desktop. → информирует mobile-трек (E04, ещё не построен).
  • Finding: task-create-complete-flow.

Q-17 · leave-quota-and-balance-formula — 🟡 PARTIAL

  • Эпик/экран: E09 HR, S14 Attendance Monthly + настройки Annual Leave.
  • Вопрос: реальные годовые квоты отпуска и правило начисления; пропорция при найме в середине года?
  • → Решение (2026-06-22): единая константа на всех активных сотрудников (~17 дней/год, точная цифра 17 vs 12 — у HR, action Akira). Отпуск не зависит от срока службы, но зависит от статуса контракта: только active (не trial) сотрудники накапливают. Правило начисления: нельзя взять больше дней отпуска, чем отработано месяцев в этом году (accrual = leaveDaysTaken ≤ monthsWorkedThisYear). Управление — через Annual Leave settings/schedules (по образцу attendance schedules): лист графиков (обычно один — «Annual Leave Bali Office»), у каждого — дней/год + правило начисления, к графику подписываются сотрудники (см. K-1). Настройка — не отдельная админ-страница отпусков, а секция в единой «Странице настроек отделов» (Departments Settings), куда стекаются ВСЕ конфигурируемые переменные.
  • Открыто: точная квота (17/12) — ждём HR; дизайн «Страницы настроек отделов» (Departments Settings) как единого места конфигурации.
  • Дельта к fallback: модель LEAVE_QUOTA константа → leave-schedule с accrual-правилом; число не зашивать до ответа HR. → эпик E09 + новый экран.
  • Finding: leave-quota-and-balance-formula.

Q-18 · monthly-yearly-aggregate-source — 🟢 ANSWERED

  • Эпик/экран: E09 HR, S14 Monthly + S19 Yearly + S03 Daily.
  • Вопрос: откуда сворачиваются агрегаты; таксономия типов отпуска?
  • → Решение (2026-06-22): источник истины — Attendance Daily. Ежедневный движок забирает всех сотрудников, резолвит их графики (schedules+shifts), проверяет реквесты/ливы и постит на день: expected check-in/out, holiday/выходной да-нет, leave-тип. Затем сотрудник чекинится в мобильном приложении → в ту же запись пишутся фактический check-in/out + фото. Месячные/годовые агрегаты (attendance и leave) роллапятся из этой daily-БД на бэке. Прототип хранит pre-aggregated snapshot — это ОК. Таксономия типов: Annual / Sick / Holiday / Day-off / Attendance(correction).
  • Дельта к fallback: подтверждает snapshot-подход фронта; реальная агрегация — бэкенд-движок. → доки E09 (механика движка).
  • Finding: monthly-yearly-aggregate-source.

Q-25 · projects-tasks-tab-removal-confirm — 🔵 OPEN

  • Эпик/экран: E07 Projects, S30 Proposal detail (вкладка Tasks).
  • Контекст: ответ Q-03 (2026-06-22) вскользь упомянул «Tasks-вкладки в Projects быть НЕ должно». Сейчас вкладка рабочая и показывает project-задачи, привязанные к proposal (по UC-5 порождаются после стадии Paid). Sergey (2026-06-24) притормозил удаление: убирать работающую фичу с реальной связью proposal↔задачи по одной обмолвке — преждевременно, нужно явное подтверждение.
  • Вопрос: (а) действительно убрать вкладку Tasks из карточки проекта полностью? (б) если да — куда уходит связь proposal ↔ project-задачи (E03), которую она отображала: переезжает в другое место, или больше не нужна в Projects? (в) или вкладку оставить (она показывает задачи проекта после согласования)?
  • Fallback в прототипе: Tasks-вкладка ОСТАВЛЕНА как есть (табы Proposal · Tasks · Costs · History). WP-1 (Costs-refinement) её не трогает; удаление отложено до явного «да».
  • Влияет на: E07 S30 (структура табов); потенциально E03 (где живёт связь proposal↔tasks).
  • Finding: e07-projects-tasks-tab-removal.

NIT

Q-07 · filter-hierarchy-assignee — 🟡 PARTIAL

  • Эпик: E03 Tasks (автоназначение). Sticky: «Department > Cluster > All Assignee».
  • Вопрос: структура авто-назначения задач.
  • → Решение (2026-06-22): трёхступенчатая иерархия department → cluster → property (по логике Breezeway). Дефолтный ответственный берётся с самого специфичного уровня: если у профиля проперти для этого департамента задан ответственный → он; иначе если у кластера для этого типа тасков есть авто-ответственный → команда/ответственный кластера; иначе → дефолт департамента. Cleaning: clean-staff прикреплён группой к кластеру → cleaning-таск по дефолту назначается на всю команду кластера в clean-департаменте (дальше распределяют сами). Engineering: иначе, авто-логику надо допродумать. Edge-case: проперти в кластере, но её уборщик не в команде кластера → потому и нужна иерархия с override на уровне проперти.
  • Решение по реализации (2026-06-23): ПРИНЯТadjacency list (иерархия) + полиморфные targets[] (композиция, сохраняет идентичность группы) + резолюция most-specific-wins на чтение; ReBAC (OpenFGA/SpiceDB) отложен как overkill. См. ADR-001 (betterplace-staff-app-technical.md). Анти-паттерн user_id/group_id — запрещён.
  • Открыто: engineering-edge-cases авто-логики + tie-break most-specific-wins — обсудить с Соей (Akira action).
  • Дельта к fallback: написать quality-эпик автоназначения; плоские фильтры пока остаются. → доки E03 (эпик-описание).
  • Finding: filter-hierarchy-assignee.

Q-08 · issues-req-and-not-req — 🟢 ANSWERED

  • Эпик: E05 Issues / E02 Templates. Sticky: «issues both req and not req».
  • Вопрос: семантика флага required/not-required.
  • → Решение (2026-06-22): это про task templates и про два типа работ. Решение — разделить Tasks и Inspections как отдельные типы темплейтов. Обычный task: только описание/департамент/категория + да-нет (выполнил/не выполнил), никаких issues и score. Inspection: по каждому пункту да-нет + score; если «нет»автоматически создаётся issue. По сути та же сущность задачи (живёт в тех же листах тасков), но отдельный тип темплейта с другой настройкой — чтобы не путать оператора (нужны качественные пресеты).
  • Дельта к fallback: новый тип темплейта Inspection (score + yes/no → auto-issue). → эпик E02/E05 + верстка темплейтов.
  • Finding: issues-req-and-not-req.

Q-09 · task-priority-scale — 🟢 ANSWERED

  • Эпик: E03 Tasks / E05 Issues.
  • Вопрос: полная шкала приоритетов (в данных только Standard).
  • → Решение (2026-06-22): Low / Standard / High / Emergency (4 уровня). Дефолт при создании — всегда Standard (можно поменять при создании). (NB: «Emergency», не «Urgent»; и убрать «Normal/Medium» — это то же, что Standard.)
  • Дельта к fallback: enum IssuePriority Urgent → Emergency; mock Normal → Standard; распространить единый enum на tasks/services. → верстка + типы (E03/E05).
  • Finding: task-priority-scale.

Q-10 · occupancy-vacancy-trigger-terminology — 🟢 ANSWERED

  • Эпик: E02 Services. Контекст: S53/S54 occupancy vs vacancy.
  • Вопрос: выверить термины occupancy / vacancy / reservation.
  • → Решение (2026-06-22): у Property ровно два статуса — Occupied / Vacant (Reservation — это источник, не статус). Вычисляется автоматически из импортированных с Hostify броней: сегодня check-in или длящаяся бронь покрывает сегодня → Occupied; сегодня check-out либо нет брониVacant. Используется напр. для инспекций (какие виллы свободны сегодня).
  • Дельта к fallback: подтверждает текущие 2 статуса (OCCUPIED/VACANT); зафиксировать правило деривации. → доки E02/E01.
  • Finding: occupancy-vacancy-trigger-terminology.

Q-11 · reservation-task-date-linkage — 🟢 ANSWERED

  • Эпик: E02 / E04. Sticky: «Link to dates for reservations and tasks?».
  • Вопрос: связывать ли даты задач с датами броней.
  • → Решение (2026-06-22): нет, даты задач НЕ привязаны к датам броней. У каждого таска свои даты (дата создания + duration/deadline). Только booking-triggered таски порождаются из броней, но их даты остаются независимыми; issue-таски и периодические — к броням вообще не относятся.
  • Дельта к fallback: подтверждает независимость дат; duration ≈ deadline. → доки E02/E04.
  • Finding: reservation-task-date-linkage.

Q-12 · units-scope-live-only — 🟢 ANSWERED

  • Эпик: E01 Properties/Units. Sticky: «which units? only live?».
  • Вопрос: показывать только live-юниты или все.
  • → Решение (2026-06-22): импортируем из Lark все PM-юниты (всё, где pmStatus != "not in management"); статусы бывают launching / live / terminated. Хранить ВСЕ (нужна история). На странице Properties дефолтный фильтр — только активные (live). Добавить в модель юнита поле Lark Status (pmStatus) в дополнение к внутреннему статусу. Синхронизация: первичный bulk-импорт, далее push из Lark при изменении статуса (не поллинг — pm-статус меняется очень редко).
  • Дельта к fallback: дефолт-фильтр все → live; добавить поле Lark Status. → верстка E01 + бэкенд-синк.
  • Finding: units-scope-live-only.

Q-13 · checkin-history-tasks-per-employee — 🔵 OPEN (deferred)

  • Эпик: E09 HR & Attendance / Schedule (S44). Sticky: «history for check ins? tasks per employee?».
  • Вопрос: нужна ли история чек-инов и разрез «задачи на сотрудника».
  • → Статус (2026-06-22): отложено на следующую встречу (закончилось время). Не блокер.
  • Fallback: Schedule = per-employee календарь; история чек-инов не выведена.
  • Finding: checkin-history-tasks-per-employee.

Q-14 · numeric-filters — 🔵 OPEN (deferred)

  • Эпик: cross. Sticky: «filters for numbers options».
  • Вопрос: где нужны числовые фильтры (диапазоны).
  • → Статус (2026-06-22): не обсуждалось, отложено. Не блокер.
  • Fallback: числовых фильтров нет.
  • Finding: numeric-filters.

Q-15 · placeholder-copy — 🔵 OPEN (deferred)

  • Эпик: cross. Контекст: заглушки («Text text text», «John Wick», «uid_324309483»).
  • Вопрос: реальные подписи / финальный копирайт.
  • → Статус (2026-06-22): не решено (John Wick — шутка про placeholder). Не блокер, косметика.
  • Fallback: placeholder как есть.
  • Finding: placeholder-copy.

Q-16 · original-board-reference — 🔵 OPEN (deferred)

  • Эпик: process. Sticky: «back https://miro.com/app/board/uXjVHVGirS4=/…».
  • Вопрос: актуальна ли «Copy of Staff App» vs оригинал.
  • → Статус (2026-06-22): не подтверждено явно, отложено. Не блокер.
  • Fallback: работаем по Copy (uXjVHDhsi4w=).
  • Finding: original-board-reference.

Q-19 · daysoff-count-vs-dates-and-assignment — 🟡 PARTIAL

  • Эпик/экран: E09 HR, S42 Public Holidays.
  • Вопрос: Days Off — счётчик vs даты; Assignment — роль vs локация?
  • → Решение (2026-06-22): Assignment = люди (см. K-1) — единообразно во всех HR-модулях; UI даёт выбор группы/роли + отдельных людей. Public Holidays имеют свои графики (как attendance/leave), к которым подписываются сотрудники (графики праздников разные). Day-off (неоплачиваемый отгул) — через request: у него нет баланса (не лимитирован), HR аппрувит → пишется в attendance как day-off. Точка ввода — Requests-модуль HR (пока не дописан).
  • Открыто: «Days Off = счётчик vs перечень дат» внутри Public Holidays явно не закрыто (Akira ушёл в assignment/schedules). Для расчёта дневных holiday-колонок логично нужны даты — уточнить в эпике.
  • Дельта к fallback: assignment свободная строка → люди; PublicHoliday получает schedule+подписки. → эпик E09 + верстка.
  • Finding: daysoff-count-vs-dates-and-assignment.

Q-20 · schedule-binding-level — 🟢 ANSWERED

  • Эпик/экран: E09 HR, S32 Schedules.
  • Вопрос: расписание привязано к роли/группе или к сотруднику?
  • → Решение (2026-06-22): канон на бэке — per employee (делаем 100% сейчас). Привязка к роли/группе — UI-удобство (второй сценарий, продумать): добавил расписание роли → новые сотрудники роли автоматически попадают; но т.к. внутри одной роли бывают разные графики, базовая привязка обязана быть per-employee. При role-назначении нужен multi-select (office standard work ≈ 95% офиса). В Schedules не хватает значка «добавить сотрудника» в смену.
  • Дельта к fallback: Schedule.role: string → привязка людей (per-employee) + UI add-employee; role = разворачиваемый шорткат. → эпик E09 + верстка S32/S38.
  • Finding: schedule-binding-level.

Q-21 · shift-name-vs-assignment-semantics — 🟢 ANSWERED

  • Эпик/экран: E09 HR, S38 Shifts.
  • Вопрос: что такое Name и Assignment у смены?
  • → Решение (2026-06-22): Name = свободный текст, просто лейбл записи, ни к чему не привязан (может с пресетами). Assignment = один конкретный сотрудник (выбор из базы сотрудников), НЕ роль и НЕ локация — потому что shift = единичное изменение графика конкретного человека на один день. (Вопрос был «без правильных вариантов» — ни A, ни B.)
  • Дельта к fallback: Shift.assignment свободная строка Office/Handymanemployee-picker (один человек). → верстка S38 + тип.
  • Finding: shift-name-vs-assignment-semantics.

Q-22 · expected-time-priority — 🟢 ANSWERED

  • Эпик/экран: E09 HR, S03/S32/S38 (вычисление Exp Check In/Out).
  • Вопрос: приоритет источников ожидаемого времени при конфликте.
  • → Решение (2026-06-22): движок смотрит Schedule (база), затем Shift (перезаписывает schedule на этот день для этого сотрудника), затем Leaves/Holiday (перезаписывают). Итоговый приоритет (побеждает верхний): Leave/Holiday > Shift (конкретная дата) > Schedule (шаблон недели)подтверждает прототипный resolveExpectedTimes. expected нужно популяризировать в daily-БД заранее (иначе нет инфо «во сколько должен был»).
  • Дельта к fallback: подтверждает текущую логику (5 веток, tested). → доки E09; wiring в S03 — бэкенд.
  • Finding: expected-time-priority.

Q-23 · leave-attendance-chip-scope — 🟢 ANSWERED

  • Эпик/экран: E09 HR, S22 Leave Request / Requests.
  • Вопрос: что фильтрует чип Attendance рядом с leave-типами?
  • → Решение (2026-06-22): верхние вкладки Requests — это пред-фильтры по типу реквеста: All / Annual leave / Holiday / Sick / Attendance / others. Attendance — легитимный тип реквеста (коррекция): сотрудник забыл зачекиниться → просит HR проставить attendance за прошлый день (с подтверждением). То есть это отдельный поток коррекций, не «убрать совсем». НО весь Requests-модуль HR пока не задизайнен (Сергей отложил, т.к. было неясно, что делать с attendance) → следующий этап. В прототипе чип пока убран, до постройки Requests.
  • Дельта к fallback: концептуально Attendance остаётся как request-тип; имплементация Requests-модуля — отложена. → эпик E09 (Requests), верстка позже.
  • Finding: leave-attendance-chip-scope.

Q-24 · leave-balance-sick-other — 🟢 ANSWERED

  • Эпик/экран: E09 HR, S22 Leave Request (Current Balance по типу).
  • Вопрос: есть ли квота/баланс у Sick и Other?
  • → Решение (2026-06-22): нет квот ни у Sick, ни у Other (и у day-off). Всё по согласованию (директор/супервайзер аппрувит или нет), лимита нет. Current Balance для Sick/Other = «—» (подтверждает прототип). Только Annual/Public Holiday имеют квоту (Q-17).
  • Дельта к fallback: подтверждает текущее (null баланс для Sick/Other). → без изменений.
  • Finding: leave-balance-sick-other.

Что дальше — перенос решений (PDD-проходами)

Решения зафиксированы; перенос в эпик-спеки и вёрстку идёт отдельными логическими единицами (один PR — одна единица), каждая через PDD-план + pre-review. Открытые хвосты (Q-17 квота от HR, Q-07 edge-cases с Соей, Requests-модуль, Q-13/14/15/16) не блокируют перенос остальных.


Answered (архив)

Решения зафиксированы inline у каждого вопроса (метка **→ Решение (2026-06-22)**) + статус в сводной таблице. По мере переноса в эпик-спеки — дублировать в соответствующий findings.md (Resolved) с датой.