Перейти до змісту

🔮 BACKLOG — Відкладені ідеї та майбутні розширення

Автогенеровано зі секцій ## 🔮 Deferred / Ideas модульних документів. Не редагувати вручну — правки робіть у відповідному джерелі, потім перегенеруйте:

python docs/_build_backlog.py

Назад до оглавлення — DOCS.md

Всього джерел: 39 · категорій: 8

🧱 Horizontal-модулі

'E-Commerce Module'

Джерело: dop/modules/horizontal/commerce/README.md

Повна реалізація E-Commerce engine

Мотивація: є запит на маркетплейс не тільки для DOP-модулів, а для звичайних товарів Чому відкладено: великий scope, потрібен окремий sprint Trigger: клієнт зі стійким інтересом до e-commerce + бюджет

B2B vs B2C режими

Мотивація: B2B потребує price tiers, credit limit, кредит-нот Чому відкладено: після MVP B2C Trigger: запит B2B-клієнта

PIM (Product Information Management)

Мотивація: для каталогу 10k+ SKU потрібно потужне PIM Чому відкладено: залежить від обсягу клієнтського каталогу Trigger: клієнт з >5k товарів

Headless storefront templates

Мотивація: клієнти хочуть швидко запустити свою вітрину Чому відкладено: потрібен шаблон + конфігуратор Trigger: після першого e-commerce клієнта


'Consolidator Module'

Джерело: dop/modules/horizontal/consolidator/README.md

Повна реалізація Consolidator MVP

Мотивація: клієнти-холдинги хочуть бачити фінстан групи Чому відкладено: в розробці, потрібна якісна elimination логіка Trigger: запит холдингу з 3+ юросіб

Multi-currency translation methods

Мотивація: IFRS пропонує current rate vs temporal method Чому відкладено: після MVP single-currency Trigger: клієнт з валютною дочіркою

Audit trail для консолідації

Мотивація: аудитори вимагають traceable джерела цифр Чому відкладено: після MVP Trigger: клієнт під аудитом Big4

Drill-down на дочірню компанію

Мотивація: клік на цифру у консолідованому звіті → деталь по дочірці Чому відкладено: після MVP Trigger: перші користувачі


'Sales Field Manager — супервізор польових ТП'

Джерело: dop/modules/horizontal/crm-sales/sales-field.md

Territory-based assignment

Мотивація: автоматично розподіляти нових клієнтів за територіями Чому відкладено: потрібна геолокація + правила розподілу Trigger: >10 ТП

Incentive / commission engine

Мотивація: автоматичний розрахунок комісій від оборотів ТП Чому відкладено: різні схеми у різних компаніях, потрібен DSL Trigger: запит sales director

AI call-script assistant

Мотивація: перед дзвінком у клієнта — підказки (останнє замовлення, debt, потреби) Чому відкладено: потрібен prompt engineering + інтеграція з Chat Trigger: стабілізація основного флоу

Competitor tracking at PoS

Мотивація: ТП на точці може зафіксувати ціни / наявність конкурентів Чому відкладено: складний UX + база конкурентів Trigger: FMCG-сектор


'План рахунків та бізнес-операції'

Джерело: dop/modules/horizontal/essentials/accounting-setup.md

IFRS / GAAP mode switch

Мотивація: для експортних компаній — звіти в IFRS Чому відкладено: потрібен паралельний план рахунків + reclassification Trigger: клієнт зі звітністю у банк / аудитор

Custom operations per tenant

Мотивація: клієнти зі специфічними галузями мають свої операції Чому відкладено: зараз BusinessOperation — глобальний. Треба per-tenant Trigger: перший клієнт зі специфічними потребами

Visual posting debugger

Мотивація: бухгалтерам складно зрозуміти, чому згенерувались такі проводки Чому відкладено: потрібен UI PostingExplainer Trigger: support-тикети про незрозумілі проводки


'Bank Reconciliation — узгодження банківських виписок'

Джерело: dop/modules/horizontal/essentials/bank-reconciliation.md

Direct bank API integration (push-style)

Мотивація: виписки в реальному часі без щоденного імпорту .xml/.csv Чому відкладено: у кожного банку свій REST API + OAuth handshake; 4 файлові формати поки покривають ~95% кейсів Trigger: клієнт з потребою intraday balance (>100 транзакцій/день)

AI matching by purpose field

Мотивація: з призначення платежу LLM може вгадати invoice/контрагента Чому відкладено: потрібен достатній обсяг історичних узгоджень для прецизійної рекомендації + per-line LLM-call коштує Trigger: >500 неприв'язаних платежів на місяць у одного tenant'а

Multi-bank consolidated dashboard

Мотивація: клієнт з 3+ розрахунковими рахунками у різних банках хоче єдиний view залишків Чому відкладено: залежить від наявних інтеграцій; 1-2 рахунки покривається існуючим Cash Flow звітом Trigger: після підключення 3+ розрахункових рахунків у одного клієнта

Drag-and-drop reconciliation

Мотивація: UX-покращення «перетягнути картку зі списку Pending на Matched» Чому відкладено: drop-target вимагає вибору конкретного кандидата (payment_id), а не просто колонки — drag без picker'а нічого не вирішує Trigger: UX-фідбек від користувачів після 3-6 місяців експлуатації

Export платіжних доручень (DOP → банк)

Мотивація: генерація пакета платежів з approved OutgoingPayment для завантаження у банк-клієнт Чому відкладено: немає сучасного UA-формату-стандарту: одні банки приймають .dbf, інші .xml, треті — тільки ручне введення; без типового файла треба адаптер per банк Trigger: клієнт з >50 outgoing/день, де ручне введення у банк-клієнт стає bottleneck'ом

Cheque / Promissory note tracking (B-8)

Мотивація: експортні UA-клієнти приймають векселі від іноземних покупців Чому відкладено: окремий lifecycle (received → cleared / dishonoured), не вкладається у поточну BankStatement модель Trigger: перший експорт-клієнт з вексельними розрахунками


'Звітність — журнали, леджери, аналітика'

Джерело: dop/modules/horizontal/essentials/cashflow-reports.md

Real-time dashboard (WebSocket)

Мотивація: CFO хоче live-статус каси, заборгованостей, очікуваних надходжень Чому відкладено: потрібен stream aggregation Trigger: запит CFO великого клієнта

Multi-entity consolidated reports

Мотивація: холдинг має 5 Organization → консолідований P&L Чому відкладено: потрібен модуль Consolidator Trigger: група компаній

Budget vs Actual variance reports

Мотивація: порівняння планових платежів / виручки з фактом Чому відкладено: треба модуль Budgeting Trigger: клієнт з річним плануванням

Drill-down from report to source document

Мотивація: клік на цифру у звіті → перехід до первинки Чому відкладено: link-back потребує розширення звітного API Trigger: постійні support-запити бухгалтерів

Scheduled report delivery (email)

Мотивація: керівники хочуть щоденні/щотижневі звіти на пошту Чому відкладено: потрібен email template engine + scheduler Trigger: корпоративний клієнт


'Договори та специфікації'

Джерело: dop/modules/horizontal/essentials/contracts.md

Contract templates + generation

