From d7f104ff250b85b5e1531a1cd06b141b84aa33c1 Mon Sep 17 00:00:00 2001 From: Thanakorn S Date: Wed, 27 May 2026 08:15:29 +0700 Subject: [PATCH] =?UTF-8?q?Stop=20tracking=20docs/=20=E2=80=94=20already?= =?UTF-8?q?=20in=20.gitignore?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Sonnet 4.6 --- docs/reviewed/README.md | 53 ----- docs/reviewed/coverage-matrix.md | 138 ----------- docs/reviewed/document-lifecycle.md | 148 ------------ docs/reviewed/live-dashboard.md | 206 ----------------- docs/reviewing/accounting.md | 308 ------------------------- docs/reviewing/helper-endpoints.md | 97 -------- docs/reviewing/master-data.md | 158 ------------- docs/reviewing/runtime-architecture.md | 108 --------- docs/reviewing/setup-landing.md | 75 ------ docs/reviewing/system-settings.md | 224 ------------------ docs/reviewing/transaction-limits.md | 143 ------------ 11 files changed, 1658 deletions(-) delete mode 100644 docs/reviewed/README.md delete mode 100644 docs/reviewed/coverage-matrix.md delete mode 100644 docs/reviewed/document-lifecycle.md delete mode 100644 docs/reviewed/live-dashboard.md delete mode 100644 docs/reviewing/accounting.md delete mode 100644 docs/reviewing/helper-endpoints.md delete mode 100644 docs/reviewing/master-data.md delete mode 100644 docs/reviewing/runtime-architecture.md delete mode 100644 docs/reviewing/setup-landing.md delete mode 100644 docs/reviewing/system-settings.md delete mode 100644 docs/reviewing/transaction-limits.md diff --git a/docs/reviewed/README.md b/docs/reviewed/README.md deleted file mode 100644 index 16a64c0..0000000 --- a/docs/reviewed/README.md +++ /dev/null @@ -1,53 +0,0 @@ -# MN3 WMS Feature Documentation - -This folder documents the main product features discovered from the current PHP codebase. - -The app is split into three operating areas: - -- WMS: warehouse operations, stock movement, sales and purchase workflows. -- Accounting: revenue, expense, finance, journals, batch GL posting, and financial reports. -- Master Data: shared setup for products, locations, contacts, chart of accounts, departments, formulas, and posting rules. - -## Documents - -- [Coverage Matrix](coverage-matrix.md) — codebase surface mapped to documentation status -- [WMS Features](../reviewing/wms.md) -- [Accounting Features](../reviewing/accounting.md) -- [Master Data Features](../reviewing/master-data.md) -- [System And Settings Features](../reviewing/system-settings.md) -- [Runtime Architecture](../reviewing/runtime-architecture.md) -- [Setup And Landing Pages](../reviewing/setup-landing.md) -- [Helper Endpoint Contracts](../reviewing/helper-endpoints.md) -- [Document Lifecycle And Status](../reviewing/document-lifecycle.md) -- [Transaction Limits](../reviewing/transaction-limits.md) — package tiers, daily/weekly quotas, report gating - -## Architecture - -- Architecture coverage is currently split between [System And Settings Features](../reviewing/system-settings.md), [Accounting Features](../reviewing/accounting.md), and [Coverage Matrix](coverage-matrix.md). - -## Cross-Cutting Specs - -- [Running Number](running-number.md) — document number format, sequences, manual entry, gap policy -- [Session Concurrency](session-concurrency.md) — single-session enforcement, heartbeat, PHP GC stale detection, single-factor auth -- [Live Dashboard](live-dashboard.md) — real-time Socket.IO events, section reload map, flash card effect -- [Role Guards](role-guards.md) — CRUD access matrix per role -- [Soft Delete](soft-delete.md) — mechanism, downstream blocks, stock/GL side effects, deletion order - -## Core Architecture - -The UI is mostly PHP pages under `app/`, with AJAX endpoints under each module's `api/engine` or `api/engine_report` folder. - -Common backend behavior is concentrated in manager classes: - -- `app/assets/utils/classes/*Manager.php` handles WMS, document, contact, product, finance, and report logic. -- `app/assets/utils/classes_ac/*` handles accounting setup, GL posting, financial statements, posting windows, and tax reports. -- `app/assets/js/custom.js` contains shared AJAX, pagination, account autocomplete, locks, batch processing, and display formatting helpers. - -## Cross-Cutting Rules - -- Company scoping is applied through `company_id` from the authenticated session. -- Most write APIs load `app/assets/utils/db_auth.php`, which validates session, OTP freshness, CSRF token, and request payload. -- Role checks use `require_role()` where a route is limited to owners/admins. -- Audit logs are stored as JSON in many business tables through the `$logging` object from `db_auth.php`. -- Numeric display uses shared frontend formatting to suppress floating point noise and avoid scientific notation in the UI. - diff --git a/docs/reviewed/coverage-matrix.md b/docs/reviewed/coverage-matrix.md deleted file mode 100644 index 0e85db8..0000000 --- a/docs/reviewed/coverage-matrix.md +++ /dev/null @@ -1,138 +0,0 @@ -# Documentation Coverage Matrix - -This matrix compares the current codebase surface area with the feature specs in `docs/`. - -Status legend: - -- `Covered` - behavior is described by a reviewed spec. -- `Draft-covered` - behavior is described in `docs/reviewing/` and still needs review sign-off. -- `Partial` - behavior is mentioned, but important routes, events, or edge cases are missing. -- `Missing` - no product/spec coverage was found. -- `Internal` - infrastructure or shared code that is not a user-facing feature by itself. - -## Summary - -| Area | Code surface | Coverage | -|---|---:|---| -| App PHP pages/routes | 108 | Mostly draft-covered | -| App API endpoints | 192 | Mostly draft-covered | -| Reviewed specs | 6 | Cross-cutting behavior only | -| Reviewing specs | 10 | Main feature families plus runtime/setup/helper coverage | - -The docs cover the main product domains, but the full feature set is not all reviewed. The main business specs remain in `docs/reviewing/`. - -## Specification Map - -| Spec | Status | Primary coverage | -|---|---|---| -| `docs/reviewing/wms.md` | Draft-covered | WMS dashboard, stock overview, stock in/out/transfer, labels, sales orders/returns/invoices, purchase orders/supplier returns/purchase invoices, stock reports | -| `docs/reviewing/accounting.md` | Draft-covered | Accounting dashboard, revenue/expense documents, finance, chart of accounts, departments, formulas, product account mapping, manual journals, GL posting, financial reports | -| `docs/reviewing/master-data.md` | Draft-covered | Products, categories, warehouses/storage, contacts, chart of accounts, departments, formulas, posting window | -| `docs/reviewing/system-settings.md` | Draft-covered | Authentication, sessions/security, users, profile/password, company settings, SMTP, branch switching, shared JS, locks, ETL maintenance, file uploads | -| `docs/reviewing/document-lifecycle.md` | Draft-covered | Document statuses, void strategy, soft delete strategy, GL versioning | -| `docs/reviewing/transaction-limits.md` | Draft-covered | Package tiers, quota counting, report/dashboard gating | -| `docs/reviewing/invited-onboarding.md` | Draft-covered | Invited user activation flow | -| `docs/reviewed/role-guards.md` | Covered | Role access matrix | -| `docs/reviewed/soft-delete.md` | Covered | Soft delete and downstream deletion guards | -| `docs/reviewed/session-concurrency.md` | Covered | Single-session login enforcement and heartbeat | -| `docs/reviewed/live-dashboard.md` | Covered | Socket.IO dashboard event behavior | -| `docs/reviewed/running-number.md` | Covered | Document numbering configuration and generation | -| `docs/reviewing/runtime-architecture.md` | Draft-covered | App shell, config, database connections, Node.js realtime server, cron scheduler, setup script | -| `docs/reviewing/setup-landing.md` | Draft-covered | Root redirect, landing page, legal pages, CLI setup behavior | -| `docs/reviewing/helper-endpoints.md` | Draft-covered | Helper/search/retrieve/stats endpoint contracts | - -## Page Coverage - -| Code area | Pages | Coverage | Spec | -|---|---|---|---| -| WMS dashboard | `app/dashboard/index.php`, `app/dashboard/low_stock_products.php` | Draft-covered | `docs/reviewing/wms.md`, `docs/reviewed/live-dashboard.md` | -| Stock operations | `app/ics/stock_in.php`, `app/ics/manage_stock_in.php`, `app/ics/stock_out.php`, `app/ics/manage_stock_out.php`, `app/ics/stock_transfer.php`, `app/ics/manage_stock_transfer.php`, `app/ics/stock_overview.php` | Draft-covered | `docs/reviewing/wms.md`, `docs/reviewing/document-lifecycle.md` | -| Barcode labels | `app/ics/sku_barcode_label.php`, `app/ics/location_barcode_label.php` | Draft-covered | `docs/reviewing/wms.md` | -| Inventory master data | `app/inventory/product.php`, `app/inventory/manage_product.php`, `app/inventory/warehouse.php`, `app/inventory/manage_warehouse.php`, `app/inventory/manage_category.php`, `app/inventory/manage_storage.php` | Draft-covered | `docs/reviewing/master-data.md` | -| Contacts | `app/contact/contact.php`, `app/contact/manage_contact.php`, `app/contact/manage_contact_type.php` | Draft-covered | `docs/reviewing/master-data.md` | -| WMS sales | `app/order/order.php`, `app/order/manage_order.php`, `app/order/confirm_order.php`, `app/order/return.php`, `app/order/manage_return.php`, `app/order/invoice.php`, `app/order/manage_invoice.php`, `app/order/print_invoice.php` | Draft-covered | `docs/reviewing/wms.md`, `docs/reviewing/document-lifecycle.md` | -| WMS purchase | `app/po/po.php`, `app/po/manage_po.php`, `app/po/supplier_returns.php`, `app/po/manage_supplier_return.php`, `app/po/invoice.php`, `app/po/manage_purchase_invoice.php` | Draft-covered | `docs/reviewing/wms.md`, `docs/reviewing/document-lifecycle.md` | -| Revenue documents | `app/revenue/quotation.php`, `app/revenue/manage_quotation.php`, `app/revenue/order.php`, `app/revenue/manage_order.php`, `app/revenue/invoice.php`, `app/revenue/manage_invoice.php`, `app/revenue/manage_credit_note.php`, `app/revenue/view_invoice.php`, `app/revenue/receipt.php` | Draft-covered | `docs/reviewing/accounting.md` | -| Expense documents | `app/expense/purchase_request.php`, `app/expense/manage_purchase_request.php`, `app/expense/purchase_order.php`, `app/expense/manage_purchase_order.php`, `app/expense/purchase_invoice.php`, `app/expense/manage_purchase_invoice.php`, `app/expense/manage_supplier_credit_note.php`, `app/expense/payment.php` | Draft-covered | `docs/reviewing/accounting.md` | -| Finance | `app/finance/receipt_billing.php`, `app/finance/manage_receipt_billing.php`, `app/finance/receipt.php`, `app/finance/manage_receipt.php`, `app/finance/payment_billing.php`, `app/finance/manage_payment_billing.php`, `app/finance/payment.php`, `app/finance/manage_payment.php` | Draft-covered | `docs/reviewing/accounting.md` | -| Accounting dashboard | `app/ac_dashboard/index.php` | Draft-covered | `docs/reviewing/accounting.md`, `docs/reviewed/live-dashboard.md` | -| Accounting setup | `app/accounting/chart_of_accounts.php`, `app/accounting/manage_account.php`, `app/accounting/departments.php`, `app/accounting/manage_department.php`, `app/accounting/account_formulas.php`, `app/accounting/posting_window.php` | Draft-covered | `docs/reviewing/accounting.md`, `docs/reviewing/master-data.md` | -| Accounting journals and reports | `app/accounting/gl_entries.php`, `app/accounting/journal_listing.php`, `app/journal/index.php`, `app/journal/new.php`, `app/accounting/trial_balance.php`, `app/accounting/pl_statement.php`, `app/accounting/balance_sheet.php`, `app/accounting/gl_movement.php`, `app/accounting/vat_report.php` | Draft-covered | `docs/reviewing/accounting.md` | -| WMS reports | `app/reports/stock_movement.php`, `app/reports/expired_stock.php`, `app/reports/occupy_rack.php`, `app/reports/product_lot.php` | Draft-covered | `docs/reviewing/wms.md`, `docs/reviewing/transaction-limits.md` | -| Authentication | `app/login/index.php`, `app/login/register.php`, `app/login/verify.php`, `app/login/forgot_password.php`, `app/login/onboarding.php`, `app/login/invited_onboarding.php` | Draft-covered | `docs/reviewing/system-settings.md`, `docs/reviewing/invited-onboarding.md`, `docs/reviewed/session-concurrency.md` | -| Settings | `app/setting/users.php`, `app/setting/profile.php`, `app/setting/company.php`, `app/setting/system_config.php`, `app/setting/smtp.php`, `app/setting/document_types.php`, `app/setting/gl_maintenance.php`, `app/setting/stock_maintenance.php` | Draft-covered | `docs/reviewing/system-settings.md`, `docs/reviewed/running-number.md` | -| Cron | `app/cron/etl_gl_maintenance.php`, `app/cron/etl_stock_maintenance.php` | Draft-covered | `docs/reviewing/system-settings.md` | -| Shared app shell | `app/index.php`, `app/session.php`, `app/preset.php`, `app/dbconn.php`, `app/config.php`, `app/config.example.php`, `app/include_*.php` | Draft-covered | `docs/reviewing/system-settings.md`, `docs/reviewing/runtime-architecture.md` | -| Landing/setup | `index.php`, `setup.php`, `landing/index.php`, `landing/privacy.php`, `landing/terms.php`, `SESSION.php` | Draft-covered | `docs/reviewing/setup-landing.md`, `docs/reviewing/runtime-architecture.md` | - -## API Coverage By Module - -| Module | Endpoints | Coverage | Notes | -|---|---:|---|---| -| `ac_dashboard/api/engine` | 6 | Draft-covered | Dashboard APIs are `by_source`, `journals`, `pl`, `posting_window`, `recent`, `trend` | -| `accounting/api/engine` | 25 | Draft-covered | CRUD, journal, posting, report, lock, and batch-log APIs are described by accounting/system specs | -| `contact/api/engine` | 9 | Draft-covered | Contact and type CRUD plus stats are covered at feature level | -| `dashboard/api/engine_report` | 2 | Draft-covered | WMS dashboard stats and low-stock APIs | -| `expense/api/engine` | 6 | Draft-covered | Purchase request and supplier credit note APIs; purchase invoice behavior is shared through invoice managers/routes | -| `finance/api/engine` | 8 | Draft-covered | Receipt/payment billing and receipt/payment CRUD/delete APIs | -| `ics/api/engine` | 27 | Draft-covered | Core stock and label flows are covered by WMS; helper lookup endpoints are covered by `helper-endpoints.md` | -| `ics/api/engine_report` | 7 | Draft-covered | Stock overview and activity/report APIs | -| `inventory/api/engine` | 17 | Draft-covered | Product/category/warehouse/storage CRUD and stats | -| `login/api/engine` | 9 | Draft-covered | Login, OTP, registration, onboarding, password reset, logout | -| `order/api/engine` | 18 | Draft-covered | Sales order, return, invoice lifecycle | -| `po/api/engine` | 17 | Draft-covered | PO, receive, supplier return, purchase invoice/credit note lifecycle | -| `reports/api/engine_report` | 7 | Draft-covered | Stock reports and quota gating | -| `revenue/api/engine` | 10 | Draft-covered | Quotation, revenue order, invoice conversion, credit note APIs | -| `setting/api/engine` | 18 | Draft-covered | Users, company/profile/SMTP/system settings, document types, ETL maintenance, branch switching | - -## API Helper Endpoint Coverage - -These endpoints are implemented and used by forms. They are now covered at contract level by `docs/reviewing/helper-endpoints.md`: - -- `app/ics/api/engine/contact_search.php` -- `app/ics/api/engine/product_search.php` -- `app/ics/api/engine/retrieve_active_lot.php` -- `app/ics/api/engine/retrieve_active_serial.php` -- `app/ics/api/engine/retrieve_aisle.php` -- `app/ics/api/engine/retrieve_lot.php` -- `app/ics/api/engine/retrieve_rack.php` -- `app/ics/api/engine/retrieve_warehouse.php` -- `app/ics/api/engine/retrieve_zone.php` -- `app/ics/api/engine/validate_scan_location.php` -- `app/inventory/api/engine/manager.php` -- `app/accounting/api/engine/account_stats.php` -- `app/accounting/api/engine/department_stats.php` -- `app/contact/api/engine/contact_stats.php` -- `app/inventory/api/engine/product_stats.php` -- `app/inventory/api/engine/warehouse_stats.php` - -## Cross-Cutting Coverage - -| Behavior | Coverage | Spec | -|---|---|---| -| Role authorization | Covered | `docs/reviewed/role-guards.md` | -| Soft delete and deletion order | Covered | `docs/reviewed/soft-delete.md` | -| Running numbers | Covered | `docs/reviewed/running-number.md` | -| Session concurrency | Covered | `docs/reviewed/session-concurrency.md` | -| Dashboard socket events | Covered | `docs/reviewed/live-dashboard.md` | -| Transaction quotas | Draft-covered | `docs/reviewing/transaction-limits.md` | -| Posting window | Draft-covered | `docs/reviewing/accounting.md`, `docs/reviewing/master-data.md` | -| Document statuses | Draft-covered | `docs/reviewing/document-lifecycle.md` | -| Operation locks | Draft-covered | `docs/reviewing/system-settings.md`, `docs/reviewing/accounting.md` | -| ETL maintenance | Draft-covered | `docs/reviewing/system-settings.md` | -| File uploads | Draft-covered | `docs/reviewing/system-settings.md` | -| Node.js server and cron runtime | Draft-covered | `docs/reviewed/live-dashboard.md`, `docs/reviewing/system-settings.md`, `docs/reviewing/runtime-architecture.md` | -| Installation/setup and landing site | Draft-covered | `docs/reviewing/setup-landing.md`, `docs/reviewing/runtime-architecture.md` | - -## Known Stale Or Corrected References - -- `docs/reviewed/README.md` previously linked reviewing specs as if they lived in `docs/reviewed/`. -- `docs/reviewed/README.md` previously referenced `docs/architecture.md`, which is not present. -- `docs/reviewing/accounting.md` previously referenced `app/ac_dashboard/api/engine/stats.php`; the actual accounting dashboard endpoints are split by section. -- `docs/reviewing/system-settings.md` previously referenced `migrations/*.sql`; schema setup wording now reflects this repository snapshot. - -## Remaining Documentation Work - -1. Promote or revise the `docs/reviewing/` specs after review. -2. Add exact request/response payload tables for helper endpoints where frontend code depends on field-level contracts. -3. Reconcile `schema_migrations` usage with the absence of a `migrations/` directory if file-based migrations are reintroduced. diff --git a/docs/reviewed/document-lifecycle.md b/docs/reviewed/document-lifecycle.md deleted file mode 100644 index 8eb2aec..0000000 --- a/docs/reviewed/document-lifecycle.md +++ /dev/null @@ -1,148 +0,0 @@ -# Document Lifecycle And Status - -## Status Values - -Document status is stored as an integer column on each transaction table. The meaning is consistent across most document types but not guaranteed to be identical everywhere — always read the manager before assuming. - -### Sales and Purchase Invoices (`td_invoice`, all `doc_type` values) - -| Status | Meaning | -|---|---| -| `0` | Draft | -| `1` | Issued / Active | -| `2` | Paid / Settled (fully allocated) | -| `4` | Void | - -`doc_type` values on `td_invoice`: `invoice`, `credit_note`, `purchase_invoice`, `supplier_credit_note`. - -Voiding is handled by a shared status endpoint. When a document is voided, `InvoiceManager` calls `GlManager::delete()` to remove any posted GL entry. Void is blocked if settlement documents (receipts or payments) are still allocated to the invoice — those must be voided first. - -### Receipts and Payments (`td_receipt`, `td_payment`) - -| Status | Meaning | -|---|---| -| `1` | Active / posted business document | -| `4` | Void | - -Void calls `GlManager::delete()` through `ReceiptManager` and `PaymentManager` respectively. Posting window is enforced on both save and void. - -### Receipt Billing Notes and Payment Billing Notes (`td_receipt_billing`, `td_payment_billing`) - -Billing notes group one or more invoices into a single collection document sent to a customer (receipt billing) or supplier (payment billing). Each line in `td_receipt_billing_item` / `td_payment_billing_item` references a `td_invoice.id` and carries an allocated amount. - -| Status | Meaning | -|---|---| -| `1` | Open — no receipts / payments posted against it yet | -| `2` | Fully received / paid — allocated receipts or payments equal the billing total | -| `3` | Partially received / paid — some but not all receipts or payments have been posted | -| `4` | Void | - -Status is never set manually — `ReceiptBillingManager::refreshBillingStatus()` and `PaymentBillingManager::refreshBillingStatus()` derive and write the correct value after each receipt or payment change. - -Void is blocked if any posted receipt (`td_receipt.status = 1`) or payment (`td_payment.status = 1`) is allocated to the billing note — those must be voided first. Voiding a billing note does **not** void the invoices it references. Invoices cannot be voided while an active billing note (`status` ∈ `{1, 2, 3}`) references them. - -### Quotations (`td_quotation`) - -| Status | Meaning | -|---|---| -| `-1` | Cancelled | -| `0` | Draft | -| `1` | Sent | -| `2` | Accepted | -| `3` | Rejected | -| `5` | Converted | - -Status transitions are enforced by `QuotationManager::updateStatus()`: - -- `0 → 1` (send), `1 → 2` (accept), `1 → 3` (reject) -- `1 / 2 / 3 → 0` (reopen) — blocked if any item already has `converted_qty > 0` -- `0 / 1 → -1` (cancel) - -`status = 5` is never set via `updateStatus()`. It is written automatically by `QuotationManager::incrementConvertedQty()` once all line items are fully converted to a sales order. `OrderManager::linkQuotationToOrder()` calls this after a successful order creation. When the linked order is later cancelled or soft-deleted, `OrderManager` reverts the quotation back to `status = 2` (Accepted). - -### Sales Orders (`td_order`) - -| Status | Meaning | -|---|---| -| `-2` | Pending warehouse selection or source completion | -| `-1` | Cancelled | -| `0` | Draft | -| `1` | Confirmed | - -Confirmation can create stock-out rows. Cancellation reverses stock-out rows where required and is blocked when active invoices or returns exist. - -### Purchase Orders (`td_purchase_order`) - -| Status | Meaning | -|---|---| -| `-2` | Pending warehouse selection or source completion | -| `-1` | Cancelled | -| `0` | Draft | -| `1` | Confirmed | - -`td_purchase_order.status` only ever holds the values above. **Partially received** and **fully received** are not stored statuses — they are derived on the fly by `PurchaseOrderManager::deriveReceiptStatus()` into a virtual `receipt_status` field returned alongside the PO row. This derived value reflects the ratio of approved stock-in rows to ordered quantities and is never written back to `td_purchase_order.status`. - -Receiving creates stock-in rows. Close and cancel rules apply based on receiving progress and approved stock-in rows. - -### Purchase Requests (`td_purchase_request`) - -| Status | Meaning | -|---|---| -| `-1` | Cancelled | -| `0` | Draft | -| `1` | Submitted | -| `2` | Approved / reopened after conversion rollback | -| `3` | Rejected | -| `5` | Converted | - -Converted requests have a linked purchase order. - -### Returns and Supplier Returns (`td_return`, `td_supplier_return`) - -| Status | Meaning | -|---|---| -| `-1` | Cancelled | -| `0` | Draft | -| `1` | Confirmed | - -Confirmation creates stock-in (sales return) or stock-out (supplier return) rows. Conversion creates a credit note or supplier credit note document via `InvoiceManager`. - -### Stock Entries (`td_stock_`) - -Draft stock entries await approval. Approved entries update warehouse balances. Approved entries cannot be deleted without reversal; editing and deletion are also blocked outside the posting window. - -## Void And Soft Delete Strategy - -The current strategy (as of 2026-05-19): - -- **Draft or unposted documents** may be soft-deleted or cancelled freely. -- **Posted or issued documents** use a void workflow. The source document is preserved in audit history. Void removes the linked GL entry through `GlManager::delete()` and enforces the posting window. -- **Master data** is soft-deleted by setting `status = 0`. Deletion is blocked when active documents reference the record. - -Void convention uses `status = 4` for `td_invoice` document types (covers `invoice`, `credit_note`, `purchase_invoice`, `supplier_credit_note`). Credit notes are considered inactive at `status = 4`, not `status = -1`. - -### Soft-delete tombstone mechanism - -Draft transaction documents (invoices, receipts, payments, billing notes, orders, quotations, returns, etc.) are soft-deleted by **negating `company_id`** on the header row and all child item rows: - -```sql -UPDATE td_invoice SET company_id = company_id * -1 WHERE id = :id AND company_id = :cid -UPDATE td_invoice_item SET company_id = company_id * -1 WHERE invoice_id = :id AND company_id = :cid -``` - -This is the tombstone convention used by every `softDelete()` method across all managers. Because every read query filters `WHERE company_id = :cid` (positive), tombstoned rows are automatically excluded without any additional flag. Any query that omits the `company_id` filter will expose tombstoned rows — treat this filter as mandatory. - -`deleted_at`, `deleted_by`, and `delete_reason` audit columns are not yet implemented. - -## GL Versioning - -When a source document is posted to the GL more than once (re-post after edit), `GlManager::replace()` is called instead of `GlManager::post()`. The replace path: - -1. Reads the current `td_gl` and `td_gl_item` rows. -2. Appends a snapshot of the current lines as JSON into the `td_gl.history` column. -3. Increments `td_gl.current_version`. -4. Writes the new lines into `td_gl_item`. - -This means the full posting history for a document is preserved in `td_gl.history` as a versioned JSON array. `GlManager::delete()` creates a **reversal journal entry** (debits and credits swapped, lines prefixed with `VOID:`) linked to the original `source_id`, then tombstones the original `td_gl` row. No rows are physically deleted — the full audit trail is preserved in the database. - -Manual journal entries use `GlManager::postManual()` and `GlManager::replaceManual()` which follow the same versioning pattern. diff --git a/docs/reviewed/live-dashboard.md b/docs/reviewed/live-dashboard.md deleted file mode 100644 index 08c26e6..0000000 --- a/docs/reviewed/live-dashboard.md +++ /dev/null @@ -1,206 +0,0 @@ -# Live Dashboard — Real-Time Event Specification - -## Mechanism - -PHP engine files emit named events to a Node.js process over HTTP after a successful DB commit. Node.js broadcasts the event to all browser tabs in the same company room via Socket.IO. Each dashboard page listens for relevant events and reloads only the sections that changed — without a full page refresh. - -``` -PHP (engine file) - └─ notify_node(event, payload, company_id) // fire-and-forget POST to Node - └─ Node.js /emit endpoint - └─ io.to('company_{id}').emit(event, payload) - └─ Browser (dashboard JS) - └─ targeted section reload + flash effect -``` - ---- - -## `notify_node()` (`app/assets/utils/notify_node.php`) - -Fire-and-forget HTTP POST from PHP to the local Node.js `/emit` endpoint. Called **after** `$pdo->commit()` so the event is never sent for rolled-back transactions. - -```php -notify_node(string $event, array $payload, int $company_id): void -``` - -Failure is silently ignored — the DB write is authoritative; the live update is a UX enhancement only. - ---- - -## Socket.IO Room - -Each company gets its own room: `company_{company_id}`. The browser joins this room on page load via `window._socket` (initialized in `include_ending.php`, always before page `