businesses sharing one platform. It triages inbound work opportunities: classify → score → route to the right

4Consumes5Technologies

leadplatform — Repo Digest

The inbound side of Inexis lead generation: triage buyer-intent work opportunities and route each to the right business with a decision brief. Consumes the Intelligence Products packs; complementary to the Website Assessment engine.

What it is

“leadplatform — Lead / Opportunity Intelligence Platform. Internal decision-support tool for two Australian businesses sharing one platform. It triages inbound work opportunities: classify → score → route to the right business → produce an internal decision brief.” (CLAUDE.md). Explicitly “not a generic Upwork job scraper… a Lead Intelligence Platform that happens to use Upwork as its first live lead source.” (docs/vision).

Why it exists

Inbound opportunities (people actively looking to buy) are high-leverage but noisy. This platform qualifies and routes them deterministically to Inexis Digital (websites) or Inexis Consulting (AI/automation), producing a decision brief — so a human can bid with context. It “does not submit proposals, run outreach, or act as a CRM — humans still bid manually in Upwork.”

At a glance

Field Value
Slug leadplatform
System applications-agents
Architecture layer Applications & Agents (layer 4)
Owner Azwaan (github.com/azwaanameer/leadplatform)
Lifecycle active
Maturity active-development (Phase 1 complete; live Upwork ingestion wired, scoring deferred)
Stack Next.js 16 + React 19 (OpenNext→Cloudflare), Cloudflare Worker + D1, shared TS lib/
Latest commit proposals: 1 draft(s)
Last reviewed 2026-07-06

Business capability provided

Opportunity intelligence & routing — classify, score, and route inbound buyer-intent jobs to the correct Inexis business, with a decision brief and a 0–100 Upwork opportunity score (70+ surfaces).

Technical responsibilities

  • Own classification, scoring, routing, brief generation, and live Upwork ingestion → D1.
  • Explicitly does not: “submit proposals, run outreach, or act as a CRM”; and per ADR-002 excludes automated proposal submission, outreach automation, and any change to the website-assessment engine.

Core concepts

Concept Meaning
Job / UpworkJob An inbound opportunity (normalised + raw Upwork form).
Classification service / industry / complexity (an “AI-swappable seam”).
ScoreResult Six-dimension opportunity score (deterministic).
Route → Inexis Digital / Inexis Consulting / Review.
Upwork score 0–100 from budget / competition / client-spend / match.

Key workflows

  1. Live ingestion (Worker): OAuth2 Upwork fetch → pipeline.ts (classify + route; no scoring yet) → db.ts upsert (de-dupe on id) into D1.
  2. Engine validation: npm run validate:upwork over data/upwork-sample-jobs.json.
  3. Interactive triage (Next.js): manual job list → /new/[id] decision brief.

Technologies used

  • Two runtimes, one repo, sharing pure lib/ engines:
    • Web: Next.js 16, React 19, shadcn/Tailwind v4, deployed via OpenNext → Cloudflare; localStorage persistence (Phase 1).
    • Worker: Cloudflare Workers + D1, TypeScript, wrangler ^4, cron */30.
  • @base-ui/react, tsx for scripts. Two wrangler configs (leadplatform-web, leadplatform-ingest).
  • “This is NOT the Next.js you know” (AGENTS.md) — Next 16 has breaking changes.

Major modules / components

Module Responsibility
lib/ Framework-free decision engines (classify, score, route, upwork-score, upwork, types)
app/jobs/ Next.js triage/brief pages
worker/src/ index.ts (fetch + scheduled), pipeline.ts, db.ts, upwork-client.ts (OAuth2 + GraphQL)
migrations/ 0001_initial_schema.sql (jobs table, nullable score)
vendor/intelproducts/ Pinned git submodule (read-only pack contract)
scripts/ validate-upwork.ts, upwork-oauth-bootstrap.mjs

