tblN51a88qTDB6iMH), Transactions (tbln0gzhCAorFc3zB), Tenants (tblX4elTuu01gwBYh)CFV_TOLERANCE_DAYS = 2) Used for re-flagging and for how long a dismissal lasts. It is not a waiting period before a new CFV is spottedThe Cash Flow Voids (CFVs) tab automatically detects tenancies where expected rent has not been received. It compares each tenancy's rent due day against reconciled bank transactions that are directly linked to that tenancy in Airtable.
There is no separate CFV table in Airtable. CFVs are derived in real time from the Tenancies table and Transactions table every time the tab loads or the dashboard refreshes.
data.records:read, data.records:write, data.recordComments:read and data.recordComments:write. The write scope is what lets the tab save its audit comments — including the dismissal tag it later reads back.Five KPI cards appear at the top of the CFV tab, providing an at-a-glance summary:
| Card | What It Shows | Colour |
|---|---|---|
| Potential CFVs | Number of tenancies auto-detected as likely missed payments, awaiting your review. Only appears if count is greater than zero. | Amber border |
| Confirmed CFVs | Number of tenancies with Airtable status set to CFV (confirmed voids with active chase). | Red text |
| Total Exposure | Combined monthly rent (in £) across all CFVs and potential CFVs on the list. | Red text |
| Oldest Overdue | The highest number of days overdue across all CFVs. Shows “Escalation may be required” if over 14 days. | Default |
| CFV Actioned | Number of tenancies marked as CFV Actioned (acknowledged, action taken, awaiting payment confirmation). | Amber text |
The detectCFVs() function runs each time the CFV tab renders. It processes every tenancy record and follows two paths:
CFV_TOLERANCE_DAYS), mark as re-flagged (see Section 10). This is the only place a plain days-since-due count is still used.txTenancy linked record field on transactions — not keyword matching or surname matching. A transaction must be reconciled and linked to the tenancy record in Airtable for the system to recognise it as payment.
js/arrears.js) fails to load, the check drops back to the old rule: any reconciled linked transaction dated in the current calendar month counts as payment. That older rule both missed early payments and accepted unrelated ones, so it is a safety net, not the live behaviour.
CFV tenancies move through these statuses. The Payment Status field (tenPayStatus) on the Tenancies table in Airtable is the source of truth.
| Transition | How It Happens | Airtable Updated? |
|---|---|---|
| In Payment → Potential CFV | Automatic: the rent cycle that should have been paid by now has no linked reconciled payment (see Section 4) | No — display only in dashboard |
| Potential CFV → CFV | User clicks “Confirm CFV” button | Yes — PATCH to set status to CFV |
| Potential CFV → dismissed | User clicks “Not a CFV” button. Only a Potential CFV can be dismissed. The dismissal lasts until the tenancy’s next rent due day plus the 2-day tolerance, then the tenancy is re-checked. | Yes — posts a tagged [CFV-DISMISSED:YYYY-MM-DD] comment on the tenancy, as well as saving it in localStorage |
| CFV → CFV Actioned | User clicks “Mark Actioned” button | Yes — PATCH to set status to CFV Actioned |
| CFV Actioned → In Payment | User clicks “In Payment” button, or automatically when a reconciled linked transaction is detected | Yes — PATCH to set status to In Payment |
| CFV Actioned → CFV | User clicks “Move to CFV” button, or user confirms a re-flag | Yes — PATCH to set status to CFV |
| CFV / CFV Actioned → In Payment | Auto-return: the payment check finds the current rent cycle paid by a reconciled transaction linked to this tenancy | Yes — automatic PATCH + audit comment |
When the payment check (Section 4) finds that a tenancy currently in CFV or CFV Actioned status has cleared its current rent cycle, it automatically:
cfv_{id}_returned) to prevent the tenancy from re-appearing before Airtable syncs.Not only on the CFV tab. Auto-return is a side effect of CFV detection, and detection runs on four paths — every one of them can write to Airtable:
cfv_{id}_returned flag stops it repeating within one browser,
but it is local, so a different browser or a cleared cache can run it again.
The CFV table displays all detected cash flow voids, sorted by status (Potential first, then CFV, then CFV Actioned) and then by due day.
| Column | Source | Description |
|---|---|---|
| Tenant | tenSurname + tenRef | Tenant surname (bold) with tenancy reference below in grey. |
| Property | tenProperty + tenUnitRef | Property name with unit reference below. |
| Rent | tenRent | Monthly rent amount in £, right-aligned with tabular numerals. |
| Due Day | tenDueDay | The day of the month rent is due (e.g. 1, 15, 28). |
| Days Overdue | Calculated | Days since the rent cycle that the last received payment did NOT cover (see below). Colour-coded: black (0–3), amber (4–7), red (8+). |
| Last Payment | Calculated | The date and amount of the most recent reconciled transaction linked to this tenancy. This is the figure the Days Overdue count is built from. |
| Status | tenPayStatus | Badge: Potential CFV, CFV, CFV Actioned, or Re-flagged |
| Contact | tenantPhone + tenantEmail | Clickable phone (tel:) and email (mailto:) links. Shows warning if no contact info. |
| Actions | — | Context-sensitive action buttons (see Section 8). |
Days overdue is worked out live from the last rent payment actually received for that tenancy. Nothing is stored on your computer, so the number is the same on every device.
CFV_EARLY_PAY_DAYS = 5). A tenant who pays up to five days early has still paid that month, and without this the payment would be credited to the wrong cycle.Each row in the CFV table shows different action buttons depending on the tenancy’s current status. Every status-changing action shows a confirmation dialog before proceeding.
| Button | Appearance | What It Does |
|---|---|---|
| Confirm CFV | Red background, white text | After confirmation dialog: sends PATCH to Airtable to set status to CFV. Adds audit comment “Confirmed as CFV from Leadership Dashboard.” Re-renders CFV tab after 1.5s, reloads dashboard after 3s. |
| Not a CFV | Green/success style | After confirmation dialog: stores the dismissal timestamp in localStorage (cfv_dismissed_{id}) and posts a tagged comment to the tenancy in Airtable — “[CFV-DISMISSED:YYYY-MM-DD] Dismissed as not a CFV from Leadership Dashboard. Payment confirmed via other means.” Clears chase tracking data. Expires at the tenancy’s next rent due day plus the 2-day tolerance, then the system re-checks. Only a Potential CFV can be dismissed. |
| Button | Appearance | What It Does |
|---|---|---|
| Mark Actioned | Blue/primary | After confirmation: PATCHes Airtable to set status to CFV Actioned. Adds audit comment. Button shows “Done ✓” in green on success. |
| 💬 Comments | Default style, shows count | Opens the comments panel for this tenancy (see Section 11). Shows the number of existing comments as a badge. |
| Button | Appearance | What It Does |
|---|---|---|
| In Payment | Green/success | After confirmation: PATCHes status to In Payment. Clears all localStorage tracking. Adds audit comment “Returned to In Payment from Leadership Dashboard. Payment confirmed.” Sets local returned flag. |
| Move to CFV | Red border, red text | After confirmation: PATCHes status back to CFV. Adds audit comment “Moved back to CFV from CFV Actioned via Leadership Dashboard.” |
| 💬 Comments | Default, shows count | Opens comments panel. |
| Button | Appearance | What It Does |
|---|---|---|
| Confirm CFV | Red background | After confirmation: PATCHes status back to CFV. Adds comment “Re-flagged as CFV — payment not received on next due date.” Clears re-flag dismissal. |
| Dismiss | Default | Stores dismissal in localStorage. The re-flag badge disappears but the tenancy stays as CFV Actioned. |
| 💬 Comments | Default, shows count | Opens comments panel. |
Each CFV is assigned a chase stage based on how many days have passed since the chase was initiated. Chase stages never trigger automated communications.
| Stage | Days Since Chase Start | Label | Description | Badge Colour |
|---|---|---|---|---|
| Stage 1 | 0+ days | Friendly reminder | Initial stage — contact the tenant informally to remind them of the missed payment. | Blue/default |
| Stage 2 | 3+ days | Follow-up chase | If Stage 1 hasn’t resolved, escalate to a more formal follow-up. | Amber |
| Stage 3 | 7+ days | Escalation | Formal escalation — may require letters, legal references, or management review. | Red |
cfv_{id}_chaseStart, and persists across sessions on that browser. It is the only CFV date that lives in your browser — Days Overdue does not (see Section 7).
A CFV Actioned tenancy can be automatically re-flagged if the next month’s due date passes without payment. The system checks:
CFV_TOLERANCE_DAYS) elapsed since the due day?cfv_reflag_dismissed_{id} in localStorage.)If all conditions are met and the re-flag hasn’t been dismissed, the row shows a “Re-flagged ⚠” badge in amber/warning style, along with “Confirm CFV” and “Dismiss” buttons.
Every CFV action creates an audit comment on the Airtable tenancy record via the Comments API. You can also view and add comments manually.
The following actions automatically add a comment to the tenancy record:
[CFV-DISMISSED:YYYY-MM-DD] Dismissed as not a CFV from Leadership Dashboard. Payment confirmed via other means.” The date tag is what the dashboard reads back — do not edit or delete these comments.When the CFV tab loads on a computer that has no record of a dismissal — a different device, a new browser, or after clearing browser data — it reads the tenancy’s Airtable comments and looks for the newest [CFV-DISMISSED:YYYY-MM-DD] tag. Older dismissals made before the tag existed are still recognised by their wording. If that dismissal has not yet reached the next rent due day plus the 2-day tolerance, the tenancy stays hidden and the dismissal is saved locally again.
data.recordComments:write scope for this to work. If a comment fails to save you now get a warning message on screen; before August 2026 that failure was silent, and the dismissal simply came back on the next device.
data.recordComments:read scope. Update your PAT at airtable.com/create/tokens.
The badges sit on the Leadership Dashboard item in the sidebar (there is no Cash Flow Voids item of its own). They update every time the dashboard loads or the CFV tab renders:
| Badge | Colour | What It Counts |
|---|---|---|
| CFV count | Red | Number of confirmed CFVs + non-dismissed potential CFVs |
| Actioned count | Orange | Number of CFV Actioned tenancies |
Badges are hidden when their count is zero. Dismissed potential CFVs are excluded from the red badge count.
Below the CFV table the same tab renders a second block called Rent Statements. It is a different feature with a different job: the CFV table asks “did this month’s rent arrive?”, Rent Statements asks “how much does this tenant owe in total?”
Each row shows the tenant and unit, the tenancy type, the monthly rent, the running balance, how many days of rent that balance represents, and whether the arrears have reached the Section 8 threshold.
| Figure | How it is worked out |
|---|---|
| Balance | Rent charged for the tenancy so far, less every reconciled payment linked to it. |
| Days in arrears | Balance divided by the daily rent, where daily rent = monthly rent ÷ 31. It is a measure of the debt, not of how long it has been owed. |
| Section 8 | Flagged once days in arrears reaches 62 — two months at 31 days a month, the threshold for a Section 8 ground 8 notice. It is an indicator, not legal advice: check the position before serving anything. |
Click a row to expand it and you see every payment attached to that tenancy, each with five dropdowns: Category, Sub-Category, Tenancy, Unit and Property.
| Human Name | Field ID | Type | Used For |
|---|---|---|---|
| Payment Status | fldxU3dPUnbK0SCDq | Single Select | Current status: In Payment, CFV, CFV Actioned |
| Monthly Rent | fldDMyfZLFMeONPq8 | Currency | Expected rent amount |
| Due Day | fldhy2U0CQmM2oS4P | Number | Day of month rent is due |
| Surname | fldOXazTqBWieEOK2 | Text | Tenant display name |
| Tenancy Reference | fldyNVvFn4x8GY14q | Text | Unique reference code |
| Unit Reference | fldql2nyQlPfkPP4p | Lookup | Linked rental unit name |
| Property | fldxfIa0W1nqCbLo2 | Lookup | Property name |
| Linked Tenant | fld1i5bDoHL3B6rUf | Link | Links to Tenants table for contact info |
| Tenant Status | fldgWAyha1Uij1SZP | Rollup | Active/Former — only Active tenancies are checked |
| Human Name | Field ID | Type | Used For |
|---|---|---|---|
| Reconciled | fldxKX1IbIFcAOnn5 | Checkbox | Only reconciled transactions count as payment |
| Tenancy (link) | fldPmAMmxwqs4SdPa | Link | Direct link to tenancy record — this is how payment is matched |
| Date | fldoyQ6Rr9cHp3bgQ | Date | Compared against the rent cycle that is due, allowing payment up to 5 days early. Also the date shown in the Last Payment column |
| Human Name | Field ID | Type | Used For |
|---|---|---|---|
| Tenant Name | fldxBKW7QnujSDWqA | Text | Full name display |
| Contact Number | fldraHUkWfqo4olLF | Phone | Clickable tel: link in Contact column |
| Email Address | fldybEduFY3DWWTfT | Clickable mailto: link in Contact column |
| Status Name | Select Option ID | Used In Code As |
|---|---|---|
| In Payment | sel4I99slfpd7Vc1t | CFV_STATUS_IDS.inPayment |
| CFV | sel2mWzsvOd8d8de0 | CFV_STATUS_IDS.cfv |
| CFV Actioned | selmhFXah5Bodgg9x | CFV_STATUS_IDS.cfvActioned |
js/cfv.js to match.
| Method | Endpoint | When |
|---|---|---|
PATCH | /v0/{base}/Tenancies/{id} | Every status change (Confirm CFV, Mark Actioned, In Payment, Move to CFV, auto-return) |
POST | /v0/{base}/Tenancies/{id}/comments | Every status change + manual comment add |
GET | /v0/{base}/Tenancies/{id}/comments | When rendering the CFV table (comment counts) and when opening the comments panel |
The Cash Flow Voids tab stores tracking data in your browser’s localStorage. These persist across sessions but are specific to the browser/device.
| Key Pattern | Value | Purpose | Cleared When |
|---|---|---|---|
cfv_{id}_chaseStart | ISO date string | When the chase stage tracking began. Used to determine Stage 1/2/3. | Returned to In Payment or dismissed |
cfv_{id}_returned | “1” | Prevents a just-returned tenancy from re-appearing before the next full data load. | Cleared if Airtable PATCH fails |
cfv_{id}_returnDismissed | “1” | Legacy flag for dismissing return banners. | Returned to In Payment |
cfv_dismissed_{id} | ISO date string | Potential CFV dismissed by user. Backed up as a [CFV-DISMISSED:date] comment in Airtable and restored from it on another device. | Expires at the next rent due day + 2 days, then the system re-checks |
cfv_reflag_dismissed_{id} | ISO date string | Re-flag dismissed by user. Tenancy stays CFV Actioned. | When user confirms re-flag as CFV |
cfv_{id}_startDate | — | Dead legacy key. It used to hold a frozen CFV start date that drove Days Overdue. Nothing writes it any more; the code only ever deletes it, to clear up leftovers from the old build. Days Overdue is now worked out from the last reconciled payment instead (Section 7). | Deleted on dismissal, on return to In Payment, and on auto-return |
data.records:write scope. Go to airtable.com/create/tokens, edit your token, and ensure this scope is enabled. Also check your internet connection.data.recordComments:read scope. The system will show a link to update your token. Add the scope and refresh.| Version | Date | Changes |
|---|---|---|
| 1.35 | 3 Sep 2026 | Drift repair against the live code (findings 035, 055, 170, 171, 276). Rewrote Section 4: detection no longer waits 2 days after the due day and no longer asks whether a payment landed in the current calendar month. Both paths now run one payment check, described in full — no linked payment at all means unpaid, otherwise the cycle that is due (this month’s once the due day has passed by 2 days, last month’s until then) must have a payment dated within 5 days before its due day. The calendar-month rule is documented as the fallback it now is. Corrected the same wording in the lifecycle table, Section 6, the flow diagrams, the Transactions field table and troubleshooting. The 2-day tolerance is now described where it is really used: re-flagging and dismissal expiry. Removed the Chase column from the Section 7 table (it is gone from the page) and added the Last Payment column that replaced it; Section 9 now says the chase stage is computed but not shown. Added the dead cfv_{id}_startDate key to Section 15 and corrected the note that said clearing browser data resets Days Overdue. |
| 1.34 | 26 Aug 2026 | Drift repair against the live code (findings 164–169, 172). Dismissals expire at the next rent due day + 2 days, not after 25 days, and are backed up as tagged Airtable comments that restore them on another device. Days Overdue is derived from the last reconciled payment with a 5-day early-pay window; the localStorage start date is gone. New section 13 documents the Rent Statements block and its live writes to the Transactions table. Corrected how the tab is opened (dashboard button, not a sidebar item) and where the badges render. Payment Status is PATCHed by NAME, so a renamed option is what breaks it. Added the data.recordComments:write scope; a failed comment now warns on screen instead of failing silently. |
| 1.6 | 16 Apr 2026 | Complete SOP rewrite. Documented: direct tenancy-linked payment detection (replaced keyword matching), auto-return to In Payment, re-flagging logic, sidebar badges, all action buttons per status, comments system via Airtable Comments API, localStorage tracking keys, chase stages (visual only, not automated), all Airtable field IDs and select option IDs. |
| 1.4 | 12 Apr 2026 | Added Potential CFVs section, UC Check section, status IDs reference. |
| 1.0 | Mar 2026 | Initial SOP release. |