Мотивація: менеджери створюють договори вручну, багато помилок Чому відкладено: потрібен шаблоноутворювач з плейсхолдерами Trigger: >100 договорів на місяць

Digital signing (Vchasno, DiiaSign)

Мотивація: ручна друк + кур'єр = втрата 3-5 днів на підписання Чому відкладено: різні провайдери підпису, варто узгодити Trigger: запит клієнта з великим обсягом B2B

Auto-prolongation workflow

Мотивація: договори з auto_prolong=True мають автоматично продовжуватись Чому відкладено: потрібна задача у фоні (Celery) + сповіщення Trigger: більше 20 договорів на пролонгацію

Contract performance dashboard

Мотивація: скільки зароблено/витрачено за договором, кредитний ліміт Чому відкладено: потрібна агрегація з кількох регістрів Trigger: запит фін. директора


'Універсальні бухгалтерські документи'

Джерело: dop/modules/horizontal/essentials/document-operations.md

Natural-language input (AI)

Мотивація: бухгалтер пише "нарахувати резерв 10000 від 281", система генерує проводки Чому відкладено: потрібна навчена LLM + класифікатор Trigger: достатня база прикладів (>1000 документів)

Approval workflow for large manual postings

Мотивація: ручні проводки > X грн — вимога головбуха Чому відкладено: workflow engine Trigger: корпоративний клієнт

Period closing wizard

Мотивація: помічник для закриття місяця (перевірки + автогенерація закриваючих операцій) Чому відкладено: потрібен чек-лист + генератор Trigger: стабільна база клієнтів з щомісячним закриттям

Audit trail with versioning

Мотивація: регулятор вимагає незмінні записи після закриття Чому відкладено: поточний AuditLog агностичний, потрібен immutable mode Trigger: аудит перевірка


'Фінансові рахунки — каси, банки, податки'

Джерело: dop/modules/horizontal/essentials/finance-accounts.md

Cash limits & overlimit notifications

Мотивація: закон України обмежує залишок у касі на кінець дня Чому відкладено: потрібен workflow з керівниками для скидання на р/р Trigger: запит клієнта після податкової перевірки

Multi-currency cashbox with automatic conversion

Мотивація: каси в готелях / на митниці працюють з USD/EUR готівкою Чому відкладено: потрібен курс на момент операції (НБУ / комерційний) Trigger: перший клієнт з валютними касовими операціями

Bank API direct integration (Monobank, Privat24)

Мотивація: імпорт виписок у реальному часі, без .mt940 файлів Чому відкладено: кожен банк має свій API, потрібен адаптер Trigger: частіше 100 транзакцій/день через банк


'Fixed Assets — основні засоби та амортизація'

Джерело: dop/modules/horizontal/essentials/fixed-assets.md

Auto-monthly cron

Мотивація: ручний клік щомісяця — easy to forget. Чому відкладено: потребує task-scheduler (Celery beat або APScheduler) і error-recovery. Trigger: перший production deploy.

Component-level depreciation

Мотивація: двигун автомобіля має свій ресурс і амортизується окремо від кузова. Чому відкладено: ускладнює модель (FixedAsset + FixedAssetComponent), а в практиці клієнти зазвичай ведуть весь автомобіль як один актив. Trigger: запит на componentized PP&E з виробничого підприємства.

Тax depreciation register (паралельний облік)

Мотивація: податкова амортизація може йти за іншими ставками, ніж бухгалтерська. Чому відкладено: UA-податок — окрема локалізація (див. accounting-ua у accounting-tax/README.md). Trigger: разом з UA-локалізацією бухгалтерії.

Friendly disposal — sale transaction

Мотивація: disposal через продаж має створити проводку Дт 5310/4100 / Кт asset_account + проводку прибутку/збитку від вибуття. Чому відкладено: MVP — лише статус-маркер; реальна проводка робиться вручну через JournalEntry. Trigger: запит автоматизації disposal-flow.

'Manual JournalEntry — ручні проводки'

Джерело: dop/modules/horizontal/essentials/journal-entry.md

Шаблони ручних проводок

Мотивація: часто повторювані ручні проводки (напр. місячне нарахування резерву) дублюються вручну. Чому відкладено: для типових сценаріїв є DocumentOperation з BusinessOperation — він закриває цю потребу. Trigger: запит від користувача з конкретним сценарієм, який не вписується у DocumentOperation-flow.

Multi-currency lines

Мотивація: проводка з валютними рядками (наприклад, переоцінка USD-залишку). Чому відкладено: MVP оперує однією валютою на JE; складніше — окрема ітерація разом із dual-currency PostingEntry. Trigger: перший випадок переоцінки валютного активу клієнтом.

Reverse-on-date scheduling

Мотивація: автоматичний контр-сторно через N місяців (для нарахувань резервів). Чому відкладено: потребує task-scheduler (Celery/Cron). MVP — лише ручне сторнування. Trigger: поява потреби у регулярних reverse-проводках.

'Month Closing — процес закриття місяця'

Джерело: dop/modules/horizontal/essentials/month-closing.md

Auto-run по крону

Мотивація: бухгалтер часто забуває запустити амортизацію останнього числа місяця. Чому відкладено: потребує Celery beat у production, error-notifications через Slack/email. Trigger: production deploy із job scheduler.

Progress bar під час run-all

Мотивація: якщо тенант має 500 активів + 20 валютних рахунків + купу закриттів — run-all може тривати хвилини. Чому відкладено: поточна реалізація синхронна; для прогресу треба WebSocket або polling. Trigger: клієнт з великим обсягом даних скаржиться на «зависання».

Diff «що зміниться» перед запуском

Мотивація: перед закриттям показати оператору — «буде створено X проводок на Y грн». Чому відкладено: вимагає dry-run режиму у кожному сервісі (fx / cost / pnl). Trigger: запит корпоративного клієнта з чотирма очима.

Approval workflow

Мотивація: закриття ↔ підтвердження головбухом перед посиленням posting_lock_date. Чому відкладено: MVP — один користувач; ролі ще не гранульовані. Trigger: клієнт з > 2 бухгалтерів.

Відкат кроку з компенсуючими проводками

Мотивація: reset_step зараз лише чистить step_results, але фактичні проводки залишаються у PostingEntry. Для реального відкату треба зробити reverse-group. Чому відкладено: складно — відкат амортизації безпечний (unique constraint дозволить re-run), але відкат fx_revaluation потребує явної протилежної проводки. Trigger: реалізація не-idempotent кроків (які не можна просто повторити).


'Номенклатура — товари, одиниці, статті витрат'

Джерело: dop/modules/horizontal/essentials/nomenclature.md

Multi-language item names

Мотивація: експорт, B2B-клієнти, двомовний інтерфейс Чому відкладено: потрібна ItemTranslation модель + UI-розширення Trigger: перший клієнт з експортною діяльністю

Barcode autogeneration (GS1, EAN-13)

Мотивація: ручне введення штрих-кодів — помилки, дублі Чому відкладено: вимагає GS1-префіксу компанії Trigger: при підключенні касових апаратів

Item lifecycle states

Мотивація: розрізнення "активний / archival / blocked" Чому відкладено: зараз достатньо deletion_mark Trigger: коли каталог товарів перевищить 10k SKU


