Acasuso.
← All work

Prospector – internal lead intelligence

ICP evidence for one prospect: nine criteria, each scored with its source and verification state. Names blurred.Open full-size image ↗
ICP evidence for one prospect: nine criteria, each scored with its source and verification state. Names blurred.
Prospector on mobile: prospects ranked by ICP score with stage and next action. Company and owner names blurred.Open full-size image ↗
Prospector on mobile: prospects ranked by ICP score with stage and next action. Company and owner names blurred.

Category: Internal tool Status: Live, active development Time window: June 2026 → ongoing (182 commits over eight weeks) Live URL: Private subdomain, auth-gated

Purpose

Sales workbench for Stratas – deterministic ICP scoring, restricted-role Postgres access in a shared Supabase project, GDPR-defensible exports, mobile-first "Today" view.

Who it is for

Stratas' internal sales function. Replaces a prior fragmented setup (Google Sheet + Notion + LinkedIn tabs).

Stack

  • Frontend: Next.js 16 (App Router) + TypeScript + Tailwind
  • Auth: NextAuth (JWT credentials, bcrypt cost 12, session-version revocation)
  • Data: Supabase (shared project with dedicated prospector schema; restricted prospector_app DB role, NOLOGIN)
  • Orchestration: Trigger.dev v4 (enrichment, demo-build, sequence generation)
  • Paid APIs: Hunter, Firecrawl, EXA, Claude (Langfuse-tagged per call)
  • Exports: ExcelJS with formula-injection sanitizer

My contribution

Defined the sales workflow, shaped the workbench and scoring model, designed the tenant and data boundaries, and implemented the product. Tested authentication and isolation, delivered the application, and refined the daily workflow around sales use.

Notable capabilities

  • Dedicated Postgres schema + restricted DB role: PostgREST cannot escape the schema boundary
  • Deterministic ICP scoring with SHA-256 config-hash staleness detection; missing inputs = unscored (never zero-defaulted)
  • Excel export with formula-injection sanitizer (strips leading =, +, @, –)
  • GDPR default: personal emails excluded, ?includePersonalEmails=1 overrides with audit trail
  • Session revocation via session_version bump – no logout endpoint needed
  • SSRF guard: blocks internal ranges, caps redirects at 3, probes with GET Range: bytes=0-0

Outcome

80 test files, ~11,000 lines of test code. 16 idempotent migrations. Zero cross-schema access from Prospector's PostgREST calls – enforced by the database. Deterministic score, explainable per criterion.

Evidence

  • Case study: Related case study
  • Repo: private
  • Key files: supabase/migrations/002_prospector_app_role.sql, src/lib/scoring.ts, src/lib/xlsx-sanitize.ts, src/lib/ssrf-guard.ts, src/middleware.test.ts

Skills demonstrated

nextjs-16, nextauth-jwt, supabase-schema-isolation, postgres-restricted-role, postgrest-role-signing, deterministic-scoring, exceljs, formula-injection-defense, ssrf-guard, gdpr-marketing-defaults, bcrypt, trigger-dev-v4, mobile-native-workbench

Want to discuss the decisions behind it?

Over fifteen years of consulting and growth, and hands-on AI delivery from discovery to daily operations. I can share my CV and talk through how I connect business outcomes with systems that run.

Available for a chat. In person in Stavanger, or remotely worldwide.