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
- Live ingestion (Worker): OAuth2 Upwork fetch →
pipeline.ts(classify + route; no scoring yet) →db.tsupsert (de-dupe on id) into D1. - Engine validation:
npm run validate:upworkoverdata/upwork-sample-jobs.json. - 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;
localStoragepersistence (Phase 1). - Worker: Cloudflare Workers + D1, TypeScript,
wrangler ^4, cron*/30.
- Web: Next.js 16, React 19, shadcn/Tailwind v4, deployed via OpenNext → Cloudflare;
@base-ui/react,tsxfor 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 opportunitieslead-ingestion— live Upwork OAuth2 ingestion → D1decision-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
intelproductsskills/proposal-generatorto 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
intelproductssubmodule (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/napifails 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.
Links
- Source:
github.com/azwaanameer/leadplatform(private) - System: Applications & Agents
- Registry row: repo registry