'Партнери — контрагенти, організації, фізособи'

Джерело: dop/modules/horizontal/essentials/partners.md

GDPR-compliant contact storage

Мотивація: ЄС/UA закон про захист персональних даних Чому відкладено: потрібен аудит-лог доступу до PII Trigger: вихід на EU-ринок

Автоматична дедуплікація Client за EDRPOU

Мотивація: менеджери створюють дублі при швидкому введенні Чому відкладено: потрібен UI для злиття дублів Trigger: коли БД клієнтів перевищить 5k

Автоматичне підтягування реквізитів з державного реєстру

Мотивація: ввести EDRPOU → автоматично підтягнути name, address, tax status Чому відкладено: платний API, потрібна інтеграція Trigger: запит клієнта + бюджет на API


'PartyLedger — розрахунки з контрагентами'

Джерело: dop/modules/horizontal/essentials/party-ledger.md

Aging Report (0-30 / 31-60 / 61-90 / 90+)

Мотивація: стандартний звіт для CFO — «який відсоток дебіторки простроченої». Чому відкладено: потрібен due_date у документі + bucket-агрегація. Trigger: запит клієнта з великою дебіторкою.

Currency-aware ledger

Мотивація: контракт у USD → payment теж USD — running_balance має бути у валюті документа, а не лише UAH. Чому відкладено: поточна реалізація агрегує у functional currency. Trigger: імпортер/експортер.

Автоматичне закриття (matching Invoice ↔ Payment)

Мотивація: бухгалтер хоче бачити, який рахунок яким платежем закритий. Чому відкладено: FIFO-matching потребує окремого регістру Settlement. Trigger: робота з великою кількістю часткових оплат.

Statement of account (акт звірки) PDF/email

Мотивація: юристу/бухгалтеру — документ на підпис клієнту. Чому відкладено: потрібен print template + signing flow. Trigger: B2B-операції з формальною звіркою.


'Платежі — вхідні, вихідні, планові'

Джерело: dop/modules/horizontal/essentials/payments.md

Auto-matching by AI (NLP on purpose field)

Мотивація: з призначення платежу можна вгадати Invoice Чому відкладено: потрібне навчання на історії + UA-мова Trigger: >500 неприв'язаних платежів / місяць

Multi-stage approval for large outgoing payments

Мотивація: платіж >X грн вимагає approval керівника + фіндиректора Чому відкладено: workflow engine Trigger: корпоративний клієнт

Payment forecasting (30-90 day outlook)

Мотивація: фіндиректор планує ліквідність Чому відкладено: потрібен прогноз оплат з Invoice.due_date Trigger: запит CFO

Automated salary payment batches

Мотивація: генерація пакета платежів для зарплати за рахунок списку співробітників Чому відкладено: інтеграція з HRM модулем Trigger: клієнт >50 співробітників

Cryptocurrency payments (USDT, ETH)

Мотивація: B2B-експорт, IT-послуги Чому відкладено: legal + бухоблік в UAH Trigger: клієнт з IT-сектору


'Ціноутворення — види цін та прайс-листи'

Джерело: dop/modules/horizontal/essentials/prices.md

Volume-based pricing (tiered)

Мотивація: ціна залежить від обсягу: 1-100 шт — 50 грн, 101+ — 45 грн Чому відкладено: ItemPrice — flat, треба ItemPriceTier Trigger: B2B-клієнт з великими замовленнями

Dynamic pricing (rule engine)

Мотивація: ціна залежить від попиту, залишків, сезону Чому відкладено: потрібен rule engine + ML-модель Trigger: e-commerce з >10k SKU

Customer-specific pricing overrides

Мотивація: для VIP-клієнтів ціна нижча за стандартну оптову Чому відкладено: зараз через Contract.discount — достатньо для старту Trigger: запит sales-департаменту

Competitor price tracking

Мотивація: автоматично порівнювати наші ціни з конкурентами Чому відкладено: scraping + legal issues Trigger: e-commerce domain


'Quality Control — контроль якості вхідних товарів'

Джерело: dop/modules/horizontal/essentials/quality-control.md

AI-based visual inspection

Мотивація: замість ручної інспекції — AI класифікує дефекти з фото Чому відкладено: потрібен навчений CV-модель Trigger: автоматизація + великий обсяг

QC sampling rules

Мотивація: замість перевірки 100% партії — статистична вибірка (AQL) Чому відкладено: складна математика, потрібна конфігурація per-товар Trigger: клієнт зі стандартизованими товарами

Supplier quality scorecard

Мотивація: автоматичний рейтинг постачальників за % defect rate Чому відкладено: зараз звіт "QC performance" покриває базовий випадок Trigger: >5 активних постачальників

Integration with supplier portal

Мотивація: постачальник у особистому кабінеті бачить % відбракування Чому відкладено: потрібен модуль Client Portal Trigger: обмінний flow з постачальниками


'Продаж — Invoice + GoodsShipment'

Джерело: dop/modules/horizontal/essentials/sales-invoice.md

Sales Return workflow

Мотивація: зараз повернення роблять через Adjustment — не прозоро Чому відкладено: потрібен окремий документ + реверс проводок Trigger: запит від roznichny клієнта

Recurring invoices (subscription billing)

Мотивація: для послуг з місячною оплатою (оренда, абонемент) Чому відкладено: потрібен scheduler + генератор Trigger: SaaS-клієнт

Invoice dunning (auto-reminders)

Мотивація: прострочені платежі — треба автоматичне нагадування Чому відкладено: потрібен email-template engine + schedule Trigger: коли overdue_receivables > 5% обороту

Multi-level approval for large invoices

Мотивація: рахунки > X грн вимагають погодження керівника Чому відкладено: потрібен workflow engine Trigger: корпоративний клієнт з контролем


'Списання товарів — GoodsWriteoff'

Джерело: dop/modules/horizontal/essentials/writeoffs.md

Automated expiry scanning

Мотивація: прострочена продукція не вивозиться вчасно Чому відкладено: потрібна cron + email-сповіщення Trigger: FMCG-клієнт

Damage photo attachments

Мотивація: доказ для страхової / винної особи Чому відкладено: потрібен file upload + gallery UI Trigger: клієнт зі страхуванням товарів

Insurance claim workflow

Мотивація: списати через страхову = отримати відшкодування Чому відкладено: потрібен окремий документ + зв'язок зі страховиком Trigger: склад з великим інвентарем

Integration with inventory audit

Мотивація: підрахунок при інвентаризації → автоматичне списання неузгоджень Чому відкладено: модуль InventoryAudit ще не реалізовано Trigger: вимога регулятора або внутрішня політика


Прохідна та вагова (Gatehouse)

Джерело: dop/modules/horizontal/gatehouse/README.md

Tech debt і розширення після MVP (всі 5 sprints + post-MVP polish 2026-04-30 — 2026-05-07). Закриті пункти переїхали в done.md. Тригер реактивації нижче — або реальний customer-flow, або суміжний модуль, що залежить від цього debt'у.

