TenderLo is a Pakistan Tender Intelligence SaaS for contractor companies. It combines official tender portals, publicly accessible newspaper notices, deterministic field extraction, Profile Vault compliance checks, RECON recommendations, QA review, alerts, and billing.
- Install Node 22+ and npm 9+.
- Install Supabase CLI and Tesseract OCR on your machine.
- Copy
.env.exampleto.env.localand fill Supabase, SMTP, PayFast, and Meta WhatsApp values. - Install dependencies:
npm install- Apply database migrations with Supabase:
npm run db:push- Apply seed data from
packages/db/seeds/seed.sqlthrough your Supabase SQL editor or localpsqlconnection. The seed creates source adapters, extraction rules, and a confirmed local ops admin account:
Email: admin@tenderlo.local
Password: TenderLo Admin123!
Role: ops_admin
- Run the web app:
npm run dev- Run worker jobs:
npm run worker -- ingest-all- Public visitors can open marketing, pricing, demo, and tender preview pages.
- Protected SaaS routes redirect unauthenticated users to
/loginwith a safe return path. - Sign-up validates name, email, password length, and password confirmation before creating a Supabase Auth user.
- If Supabase requires email confirmation, sign-up sends the user back to sign in instead of opening onboarding without a session.
- Authenticated users without an active organization membership are routed to
/onboarding; users with membership go to/dashboard.
apps/web: Next.js App Router UI and API routes.apps/worker: Node worker for ingestion, parsing, scoring, and alerts.packages/db: Supabase clients, migrations, and database helpers.packages/sources: source adapters for portals, departments, and newspapers.packages/parsing: local HTML/PDF/DOCX/OCR parsing.packages/intelligence: deterministic extraction, classification, and dedupe.packages/scoring: PEC-aware recommendations, compliance checks, and plan gates.packages/notifications: SMTP, in-app, and Meta WhatsApp notification delivery.packages/shared: schemas, constants, and shared contracts.
Tender intelligence is deterministic and evidence-backed. Hosted AI, hosted OCR, hosted document-intelligence APIs, and opaque recommendation logic are intentionally not used.
- Public tender previews live at
/tenders; authenticated contractor search lives at/search. GET /api/tenderssupports primary filters foravailability,closing_date_filter,estimated_cost_filter,category,city,province, andorganization, plus compatible advanced filters such assector,source,department, explicit closing-date/value ranges,pec_category,eligible_only,sort,page, andlimit.- The API returns
{ data, pagination, meta }, wheremeta.planAccessisfree,paid, orops. - Non-ops searches are limited to public tender lifecycle states and default to active tenders. Free/public responses omit source URLs, tender values, bid security, document fees, and documents.
- Search uses the generated Postgres
search_documenttsvector plus filter indexes on status/source/closing date, geography, sector, department, estimated value, bid security, PEC extracted fields, and recommendation status/score. - Procurement category filtering uses the controlled 55-category tender taxonomy, and province filtering uses the seven major Pakistan administrative regions.
- The web app uses Tailwind design tokens in
apps/web/tailwind.config.tsand motion-safe global utilities inapps/web/app/globals.css. - Framer Motion powers page transitions, staggered lists, animated counters, progress bars, and RECON score rings through shared components in
apps/web/components/motion.tsx. - Shared UI primitives in
apps/web/components/ui.tsxprovide consistent cards, buttons, badges, skeletons, empty states, and metric cards. - Public pages, auth forms, app shell navigation, dashboard, search, tender previews, recommendations, Profile Vault, billing, documents, alerts, and team screens use the updated visual system.
- Reduced-motion preferences are respected through CSS and motion component fallbacks.
- Schema, RLS policies, storage buckets, and seed data live in
packages/db; the Supabase migration mirror is kept insupabase/migrations. - Private storage buckets are
tender-source-snapshots,tender-documents, andprofile-documents, with additional private buckets for newspaper clippings and bid-package documents. - Source adapters pass raw snapshot content when available; the worker stores it with a
content_hashintender-source-snapshotsand records metadata inraw_source_snapshots. - Automated ingestion preserves human-verified tender rows and verified extracted fields, while low-confidence extraction, parser failures, duplicate review, and repeated source failures create deduped QA tasks.