Documentation Methodology — the validation standard
Every claim in this tree must be validated against the actual codebase and database at the time of writing. Do not copy assertions out of systemflow/ or docs/ — those are dated audits and are frequently stale. Identify the claim, verify it against code + DB, then write the entry. When code and an older doc disagree, code wins, and the disagreement is recorded as a note.
This standard exists because the first pass of these very tables already surfaced drift: a systemflow inventory cited koovira_newmasterdb_opt with "1,792 tables" while the live DB has 1,797; it referenced order_items as the order-line store when that table holds 0 rows and the live commerce path writes lines directly onto orders_master. Both were caught only by querying the database. Assume every unverified number is wrong until you run it.
The four evidence sources
- Source code — read the real file. Cite
path:line. - Live database schema —
SHOW COLUMNS,information_schema. Cite table + column names exactly. - Live row counts — exact
COUNT(*), neverinformation_schema.table_rows(an estimate).
A count is a snapshot — always date it.
- Configuration / flags —
config/,kv_module_control, env vars. State the flag and its value.
A claim with no source from this list is a hypothesis, not documentation. Mark it as such.
How to validate (the harness)
The repo runs on Laragon: PHP 8.3 CLI and the MariaDB client are both available, and a CLI script that includes the app config connects to the same live DB the site uses.
Minimal probe (this is what the _tools/ scripts wrap):
<?php
require __DIR__ . '/config/baseconfig/config.php'; // adjust depth to repo root
global $conn; // a KVGuardedPDO on koovira_newmasterdb_opt
$rows = $conn->query("SELECT COUNT(*) FROM orders_master")->fetchColumn();
Reusable helpers live in _tools/kv_docs_db.php: tbl_exists(), row_count(), columns(), foreign_keys(), like_tables(). Use them instead of re-deriving.
Never write a probe that mutates data. KVGuardedPDO already blocks DDL from any non-migration context, but reads are the only thing documentation needs. Keep probe scripts in the scratchpad, not in the repo.
Status vocabulary (use these exact words)
A feature's status is a claim like any other — back it with evidence.
| Status | Means | Evidence required |
|---|---|---|
| Production | Live, in real use | code path + non-zero real rows |
| Production Ready | Complete, deployed, not yet exercised | code path + tables exist, rows may be 0 |
| Partially Implemented | Some paths work, others stubbed/empty | name exactly what works and what does not |
| Backend Only | Engine exists, no reachable UI/nav | prove zero entry points (grep nav registries) |
| Under Development | Actively being built | — |
| Deprecated | Superseded, still present | name the replacement |
| Disabled | Built but switched off | cite the flag and its value |
| Planned | Named in code/docs, not built | prove absence (grep, table-existence) |
| Requires Verification | Could not confirm this pass | say exactly what to check |
"Missing"/"absent" is only assertable after a real search: grep the name across incfiles/, cpages/, classs/, config/, root *.php, and the nav registries, and confirm table-existence via information_schema. A single failed grep on this repo is not proof — the tree is large and full-tree greps can truncate. Narrow the path and use a positive control.
What every module page must answer (Definition of Done)
Copy _templates/module.template.md. A module is documented when its pages answer, with citations:
- What the feature does and who can use it (actor + permission + membership + KYC gate).
- How the user reaches it (URL/route/nav entry, or "no entry point" if hidden).
- Frontend → backend → business logic → DB → money → notification → final state.
- Which tables are involved, their real columns, and their relationships (ER).
- The state machine for each stateful entity (who triggers each transition).
- The money flow (source → ledger → destination → reversal path), tied to the central ledger.
- The code map: page → controller/dispatcher → service/class → method → tables.
- Failure flows, not just the happy path.
- Change-impact: what else breaks if this is modified.
Writing rules
- Cite specifics.
classs/CommerceOrdersModule.php:142,orders_master.payment_status,
commission_transactions (92 rows, 2026-09-06). Vague prose is not validation.
- Date every count and every flag reading. They are snapshots.
- Prefer the reverse-verifiable claim. "Order lines are on
orders_master(one row per
line item); order_items exists but is empty" beats "orders have items".
- Flag ambiguity, never guess. If which of two tables is canonical is a product decision,
say so — do not invent an answer.
- No copyright / no secrets. Never paste credentials, keys, or tokens into a page. Describe
behavior, not secret values.