P1 — production / horizontal-scaling blockers

  • [ ] Лабораторія якості (QualityInspection). QC-крок плану візиту тригериться через gate_point.role.step_kind_system_code='qc' + record_checkpoint (див. business-rules.md § QC checkpoint mechanism). Substitute доти, доки немає реального документа з параметрами огляду / fail-pass / прив'язкою лабораторного протоколу. Поле VisitPlanStep.quality_inspection_id (loose-FK PositiveBigIntegerField) уже зарезервовано. Локація: essentials_quality plugin (вже існує — додати документ) або новий core документ. Trigger: реальний customer з вимогами до лабораторії якості.
  • [ ] ANPR + scale correlator: Redis-backing для multi-worker. Сьогодні services._recent: dict[(tenant_id, gate_point_id), deque] — in-memory per-process. Один Daphne worker — OK. Горизонтальне масштабування ламається: подія летить у worker А, парна — у worker B, кореляція не відбувається. Public API (correlate_event(payload) → ticket | None) лишається той самий. Див. hardware-integration.md § 7. Trigger: реальний прокід > 1 RPS на гейт або deploy multi-worker.
  • [ ] VisitPlan materialization edge case — entry без template. Якщо pick_visit_template повернув None (профіль авто не відповідає жодному applies_to), візит реєструється, але без плану → exit-block check не спрацьовує, і force_exit не потрібен. Fallback: за-tenant налаштовуваний «default minimal plan» (тільки entry → exit) щоб шар exit-control завжди працював. Локація: services.py:1594.

P2 — UX / operational ergonomics

  • [ ] EasyOCR pre-warm на startup. /api/v1/gatehouse/ocr/license-plate/ блокує перший запит ~1–2 хв (download model + warmup). Користувач натиснув «Розпізнати» на WebcamANPRTester і думає що зависло. Варіанти: (а) async warmup при старті Daphne; (б) окремий celery / RQ worker з ready-стейтом + 503 поки не готово; (в) explicit endpoint POST /ocr/warmup/ що запускається cron-ом раз на день. Локація: backend/gatehouse/ocr.py.
  • [ ] GateOperator settings drawer. TODO-заглушка показує «Coming soon» notification: frontend/erp/src/components/Gatehouse/GateOperator.tsx. Має бути drawer з: auto-accept whitelist (vehicle-profiles бо template з auto_accept_event=True), exit-without-tare policy (force-exit-без-зважування для VIP), equipment binding mapping (live видно scale/ANPR last_seen_at).
  • [ ] GateEquipment.connection_config schema-validation. Зараз JSON Textarea без runtime-валідації → invalid configs зберігаються → backend driver падає в runtime, error невиразний. Drivers вже виставляють required поля у gatehouse/driver_registry.py. Зробити explicit validator на serializer-рівні: validate_connection_config(value, driver) шукає схему driver'а, перевіряє required + types.
  • [ ] FortNet integration — повний UI для settings. csv_path / pull_interval_sec / is_enabled уже редаговані; не реалізовано: db_dsn (production-режим), gate_mapping (zip externalGateID → DOP GatePoint). Без них production-перемикач = manage.py shell для tenant_admin. Локація: frontend/erp/src/components/Gatehouse/FortnetIntegrationPage.tsx.
  • [ ] Status marked ≠ delete. Документи Gatehouse мають universal state ∈ {draft, posted, marked}, але UI не показує marked-стан окремо — він тільки фільтрується з default списку. На GateEvent / WeighingTicket / QueueTicket / VisitorPass треба чіткий індикатор «помічено для видалення» + права на unmark.

P3 — codebase hygiene / docs-debt

  • [ ] QueueKiosk + WebcamANPRTester — статус не ясний. QueueKiosk уже не в config/gatehouse.ts (фактично прихований), але файл живе. WebcamANPRTester — dev-tool без production-use-case. Вирішити: документувати як kiosk-only public або deprecated → видалити. Якщо лишаємо — додати в README.md як reference dev-screen.
  • [ ] GateCheckpoint itemType=MASTERDATA — misleading. В gatehouse.ts записаний як MASTERDATA, але це read-only journal (immutable child of GateEvent). Існуючий JOURNAL/LEDGER itemType не повністю підходить. Варіанти: (а) новий itemType JOURNAL_READONLY; (б) explicit prop readOnlyJournal: true на MasterData item; (в) лишити як є + явний коментар (showInMenu:false уже мітигує).
  • [ ] Bundle docs не дотягують до essentials/invoices/ reference. У docs/ai/domains/gatehouse/ є README.md, entities.md, business-rules.md. Відсутні: api-contract.md (OpenAPI snippets), test-scenarios.md (Given/When/Then), ui-spec.md (стек-нейтральний UX опис). Заповнити коли почнеться POC-порт Gatehouse в інший стек, або як планове доповнення.

'Production & BOM'

Джерело: dop/modules/horizontal/production-bom/README.md

P1 — наступна сесія (високий пріоритет)

  • [ ] Labor tracking на Manufacturing. Нова модель ManufacturingLaborLine(document, operation, operator, hours, rate). UI: додати вкладку «Праця» в формі Manufacturing. Звіт Actual cost буде показувати реальний labor замість plan.
  • [ ] Auto-cascade subassembly WO. При complete_work_order: якщо input_item сам має активний BOM і немає на складі — створити вкладений WO автоматично, зв'язати через parent_work_order_id. Prevent infinite recursion (уже є в explode_bom).
  • [ ] BOM snapshoting. При Manufacturing.post — клон BOM.lines у ManufacturingBOMSnapshot для повної відтворюваності аудитом. Cost Analysis (actual) буде використовувати snapshot, не поточний BOM.

P2 — середньострокова перспектива

  • [ ] Capacity planning з календарем. Сторінка-дашборд «Завантаження WC на тиждень». Перетягування WO між датами (react-dnd). На backend: WorkOrder.scheduled_start + scheduled_end, WorkCenterCalendar модель з робочими/вихідними днями.
  • [ ] Quality Control integration. Модель QualityInspection(manufacturing_output_line, status, inspector, notes). Item.requires_qc тригер → output batch у «QC hold» локації до approval. Integration point — essentials_quality plugin (вже є hook-пункт у manufacturing_service).
  • [ ] Price-variance breakdown. Розщеплення material variance на:
    • Price variance = (actual_price − std_price) × actual_qty
    • Quantity variance = std_price × (actual_qty − std_qty) Формула з classical management accounting. У UI — два окремі рядки у summary.
  • [ ] Кастомна форма Warehouse з capacity. Зараз capacity_weight / capacity_volume редагуються лише через generic MasterDataForm. Треба кастомна форма з валідацією + доп. полями zone_count, operating_hours, temperature_controlled.

P3 — стратегічні фічі

  • [ ] Real subcontracting. Мануфактуру виконує зовнішній виконавець. Новий flow: WorkOrder.external_vendor (Client FK), матеріали відправляються Transfer-документом, готова продукція — приходить як GoodsReceipt із BOM-референсом.
  • [ ] Shop Floor UI / Kiosk mode. Планшет у цеху: оператор відкриває поточний крок маршруту → вводить фактичний час → наступний крок. Інтеграція з Labor tracking (P1).
  • [ ] Multi-facility ProductionSettings. Заміна singleton на ProductionSettings(facility) з unique_together(tenant, facility). Facility — нова модель, FK з Organization.
  • [ ] Actual Cost із capacity-утилізацією. Overhead algorithm: якщо WC використовується на 80% від capacity, overhead rate normalized; якщо 30% — overhead стає дорожчий (ідле-час).

