Аудит ESWF / DOP — пост-MVP era¶
Дата: 2026-04-22 Автор: Claude Code Попередній: audit-2026-04-21.md — закритий 2026-04-22, всі базові фази виконано. Область: delta-аудит тільки нових артефактів (Phase D/E/F) + перегляд незавершеного backlog. Методологія: код-ревʼю нових 4 backend apps (
hrm,production,baf_sync,budgeting) + сервісних розширень (crm/services,essentials/services/journal_entry,essentials/services/depreciation) проти усталених патернів проєкту.
0. TL;DR¶
Стан після Phase A → F-4:
- 21 backend app (+4 нові MVP), 143 backend tests passing, 80 frontend tests.
- Закриті: модулі hrm, production, baf_sync, budgeting + Manual JournalEntry + FixedAsset + 4 CRM analytics endpoints + 4 нові frontend reports (Trial Balance, P&L Drill-Down, ПСБО Form 1, Budget Variance).
- Документація синхронізована (10 файлів оновлено / 2 створено).
Топ-5 знахідок цього мікро-аудиту:
- 🐛 Phase D — пропущений
super()у CRM overrides.ActivityViewSet.perform_createіDealViewSet.perform_updateне викликаютьsuper(), тому оминаютьTenantFilterMixin-логіку: tenant injection, created_by/updated_by, auto-numbering, audit log. Тести проходять, бо обходять API через ORM. Дрібний, але реальний баг — фікс ~5 рядків. - ⚠️ Production MVP — розрив зі StockTransaction.
complete_work_orderпише напряму уPostingGroup, не оновлюючиStockTransaction/Batch/ItemWarehouseStock. Як наслідок — звіт «Inventory valuation» і «WorkOrder completion» можуть розходитись. Документовано вproduction-bom/README.md, але потребує rounded fix перед production. - ⚠️ HRM MVP — спрощений UA-tax. Єдиний
tax_rate_pctна gross — фактично placeholder. Реальний UA payroll: PDFL 18% + military 1.5% + ESV 22% з нарахування. Готовність до production вимагає або (a) розгортання повної UA tax-моделі або (b) явного маркеру «Demo-tax mode» у UI. - ⚠️ BAF Sync — fake transport only. Реальний
httpx.Clientне реалізовано; всі production-екземпляри сидять у dry-run. Інтеграція не може бути ввімкнена для реального BAF без додаткових 30-50 рядків коду. - 🧪 Frontend tests gap. 9 нових frontend-компонентів (5 dashboards + 4 forms) — 0 тестів. Існуючі 80 vitest-тестів покривають базову інфраструктуру (stores, API client, ErrorBoundary, LoginPage), але не нові business-screens.
Решта детально — у §§ 1-6.
1. Що змінилось з 2026-04-21 (delta)¶
1.1 Backend apps¶
| App | До | Після |
|---|---|---|
core, essentials, fleet, transport, registers, crm, eswf_chat, news, shop, mobile_api, sales_mobile_api, sales_field, medoc_exchange |
17 | 17 (без змін у списку) |
hrm |
— | +4 моделі (Position, Employee, PayrollPeriod, PayrollSlip) |
production |
— | +3 моделі (BOM, BOMLine, WorkOrder) |
baf_sync |
— | +3 моделі (Settings, Mapping, Log) |
budgeting |
— | +2 моделі (Budget, BudgetLine) |
| Разом | 17 | 21 |
1.2 Нові моделі в існуючих app-ах¶
essentials.JournalEntry+JournalEntryLine— Phase E.essentials.FixedAsset+DepreciationEntry— Phase E.essentials.EssentialsModuleSettings.default_*_operation× 4 — Phase A (вже були в коді, але не експоновані).
1.3 Нові endpoints¶
/api/v1/essentials/reports/trial-balance/ (Phase B — frontend)
/api/v1/essentials/reports/profit-loss/drill-down/
/api/v1/essentials/reports/psbo-form1/
/api/v1/essentials/journal-entries/ (Phase E)
/api/v1/essentials/journal-entry-lines/
/api/v1/essentials/fixed-assets/ (Phase E)
/api/v1/essentials/fixed-assets/{id}/{depreciate,dispose}/
/api/v1/essentials/fixed-assets/run-monthly/
/api/v1/essentials/depreciation-entries/
/api/v1/crm/analytics/{funnel,stage-duration,win-loss,manager-activity}/ (Phase D)
/api/v1/hrm/{positions,employees,payroll-periods,payroll-slips}/ (Phase F-1)
/api/v1/production/{boms,bom-lines,work-orders}/ (Phase F-2)
/api/v1/baf-sync/{settings,run,mappings,logs}/ (Phase F-3)
/api/v1/budgeting/{budgets,budget-lines}/ (Phase F-4)
/api/v1/budgeting/budgets/{id}/variance/
1.4 Нові frontend-компоненти¶
| Категорія | Файл |
|---|---|
| Reports | TrialBalanceReport.tsx, PnlDrillDownReport.tsx, PsboForm1Report.tsx, BudgetVarianceReport.tsx |
| Forms | JournalEntry/JournalEntryPage.tsx, FixedAsset/DepreciationRunner.tsx, BAFSync/BAFSyncPage.tsx |
| Dashboards | CRM/SalesFunnelDashboard.tsx, CRM/ManagerActivityDashboard.tsx |
| Settings | розширений AccountingSettings.tsx (4 default-BO selects) |
1.5 Тести¶
| Категорія | Було | Додано | Стало |
|---|---|---|---|
| Backend (pytest) | 86 | +57 (11 CRM + 19 JE/FA + 9 HRM + 7 Production + 7 BAF Sync + 4 Budgeting) | 143 |
| Frontend (vitest) | 80 | 0 | 80 |
| Mobile | 0 | 0 | 0 |
2. Знахідки за результатами імплементації¶
2.1 🐛 [BUG] Phase D — пропущений super() у CRM overrides¶
Де: backend/crm/views.py, ActivityViewSet.perform_create, DealViewSet.perform_update.
class ActivityViewSet(TenantFilterMixin, viewsets.ModelViewSet):
def perform_create(self, serializer):
from crm.services import record_activity
instance = serializer.save() # ❌ оминає TenantFilterMixin
record_activity(instance)
Що саме оминається (master_data.py:87-126):
- ❌ tenant injection (Activity створюється без tenant — впаде на CONSTRAINT тільки якщо tenant вимагається в моделі, інакше тихий tenant=NULL leak).
- ❌ created_by/updated_by injection.
- ❌ Auto-generated number для TransactionModel.
- ❌ audit_service.log() — ця активність не з'являється в AuditLog.
Чому тести проходять: test fixtures створюють Activity напряму через ORM (Activity.objects.create(tenant=..., number=..., created_by=...)), оминаючи API. Потрібен інтеграційний test, що POST-ить через auth_client.post('/api/v1/crm/activities/', {...}).
Фікс (~5 рядків):
def perform_create(self, serializer):
from crm.services import record_activity
super().perform_create(serializer) # ← робить tenant + created_by + number + audit
record_activity(serializer.instance)
Те ж саме для DealViewSet.perform_update — викликати super().perform_update(serializer) ДО запису stage transition.
Пріоритет: 🟠 P1 (тихий баг — невидимий tenant leak).
2.2 ⚠️ Production MVP — розрив зі StockTransaction¶
Де: backend/production/services/completion.py.
complete_work_order створює PostingGroup + PostingEntry напряму, але:
- ❌ Не створює StockTransaction (рух товарів на складах).
- ❌ Не оновлює ItemWarehouseStock (залишки).
- ❌ Не списує / не оприбутковує Batch (партіонний облік).
Наслідок:
- Звіт BalanceSheet (через PostingGroup → 1100) покаже зміну вартості inventory.
- Звіт InventoryValuation (через ItemWarehouseStock) покаже інше.
- Розбіжність між finance- і inventory-картками.
Документовано: production-bom/README.md явно перелічує цю обмеженість як "MVP scope".
Фікс (правильний):
1. У complete_work_order після кожного PostingEntry зі quantity створювати StockTransaction (consumption: type='write_off' на input_warehouse; production: type='receipt' на output_warehouse).
2. Через batch_service оновлювати Batch.remaining_qty для FIFO write-off.
Пріоритет: 🟡 P2 (поки немає виробничого клієнта, MVP працює; перед production-deploy для виробництва — обов'язково).
2.3 ⚠️ HRM MVP — placeholder UA tax model¶
Де: backend/hrm/services/payroll.py:compute_slip.
Один FK tax_payable_account + один tax_rate_pct — це різко спрощений сценарій. Реальна UA-зарплата:
| Вирахування | Ставка | Кому платять | Куди записати |
|---|---|---|---|
| ПДФО (Personal Income Tax) | 18% від gross | ДПС | 4421 (Розрахунки за ПДФО) |
| Військовий збір | 1.5% від gross | ДПС | 4422 (Військовий збір) |
| ЄСВ (роботодавець, нарахування) | 22% від gross | ПФУ | 6450 + 4427 |
| Утримання за пенс. внески | — | — | — (зараз 0) |
Фікс: PayrollSlip має 4-5 окремих полів tax_*_amount + 4-5 FK на CoA + service expand на 4 окремих posting-leg-и. Або винести у конфігурацію PayrollTaxSetting (per tenant, per year — щоб ставки можна було змінювати з історією).
Пріоритет: 🟡 P2 (демо-моделі достатньо для презентацій; production-клієнт UA — обов'язково).
2.4 ⚠️ BAF Sync — Fake transport, без реального httpx¶
Де: backend/baf_sync/services/sync.py.
Реалізовано:
- BAFTransport Protocol — interface.
- FakeTransport — для тестів і dry-run-проксі.
Не реалізовано:
- HttpxTransport — реальний httpx.Client.post(url, json=payload, headers={'Authorization': f'Bearer {token}'}, timeout=30).
- Retry / backoff.
- Connection pooling.
- Error mapping (5xx → retry, 4xx → fail, 401 → reauth).
Фікс (~30-50 рядків):
@dataclass
class HttpxTransport:
def send(self, entity_type, payload, base_url, auth_token):
url = f'{base_url}/{entity_type}'
try:
r = httpx.post(url, json=payload,
headers={'Authorization': f'Bearer {auth_token}'},
timeout=30)
r.raise_for_status()
return BAFResponse(success=True, baf_uuid=r.json().get('uuid', ''))
except httpx.HTTPStatusError as e:
return BAFResponse(success=False, detail=f'HTTP {e.response.status_code}: {e.response.text[:200]}')
except httpx.RequestError as e:
return BAFResponse(success=False, detail=f'Network: {e}')
Plus mechanism wiring: ViewSet BAFSyncRunView вибирає transport на основі settings.dry_run.
Пріоритет: 🟡 P2 (поки немає клієнта з BAF — MVP-демо достатньо).
2.5 🧪 Frontend tests gap¶
9 нових бізнес-компонентів — 0 тестів:
- SalesFunnelDashboard.tsx, ManagerActivityDashboard.tsx
- JournalEntryPage.tsx, DepreciationRunner.tsx, BAFSyncPage.tsx
- TrialBalanceReport.tsx, PnlDrillDownReport.tsx, PsboForm1Report.tsx
- BudgetVarianceReport.tsx
Існуючі 80 тестів покривають інфраструктуру (api/client, store/auth, ErrorBoundary), але не business-screens.
Опціональний фікс (vitest + RTL + msw): - Mock API через msw для кожного компонента. - Smoke-render + click "Generate"/"Save" → перевірка ключових елементів у DOM. - ~50-100 рядків на компонент × 9 = ~600 рядків test-коду.
Пріоритет: 🟢 P2-P3 (нижче за backend tests; feature complete = перевірка ручна, регресії ловлять бекенд-тести через API contracts).
2.6 Інші дрібні знахідки¶
| # | Що | Де | Пріоритет |
|---|---|---|---|
| 6 | Жоден з 4 нових app-ів не має seed-команди для демо-даних |
hrm/, production/, baf_sync/, budgeting/ |
🟢 P3 — для DemoDataset перед презентаціями |
| 7 | JournalEntryPage.tsx робить N+1 PATCH (sync рядків через цикл, по одному API call на лінію) |
JournalEntryPage.tsx |
🟢 P3 — перейти на bulk endpoint при перших 100+ рядкових JE |
| 8 | compute_variance(budget) робить N запитів до IncomeExpenseJournal (по одному на BudgetLine) |
budgeting/services.py |
🟡 P2 — при сотнях рядків бюджету буде повільно. Фікс: один query з GROUP BY (account_id, EXTRACT(month FROM date)). |
| 9 | JournalEntryLineSerializer приймає entry з payload, але також прив'язується через ViewSet — ризик невідповідності |
accounting_extra.py |
🟢 P3 — перевести на nested-serializer на JournalEntrySerializer |
| 10 | BAFSyncSettings.auth_token зберігається у plain text у БД |
baf_sync/models/settings.py |
🟠 P1 — зашифрувати через cryptography (Fernet) перед prod-deploy |
3. Що НЕ змінилось з 2026-04-21 (повторно — досі deferred)¶
| Що | Звідки | Поточна позиція |
|---|---|---|
| CI/CD (GitHub Actions, production Dockerfile, pre-commit) | audit-2026-04-21 §10 Фаза 2 | ⏸️ Свідомо відкладено до колективної розробки. Trigger: перший зовнішній PR / prod-deploy. |
| God-components refactor | audit-2026-04-21 §10/13 | ⏸️ Активна розробка створює ризик конфліктів. Trigger: стабілізація 1+ місяць без значущих змін у ChatPage, AdminToolsPage, ChatDrawer, ETTNPage, DevToolsPage, SalesFieldManager. |
| Mobile tests | audit-2026-04-21 §6 | ⏸️ 0 tests для mobile/, mobile-sales/. Не пріоритет, бо мобільні застосунки relatively stable і не змінювались. |
| Logistic backend | audit-2026-04-21 §1.1 | 🧩 Свідомо за межами community-build. Зараз — еталон exclusion-flow, не fault. |
| Consolidator | audit-2026-04-21 §8 | 🔮 Backlog — немає клієнта з groupp consolidation. |
| Headless e-commerce engine | audit-2026-04-21 §1.4 | 🔮 Backlog — Store Manager (DOP-license-store) покриває поточні потреби. |
| Client Portal B2B розширення | audit-2026-04-21 §1.4 | 🔮 Backlog — поточний Next.js frontend/shop/ достатній для MVP. |
4. План робіт на наступний цикл¶
Пріоритет від найшвидшого / найдешевшого до глибшого. P0 = цього тижня, P1 = цей місяць, P2 = квартал, P3 = backlog.
Фаза G — Cleanup після MVP-ери (1-2 дні, P0/P1)¶
Мета: закрити tech-debt-знахідки §2, не додаючи нових фіч.
-
🐛 Виправити Phase D super()-bug (P1, ~10 рядків): додати
super().perform_create()/super().perform_update()уActivityViewSet/DealViewSet. Додати інтеграційний тест, що перевіряє: POST/api/v1/crm/activities/створює Activity з правильним tenant + audit_log entry. -
🔐 Зашифрувати
BAFSyncSettings.auth_token(P1): додатиcryptography.fernet.Fernet, ENV-varBAF_TOKEN_SECRET. Migration з конвертацією існуючих plain-text-значень (якщо є). -
⚡
compute_variance— bulk-query (P2): замість N запитів — один зGROUP BY (account_id, EXTRACT(month))+JOINна BudgetLine. Покрити test'ом на 100+ рядкових бюджетах. -
📦 Seed-команди для нових app-ів (P3):
seed_hrm,seed_production,seed_budgeting(генерують 5-10 типових записів для демо).baf_sync— без seed (треба реальний BAF).
Фаза H — Зміцнення accounting основи (1-2 тижні, P1)¶
-
💼 Production MVP — bridge with StockTransaction (P2):
complete_work_orderпісля PostingGroup має створитиStockTransaction(write_off на input_warehouse, receipt на output_warehouse) + апдейтItemWarehouseStock. Інтеграційний test «Production cycle» що перевіряє consistency черезinventory/valuation/endpoint vsBalanceSheet-1100. -
🇺🇦 HRM MVP — реалізація 4-leg UA tax (P2): розширити
PayrollSlip4 полямиpdfl_amount,military_amount,esv_employee_amount,esv_employer_amount+ 4 FK на CoA.compute_slip= ПДФО18% + Військ1.5% + ЄСВ22%/нарахування. Servicepost_slipстворює 4 окремих posting-leg-и. Або (краще) винести уPayrollTaxConfigper tenant per year з історією ставок. -
🌐 BAF Sync — реальний
httpx.Client(P2): додатиHttpxTransport(~30 рядків). Wire-in уBAFSyncRunView:transport = HttpxTransport() if not settings.dry_run else None. Mock-test черезhttpx.MockTransport.
Фаза I — End-to-end перевірки (3-5 днів, P2)¶
-
🧪 Frontend smoke-tests (P2-P3): для 9 нових business-компонентів — vitest + RTL + msw mock. Тільки smoke (render + один-два user-event), без deep-coverage.
-
🔁 Integration tests (P2): для кожного нового app — кінцевий test-сценарій (наприклад, для HRM: створити Position → Employee → Period → Slip → POST compute → POST post_document → перевірити PostingGroup в звіті Trial Balance).
Фаза J — Нові фічі (квартал+, P2-P3)¶
-
⏰ JournalEntry templates / recurring — вирішення місячного резерву через одноразову проводку, що автоматично повторюється кожен місяць. Trigger: запит CFO про resource accruals.
-
📊 Budget approval workflow —
BudgetApprovalмодель + 3-step approval (draft → submitted → approved/rejected). Trigger: запит у multi-stakeholder-команді. -
📈 Pipeline History dashboard в CRM — окремий drill-down звіт з фільтрами по менеджеру / клієнту / стадії. Trigger: запит CRM-команди на «conversion-кей-метрики».
-
🔄 BAF Sync — pull-flow (зараз тільки push): отримання змін з BAF → апдейт DOP-довідників + конфлікт-резолюція (last-write-wins / manual queue).
-
🏭 Production — multi-level BOM + WIP costing.
Фаза K — Backlog без планової дати (P3)¶
- 🔮 Consolidator (intercompany elimination).
- 🔮 Client Portal B2B-розширення (statement of account, individual pricing, returns).
- 🔮 Headless e-commerce engine (
backend/ecommerce/з LiqPay, Нова Пошта). - 🔮 VRP (route optimization) для Logistic.
- 🔮 ПСБО Форма 1 → офіційна форма (через
accounting-ua). - 🔮 Tax-accounting у DOP (повний lifecycle ПН в DOP замість M.E.Doc).
5. Метрики (стан на 2026-04-22, друга сесія)¶
| Метрика | До 21-го | 21-го | 22-го | Δ |
|---|---|---|---|---|
| Backend apps | 15 | 17 (+2 plugins) | 21 | +4 нові MVPs |
| Backend tests | 0 | 86 | 143 | +57 (+66%) |
| Frontend tests (ERP) | 80 | 80 | 80 | 0 |
Backend models — essentials |
42 | 42 | 46+ | +JE/JEL +FA +Depreciation |
| Реалізовані horizontal модулі | 4 | 4 | 8 | +HRM, +Production, +Budgeting, +BAF Sync (was integration) |
| Frontend reports | 4 | 4 (+ PartyLedger, Matching) | 8 (+ TrialBalance, PnL Drill, PSBO, BudgetVariance) | +4 |
| Phase 4 нових модулів | — | planned | 4 done MVP | DONE |
| God-components (≥1000 рядків) | 6 | 6 | 6 | 0 (не торкались) |
Документи в docs/ |
60 | 60 | 62 | +2 (journal-entry.md, fixed-assets.md) |
| Documented status mismatch між doc/code | багато | mostly resolved | 0 | resolved |
Test breakdown (2026-04-22)¶
core: 21 tests (TenantFilterMixin, UniversalViewSet, permissions, plugin-exclusion)
essentials: 66 tests (party_ledger 12, reports 21+10, serializers, JE 6, FixedAsset 13)
crm: 11 tests (pipeline_history, services, analytics endpoints)
hrm: 9 tests (compute_slip, post_slip, endpoint smoke)
production: 7 tests (BOM constraint, complete_work_order, cancel)
baf_sync: 7 tests (FakeTransport, dry_run, only_posted, settings)
budgeting: 4 tests (variance computation, period filter, endpoint)
medoc_exchange: 6 tests (existing — Phase 3 tax invoice lifecycle)
─────
TOTAL: 143 passing
6. Рекомендований найближчий крок¶
Старт: Фаза G — швидкі правки (1-2 дні).
Аргумент: §2.1 (super() bug) — тихий tenant-leak, який варто закрити раніше, ніж він проявиться у production. §2.5 (auth_token шифрування) — security hygiene перед першим живим клієнтом BAF Sync. Решта §2.6 — на свій розсуд.
Після Фази G можна або (a) переходити до Фази H (зміцнення Production/HRM), або (b) залишити Phase G як один маленький cleanup-цикл і йти до нових фіч (Фаза J).
7. Глибинний аудит блоків Essentials (додано 2026-04-22)¶
Контекст: раніше ми зробили подібний аудит блоку Покупки в Essentials (тоді він мав лише прихідну накладну). Після порівняння з SAP / Odoo / 1C / Dynamics з'явився повний flow PO → GR → PI з 3-way matching + Quality Control plugin (Receiving Dock → QC Cage → Stock).
Цей аудит застосовує ту саму методологію до решти блоків. Ціль: не просто перерахувати моделі, а критично оцінити чи блок виконує бізнес-функцію (proper posting flow + reports + workflow), або це лише CRUD-заглушки.
Класифікація: ✅ fully wired (post → registers → reports + workflow) · ⚠️ half-wired (часткове posting/reports) · 🟧 stubs only (CRUD endpoints без бізнес-логіки).
7.0 Що знайдено — реальний стан (без wishlist'у)¶
| Блок | Posting service | Реєстри (CashJournal/InventoryJournal/PartyLedger) | Reports / aggregations | Workflow actions | Класифікація |
|---|---|---|---|---|---|
| Sales (Invoice/Shipment/IncomingPayment) | ✅ post_invoice_*, post_incoming_payment |
✅ PartyLedger, CustomerOrderLedger, PlannedPaymentJournal | ⚠️ P&L, BS, PaymentCalendar (без AR aging UI поза PartyLedgerReport) | ✅ post/unpost + recalculate_status + Kanban | ⚠️ half-wired |
| Inventory (Receipt/Shipment/Writeoff/Batch) | ✅ receive_batch/deduct_fifo/reverse_* (WAC + FIFO) |
✅ InventoryJournal + StockTransaction + ItemWarehouseStock | ✅ InventoryValuation (FIFO vs WAC) | ✅ post_document + BatchPickerModal | ✅ fully wired (basic) |
| Bank/Cash (IncomingPayment/OutgoingPayment + Bank Exchange) | ✅ post_incoming_payment/post_outgoing_payment (із 3-way-match-блокуванням) |
✅ CashJournal | ⚠️ CashFlow + PaymentCalendar (без bank reconciliation статусу) | ⚠️ post/unpost + parse-only (не auto-create) | ⚠️ half-wired |
| Payroll (HRM MVP) | ⚠️ compute_slip + post_slip (placeholder UA tax) |
— (тільки PostingGroup) | ❌ NONE | ⚠️ compute + post_document + post_all | 🟧 stubs+ |
| Production (BOM/WorkOrder MVP) | ⚠️ complete_work_order (без StockTransaction!) |
— (PostingGroup без InventoryJournal) | ❌ NONE | ⚠️ complete + cancel | 🟧 stubs+ |
| Fixed Assets (FixedAsset MVP) | ✅ post_depreciation + run_monthly_depreciation |
— (PostingGroup + DepreciationEntry) | ⚠️ З BalanceSheet (через 1100 рах.), без власного asset register | ⚠️ depreciate + run-monthly + dispose (без gain/loss) | 🟧 stubs+ |
Критична знахідка: з 6 блоків — 1 fully wired (Inventory), 2 half-wired (Sales, Bank/Cash), 3 stubs+ (Payroll, Production, Fixed Assets). Користувацька гіпотеза «склад може бути заглушкою» спростована: inventory-сервіси (469 рядків
batch_service.py+ 402 рядкиgoods_receipt_service.py) реалізують справжній FIFO/WAC. Натомість Production MVP дійсно «не виконує своєї функції зі складом» — посту в PostingGroup є, алеStockTransaction/Batch/ItemWarehouseStockНЕ оновлюються (підтверджено §2.2).
7.1 SALES — Order-to-Cash¶
Що реально працює:
- Invoice → planned payment → actual payment → party-ledger sync (через post_invoice_party_ledger + post_incoming_payment_party_ledger).
- GoodsShipment з FIFO write-off + COGS posting.
- recalculate_status синхронізує paid_amount/shipped_amount з пов'язаних документів.
- InvoiceKanbanBoard — візуалізація 8-status workflow (draft / sent / partially_paid / paid / shipped / closed / overdue / cancelled).
- AR aging фактично доступне через PartyLedgerReport (з drill-down).
Gap-таблиця проти SAP/Odoo/1C/Dynamics:
| # | Фіча | SAP SD | Odoo Sales | 1С УТ | Dynamics 365 SCM | DOP зараз | Пріоритет | Trigger |
|---|---|---|---|---|---|---|---|---|
| S-1 | Sales Order як окремий документ перед Invoice (резервування + контроль наявності) | ✅ Sales Order | ✅ Sale Order | ✅ Замовлення покупця | ✅ Sales Order | ❌ Quotation→Invoice напряму | 🟠 P1 | Замовлення на склад > 1 дня |
| S-2 | Customer credit limit + блокування при перевищенні | ✅ | ✅ Credit Limits | ✅ | ✅ | ❌ Поле є (Contract.credit_limit?), не enforced | 🟠 P1 | Перший збиток від невплати |
| S-3 | Returns / Credit Note (повернення від клієнта з reverse FIFO) | ✅ | ✅ Refund | ✅ Повернення | ✅ Sales Return | ❌ NONE (workaround: GoodsWriteoff + Invoice negative) | 🟠 P1 | Перше повернення |
| S-4 | Pricelist scheduling (валідні from-to + multi-tier) | ✅ Condition records | ✅ Pricelist + rules | ✅ Тип цін з історією | ✅ Sales Pricing Hierarchy | ⚠️ ItemPrice без valid_from/valid_to | 🟡 P2 | Регулярні промо |
| S-5 | Discounts (% + abs + cascade + per-line/document) | ✅ | ✅ | ✅ | ✅ | ⚠️ InvoiceLine.discount_pct тільки на лінії | 🟡 P2 | Запит торгової акції |
| S-6 | Sales analytics dashboard (по менеджеру / клієнту / товару / періоду) | ✅ COPA | ✅ Sales analysis | ✅ Аналіз продажів | ✅ Power BI sales | ❌ Тільки P&L (агрегований) | 🟡 P2 | Запит CFO/COO |
| S-7 | AR aging report (current / 30 / 60 / 90 / 120+) | ✅ | ✅ Partner Ledger | ✅ Звіт по дебіторах | ✅ Aging by buckets | ⚠️ PartyLedger показує суми, але без bucket-розкладки | 🟠 P1 | Перший fin.controller |
| S-8 | Statement of Account (акт звірки) | ✅ | ✅ | ✅ | ✅ | ❌ NONE | 🟠 P1 | Перший аудит |
| S-9 | Quotation→Invoice convert + Quotation expiry | ✅ Quotation | ✅ + auto-expire | ✅ КП | ✅ Sales Quote | ⚠️ Quotation в crm/, але convert-to-order не створює Invoice |
🟡 P2 | CRM team workflow |
| S-10 | Recurring/Subscription invoices (auto-create N invoices з шаблону) | ✅ | ✅ Subscriptions | ✅ Підписки | ✅ Recurring billing | ❌ NONE | 🟢 P3 | SaaS-клієнт |
| S-11 | Multi-currency invoice (invoice валюта ≠ tenant base) з FX rate locking | ✅ | ✅ | ✅ | ✅ | ⚠️ Invoice.currency є, але без auto FX-locking | 🟡 P2 | Перший import-клієнт |
7.2 INVENTORY — Stock & Batch Management¶
Update 2026-05-09: P0/P1 gaps з цієї секції закрито у planning/inventory-overhaul-2026-05-09.md. Деталі статусів — нижче в gap-таблиці.
Що реально працює:
- FIFO write-off через batch_service.deduct_fifo (тепер з expiry policy + reservation respect — Phase 9, 2026-05-09).
- WAC perpetual moving average через receive_batch (оновлює ItemWarehouseStock.average_cost).
- StockTransaction як append-only audit log (filterable за item/warehouse) — додано тип TRANSFER (Phase 8).
- 6 стандартизованих звітів через Report Framework: Stock Balance / Inventory Turnover / Item Card / Batch Aging / Batch Movements / Expiring Batches (Phase 5+9).
- BatchPickerModal дзеркалить FIFO на frontend для preview.
- GoodsWriteoff тепер створює PostingGroup (Phase 0 fix — раніше тихо drift'ив).
- InventoryCount документ + from-stock ergonomy action (Phase 4+6).
- StockTransfer документ (Phase 8).
- CurrencyRevaluation документ + інтегровано у Period Close wizard (Phase 7).
- L4 / L5 reconciliation перевіряють cross-domain integrity (Phase 2).
- Batch reservations + expiry policy block_expired_shipment (Phase 9).
Critical gap (закрито 2026-05-09):
- ✅ Inventory Count / Cycle Count документ — реалізовано Phase 4 (InventoryCount + InventoryCountLine, BO Surplus/Shortage).
Gap-таблиця:
| # | Фіча | SAP MM | Odoo Inventory | 1С УТ | Dynamics SCM | DOP зараз | Пріоритет | Trigger |
|---|---|---|---|---|---|---|---|---|
| I-1 | Inventory Count / Cycle Count документ | ✅ Physical Inventory | ✅ Inventory Adjustment | ✅ Інвентаризація | ✅ Counting Journal | ✅ DONE 2026-05-09 (Phase 4) | 🔴 P0 | Перший аудит / квартальна інвентаризація |
| I-2 | Stock Transfer between warehouses (single document) | ✅ Transfer Order | ✅ Internal Transfers | ✅ Переміщення | ✅ Transfer Journal | ✅ DONE 2026-05-09 (Phase 8) | 🟠 P1 | Перший multi-warehouse клієнт |
| I-3 | Reservation (резерв партії під замовлення) | ✅ | ✅ Reserved/Available | ✅ Резервування | ✅ Reservation hierarchy | ✅ DONE 2026-05-09 (Phase 9 — BatchReservation + available_qty; SalesOrder integration — окрема таска) |
🟠 P1 | E-commerce-flow |
| I-4 | Reorder point + reorder quantity + auto-PO suggestion | ✅ MRP | ✅ Reordering Rules | ✅ Параметри номенклатури | ✅ Item coverage | ❌ NONE | 🟡 P2 | Перший production-ready stock manager |
| I-5 | Lot/Batch expiry tracking + alerts | ✅ Batch management | ✅ Lots & Expiry | ✅ Серії | ✅ Lot expiration | ✅ DONE 2026-05-09 (Phase 9 — block_expired_shipment policy + expiring-batches report) |
🟠 P1 | Харчова/фарма |
| I-6 | ABC analysis (за обертом / маржею) | ✅ | ✅ ABC Classification | ✅ ABC-аналіз | ✅ Item Velocity | ❌ NONE | 🟢 P3 | Запит retail/wholesale |
| I-7 | Inventory turnover report + aging slow-movers | ✅ | ✅ | ✅ | ✅ | ✅ DONE 2026-05-09 (Phase 5 — inventory-turnover + batch-aging reports) |
🟡 P2 | Запит фінансиста |
| I-8 | Serial number tracking (унікальні серійники, не партії) | ✅ Serialized stock | ✅ Lots & Serial | ✅ Серії | ✅ Tracking dimensions | ❌ NONE (Batch ≠ serial) | 🟢 P3 | Електроніка/обладнання клієнт |
| I-9 | Кит-set / bundle assembly (без production WO) | ✅ | ✅ Kits | ✅ Комплектація | ✅ Kits / Templates | ❌ NONE | 🟢 P3 | Retail multi-pack |
| I-10 | Multi-UoM (закуповуємо у коробках, продаємо штуками) | ✅ Alternative UoM | ✅ Multiple UoM | ✅ Багато од. виміру | ✅ Multiple UoM | ⚠️ Item.unit єдина | 🟡 P2 | Дистрибутор |
| I-11 | Stock-out alerts (push notification або email) | ✅ | ✅ | ✅ | ✅ | ❌ NONE | 🟢 P3 | E-commerce backbone |
7.3 BANK / CASH¶
Що реально працює:
- Posting incoming/outgoing payment у CashJournal.
- 3-way-matching блокування OutgoingPayment, якщо PurchaseInvoice не пройшла match.
- BankExchangeProcess: parse CSV → preview (БЕЗ автоматичного створення payment-документів — лише UI-helper).
- CashFlow report (Direct Method) + PaymentCalendar (planned vs actual).
Critical gaps: - 🟥 Bank reconciliation документ відсутній. Tobто немає способу: «у виписці є проводка, у DOP — немає; або в DOP є, у виписці — немає». Це типовий end-of-month процес для будь-якого фін.відділу. - 🟥 Internal cash transfer (між касами / з каси на рахунок) — відсутній. Зараз тільки IncomingPayment / OutgoingPayment, що передбачає клієнта/постачальника.
Gap-таблиця:
| # | Фіча | SAP FI | Odoo Accounting | 1С Бух | Dynamics F&O | DOP зараз | Пріоритет | Trigger |
|---|---|---|---|---|---|---|---|---|
| B-1 | Bank Reconciliation документ (matched/unmatched) | ✅ | ✅ Bank Reconciliation | ✅ Виписка банку (повний flow) | ✅ Bank Reconciliation | ❌ Тільки parse, не reconcile | 🔴 P0 | Перший живий клієнт |
| B-2 | Internal Transfer документ (Cashbox→Bank, Bank→Bank) | ✅ | ✅ Internal Transfers | ✅ Переміщення коштів | ✅ Bank Funds Transfer | ❌ NONE (workaround: Out + In вручну) | 🟠 P1 | 2+ касові точки |
| B-3 | Cash Count / Касовий ордер (РКО+ПКО з підписом) | ✅ | — | ✅ Друкована форма ПКО/ВКО | ✅ | ⚠️ IncomingPayment/OutgoingPayment без друкованої форми ПКО/ВКО | 🟡 P2 | UA-аудит |
| B-4 | Bank statement auto-import (формати IBAN/CSV/MT940) | ✅ Multi-format | ✅ + auto-pull from bank | ✅ Клієнт-Банк | ✅ Electronic banking | ⚠️ CSV є, MT940/MTBank/IBAN — NONE | 🟡 P2 | Mass adoption |
| B-5 | FX revaluation на кінець періоду (валютний рах. → переоцінка курсу) | ✅ FX Revaluation | ✅ Currency Revaluation | ✅ Переоцінка валюти | ✅ Foreign Currency Revaluation | ❌ NONE | 🟠 P1 | Перший валютний клієнт |
| B-6 | Payment matching (auto-match payment to invoice by amount/ref) | ✅ Auto-clearing | ✅ Bank Reconciliation matching | ✅ Списання боргу | ✅ Settlement | ⚠️ IncomingPayment.invoice FK є, але без auto-suggest | 🟡 P2 | Bulk payments |
| B-7 | Cash forecast (на наступні N днів, з рахунками planned) | ✅ Cash Position | ✅ Cash Flow Forecast | ✅ Платіжний календар | ✅ Cash Flow Forecasting | ⚠️ PaymentCalendar є, але без forecast > 60 днів | 🟡 P2 | CFO daily |
| B-8 | Cheque/Promissory note tracking | ✅ | ✅ | ✅ Чеки | ✅ Bills of Exchange | ❌ NONE | 🟢 P3 | Експорт-клієнт |
| B-9 | Multi-currency cashbox (одна каса з кількома валютами) | ✅ | ✅ | ✅ | ✅ | ⚠️ Cashbox.currency єдина | 🟡 P2 | Клієнт з валютною касою |
7.4 PAYROLL (HRM)¶
Що реально працює:
- compute_slip: gross = base × days/standard, tax = gross × rate, net.
- post_slip: PostingGroup з 4 entries (gross + tax withholding).
- post_period: bulk-post всіх drafts.
Critical gaps:
- 🟥 Tax model один прапорець — повторно з §2.3.
- 🟥 Timesheet немає — days_worked зашитий у slip.
- 🟥 Vacation/Sick balance не tracked.
Gap-таблиця:
| # | Фіча | SAP HCM | Odoo HR/Payroll | 1С ЗУП | Dynamics HR | DOP зараз | Пріоритет | Trigger |
|---|---|---|---|---|---|---|---|---|
| P-1 | Timesheet (день+години+проект) | ✅ CATS | ✅ Timesheets | ✅ Табель | ✅ Timesheet | ❌ days_worked напряму у slip | 🟠 P1 | Project-based billing |
| P-2 | Vacation/Sick leave balance + request workflow | ✅ Time mgmt | ✅ Time Off | ✅ Відпустки | ✅ Leave & Absence | ❌ NONE | 🟠 P1 | 5+ employees |
| P-3 | UA tax 4-leg (PDFL18% + Військ1.5% + ЄСВ22% з нарахування) | — UA-локалізація | — UA-локалізація | ✅ | — | ❌ Один tax_rate_pct | 🔴 P0 | UA production |
| P-4 | Payroll register (звіт за період по всіх slip) | ✅ Payroll Posting | ✅ Payslip register | ✅ Реєстр ЗП | ✅ | ❌ NONE | 🟠 P1 | Перший live payroll |
| P-5 | KPI / bonus calculation engine | ✅ | ✅ Compensation | ✅ Преміювання | ✅ Performance | ❌ NONE | 🟡 P2 | Sales-team з bonus |
| P-6 | Pay grades / salary bands | ✅ | ✅ Compensation | ✅ Сітки | ✅ Compensation Plans | ⚠️ Position.base_salary без grade-діапазону | 🟢 P3 | HR-driven org |
| P-7 | Payslip PDF (з підписом, штрих-кодом для працівника) | ✅ | ✅ | ✅ | ✅ | ❌ NONE | 🟠 P1 | Перша видача ЗП |
| P-8 | Garnishments / utримання за рішенням суду | ✅ | ⚠️ кастом | ✅ | ✅ | ❌ NONE | 🟢 P3 | Алименти-кейс |
| P-9 | Year-end tax report (1ДФ для UA) | — UA-локалізація | — UA-локалізація | ✅ 1-ДФ | — | ❌ NONE | 🟡 P2 | Перша річна звітність |
| P-10 | Onboarding / Termination workflow + автогенерація документів | ✅ | ✅ Recruitment + Contract | ✅ Кадрові накази | ✅ Employee lifecycle | ❌ NONE (поля hire_date/termination_date є) | 🟢 P3 | HR-driven org |
7.5 PRODUCTION¶
Що реально працює:
- complete_work_order: PostingGroup з consumption + output legs (placeholder cost=1).
Critical gaps: - 🟥 Production не оновлює Inventory — повторно §2.2. Це основна функція виробничого обліку. - 🟥 Реальна собівартість не calculated — unit_cost=1 placeholder. Тобто блок «не виконує своєї функції» по cost accounting.
Gap-таблиця:
| # | Фіча | SAP PP | Odoo MRP | 1С ERP | Dynamics SCM | DOP зараз | Пріоритет | Trigger |
|---|---|---|---|---|---|---|---|---|
| Pr-1 | StockTransaction integration (consumption з warehouse, production на warehouse) | ✅ | ✅ | ✅ | ✅ | ❌ Posting є, StockTransaction — NONE | 🔴 P0 | Перший production-cycle |
| Pr-2 | Real costing (FIFO/WAC з batch_service.deduct_fifo) | ✅ Standard/Actual | ✅ FIFO/Standard | ✅ Calculated на основі залишків | ✅ Standard/Actual/FIFO | ❌ unit_cost=1 placeholder | 🔴 P0 | Перший financial close після production |
| Pr-3 | Multi-level BOM (дерево: subassembly → assembly) | ✅ | ✅ Phantom BOM | ✅ Багаторівнева | ✅ | ❌ NONE | 🟠 P1 | Складальне виробництво |
| Pr-4 | Work Center + Operations + Routing (технологія) | ✅ Routing | ✅ Routing & Workorders | ✅ Маршрути | ✅ Route | ❌ NONE | 🟡 P2 | Виробництво з машинним часом |
| Pr-5 | WIP (Work-in-Progress) accumulation account | ✅ | ✅ Cost Account by stage | ✅ НВ | ✅ WIP Account | ❌ Нет — все одразу йде на 1100 | 🟠 P1 | Multi-day production |
| Pr-6 | Yield/Scrap tracking (фактичний випуск vs план + причини) | ✅ | ✅ + Quality Alerts | ✅ Браку | ✅ Production journal | ❌ NONE | 🟡 P2 | Перший client з браком |
| Pr-7 | Capacity planning (calendar заняття Work Centers) | ✅ Capacity | ✅ Manufacturing Calendar | ✅ Завантаження | ✅ Production Schedule | ❌ NONE | 🟢 P3 | High-utilization shop |
| Pr-8 | Subcontracting (передача матеріалів підряднику) | ✅ Subcontracting | ✅ Subcontracting | ✅ Переробка | ✅ Subcontracting | ❌ NONE | 🟢 P3 | Outsourced manufacturing |
| Pr-9 | Quality control on production output (відбракування браку) | ✅ QM | ✅ Quality | ✅ Якість | ✅ Quality | ❌ NONE (можна reuse essentials_quality plugin?) |
🟡 P2 | Регульована галузь |
| Pr-10 | Production planning (MRP — auto-generate WO з sales forecast) | ✅ MRP | ✅ MPS+MRP | ✅ Планування | ✅ Master Planning | ❌ NONE | 🟢 P3 | Make-to-Stock виробник |
7.6 FIXED ASSETS¶
Що реально працює:
- post_depreciation + run_monthly_depreciation (idempotent, 3 методи).
- dispose (status-маркер, БЕЗ gain/loss проводки).
Critical gaps:
- 🟥 Capitalization workflow відсутній. Зараз FixedAsset створюється як master-data через CRUD без зв'язку з PurchaseInvoice. Має бути: «купили обладнання → PurchaseInvoice з прапорцем is_capex → автоматично створюється FixedAsset зі ссилкою на PI».
- 🟥 Disposal без gain/loss — повторно §2.6 (поле 4 з таблиці tech-debts).
Gap-таблиця:
| # | Фіча | SAP FI-AA | Odoo Accounting | 1С Бух | Dynamics F&O | DOP зараз | Пріоритет | Trigger |
|---|---|---|---|---|---|---|---|---|
| F-1 | Acquisition від PurchaseInvoice (capex flag → auto-create FixedAsset) | ✅ Asset acquisition | ✅ Linked from vendor bill | ✅ ОЗ через ПрН | ✅ Acquisition Proposal | ❌ Тільки manual creation | 🟠 P1 | Перший capex spend |
| F-2 | Disposal з gain/loss проводкою | ✅ Asset retirement | ✅ Asset Disposal | ✅ Списання ОЗ | ✅ Asset Disposal | ⚠️ status-маркер без проводки | 🟠 P1 | Перше вибуття |
| F-3 | Asset Transfer between departments / locations | ✅ | ✅ | ✅ Переміщення ОЗ | ✅ | ❌ NONE | 🟡 P2 | Multi-location клієнт |
| F-4 | Asset register report (інвентарна книга) | ✅ Asset Explorer | ✅ Asset Register | ✅ Інвентарна книга | ✅ Asset register | ❌ NONE (тільки через generic MasterDataPage) | 🟠 P1 | Аудит / інвентаризація |
| F-5 | Depreciation schedule preview (forecast: ось так буде амортизуватись) | ✅ Depreciation Run Simulation | ✅ Forecast | ✅ Прогноз | ✅ Asset Forecast | ❌ NONE (monthly_depreciation() для 1 місяця) |
🟡 P2 | CFO planning |
| F-6 | Component-level depreciation (двигун автомобіля окремо від кузова) | ✅ Sub-assets | ⚠️ Кастом | ✅ Складові ОЗ | ✅ Asset components | ❌ NONE | 🟢 P3 | Industrial assets |
| F-7 | Revaluation / Impairment (переоцінка + знецінення) | ✅ Revaluation | ⚠️ Manual JE | ✅ Переоцінка | ✅ Revaluation | ❌ NONE (можна вручну через JournalEntry) | 🟢 P3 | ПСБО / IFRS аудит |
| F-8 | Tax depreciation (паралельно бух — інша ставка/метод) | ✅ Tax depreciation | ⚠️ Кастом | ✅ Податковий облік | ✅ Tax depreciation books | ❌ NONE | 🟢 P3 | UA-локалізація tax |
| F-9 | Repair / maintenance log + cost accumulation | ✅ Plant Maintenance | ⚠️ Maintenance | ✅ Ремонти | ✅ Asset Maintenance | ❌ NONE (можна reuse Fleet MaintenanceRecord?) |
🟢 P3 | Heavy equipment client |
8. Зведена таблиця пропозицій (для узгодження перед імплементацією)¶
Як читати: P0 = блокер для production, P1 = очікується першим клієнтом, P2 = квартал, P3 = backlog. Trigger = подія, яка зробить фічу обов'язковою.
8.1 Top-12 пропозицій з §7 (відсортовано за P+blast-radius)¶
Update 2026-05-09: Усі 4 Inventory-related рядки з топ-5 (#1 InventoryCount, #5 Stock Transfer, плюс Phase 9 reservation + expiry, плюс Phase 7 currency revaluation) — закрито в одну сесію planning/inventory-overhaul-2026-05-09.md.
| # | Блок | Фіча | Прі | Оцінка | Чому ця, чому зараз |
|---|---|---|---|---|---|
| 1 | Inventory | Inventory Count / Cycle Count документ | 🔴 P0 | 3-5 днів | ✅ DONE 2026-05-09 (Phase 4). |
| 2 | Bank/Cash | Bank Reconciliation документ | 🔴 P0 | 5-7 днів | Місячний обов'язковий процес для бухгалтера; зараз DOP лише parse-CSV без matching. |
| 3 | Production | StockTransaction + real costing у complete_work_order |
🔴 P0 | 3-5 днів | Production MVP не виконує своєї функції — повторно §2.2. |
| 4 | Payroll | UA tax 4-leg (PDFL+Військ+ЄСВ роботодавець+утримання) | 🔴 P0 | 5-7 днів | Без цього модуль не для UA-production; повторно §2.3. |
| 5 | Inventory | Stock Transfer документ | 🟠 P1 | 2-3 дні | ✅ DONE 2026-05-09 (Phase 8). |
| 6 | Sales | AR aging report (current/30/60/90/120+ buckets) | 🟠 P1 | 2-3 дні | PartyLedger показує тотал, але fin.controller хоче buckets. |
| 7 | Sales | Statement of Account (акт звірки) | 🟠 P1 | 2-3 дні | Стандартний місячний документ для клієнтів. |
| 8 | Sales | Sales Order як окремий документ перед Invoice (з резервуванням) | 🟠 P1 | 5-7 днів | Розривається з резервуванням inventory (#I-3). |
| 9 | Sales | Returns / Credit Note (з reverse FIFO) | 🟠 P1 | 3-5 днів | Перше повернення зламає поточний flow. |
| 10 | Bank/Cash | Internal Transfer (Cashbox→Bank, Bank→Bank) | 🟠 P1 | 2-3 дні | 2+ касові точки → необхідно. |
| 11 | Fixed Assets | Acquisition від PurchaseInvoice (capex flag → auto-create FA) | 🟠 P1 | 3-5 днів | Зараз FA створюється manually у відриві від PI — розрив у обліку. |
| 12 | Fixed Assets | Disposal з gain/loss проводкою | 🟠 P1 | 2-3 дні | Тільки status-маркер не закриває потребу повноцінного вибуття. |
8.2 Cluster-варіанти для імплементації¶
Варіант A — «Fix what's broken first» (P0-only, 2 тижні) Закриває критичні P0 з §8.1 #1-4. Після цього всі реалізовані MVP можна назвати "production-ready" для UA-клієнта. - Inventory Count + Bank Reconciliation + Production-StockTransaction integration + UA payroll tax. - Тести + документація для кожного.
Варіант B — «Sales completion» (P1, 1.5 тижні) Закриває §8.1 #6-9: AR aging + Statement of Account + Sales Order + Returns. Sales-блок стає fully-wired (з half-wired).
Варіант C — «Multi-warehouse readiness» (P1, 1 тиждень) Stock Transfer + Internal Cash Transfer + Inventory Count = повноцінне багатоскладське/багатокасове підприємство.
Варіант D — «Fixed Assets completion» (P1, 1 тиждень) Acquisition flow + Disposal з gain/loss + Asset register report.
Варіант E — «Все зразу» (4-5 тижнів) P0 + P1 = 12 фіч. Серйозне закриття всіх відомих gap'ів. Production-ready ERP.
9. Запит на узгодження¶
Як обговорено: перед імплементацією потрібне узгодження.
Запитання до користувача: 1. Який варіант з §8.2 обираємо: A (P0-only fix), B (Sales), C (Multi-warehouse), D (FA), E (all P0+P1), або custom-вибір окремих рядків з §8.1? 2. Чи додати наступний рівень — повну «глобальну» візію Essentials з порівнянням SAP MM-FI-CO повного циклу + дорожньою картою на півроку? Чи поточного scope §7-§8 достатньо? 3. Чи є специфічні клієнти / сценарії, які треба підняти у пріоритеті (наприклад, якщо найближчий клієнт — фарма з expiry tracking, треба додати I-5 у P0)?
Пов'язане¶
- audit-2026-04-21.md — попередній (closed) аудит з детальним TODOs.
- DOCS.md — документаційний hub (оновлено 22-го).
- todo.md — загальний backlog.
- BACKLOG.md — автогенерований backlog із
## 🔮 Deferred / Ideas. - CLAUDE.md — оновлений 22-го (21 apps, нові endpoints).
Наступна точка для перегляду — після Фази G (cleanup) або відразу після Фази H (зміцнення) залежно від темпу.