Назначение эпика: Ведение ремонтных/строительных проектов по виллам как сметных предложений (Proposal): описание проблемы → решение → калькуляция стоимости → согласование → оплата → выполнение через project-задачи → completion report → экспорт PDF для владельца. Это отдельный документ от месячного Maintenance Report (E06) — он про разовый ремонт/проект, не про периодическую эксплуатацию.
Участвует в use-cases: UC-5 (Repair Proposal → Approval → Project → PDF).
Сущности (owns/touches): owns — Proposal, ProposalItem (problem/solution/photos), ProposalCost (item/labor), ProposalCharge; touches — Unit (E01), Task (project-задачи, E03), MaintenanceReport/completion report (E06 — для прикрепления отчёта о завершении).
Экраны: S31 (Proposals list), S30 (Proposal detail), S04 (Problem/Solution/Costs), S58 (PDF cover).
Открытые findings: F-handling-fee-calculation (как считается handling fee — % от costs автоматически или вручную; влияет на Total в S04).
Статус реализации (2026-06-21):
- ✅ WP-1 DONE + PROD LIVE (PR #16
007333c, DEV+PROD на /staffapp): S31 Proposals list (/projects, status-табы Proposed/Approved/Paid + search + unit dropdown) + S30 Proposal detail (/projects/[id], 4 таба Proposal/Tasks/Costs/History; Costs = cost-строки + Total Costs subtotal). OwnsProposal/ProposalItem/ProposalTaskLine/ProposalCost{type:item|labor}/ProposalHistoryEntry. Мутации inert 🟡 (нет бэкенда). План:docs/superpowers/plans/2026-06-21-e07-projects-wp1.md.- ✅ WP-2 DONE + PROD LIVE (PR #20
c5075b9, DEV+PROD на /staffapp): S04 per-position drill-in (/projects/[id]/items/[itemId]: Room/Problem/Solution + Costs-таблица позиции + Position Total; drill-in кликом из вкладки Proposal) + Cost summary (вкладка Costs расширена:Total Costs+Charges+Handling Fee+grandTotal+Project Duration/Warranty; fallback при null-summary) + S58 PDF cover (/projects/[id]/pdf) + Export PDF wiring + inert status-transition (proposed→Approve, approved→Mark as Paid). Новые сущностиProposalItemCost/ProposalCostSummary+ поляproblem/solutionнаProposalItem. План:docs/superpowers/plans/2026-06-21-e07-projects-wp2.md. E07 desktop эпик завершён.
- Open
F-handling-fee-calculation(формула grand Total) — fallbackTotal = Total Costs + Charges + Handling Fee(§108 ASSUMPTION, помечен в коде «требует подтверждения заказчика»); поле правки inert.- Defer (backend-phase):
Report-колонка S31 как ссылка на E06-документ (нет real report-id внутри E07); реальный PDF-рендер;Total Costsагрегат (sumProposalCosts) vs §103Σ position_total— намеренная snapshot-независимость (прецедент E06), реконсилировать на бэкенде.
3458764672549068392 (controls: input_text×1, input_dropdown×1, input_button×8).Proposed · Approved · Paid) → fast-filter (search input + unit dropdown) → data-table → строка кликабельна в S30. + add proposal (button) 🟡.ID, Unit (напр. «Alaya»), Status, Started, Completed, Report. Даты в формате DD/MM/YYYY (в макете все 22/05/2026).
Report — ссылка на прикреплённый completion report (заполняется после стадии проекта; пусто до завершения).Completed — дата завершения проекта (пусто, пока не Paid+выполнено).Proposed / Approved / Paid (filter) → фильтруют список по status.Report-ссылка в строке → открыть прикреплённый completion report (E06-документ).+ add 🟡 (точная раскладка кнопок в прототипе не детализирована).Proposal (+ Unit для имени виллы, completion report для Report-колонки). Источник создания — потребность в ремонте (вручную оператором/owner services; в прототипе триггер-автоматики нет). Пишет: переход на S30; создание нового Proposal 🟡.+ add 🟡); навигация. Сам список — read.+ add proposal — в каталоге 8 безымянных кнопок, явной «создать» нет, но без неё цикл UC-5 не стартует. (2) Семантика колонки Report как ссылки на completion report — выведена из наличия столбца + стадии Paid.Proposal · Tasks · Costs · History, на вкладке Proposal — построчный перечень ремонтных позиций (item, комната, заметки, фото).3458764672525398514 (controls: input_button×3, input_text×1, input_dropdown×1). Заголовок в Miro унаследован от шаблона Maintenance Report, но контент — это Proposal (вкладка Proposal, не Area Report); трактуем как Proposal detail.Unit, Year, Month, Completed at) + Name: / Status: + Save / Cancel → tab-полоса Proposal · Tasks · Costs · History → на вкладке Proposal таблица позиций + блок Photos: с + add photo.Unit («Villa Alaya»), Year («2026»), Month («1»), Completed at («6 May, 2026»), Name:, Status:.ID, Item Name (напр. «Wall Paint», «Door Replacement», «Table Replacement»), Room (напр. «Bathroom», «Entrance», «Living Room»), Notes:.Photos: + + add photo (button) — фото к позиции/предложению.Save (button) → сохранить изменения предложения (update).Cancel (button) → отменить редактирование.Status: (вероятно dropdown/индикатор) → отражает/меняет стадию Proposed→Approved→Paid (см. мутации ниже).Unit (input_dropdown) → привязка к вилле.+ add photo (button) → прикрепить фото к позиции.Name/Notes.Proposal (позиции, этот экран), Tasks (project-задачи → E03), Costs (калькуляция → S04), History (журнал смены статусов/правок).Proposal — перечень позиций (problem/solution на уровне позиции раскрывается в S04).Tasks — связанные project-задачи (см. cross-ref E03); до Approved/Paid может быть пусто.Costs — финансовый расчёт (S04).History — аудит изменений и переходов статуса.Proposal + ProposalItem (+ Unit). На вкладке Costs читает ProposalCost/ProposalCharge (S04). На вкладке Tasks — Task, отфильтрованные по proposal (E03). На завершении прикрепляется completion report (E06), который всплывает в колонке Report списка S31. Пишет: update позиций/заметок/фото, смену статуса.Proposal (name, items, notes, photos) — Save.status: Proposed → Approved (согласование владельцем/owner services) → Approved → Paid (фиксация оплаты). После Paid — порождение/привязка project-задач (E03) и по завершении — completion report.Year/Month/Completed at унаследованы от шаблона отчёта — для Proposal трактуем Completed at как дату завершения проекта, Year/Month как период привязки (избыточны для разового проекта, оставлены ради верности макету). (2) Связь вкладки Tasks с E03 и вкладки History как audit-лога — структурно достроено (в каталоге только лейблы вкладок).Problem / Solution / Costs, затем сводная калькуляция (Total Costs + Charges + Handling Fee = Total) и параметры Project Duration / Warranty. Источник чисел для PDF.3458764672555531925 (texts=63, images=18, controls: —). Это, по сути, развёрнутый вид вкладки Costs экрана S30 (или печатная развёртка).Problem: текст → Solution: текст → Costs: с подстроками) → итоговый блок Costs (агрегированная таблица) → строки итогов → метаданные проекта.Problem: — описание проблемы (текст),Solution: — описание решения (текст),Costs: — строки стоимости: Cost Item 1 200,000.00 IDR, Cost Item 100,000.00 IDR, Cost Labor 100,000.00 IDR (две природы строк: материалы/работы (Cost Item) и труд (Cost Labor)).Costs (колонки Cost Item / Cost): агрегирует все позиции (Cost Item 1, Cost Item 2, … + соответствующие Cost Labor).Total Costs — сумма всех Cost Item + Cost Labor по позициям.Charges — дополнительные сборы (доставка/прочее) 🟡 точная природа не подписана.Handling Fee — комиссия управляющей компании (см. F-handling-fee-calculation).Total — итог к оплате владельцем.Project Duration: («5 weeks»), Warranty: («5 weeks»).controls: —) — экран преимущественно отображение/печатная развёртка. Редактирование числовых/текстовых полей предполагается на вкладке Costs S30. + add cost line / + add item 🟡 (для наполнения сметы).position_total = Σ(Cost Item) + Σ(Cost Labor) // по каждой позиции
Total Costs = Σ position_total // по всем позициям предложения
Charges = Σ дополнительных сборов (ручной ввод) // напр. доставка/вывоз
Handling Fee = ❓ F-handling-fee-calculation:
вариант A — % от (Total Costs [+ Charges]) автоматически;
вариант B — ручной ввод суммы.
Total = Total Costs + Charges + Handling Fee // сумма к оплате
Project Duration и Warranty — параметры проекта (в неделях), вводятся вручную, в расчёт суммы не входят; идут в условия предложения и в PDF.200,000.00 IDR (как в макете). Числа сохраняются как decimal; форматирование на отображении.Costs (S30). Состояния: пустая смета (нет позиций → Total = 0), заполненная, печатный режим (для PDF — без интерактивных контролов).ProposalItem (problem/solution), ProposalCost (item/labor), ProposalCharge. Пишет: значения стоимостей/сборов/handling fee/duration/warranty в Proposal. Итог Total и развёртка позиций → источник для PDF (S58 + тело документа).Total Costs/Total (derived — не хранить рассинхронно с подстроками).ProposalCost{type: item|labor, name, amount}. (2) Природа Charges (отдельный сбор vs. наценка) в прототипе не подписана — трактуем как ручные дополнительные сборы. (3) Формула Handling Fee — открытый вопрос (F-handling-fee-calculation), в спеке зафиксированы оба варианта, выбор за заказчиком.3458764672555329690 (texts=4, controls: —).betterplace → заголовок документа → период → объект.betterplace (бренд), Repair and Project Proposal (тип документа), May 2026 (период), Villa Alaya (вилла).Export PDF 🟡.Proposal (бренд статичен, период = Month/Year/Completed at, вилла = Unit.name). Тело PDF собирается из S04. Логически генерируется на стадии Paid (или Approved для отправки на согласование владельцу) — точную стадию-триггер уточнить 🟡.History).Export PDF и стадия-триггер генерации (Approved для отправки на согласование vs. Paid как финальный документ) — в прототипе только обложка, без точки запуска. (2) период обложки (May 2026) маппится на Completed at/Month+Year Proposal.S31 (list, tabs Proposed/Approved/Paid)
│ row click
▼
S30 (Proposal detail; tabs Proposal · Tasks · Costs · History)
│ tab Costs / развёртка
▼
S04 (Problem/Solution/Costs → Total Costs + Charges + Handling Fee = Total; Duration/Warranty)
│ Export PDF 🟡
▼
S58 (PDF cover) + тело = развёртка S04
Жизненный цикл (UC-5): S30.status: Proposed → Approved → Paid → порождение project-задач (E03) → выполнение → completion report (E06) → прикрепляется к Proposal → виден в колонке Report (S31). PDF (S58) генерируется из S04 на стадии Approved/Paid 🟡.
Unit (вилла), к которой привязано предложение.Tasks (S30): project-задачи, порождаемые после Paid; исполнение и стоимости работ возвращаются в смету.Report, S31). NB: это не месячный Maintenance Report — отдельный документ завершения разового проекта; модель не дублировать, переиспользовать механизм отчёта E06 как «report-документ, привязанный к Proposal».Ответы со встречи Akira × Sergey (реестр
00-client-questions.md). Перекрывают соответствующие 🟡-допущения ниже.
K-2 · Projects — отдельная вкладка, дом для денег: «Projects» — самостоятельная top-level вкладка (отделена от Maintenance Reports). Именно здесь costs/charges/handling fee. Projects = воронка согласования крупного (ремонт/реновация/инновация), в отличие от периодического maintenance.
Q-02 · handling-fee-calculation — РЕШЕНО (resolves finding F-handling-fee-calculation): handling fee = ручной ввод + возможные пресеты (НЕ авто-%). Это тип charge (charges = группа, handling fee = подтип). На вкладке Costs (S30/S04) не хватает кнопки «добавить charge» — charges-секция мануальная, поверх автоматических items.
Q-03 · total-costs structure / правильная вложенность — РЕШЕНО (resolves §103/§108 ASSUMPTION + open reconciliation). Логическая вложенность (дословно из диалога 2026-06-22):
Projects → Proposal (tab)
└─ Item ("Wall Paint")
└─ под-позиции (new sink · installation · transport · waterproof paint · painter labor)
→ position_total
Projects → Costs (tab)
├─ [AUTO] items из Proposal, под-позиции collapse/expand
│ └─ Total Costs = Σ position_total ← промежуточный итог («посередине»)
├─ [MANUAL] Charges (ГРУППА) ← кнопка «+ add charge»
│ ├─ Handling Fee = ТИП charge ВНУТРИ группы (ручной ввод + пресеты)
│ └─ …прочие charges
├─ Project Costs = Total Costs + Charges ← ФИНАЛЬНЫЙ итог (rename из «Total»)
├─ Warranty — свободный текст
└─ Duration — свободный текст
position_total.Total Costs = живой агрегат Σ position_total (§103-инвариант побеждает §27 snapshot-независимость); под-позиции collapse/expand.Total Costs + Charges + Handling Fee = Total», где handling fee стоял сиблингом — неверно. Корректно: Charges уже включает handling fee.Total Costs + Charges — финальный итог; переименовать Total → «Project Costs» (чтобы не «total total»).Warranty / Project Duration — два свободных текстовых поля (не считаются, ни от чего не зависят).U6.Status: S30; запрет регресса после Paid и точные роли-гейты переходов — наше уточнение (в прототипе явных transition-кнопок нет).ProposalCost (type: item|labor) и ProposalCharge — выведены из лейблов S04 (Cost Item / Cost Labor / Charges); в каталоге это плоские текст-строки.Export PDF + стадия-триггер) — S58 в прототипе только обложка без кнопки запуска.