Release Notes

A changelog of features, improvements, and fixes shipped to the GVCA AI Opportunity Platform.


Release 0.5.0 — Retired the Review queue

The standalone Review queue has been removed. Enrichment, triage, and auto-promote already do the lifting: construction-relevant items above 90% completeness flip to approved automatically, and everything else is now surfaced in-place on the main Opportunities list via a new Needs attention view (construction rows under 90%, not yet approved, sorted by lowest score first). One fewer screen to babysit, same workflow.


Release 0.4.0 — Partner Read API v1

Public API

  • Read-only REST API for 3rd parties (supplier portals, partner CRMs, match-as-a-service) at /api/public/v1/*. Construction-focused, paginated JSON with CORS enabled.
  • Endpoints:
    • GET /health — unauthenticated status probe.
    • GET /opportunities — cursor-paginated list with filters (status, relevance, jurisdiction, close-date window, updated-since).
    • GET /opportunities/:id — full opportunity DTO.
    • GET /opportunities/:id/documents — file metadata with 1-hour signed download URLs.
    • GET /opportunities/:id/contacts — structured contact list.
    • GET /opportunities/:id/classifications — CSI divisions, trades, market sectors, product categories.
    • GET /reference/{csi-divisions|trades|market-sectors|product-categories} — taxonomy lookups for matching engines.
  • Authentication: per-partner bearer tokens (Authorization: Bearer gvca_live_…). Keys are hashed at rest and shown once at issue time. Best-effort per-key rate limit (default 120 req/min per worker).
  • Admin UI: /admin/api-keys to issue, label, and revoke partner keys.
  • Docs: Swagger UI at /api/docs backed by a hand-written OpenAPI 3.1 spec — share the URL with partners for self-serve onboarding.

Triage tuning

  • Split construction keywords into strong (match title or scope) and weak (title-only, e.g. rehabilitation, building, infrastructure) to stop false positives like "rehabilitation sciences".
  • Added a supply/equipment denylist (supply of, purchase of, teaching model, …) to catch goods-only RFPs that previously slipped through the construction gate.

Release 0.3.0 — Analytics & auto-approval

Analytics

  • New Analytics page with a 7-day vs prior 7-day pipeline view: 5-stage funnel (Discovered → Triaged → Enriched → Docs → Approved), completeness distribution, status/relevance mix, throughput trend, and a per-connector performance table with success rate, average duration, and item deltas.

Review workflow

  • Auto-promote: opportunities flip from reviewapproved when relevance is construction and completeness ≥ 90. Manual status changes after auto-promote are respected. Header shows a muted "auto-approved" chip.
  • Retired per-field confidence badges on the opportunity detail page in favor of the project-wide Completeness score.

Triage & classification

  • Triage runs as an upfront rules gate (triage.server.ts) and routes non-construction items to a separate list so enrichment resources are spent on relevant tenders only.
  • AI triage fallback (triage-ai.server.ts) resolves ambiguous rows via Gemini when keyword rules don't decide.
  • Re-triage action on the Classification card lets you re-run the gate on a single opportunity; bulk re-triage paginates and parallelizes to stay under Worker time limits.
  • Classification card now shows the relevance verdict and how it was decided (Rules / AI / Manual).

Release 0.2.0 — Bids & Tenders to 100%

Bids & Tenders connector

  • Switched discovery to anonymous public fetches; per-portal credentials are now optional. 15 Ontario portals configured.
  • B&T detail parser extracts structured contacts, categories, trades, scope, and key dates from the sidebar HTML, overwriting low-quality AI output.
  • Hostname → owner mapping populates owning organization for all 15 B&T portals.
  • Guelph and other slow portals: faster renders via domcontentloaded, one-shot load retries, and fetch-first logic.
  • Resume cursors, active-run guards, and 20-minute stale-run cleanup prevent stuck runs.

Link2Build

  • JWT login support and Vue-SPA-aware session handling.
  • Structured JSON detail parser replaces HTML-on-AI extraction, with fallback chains for project_name, scope_summary, procurement_type, tender_stage, and federal multi-line contacts.
  • Document attach: walks detail.rootFolder and downloads files individually from /api/v1/file/{fileId}. Triggered automatically when a B&T row has fewer than 3 documents; "Attach L2B docs" button available on opportunity detail.
  • B&T ↔ L2B matching by solicitation number with fuzzy date fallback.

Documents & vectorization

  • Inngest mounted at /api/inngest for background PDF chunking and embedding via Gemini on the opportunity/docs.ready event.
  • remote_etag skip-guards avoid re-downloading unchanged files.

Enrichment runner

  • Server concurrency bumped to 8 with an 85s deadline (Cloudflare 100s cap), client-side 5-way fan-out from the dashboard.
  • overwrite flag and enrichOntarioOpen batch function with pagination and retry logic.
  • Connector detail page: collapsible Enrichment panel with live progress, 24h tender list, queued/running/done badges, and an "Enrich visible rows" action.
  • Timed-out runs marked partial instead of failed; registration_required surfaces as a muted note, not an error.

Merx

  • forceBrowser: true for JS-shell pages with hidden content.

Release 0.1.0 — Triage, scoring, and dedup

  • Completeness score replaces ad-hoc confidence as the primary quality signal across dashboard and detail views.
  • Canonical key for cross-source deduplication.
  • document_chunks table for vectorized PDF content.
  • Dashboard thermometer for Ontario open completeness with immediate invalidation after mutations.

Release 0.0.1 — Initial pilot

Platform

  • TanStack Start app shell with file-based routing.
  • Lovable Cloud backend with row-level security on all public tables.
  • Dashboard with counts by status and a recent-activity feed.
  • Opportunities and Connectors screens with create/edit flows.

Connectors

  • CanadaBuys and Bonfire polling connectors driven by the cron endpoint at /api/public/cron/run-connectors, scheduled every 30 minutes.
  • Bids & Tenders connector with multi-portal support. Tries the JSON API first and falls back to an HTML scrape; list-only on the regular run, with documents fetched on a separate pass.
  • Firecrawl rendering wired into the Bids & Tenders connector so the JS-driven list table populates correctly.

Ingestion

  • Inbound email channel accepts forwarded tender notifications and extracts attachments into draft opportunities.
  • Manual ingest page accepts pasted text or uploaded PDFs for one-off opportunities.

Review queue

  • Confidence badges highlight uncertain AI-extracted fields inline on the review screen.
  • Review queue ranks items by confidence and surfaces duplicate candidates side-by-side with the incoming opportunity.

Support

  • Unprotected /support area with this changelog and a user guide.

Coming next

  • Connector-cost telemetry on the analytics page (AI calls, tokens, $ spend).
  • Bulk approve/reject in the review queue.
  • Saved filters and email digests on the Opportunities list.