Skip to content

Sample deliverable

Sample risk report

Judge the deliverable, not the pitch.

This is the report a Technical Risk Review produces — full structure, real severity language, evidence-led findings, and a fix order a board can read.

“Ledgerline” is fictional. Every finding below is a pattern we repeatedly see in AI-built apps, recombined so no client is identifiable. Client reports stay private.

Review docket

Ledgerline — B2B invoicing SaaS

Build
7 weeks, AI pair tools + a SaaS template
Team
2 founders, 1 contractor
Stack
Next.js · Postgres · Stripe
Trigger
First paying customers; seed diligence in 6 weeks
Package
Technical Risk Review

Executive summary

The launch date holds — after two P0 fixes.

Verdict Launch-viable with conditions

Ledgerline is closer to launch-ready than most AI-built apps we review. The core flows are coherent and the data model is sound. Two findings block revenue: an account-takeover path in password reset, and cross-tenant access to invoice data.

Both are days of work, not weeks. Neither requires rearchitecting — but both need regression tests so they stay fixed.

The trust gaps (P1) don't block launch, but they will surface in enterprise procurement and diligence: unverified payment webhooks and no error visibility. The ordinary debt (P2) is schedulable and should delay nothing.

Risk map

Six findings. Severity, evidence, impact, fix path.

Real reports carry request traces, screenshots, and file references per finding. This sample keeps the structure and abbreviates the evidence.

P0 — Launch blockers

P0-1

Auth · Password reset

Reset tokens never expire and survive reuse.

Blocks launch

What we found

Reset links carry a raw token stored in plaintext. The token has no expiry and stays valid after use. We replayed a used link from an old email and set a new password in a second browser.

Why it matters

Anyone with access to an old email — a forwarded thread, a shared inbox, a breached mailbox — can take over the account. This is the quiet account-takeover path that turns into a disclosure event.

Fix path

Hash tokens at rest, 30-minute expiry, invalidate on use and on password change. Add a regression test that replays a used token and expects rejection.

Effort: ~1 day

P0-2

Data · Tenant isolation

Invoice endpoints trust the ID, not the organization.

Blocks launch

What we found

The invoice detail endpoint checks login but not organization membership, and IDs are sequential. Logged into tenant A, we fetched tenant B's invoices by decrementing the ID.

Why it matters

Cross-tenant exposure of customer names, amounts, and balances. For a finance product, one screenshot of this ends deals and can trigger notification duties.

Fix path

Enforce organization scoping in one shared query layer instead of per-route checks. Add a cross-tenant regression test that fails loud.

Effort: 2–3 days

P1 — Trust gaps

P1-1

Payments · Webhooks

Stripe webhooks accepted without signature or idempotency.

Fix this month

What we found

The webhook route parses the event body directly — no signature verification, no replay guard. A crafted POST marks any invoice as paid.

Why it matters

Forged or duplicated events corrupt payment state. Silent today; an audit finding and a reconciliation nightmare later.

Fix path

Verify the Stripe signature, key handlers by event ID for idempotency, dead-letter unknown events.

Effort: ~1 day

P1-2

Operations · Visibility

Errors vanish into a catch-all.

Fix this month

What we found

A global handler returns generic 500s with no contextual logging and no alerting. During review, a failing PDF render returned 500s for 40 minutes without leaving a trace.

Why it matters

You learn about outages from customers. Diligence teams read this as an operational-maturity gap.

Fix path

Structured logs with request IDs, error tracking with alerts on new error classes, basic uptime checks.

Effort: 1–2 days

P2 — Ordinary debt

P2-1

Codebase · Duplication

Three copies of the invoice-total logic.

Schedule

What we found

Totals are computed independently in the API, the PDF renderer, and the dashboard — already drifting on rounding behavior.

Why it matters

Ordinary AI-build debt. Becomes a billing-accuracy bug the next time tax rules change.

Fix path

Consolidate into one shared module the next time this code is touched. No dedicated sprint needed.

Effort: Opportunistic

P2-2

Infra · Migrations

Schema migrates on boot, with no rollback path.

Schedule

What we found

The app runs database migrations at startup. Two instances racing would corrupt the schema. Harmless on today's single instance.

Why it matters

Blocks horizontal scaling later; not a launch risk now.

Fix path

Move migrations into an explicit deploy step with rollback before running a second instance.

Effort: ~half a day, later

What happens next

The report ends in decisions, not homework.

01

60-minute readout

We walk founders and stakeholders through the verdict and risk map in plain language. Engineers get the technical appendix with traces and references.

02

A fix order that respects your date

P0s first, each with a named acceptance check. Nothing padded, nothing vague — every item is either scheduled or consciously accepted.

03

P0 retest

Once the blockers are fixed, we verify them against the original evidence and reissue the findings as closed.

Want this read on your app?

The sample above is a composite. Your report is specific: your stack, your risks, your fix order — private, under NDA on request.

Request review

If it's a fit, we reply within 48 hours. If it isn't, we tell you.