๐Ÿ”ง Backend Hardening Session

July 24, 2026 ยท Thursday
End of Day Report

Foundation before features.
The kind of work nobody sees but everyone trusts.

Shipped the 1:1 and MBO inspection subsystem verified end-to-end with real sessions. Closed two live security vulnerabilities and a paywall bypass. Found and fixed the biggest data integrity issue: every dashboard metric was computed over 56% synthetic demo data, invisibly. Consolidated years of schema duplication into a clean relationship model. Nothing to screenshot. Everything to trust on.

The Honest Framing
This was a day of fixing the foundation

This was not a day of visible product-building. It was a day of fixing the foundation the product sits on โ€” the kind of work that produces nothing to screenshot but everything to trust. We set out to run UAT and build role-specific kits. Before that could be safe, the schema underneath had to be made sound. It now is.

"Every dashboard number in the product was being computed over 56% synthetic demo data, and nobody could have known by looking."
The single most important find of the day
What Shipped (Verified & Committed)
The 1:1 + MBO inspection subsystem
โœ… New Table Structure
One unified one_on_ones table
Serves every persona pairing (SDRโ†”AE, AEโ†”SEAC, all leadership 1:1s). Keyed on the relationship rather than hardcoded participant columns. Adding CSM or SME 1:1s later requires no schema change โ€” it becomes configuration.
โœ… Field vs Leadership Differentiation
Smart meeting semantics
Field 1:1s (peers) carry status and asks, no coaching. Leadership 1:1s carry coaching, self-assessment, and MBO. This matches how these meetings actually work โ€” peers don't coach peers. The schema enforces it.
โœ… Private Self-Assessments
Honest feedback mechanism
The rep writes honestly because the leader cannot see it unless the rep chooses to share. Sharing is one-way (cannot be silently retracted). A self-assessment the leader can read is not a self-assessment at all.
โœ… The MBO Inspection Trail
The competitive moat
Objectives get inspected every 1:1 with cited evidence. The trail is immutable. This turns quarter-end scoring (beauty contest judged on last two weeks) into defensible payout backed by continuous evidence. Disputes are settled by data.
๐ŸŽฏ End-to-End Verification Result
The first real MBO objective was written to the database today. That write had been silently blocked by an RLS policy since before July 6 โ€” every leader paired through the new relationship model was unable to create an objective, and nothing surfaced the failure. Verified end-to-end with real authenticated sessions (Playwright, seeded accounts, torn down after). Repeatable test saved to the repo. The inspection trail is now live.
What Was Fixed (Foundation)
Two security holes + data contamination
๐Ÿ”ด Security #1: Privilege Escalation
Any user could become a leader
Any authenticated user could set their own role and subscription tier by updating their profile row. A permissive RLS policy with an empty check nullified protections. Closed with policy drop plus database-level guard that cannot be bypassed.
๐Ÿ”ด Security #2: Email-Click Privilege Grant
Email click = org-wide management access
An ordinary rep could send a "become a leader" invitation to an email they controlled and, on clicking through, be granted org-wide management privileges with zero admin approval. Now grants a neutral tier; elevation requires deliberate action.
๐Ÿ”ด Security #3: Paywall Bypass
Coupon redemption was directly callable
Coupon redemption (which writes subscription tier) was directly callable by any user session. Moved server-side only. No more tier elevation without proper flow.
โš ๏ธ Data Trust: Demo Contamination
The biggest find of the day
Every dashboard metric was computed over mixed real and demo data. Analysis_history was 56% demo. MBO was 100% demo. Leader scorecards, funnels, HQ analytics โ€” all mixed. Fixed by making demo exclusion the default at the data layer and applying it across ~20 aggregation sites.
โš ๏ธ Data Trust: Cached Counter Drift
Counter was wrong on 26% of accounts
A cached counter was wrong on 26% of accounts and shown verbatim in the UI. Replaced with a live-computed value that cannot drift.
โš ๏ธ Data Trust: Compensation on Demo Data
Reps could be paid on synthetic handoffs
Spiffs, QBRs, and career reviews were counting demo data as real. A rep could have been compensated on synthetic activity. Closed.
Architecture Consolidation
The pattern that caused the mess

The schema had accumulated 4โ€“5 competing representations of the same concepts (roles, memberships, pairings, invites) because each new persona got a parallel copy of an existing feature instead of generalizing it. This session consolidated that sprawl:

๐Ÿ”ง Removed Dead Code
First pass cleanup
8 dead tables, 10 dead columns, 7 functions removed in the first pass alone. Schema now reflects what's actually in use.
๐Ÿ”ง Relationship Model
One generic model replaces duplicates
Replaced per-persona pairing/leader tables with one generic relationship model where cardinality rules live as data. Adding SEAC/CSM/SME is now configuration, not schema change.

Established one canonical owner for each concept and wrote it into AGENTS.md, which Lovable now reads on every request as a guardrail against the next duplicate.

// AGENTS.md now defines schema ownership: - roles: one source of truth (app, not user-settable) - memberships: org โ†’ person relationship via email - pairings: generic relationship model (type field, not table) - invites: single table, not split by role
What Stays in the Repo
Continuity across sessions
Open Items Ranked
Carried forward, none blocking UAT
The Method That Worked
Worth repeating

Every meaningful find came from reading the actual schema rather than trusting the summary of it. The platform-vs-org role distinction, the empty security check, the two-different-ID-columns bug, the demo contamination โ€” none were visible from the outside. The repeatable discipline that surfaced everything:

What We Need to Work On
Immediately after UAT validation
What's Coming Next
The kit build + broader rollout

The schema is now clean. Demo data is no longer invisible. Security holes are closed. The 1:1 and MBO system is verified to work. This clears the way for: