πŸ“Œ Executive Summary & Overall Assessment

Key

RatingSeverityStatus
🟒 Green β€” 4 to 5πŸ”΄ Criticalβœ… Yes
🟑 Amber β€” 3🟠 High❌ No
πŸ”΄ Red β€” 1 to 2🟑 Medium◐ Partial
●●●○○ β€” score out of 5βšͺ Low

πŸ“‹ Summary

Midshift is a well-conceived, carefully engineered campaign-production tool for retail marketing teams and their agencies. Its code is cleaner, better documented and more thoroughly self-checked than is typical for a young, single-owner product, and its most distinctive features β€” reading copywriters' Word decks, matching designers' files to adverts by name, and building tracking links from one template β€” are well tested. As delivered, however, it carries two critical security exposures that are cheap to fix but must be fixed before any acquisition completes: database permission rules that, as written in the repository, let any signed-in user make themselves an administrator, and a web-framework version with published critical vulnerabilities. Beyond those, the largest risk is not technical but human: the code, the decisions, the operation of each client deployment and the intellectual property all sit with one person, and the git history has been squashed so that how the product was built cannot be inspected. A buyer is acquiring a sound foundation with a short, well-defined list of urgent repairs and a significant dependency on the founder's transition.

🎯 Rating

πŸ”΄ ●●○○○ Overall: 2 / 5 β€” Red (as delivered). The asset's underlying engineering would merit an Amber 3; it is held at Red by a Critical privilege-escalation path, a critically vulnerable framework pin and a bus factor of one. The first two are small (S-effort) fixes; with them made and verified on every live deployment, the overall position moves to 3 / 5 Amber within about 30 days.

πŸ” Findings

βš–οΈ Verdict

Technically, Midshift is a coherent modular monolith on a mainstream stack (Next.js, React, TypeScript, Supabase, Vercel, Resend) that a competent web team could take over. Domain logic is centralised in small, tested functions; type-checking and linting are strict and clean; the team has turned its own lessons into automated guard rails. The weaknesses cluster in one place β€” the path by which data is written and permissions are checked β€” which is the least tested part of the system and where every serious security finding sits. Operationally, each client is a separate, hand-configured deployment with hand-applied database migrations, which suits a small number of high-touch clients but not a scalable SaaS thesis. Commercially, the code is owned by an individual, and there is no history to verify authorship or delivery pace.

πŸ“Š Scorecard

#ModuleRatingRAGHeadline finding
01Product & Domain Overview●●●●○ 4🟒 GreenClear, opinionated product; ad name as the join key; distinctive deck parser and file matcher; single-tenant, English-only
02Technology Stack & Complexity●●●○○ 3🟑 AmberModern, narrow stack; moderate complexity (5/10); Next.js exact-pinned at a vulnerable release; two unused dependencies
03Architecture & Design●●●○○ 3🟑 AmberSensible modular monolith; inconsistent write paths (some browser-side writes bypass server rules); no transactions; unbounded queries
04Domain Model & Business Rules●●●○○ 3🟑 Amber75 rules catalogued, mostly in tested pure functions; contradictions around approval reset and member management; 29 rules untested
05Code Quality & Standards●●●●○ 4🟒 GreenStrict TS, clean lint, 2.3% duplication, self-enforcing gates; complex core handlers; no error tracking
06Technical Debt & Maintainability●●●○○ 3🟑 Amber~33% of source files touched by measurable debt, severe debt concentrated in ~15–20 files; debt tracked in prose, zero TODO markers
07Testing & QA●●●○○ 3🟑 Amber687/687 unit tests pass; journeys 467 passed / 7 failed (an expired-date test and a layout check) / 1 file unfinished; domain logic 67% covered; API routes 0.9%; browser suite runs against a mock, not the real routes
08Dependencies & Licensing●●○○○ 2πŸ”΄ Red24 known vulns (11 in production) incl. critical Next.js RCE on a used code path; abandoned xlsx; licences clean; IP held by an individual
09Security & DevSecOps●●○○○ 2πŸ”΄ RedRoute code careful, but DB policy allows self-promotion to admin; stored XSS; in-job approval self-grant; no CSP, rate limiting or security scanning
10Source Control, CI/CD & Practices●●●○○ 3🟑 AmberStrong CI gates; no evidenced code review; direct pushes to main; manual migrations; history squashed
11Delivery Metrics & Key-Person Risk●○○○○ 1πŸ”΄ RedBus factor of one; no DORA metric measurable
12Documentation●●●○○ 3🟑 Amber~46k words, API reference near-complete; 9 of 16 sampled claims drifted, incl. fresh-install and security facts
13Integrations●●●○○ 3🟑 AmberOnly Supabase, Vercel, Resend; deep Supabase coupling; no monitoring; e-mail failures largely invisible

Unweighted mean of module ratings: 2.8. The overall rating is set below the mean deliberately, because Critical security findings and key-person risk dominate a buyer's exposure regardless of average quality.

🚩 Top 5 risks

#RiskSeverityBusiness impactEffort
1Self-promotion to administrator. The users update policy (supabase/baseline.sql:1044–1046) has no column restriction, and admin checks read users.role; sign-up also trusts a client-supplied role (baseline.sql:947). (Module 9)πŸ”΄ CriticalAny client user could gain full control of their organisation's data, approvals and user accounts. Whether live databases match the repository is unverified.S
2Vulnerable framework pinned in production. Next.js 16.2.0 is affected by ~26 advisories including critical RCE in next/og (used by the tab icons) and middleware-bypass issues; no automated dependency scanning. (Modules 8, 9)πŸ”΄ CriticalRemote compromise of the hosting environment; exposure persists until someone manually upgrades every client deployment.S
3Key-person and IP concentration. One individual owns the code, holds the operational knowledge and access for every deployment, and directs an AI-assisted build process; history is squashed. (Modules 8, 10, 11)πŸ”΄ Critical (transactional)Loss of the founder would stall development and operations; ownership and provenance cannot be verified from the material supplied.M–L
4Sign-off integrity can be undermined. A project manager can make themselves the approver; any editor can remove the approver; a deck re-import can change carousel wording without reopening approval; stored XSS via the brief can act in an admin's browser. (Modules 4, 9)🟠 HighUndermines the product's core promise β€” that an approval means someone accountable signed off exactly this wording.S–M
5Untested write path and invisible failures. Route handlers have 0.9% unit coverage and are emulated, not exercised, by the browser suite; no error tracking or integration monitoring; missing CRON_SECRET silently disables file purge and overdue alerts. (Modules 5, 7, 13)🟠 HighDefects and outages surface only when customers report them; regressions likely when the riskiest code is changed.M

πŸ’Ž Top 5 strengths worth paying for

  1. Distinctive, well-tested domain IP. The copy-deck parser (85% covered against a 22-unit regression deck), the shared filename-to-unit matcher (98%), and the single UTM builder (100%) encode hard-won workflow knowledge competitors would have to rediscover. (Modules 1, 4, 7)
  2. Engineering discipline turned into automation. Strict TypeScript, zero lint warnings, low duplication, and bespoke guard-rail tests (every write's result must be read; every queried column must exist; every route must have a harness twin; no client identity may be committed). (Modules 5, 10)
  3. Exceptional written rationale. Architecture, API reference (82 of 83 routes) and a decision log explain why things are as they are β€” rare for a product of this size, and the main mitigation for the key-person risk once corrected for drift. (Module 12)
  4. Clean, low-cost stack and licensing. Mainstream, easily staffed technologies; only three runtime vendors; no strong-copyleft licences in the dependency tree; no AI-provider dependency or cost. (Modules 2, 8, 13)
  5. Data isolation by design. One database per client means no cross-tenant leakage risk and a straightforward story for enterprise data-protection reviews; white-labelling is built in as data. (Modules 1, 3)

❓ What could not be assessed β€” follow-up questions and access requests

#Question / requestNeeded forModule(s)
1Provide the full, unsquashed git history and GitHub organisation access (PRs, issues, Actions run history, branch protection settings)Hotspots, contributor/bus-factor analysis, commit hygiene, code-review evidence, lead time, change failure rate2, 6, 8, 10, 11
2Read access to every production Supabase project: confirm pg_policies and column privileges on users, whether public sign-up is disabled, which migrations have run (incl. 040, 061, 065, 088, 091), schema parity with baseline.sqlConfirm/clear the Critical self-promotion finding; environment parity3, 7, 9, 12
3Read access to every Vercel project: deployed Next.js version, env vars set (incl. CRON_SECRET, OWNER_EMAIL, GHOST_EMAIL), deployment and rollback history, function metrics, response headers (HSTS)Confirm Critical framework exposure; DORA deployment frequency, lead time, MTTR; performance2, 8, 9, 11, 13
4Incident log, monitoring/alerting setup and any post-mortemsChange failure rate, MTTR, operational maturity11, 13
5Number of live deployments / customers, contracts, revenue, pricing, and product roadmapCommercial context; scale of remediation roll-out1
6IP chain of title: contributor list, assignment deeds, use of AI coding tools and their terms, and access to the related FS002-dev/campaign-studio repositoryOwnership and provenance warranties8, 11
7Resend account and DNS (SPF/DKIM/DMARC) for sending domainsE-mail deliverability and spoofing protection13
8A staging deployment with test credentials for the five personasRun live e2e specs and the acceptance walk7
9Data-protection documents: privacy notice, sub-processor list, DPA with clients, backup and restore evidenceGDPR/POPIA exposure; recoverability9, 12
10Market and customer evidence (interviews, competitor positioning)Differentiation claims1

πŸ”’ Before signing (conditions precedent)

  • Owner to fix and deploy, to every client: restrict users updates to non-privileged columns (and stop trusting sign-up metadata for role); upgrade Next.js to β‰₯ 16.4; evidence both on live systems.
  • Obtain items 1–3 and 6 above; obtain a deed of IP assignment and originality warranties.
  • Agree a paid founder transition and retention period.

1️⃣ First 30 days

  • Close the High security findings: approval self-grant and approver removal, stored XSS in the brief, open redirect, unescaped e-mail HTML, QA harness routes in production builds; add rate limiting to auth endpoints.
  • Add Dependabot/Renovate, npm audit, CodeQL/Semgrep and secret scanning to CI; require PR review on main.
  • Add error tracking (e.g. Sentry) and alerts for cron failures and e-mail errors.
  • Second engineer completes a shadowed deploy, migration and incident drill.

2️⃣ 31–60 days

  • Route-level integration tests against a local Supabase for authorisation and the six most complex handlers; RLS tests for every user-writable table.
  • Move all browser-side writes behind API routes (or prove RLS enforces the same rules); introduce transactions (Postgres functions) for multi-row writes.
  • Automate migrations and record per-deployment schema state; correct the fresh-install documentation; replace xlsx.

3️⃣ 61–90 days

  • Run the journey suite in CI; stand up a shared staging environment.
  • Refactor the fat route handlers behind tests; paginate the capped queries; replace persisted long-lived signed URLs.
  • Decide the tenancy strategy: if the thesis is SaaS scale, scope the move to multi-tenant or to automated per-tenant provisioning (infrastructure-as-code).
  • Rewrite handover and process documentation for a human team; move the debt register into an issue tracker; delete dead code and orphaned schema.

🧾 Evidence

Synthesised from module files 01–13 in this folder. The highest-severity findings were independently re-verified while compiling this summary:

  • supabase/baseline.sql:1044–1046 (users update policy, no column restriction), :940–950 (handle_new_user reads role from metadata); src/lib/api-auth.ts:50, 123 (admin check reads users.role); no trigger or column grant on users found in baseline.sql or supabase/migrations/.
  • npm audit / npm audit --omit=dev (24 / 11 vulnerabilities); src/app/icon.tsx:1,16, src/app/apple-icon.tsx:1,14 (ImageResponse).
  • src/app/api/campaigns/[id]/members/[memberId]/route.ts:25–48 with src/lib/discipline.ts:58 (self-grant of approver discipline).
  • src/lib/brief.ts:187–195 returns HTML-looking text unescaped; brief-view.tsx:557 renders it; campaign PATCH accepts brief_text without sanitizeBriefHtml.
  • src/app/qa/layout.tsx:11 gates pages only; src/app/qa/{api,state,reset}/route.ts have no environment check.
  • git log --all β†’ one commit; LICENSE line 1.

⚠️ Risks

See Top 5 risks above; full registers are in each module's Risks section.

βœ… Recommendations

See Recommended next steps above. Priority order: conditions precedent β†’ 30 β†’ 60 β†’ 90 days.