P4 — «було б непогано»

  • [ ] Графічний BOM-конструктор (drag-n-drop або tree-view). Поточні generic CRUD + custom forms справляються, але для складних multi-level рецептів було б зручно.
  • [ ] Excel-імпорт BOM. Завантажив .xlsx з шаблоном → створилися BOM + BOMLine.
  • [ ] Gantt-chart WorkOrder execution. На backend уже є scheduled_start/end (якщо P2 буде), можна зображати через mantine-charts.

🚚 Vertical-модулі

'Driver App — мобільний додаток водія'

Джерело: dop/modules/vertical/fleet/driver-app.md

Voice commands for hands-free operation

Мотивація: водій за кермом — незручно тикати екран Чому відкладено: voice API (Google / Apple) + UX тестування Trigger: запит від великого автопарку

Offline maps & route display

Мотивація: зона без мережі — водій не бачить де він на маршруті Чому відкладено: потрібно завантажувати tiles (OSM offline) Trigger: маршрути у регіонах зі слабким покриттям

ePOD (electronic proof of delivery)

Мотивація: фото + підпис клієнта + OCR накладної Чому відкладено: реалізовано базово (sales-mobile); розширити для Driver App Trigger: запит логістичних клієнтів

Fuel auto-capture (OCR чеку з АЗС)

Мотивація: ручне введення л/грн — помилки Чому відкладено: OCR API + обробка шаблонів чеків Trigger: клієнт з >5 заправок/день на водія

Driver scorecard (KPI у додатку)

Мотивація: гейміфікація — водій бачить свій рейтинг (час, паливо) Чому відкладено: логіка KPI на backend + UI Trigger: запит HR-департаменту


'Logistic Module (Multimodal Freight & Forwarding)'

Джерело: dop/modules/vertical/logistic/README.md

Automated route optimization

Мотивація: диспетчер вручну планує порядок заїзду — витрачає час Чому відкладено: потрібна VRP-бібліотека + тестовий набір Trigger: логістична компанія з >20 щоденними рейсами

Customer self-service tracking portal

Мотивація: клієнт хоче бачити де його вантаж без дзвінків Чому відкладено: потрібна інтеграція з Client Portal + GPS Trigger: запит клієнтів на tracking-посилання

Automated invoice generation on delivery

Мотивація: після delivered — автоматично виставити рахунок Чому відкладено: потрібен workflow + перевірка тарифу Trigger: стабілізація процесів

Cross-docking workflow

Мотивація: при перевалці зі фури на фуру — облік у точці перевалки Чому відкладено: складна логіка статусів Trigger: склад-хаб у клієнта


🚛 Fleet

'Зарплата водіїв'

Джерело: dop/modules/vertical/fleet/driver-salary.md

Fleet ↔ HRM Payroll bridge

Мотивація: Fleet вже рахує відрядно-преміальну зарплату водіїв (DriverSalaryLedger.amount = «водій Іваненко заробив 18 500 грн у березні»). HRM Payroll plugin рахує офіційне нарахування з ПДФО/ЄСВ/військовим збором (PayrollSlipPostingGroup). Між ними немає автоматичного містка — бухгалтер мусить вручну переносити суми з DriverSalaryLedger у PayrollSlip як base_amount нарахування. Чому відкладено: для модуля собівартості перевезень Fleet (CPM-калькулятор) bridge не потрібен — собівартість читає DriverSalaryLedger напряму. Bridge потрібен лише для офіційного бухгалтерського payroll. Більшість UA-перевізників ведуть зарплату водіїв окремо (часто паралельно у 1С/Excel) і поки не просили DOP закрити цей контур. Trigger: реальний клієнт хоче офіційно нараховувати зарплату водіям через DOP-бухгалтерію (НЕ паралельно у 1С/Excel) АБО при онбордингу Wave 1 ShipCore-pilot з'ясовується що йому критично потрібен єдиний контур Fleet+Payroll.

🔌 Інтеграції

'BAF Sync — синхронізація з BAF (Business Automation Framework)'

Джерело: dop/integrations/baf-sync.md

Повна двостороння реалізація BAF Sync (pull з BAF)

Мотивація: клієнти використовують BAF як legacy-систему; хочуть, щоб оплати/акти з BAF автоматично підтягувались у DOP. Чому відкладено: уточнюється формат API BAF + scope двостороннього обміну. Trigger: підписання договору з першим клієнтом, що має live BAF.

Conflict resolution UI

Мотивація: при двосторонньому sync можливі конфлікти (одне поле змінено в обох системах). Чому відкладено: потрібна кнопка «merge» з UX-дизайном. Trigger: після MVP-релізу.

Schedule + monitoring dashboard

Мотивація: sync має йти за розкладом (cron) з моніторингом помилок. Чому відкладено: після стабілізації основного flow. Trigger: перший production-deploy.


'Bank Exchange — обмін з банком (виписки, платежі)'

Джерело: dop/integrations/bank-exchange.md

Direct API integration (без файлів)

Мотивація: виписки в реальному часі без щоденного імпорту .xml Чому відкладено: у кожного банку свій REST API + OAuth Trigger: клієнт з потребою intraday balance

AI matching by purpose field

Мотивація: з призначення платежу AI може вгадати Invoice Чому відкладено: потрібна навчена модель на історії Trigger: після накопичення базової історії узгоджень

Multi-bank dashboard

Мотивація: клієнти з кількома р/р у різних банках хочуть консолідований view Чому відкладено: залежить від наявних інтеграцій Trigger: після підключення 2+ банків


'eTTN — електронні товарно-транспортні накладні'

Джерело: dop/integrations/ettn.md

КЕП-інтеграція через УЦСК

Мотивація: обов'язкова вимога для юридично значущого документообігу в Україні Чому відкладено: потрібна сертифікація + інтеграція з токенами (Diia.Signature, IIT) Trigger: клієнт з вимогою юридично значущих eTTN

Інтеграція з ЦБД ТТН (НДЛБ)

Мотивація: Україна планує єдину базу електронних накладних Чому відкладено: API ще не релізнутий державою Trigger: запуск державного реєстру

QR-код для миттєвої передачі

Мотивація: на дорозі — водій показує QR, інспектор сканує → бачить eTTN Чому відкладено: UI для генерації + перевірки QR Trigger: дорожні перевірки + вимога ДПС

Mass-signing для пачок документів

Мотивація: оптові відвантаження — 50+ накладних/день Чому відкладено: потрібен batch-sign UI + safety Trigger: клієнт з великим обсягом

Multi-language eTTN (export)

Мотивація: експортні перевезення — потрібен документ російською/англійською Чому відкладено: необхідні шаблони для перекладу Trigger: експортний клієнт


🖥️ Frontend

'DOP App — Тонке налаштування теми (типографія, кольори, щільність)'

Джерело: eswf/frontends/dop-app-theme-tuning.md

Phase C — typography density-aware