Capabilities

  • opportunity-intelligence — classify/score/route inbound opportunities
  • lead-ingestion — live Upwork OAuth2 ingestion → D1
  • decision-brief — internal brief generation

Upstream dependencies

Dependency Type Version Notes
intelproducts internal-repo (pinned git submodule) 0aedecb5… vendor/intelproducts/ — read-only pack contract
Upwork GraphQL API external-service marketplaceJobPostingsSearch; OAuth2
Cloudflare Workers / D1 external-service Ingestion runtime + store
Shared Skills internal-repo n/a Engineering capability (layer 1)

Downstream consumers

  • Human operators (internal decision-support) — no programmatic downstream consumer.
  • Uses intelproducts skills/proposal-generator to draft proposals (proposals/).

Major interfaces & integration points

  • Worker endpoints (leadplatform-ingest.*.workers.dev): GET /health, GET /jobs?agency=…, POST /ingest, GET /upwork/preview, POST /upwork/ingest, GET /upwork/whoami; cron */30 * * * *.
  • Upwork auth: OAuth2 authorization-code + refresh token; secrets via wrangler secret put (UPWORK_CLIENT_ID/SECRET/REFRESH_TOKEN/ORG_ID).
  • Pack contract: vendored intelproducts submodule (pin a version; treat as read-only).

Reusable assets exposed to other repositories

  • The pure lib/ decision engines (runtime-agnostic; the Worker reuses the same engines as the web app).
  • The routing table and the Upwork OAuth bootstrap pattern.

Architectural decisions

  • [ADR-001] Phase-1 MVP scope (Accepted) — deterministic evaluation; exclusions.
  • [ADR-002] Upwork as first live lead source (Accepted 2026-06-16) — consolidate on Workers + D1; scoring deferred. Plus docs/vision, docs/roadmap, docs/specs (classification, opportunity-scoring, knowledge-matching, opportunity-brief), docs/architecture/mvp-architecture.md.

Architecture snapshot

graph TD
    UP[Upwork GraphQL API] -->|OAuth2, cron */30| W[Cloudflare Worker<br/>worker/src/*]
    W --> LIB[Shared lib/ engines<br/>classify · route · score]
    LIB --> DB[(D1 · jobs)]
    WEB[Next.js 16 web app<br/>OpenNext → Cloudflare] --> LIB
    OP([Human operator]) --> WEB
    PACK[(intelproducts pack<br/>pinned submodule)] -.read-only.-> LIB

Current maturity

Active-development. Phase 1 (Next.js MVP) is “complete and validated”; Phase 2 decision logic is done (verified by npm run validate:upwork); the live Upwork client is implemented but token bootstrap is pending, and the Worker computes “no score yet” (scoring deferred per ADR-002). Phases 3–6 (intelligence extraction, proposal assistant, CRM + outcome learning, pursuit automation) are planned.

Roadmap

Phase 3 AI qualification / intelligence extraction → Phase 4 Proposal Assistant (demo selection) → Phase 5 CRM + outcome learning → Phase 6 pursuit automation. “Rule-based now, AI-swappable later.”

Known limitations

  • Worker computes no score yet; Upwork client field names “marked VERIFY pending first-run introspection.”
  • Phase-1 persistence is localStorage (no shared multi-user store).
  • Web deploy must run on Linux (OpenNext @ast-grep/napi fails on Windows) — use Cloudflare Workers Builds.
  • Extensive Upwork OAuth gotchas documented (CSRF/state, scope-freeze, redirect byte-match).

Future opportunities

Wire live Upwork scoring; AI-assisted qualification; consume the Website Assessment output as evidence for website opportunities; proposal assistant + outcome learning.

Relationship to the wider AI venture ecosystem

Layer-4 application serving Inexis Digital + Inexis Consulting — the inbound counterpart to the outbound outreachagent. It consumes Intelligence Products (pinned submodule) and is designed to consume the Website Assessment output. See the Applications & Agents system.