Мотивація: density-toggle (compact/normal/comfortable) у Налаштуваннях впливає лише на Mantine --mantine-spacing-* змінні (через CSS resolver, ×0.7/1.0/1.35 multiplier). Шрифти НЕ масштабуються разом — тому ефект density візуально слабкий: на формах помітно, на списках слабо (бо там em-padding слідує за T.listRow.fontSize, який фіксований). Після цього density-toggle = реальний 1С/Salesforce-style "Compact / Normal / Comfortable" — один тумблер тисне ВСЕ. Чому відкладено: поточний ефект density вже корисний (Mantine spacing scaling помітне); типографічна частина — polish, не блокер. Два шляхи реалізації: (A) точний — замінити числові fontSize у токенах T на CSS calc-strings типу 'calc(14px * var(--eswf-density, 1))', em-padding автоматично слідує; (B) грубий — на :root встановити font-size: calc(16px * var(--eswf-density, 1)), всі rem-units реагують, але typography.ts на px-числах все одно треба чіпати. Рекомендований — A. Estimated: ~1 день. Trigger: нічим зайнятись у backlog АБО прямий запит користувача на «зробити density реально помітним на списках».

✨ Фічі

'Tab Keep-Alive — Phase 2'

Джерело: dop/features/tab-keepalive-plan.md

Автоматичне вивантаження кешованих вкладок (LRU)

Мотивація: якщо користувач відкриває 10+ вкладок з важкими компонентами (карти, великі списки), RAM росте лінійно Чому відкладено: Phase 1 (manual tab close) покриває 90% кейсів; жодної скарги на RAM досі не було Trigger: >3 скарги на повільність браузера при великій кількості відкритих вкладок

Persist cache між сесіями (sessionStorage)

Мотивація: при reload сторінки всі вкладки відновлюються, але стан форм втрачається Чому відкладено: складність серіалізації (refs, функції, DOM-позиції) перевищує вигоду Trigger: feature request від >5 користувачів

📝 Планування

'Agent Inbox — автономна розробка через AI-агента'

Джерело: planning/agent-inbox.md

Agent Inbox MVP (Tier 1)

Мотивація: масштабування розробки без постійної участі власника; особливо критично в період відсутності (армія). Клієнти не чекають тижнями. Чому відкладено: власник не може зараз приділити час на дизайн і запуск; потрібен фокус-тиждень на побудову Django app agent_inbox + промпти + guardrails. Trigger: перший випадок "клієнт пише листа, а власник недоступний 3+ дні". Або — поява другого розробника, якому можна делегувати побудову самого inbox-ядра. Оцінка: MVP Tier 1 — 1-2 вихідних (Django app + cron + headless Claude + email). Tier 2 — +тиждень (dev deploy, approval flow).

AI-powered customer reply

Мотивація: після fix — автовідповідь клієнту з поясненням "що ми виправили, де перевірити". Залежність: Agent Inbox MVP.

Автокласифікація дублікатів

Мотивація: два клієнти пишуть про один і той самий баг — агент має звʼязати з існуючим issue, а не створювати новий. Залежність: Agent Inbox MVP + embeddings на body.


'Аддон «Прохідна / Вагова» — концепція та архітектура'

Джерело: planning/gatehouse-plugin.md

Real-time ANPR з комерційною камерою

Мотивація: прохідна сама розпізнає номер авто без оператора. Чому відкладено: інтеграції з Hikvision / Axis SDK — окремий sprint, MVP закриває потреби з ручним вводом номера. Trigger: клієнт із потоком >50 заїздів/день — ручний ввід стає bottleneck.

Зернові коефіцієнти якості

Мотивація: елеватор знижує вагу прийому за вологість і сміттєвість — це не просто net=брутто−тара. Чому відкладено: потребує окремої лабораторної моделі (QualityCheck з пробами); зараз — простий net. Trigger: перший клієнт-елеватор з реальним лабораторним процесом.

Інтеграція зі стороннім СКД (Bolid / Sigur / Honeywell)

Мотивація: великі підприємства вже мають готове ПЗ контролю доступу. Чому відкладено: окремий plugin на базі Gatehouse — Sigur/Bolid API різні. Trigger: клієнт з установленим СКД, який хоче синхронізацію в DOP-табель.

Self-service driver kiosk

Мотивація: водій сам реєструється на в'їзді через планшет — оператор не потрібен. Чому відкладено: UX і захист від зловживань (фото, OTP, верифікація номера). Trigger: клієнт з 24/7 нічними заїздами без постійного оператора.

Vertical appGrainElevator

Мотивація: силоси, тарифи зберігання, mixing partii, expedition — повноцінний elevator-модуль. Чому відкладено: до появи реального клієнта-елеватора це гадання на гущі. Trigger: перший клієнт-елеватор з потребами понад «зважити + GR».

Vehicle gate QR-tracking всередині території

Мотивація: наклейка з QR — не лише на гейті, а на постах розвантаження, миття, зважування. Кожен пост — checkpoint. Чому відкладено: Sprint 4 робить базовий bridge до Logistic ContainerVisit; повноцінний multi-checkpoint workflow — наступна ітерація. Trigger: клієнт з територією 5+ постів і потребою trace-маршруту авто.

'Multi-CoA / Parallel Ledgers — реалізація і прийняті рішення'

Джерело: planning/multi-coa-implementation.md

Технічні борги після Phase 5/8/9

  • DocumentOperation + JournalEntry merge. Зараз два окремих документи з різною post-семантикою (N PostingGroup vs 1 multi-leg). Альтернатива — один документ з прапорцем multi_leg: bool, що міняє поведінку post. Зменшує меню, але вимагає аудита всіх існуючих use-cases і UI зі складним станом. Тригер: користувацький запит «не розумію, чим вони відрізняються» від >1 клієнта.
  • Manufacturing 4-leg amount mismatch. L1 verify виявляє 80 розходжень: group.amount = одна нога, sum_debit = вдвічі більше. manufacturing_service.py створює 4-leg PostingGroup, де amount має дорівнювати загальному дебету. Окрема таска для виправлення сервісу.
  • Dashboard reconciliation badge. На головному екрані банер з overall_status + лічильником issues, що споживає /accounting/reconciliation-status/. Зараз доступно лише через /settings → Бухгалтерія (адон) (картка з тим же станом).
  • L4/L5 reconciliation rivni. Поточні L1-L3 перевіряють баланс і drift. L4: document.amount == sum(PostingGroup.amount) через document.get_total() (потребує універсального інтерфейсу). L5: sum(InventoryJournal.amount) == sum(PostingEntry by inventory_account) за період.
  • Cron verify_postings daily. Інтеграція з backend scheduler + email власнику при появі drift. Зараз — лише ручний запуск.
  • IFRS BO templates. IFRS scaffolding (COA + Ledger) готове, але BusinessOperationTemplate(standard='ifrs') не створено. Тригер: перший клієнт із IFRS-вимогою.
  • Production-flow для UA. Закупка сировини у PCG = Dt 6000 / Ct 4000 (одразу витрата). У UA правильніше: Dt 201 / Ct 631 (актив), а собівартість виникає окремо при списанні. Зараз mirror зберігає PCG-семантику. Потрібні окремі UA-only BO або BusinessOperationRule engine.
  • BusinessOperationRule engine (audit-concepts § 10). Умовний вибір BO за категорією товару / складом / Item.valuation_class. Тригер: клієнт зі складною номенклатурою, де одна BO «Реалізація» → 3 різні (товари / послуги / трейд).
  • extra_legs: JSONField у BusinessOperationTemplate. Для зарплат і складних проводок (Dt 92 / Ct 661 / Ct 642 з розщепленням податків) — щоб уникнути окремого vat_debit_account поля та виходити на multi-leg-by-default templates.
  • Офіційний XML-export ПСБО Ф1/Ф2 у M.E.Doc. Поточні UA-структури — каркас. Експорт у формат J0100108/J0100208 потребує методолога з UA-обліку.

Загальні ідеї без конкретного тригера

  • Cross-ledger reconciliation report — окремий звіт «Зведена різниця між стандартами» з пояснювальною логікою (FX курсова різниця, IFRS adjustments, тощо).
  • Ledger-aware Trial Balance — поки звіт показує всі рахунки одного стандарту; corner case — коли один tenant веде НП(С)БО і IFRS, цікаві обороти між ними.
  • Audit log для BusinessOperationTemplate — хто змінив рахунок, коли, чому.

'Звіти і друковані форми — стратегія та план реалізації'

Джерело: planning/reports-and-print-strategy.md

User-facing cube / pivot (ad-hoc аналітика)

Мотивація: керівник сам будує зріз у браузері — перетягує виміри (Менеджер × Регіон × Категорія × Період) і міри (Сума / Кількість / Маржа) без звернення до розробника. Відпадає цикл «задача → нова ReportDefinition → release» для разових аналітичних запитів. Це природний наступний рівень поверх фіксованих звітів і одна з довгострокових цілей DOP.

Чому відкладено: проектувати cube без реального кейсу = гадати на здогад. Модель даних (виміри/міри), semantic layer, pivot-UI — разом тижні роботи, а шанс вгадати «той самий» зріз, який попросить клієнт, — низький. Зараз ReportFramework + SQL aggregation покриває всі фіксовані звіти.

Trigger (будь-що з цього): 1. Керівник ≥2 рази за місяць просить однотипні ad-hoc зрізи, яких немає у фіксованих звітах. 2. Обсяги JournalEntryLine / InvoiceLine переростають ~500k рядків на tenant — динамічні розрізи починають тормозити на голому SQL. 3. Клієнт явно просить Power BI-подібний dashboard або self-service аналітику в браузері.

Стартовий план (коли тригер спрацює): - DuckDB поверх існуючої Postgres/SQLite (не pandas — columnar engine ефективніший для серверних агрегацій, SQL-сумісний, легковаговий). - Один конкретний куб першим — найімовірніше «Продажі» (виміри: партнер, товар, менеджер, дата; міри: сума, кількість, маржа). - Простий pivot-UI на frontend (drag-and-drop полів у рядки/колонки/фільтри/значення). - Не будувати одразу універсальний semantic layer на всі домени — це пастка. Semantic layer з'являється після 3-го куба, коли видно повторювані патерни.

Бажані технології для оцінки: DuckDB (engine), Cube.js або dbt Metrics (semantic layer), PivotTable.js / AG Grid Pivot / кастомний Mantine-компонент (UI).

Migrate решту print doc-types на Print Framework

Мотивація: базові Invoice, GoodsShipment, Waybill уже на новому фреймворку через skill new-print-template. Решта (PurchaseInvoice, PurchaseOrder, GoodsReceipt, IncomingPayment, OutgoingPayment, JournalEntry, TransportInvoice, Manufacturing) поки покривається універсальним UniversalPrintContract.

Чому відкладено: UniversalPrintContract автоматично обслуговує будь-який TransactionModel без коду. Кастомний контракт потрібен лише коли клієнт вимагає специфічного layout / state / branding для конкретного документа.

Trigger: клієнтський запит на конкретний doc-type («у нас має бути такий-то блок у видатковій»). Або юридична вимога нового формату (e.g. зміна форми ПКО / РКО).

Fleet-type кастомні Purchase Invoice / GoodsReceipt

Мотивація: для fleet-клієнтів закупки палива / запчастин мають специфіку (vehicle reference, mileage attach). Чому відкладено: universal формa покриває базовий випадок. Кастом потрібен лише для cross-cutting fleet-полів. Trigger: перший fleet-клієнт, який вимагає прив'язку GoodsReceipt до vehicle.

'Three-Layer Documentation Strategy'

Джерело: planning/three-layer-docs-strategy.md

Фаза 4 — VitePress split + CF Access для ai-docs.eswf.dev

Мотивація: AI Portability Bundle (docs/ai/) — це IP проєкту (можливість одним промтом відтворити DOP на іншому стеку). Щоб команда могла зручно читати його у браузері з пошуком/навігацією, але назовні він не витік — потрібен окремий приватний хост.

Що робити: - Один VitePress, два режими через AI_BUILD: - npm run docs:build → публічна версія (User Manual + Dev Articles), srcExclude: ['ai/**']. - AI_BUILD=true npm run docs:build:ai → приватна версія, srcExclude: ['user/**', 'dev/**']. - Деплой приватної версії на ai-docs.eswf.dev. - Закрити Cloudflare Access (Google SSO для команди). - Технічна заготовка вже є у § «Видимість / auth» цього документа.

Чому відкладено: інфраструктурний крок без блокерів для розробки. Bundle консумується через dist/dop-port-bundle/ і npm run ai:bundle — браузерна версія потрібна тільки для зручності, не для функціональності.

Trigger: (a) перший запит на ручний перегляд bundle у браузері від члена команди / web Claude; (b) онбординг другого розробника (потрібен зручний доступ); (c) підготовка до зовнішнього POC-порту з реальним підрядником.

'Мобільний додаток комірника — інвентаризація зі смартфоном'

Джерело: planning/warehouse-mobile-app.md

Warehouse Mobile App MVP

Мотивація: комірники без зручного scan-based інструмента — інвентаризація вручну в Excel, помилки при прийманні, переміщення без трасування. Вже є два працюючі native-mobile (Driver, Sales Rep) — інфраструктура (WatermelonDB sync, JWT, push-notifications) перевикористовна. Чому відкладено: зараз пріоритет на пропрацювання Driver App (видає помилки) та Sales Field. Додатковий native-mobile — це окремий sprint (2-3 тижні: проєкт RN + WatermelonDB schema + 3 базові screen-и + sync-endpoints). Trigger: перший клієнт із складським процесом (запит на інвентаризацію або приймання по сканеру). Або стабілізація Driver App + Sales Rep до production-ready. Оцінка: MVP — 2-3 тижні з нуля, або 1 тиждень якщо стартувати з форку mobile-sales/.

Інтеграція з принтером етикеток

Мотивація: після приймання — друк етикеток партій / комірок прямо з додатка. Залежність: Warehouse Mobile MVP + ADR hardware-integration.md (BT-друк).

Voice picking

Мотивація: руки зайняті — голосові команди для confirm/skip/qty. Залежність: Warehouse Mobile MVP + Web Speech API / native voice SDK.

❔ Без категорії

'Backup & Recovery — резервне копіювання бази даних'

Джерело: dop/features/backup-recovery.md

Частина 1 — MVP для desktop (SQLite + local folder)

Мотивація: покрити критичний ризик «бухгалтер втратив БД після збою живлення» одразу при першій desktop-поставці. Скоуп: - Management command dop_backup для SQLite. - UI в Admin Tools: Frequency/Time/Retention + Destination=local folder + Test/History/Restore. - Self-healing при старті launcher.exe (integrity check + recovery modal). - Default destination: %USERPROFILE%\Documents\DOP-Backups\. Чому відкладено: ще немає жодної desktop-інсталяції; без реальних користувачів неможливо валідувати UX. Trigger: перша desktop-інсталяція бухгалтеру (разом з desktop-installer.md MVP).

Частина 2 — PostgreSQL + cloud destinations (S3, OneDrive, GDrive)

Мотивація: для production-поставки на Render / власному сервері локальна тека безсенсу — треба хмара. Скоуп: - pg_dump варіант команди. - S3 destination (через boto3). - OneDrive / Google Drive через OAuth (або просто «папка синхронізована клієнтом»). - Celery Beat scheduler. Чому відкладено: поки production-деплоймент — тільки на Render з їхніми автоматичними Postgres-бекапами; DOP-level бекап не потрібен, поки немає self-hosted клієнтів. Trigger: перший self-hosted production customer.

Частина 3 — Encryption + audit compliance

Мотивація: GDPR / комерційні клієнти вимагають encrypted backups і повний audit trail. Скоуп: - AES-256-GCM перед завантаженням у destination. - Master key в OS keyring (через keyring Python lib). - AuditLog records для всіх backup/restore events. - Anonymize-on-export для PII. Чому відкладено: без реальних клієнтів compliance вимоги невідомі. Trigger: перший paid customer з compliance вимогами (GDPR, ISO 27001).

Частина 4 — Per-tenant backup/restore

Мотивація: у SaaS-моделі треба вміти відновити одного клієнта без впливу на решту. Скоуп: - Кастомний dumpdata фільтр по tenant_id. - Restore-flow з merge (новий tenant_id → уникнення колізій). - UI: вибір конкретного tenant при backup/restore. Чому відкладено: DOP поки single-tenant на інсталяцію; multi-tenant SaaS — не пріоритет. Trigger: multi-tenant SaaS deployment (коли 1 інсталяція обслуговує >1 клієнта).

Частина 5 — Point-in-Time Recovery (PITR)

Мотивація: можливість відкотитись на довільну секунду, не на найближчий щоденний snapshot. Скоуп (PostgreSQL): WAL archiving + pg_basebackup + recovery.conf / recovery_target_time. Скоуп (SQLite): WAL-mode + continuous .wal shipping (складніше — нативно не підтримується). Чому відкладено: overkill для бухгалтерського ERP; hourly snapshots достатньо. Trigger: клієнт з вимогою RPO < 1 година.

Частина 6 — Cross-engine migration tool

Мотивація: бухгалтер пробував DOP на SQLite-demo, хоче перенести дані у production PostgreSQL. Скоуп: management command dop_migrate_engine --from=sqlite --to=postgres з merge PKs + FK-reconciliation. Чому відкладено: поки немає конверсій demo → prod у реальному кейсі. Trigger: перший клієнт робить апгрейд з demo на self-hosted production.

'Desktop Installer — поставка DOP кінцевому користувачеві'

Джерело: eswf/infrastructure/desktop-installer.md

Частина 1 — MVP інсталятор для одного користувача

Мотивація: відправити бухгалтеру DOP-Setup.exe, щоб він за 5 хвилин мав робочий DOP на машині без єдиної CLI-команди. Чому відкладено: поточна поставка (docker image через .tar) працює для технічних колег; MVP інсталятор — роботи на 1–2 дні, але не блокує нічого критичного. Trigger: перший реальний бухгалтер/менеджер, якому треба дати DOP для оцінки.

Частина 2 — Auto-update через private registry

Архітектура зафіксованаupdate-delivery.md. Реалізація відкладена. Trigger: >3 інсталяцій у зовнішніх користувачів, перша скарга на «як оновитись».

Частина 3 — Code signing + SmartScreen-compliant installer

Мотивація: без підпису Windows SmartScreen блокує .exe як «Unknown publisher» — непрофесійно виглядає для продажу. Чому відкладено: EV-сертифікат $300–500/рік, потрібен тільки коли почнемо продавати. Trigger: комерціалізація DOP (платні тарифи, реальні продажі).

Частина 4 — Mac / Linux поставка

Мотивація: не всі користувачі на Windows. Чому відкладено: 95%+ цільової аудиторії (українські бухгалтери) — Windows. Trigger: запит від не-Windows користувача.

'Update Delivery — доставка оновлень DOP клієнтам'

Джерело: eswf/infrastructure/update-delivery.md

Частина 1 — LTS-канал

Мотивація: держустанови / великі бухгалтерії хочуть «один реліз на рік + патчі безпеки», без MINOR-апдейтів. Чому відкладено: немає аудиторії з такими вимогами; додавання каналу — простий manifest + reлiз-policy, не блокує ніщо. Trigger: перший клієнт зі SLA на LTS у договорі.

Частина 2 — Background data migrations (без maintenance window)

Мотивація: довгі data migrations (>5 хв) роблять апгрейд незручним — клієнт чекає у вікні «оновлюємо». Чому відкладено: на поточних обʼємах даних найдовші міграції <30 с; інфраструктура RunPython порцiями вимагає окремого фреймворку. Trigger: перший клієнт з БД >10 GB або скарга на «довге оновлення».

Частина 3 — Delta-оновлення (image layer diff)

Мотивація: повний образ ~600 MB → за рік клієнт викачує 7 GB на 12 апдейтів. Delta дала б ~50 MB на апдейт. Чому відкладено: Docker layer caching уже частково вирішує (нові шари — лише змінені); справжня delta — окрема технологія (e.g. casync). Trigger: скарги на трафік / повільне оновлення з мобільного інтернету.

Частина 4 — Push-нотифікації про реліз (WS/SSE)

Мотивація: замість polling раз/добу — миттєва нотифікація через WebSocket з api.eswf.dev. Чому відкладено: polling достатньо для каденції раз/місяць. Trigger: kill-switch епізод де доба-затримки виявилась критичною.

Частина 5 — K8s operator для self-hosted enterprise

Мотивація: один-нодовий self-hosted виходить дешево, але enterprise-клієнти хочуть HA + rolling upgrade у K8s. Чому відкладено: немає такої аудиторії, дизайн HA — окрема велика тема. Trigger: перший корпоративний клієнт зі ставкою на K8s.

Частина 6 — Per-tenant feature flags

Мотивація: ввімкнути новий ризикований модуль (e.g. AI-агент) лише для частини tenant-ів каналу stable без окремого каналу. Чому відкладено: немає інфраструктури flags (рішення: GrowthBook / Unleash / власне). Канали поки покривають 80% потреби. Trigger: перший випадок «треба випустити фічу тільки для tenant X для тестування».