Skip to content

Gabriel-Falade/Marketlens

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

MarketLens

Pricing intelligence for informal economies.

MarketLens is a full-stack platform that tracks, analyzes, and surfaces real-time price data from informal markets across the globe. It combines crowdsourced price observations with World Bank macroeconomic data, FAO producer price records, and live humanitarian alerts to compute an Informal Inflation Index (III) for each tracked market. An AI layer powered by Claude generates contextual price analysis, negotiation guidance, and market summaries.

The platform ships as a cross-platform mobile and web app (Expo / React Native Web) backed by a Python Flask API.


Table of Contents


Features

Market Intelligence

  • Informal Inflation Index (III) - composite deviation score per market, updated in real time as observations come in
  • Volatility Score - weighted coefficient of variation across all tracked items in a market
  • Price Trend Acceleration (PTA) - percentage change in average price week-over-week
  • Real Inflation Differential (RID) - gap between the informal III and official CPI from the World Bank
  • Confidence Score - composite metric of observation volume, reporter diversity, and data recency

Price Map

  • Interactive heatmap of all tracked markets (mobile)
  • Zoom-to-market with item-level price zone circles
  • Card-based deviation view on web (native map not available in browser)

Price Observation Submission

  • Submit a price for any tracked item in any market
  • Instant AI-powered analysis: deviation score, fairness rating, and negotiation guidance
  • Dry-run mode to analyze without saving to the dataset
  • Observations persist to PostgreSQL and improve the baseline for all users

Field Scanner

  • Point camera at any market item to identify it (mobile)
  • File upload fallback on web
  • Sends image to Claude for identification, then routes to price lookup

Item Lookup

  • Search all items across any market
  • View price range (min, mean, max) with observation counts

Supply Disruption Alerts

  • Live disaster feed from ReliefWeb API
  • Disruption events automatically raise item baselines in affected categories (drought raises staples 35%, cyclone raises staples and merchandise 40%, etc.)

AI Market Analysis

  • Per-market narrative summary generated by Claude on each analysis cycle
  • Per-submission insights: price context, severity label, negotiation script with cultural adaptation per city

Architecture

┌─────────────────────────────────────────┐
│           Expo App (client/)            │
│   React Native + React Native Web       │
│                                         │
│  Mobile routes    Web-only routes       │
│  map.tsx          map.web.tsx           │
│  scan.tsx         scan.web.tsx          │
└───────────────┬─────────────────────────┘
                │  HTTP (REST)
                │  localtunnel for physical device
                v
┌─────────────────────────────────────────┐
│           Flask API (backend/)          │
│                                         │
│  /markets        /market/:id            │
│  /price/submit   /identify              │
│  /intel/global   /intel/:id             │
│  /intel/export   /heatmap               │
└──────┬───────────────────┬──────────────┘
       │                   │
       v                   v
┌─────────────┐    ┌───────────────────────┐
│  PostgreSQL │    │   External APIs       │
│             │    │                       │
│ market_     │    │  Anthropic Claude     │
│ reports     │    │  World Bank API       │
│             │    │  ReliefWeb API        │
│             │    │  FAO CSV Data         │
└─────────────┘    └───────────────────────┘

Baseline computation pipeline:

  1. FAO producer price CSV gives a historical floor for each item in each region
  2. World Bank CPI and food inflation multipliers adjust that floor for current macroeconomic conditions
  3. ReliefWeb disaster events add a category-specific shock multiplier if active
  4. Community observations from PostgreSQL further refine the baseline if enough data exists
  5. Submitted prices are scored against this adjusted baseline using a z-score method

Tech Stack

Mobile and Web Client

Technology Version Role
React Native 0.81.5 Core UI framework
Expo SDK 54 Native module management, build tooling
Expo Router 6 File-based navigation (Stack routing)
TypeScript 5.9 Type safety across all screens
React Native Web 0.21 Browser rendering of React Native components
React Native Maps 1.20 Interactive map with heatmap (mobile only)
Expo Camera 17 Live camera for field scanner (mobile only)
Expo Vector Icons 15 Ionicons icon set
React Native Reanimated 4 Smooth animations
React Native Gesture Handler 2 Gesture input
React Native SVG 15 SVG rendering

Backend

Technology Version Role
Python 3.11+ Runtime
Flask 3.x REST API framework
Flask-CORS 5.x Cross-origin request handling
psycopg2 2.9 PostgreSQL driver
NumPy 2.x Numerical computation for baseline stats
SciPy 1.x Statistical modeling, z-score anomaly detection
pandas 2.x FAO CSV ingestion and data manipulation
Anthropic Python SDK 0.x Claude API client for AI analysis
python-dotenv 1.x Environment variable management
requests 2.x HTTP calls to World Bank and ReliefWeb

Database

Technology Role
PostgreSQL Stores all price observations (market_reports table)

External APIs

API Role
Anthropic Claude Item identification from images, price analysis narratives, negotiation scripts, market summaries
World Bank API Official CPI and food inflation rates by country, used to adjust FAO baselines
ReliefWeb API Live humanitarian disaster feed, used to detect supply shocks
FAO Producer Prices Historical producer price CSV files for West Africa, India, and France, used as baseline floor

Infrastructure and Tooling

Tool Role
localtunnel Exposes local Flask server to physical devices during development
ThreadPoolExecutor Parallel baseline computation per market item on each API request
In-memory cache TTL-based response cache in Flask to avoid repeated external API calls

Getting Started

Prerequisites

  • Node.js 18+ and npm
  • Python 3.11+
  • PostgreSQL (local or remote, e.g. Neon, Supabase, Railway)
  • An Anthropic API key
  • Expo Go installed on your phone (for mobile testing)

Backend Setup

cd backend
python -m venv venv
source venv/bin/activate        # Windows: venv\Scripts\activate
pip install -r requirements.txt

Create a .env file in backend/:

DATABASE_URL=postgresql://user:password@host:5432/marketlens
ANTHROPIC_API_KEY=sk-ant-...

Run migrations and start the server:

python app.py
# API available at http://localhost:5000

Client Setup

cd client
npm install

Update app/constants.ts to point to your backend:

// Local development
export const API_BASE = 'http://localhost:5000';

// Physical device (replace with your machine's local IP)
export const API_BASE = 'http://192.168.x.x:5000';

// Tunnel (for sharing across networks)
export const API_BASE = 'https://your-tunnel.loca.lt';

Running on Mobile

cd client
npx expo start --clear
# Scan the QR code with Expo Go on your phone

Running on Web

cd client
npm run web
# Opens at http://localhost:8081

Note: the map screen automatically uses a card-based web layout instead of the native map component. The field scanner uses a file upload instead of the camera.


Project Structure

Marketlens/
├── backend/
│   ├── app.py                   # Flask app, all route definitions
│   ├── models/
│   │   ├── anomaly.py           # Z-score baseline and price anomaly detection
│   │   ├── claude_insights.py   # Claude API calls for analysis and summaries
│   │   └── intelligence.py      # III, volatility, PTA, RID, confidence computation
│   ├── services/
│   │   ├── fao.py               # FAO CSV ingestion and price floor lookup
│   │   ├── worldbank.py         # World Bank CPI/food inflation API
│   │   └── reliefweb.py         # ReliefWeb disaster feed and shock multipliers
│   └── data/
│       └── raw/                 # FAO producer price CSV files
│
├── client/
│   └── app/
│       ├── constants.ts         # API base, color palette, market and item definitions
│       ├── index.tsx            # Home screen with active indices
│       ├── map.tsx              # Interactive price map (mobile)
│       ├── map.web.tsx          # Card-based deviation view (web)
│       ├── scan.tsx             # Camera-based field scanner (mobile)
│       ├── scan.web.tsx         # File upload scanner (web)
│       ├── search.tsx           # Item lookup and price search
│       ├── report.tsx           # Price observation submission
│       ├── intelligence.tsx     # III dashboard with signals
│       ├── market/[id].tsx      # Market detail with price index
│       ├── item/[name].tsx      # Item detail with price history
│       └── lib/
│           └── cache.ts         # Client-side fetch cache
│
└── design/
    └── web-dashboard-spec.md    # B2B web dashboard design specification

API Reference

All endpoints are served from the Flask backend. Default port: 5000.

Method Endpoint Description
GET /health Server health check
GET /markets All markets with current deviation rates and disaster flags
GET /heatmap Simplified heatmap data (coordinates, color, deviation)
GET /market/:id Full market detail: items, price ranges, summary, disaster status
POST /price/submit Submit a price observation; returns AI analysis and score
POST /identify Identify an item from a base64 image using Claude
GET /intel/global Global composite III, volatility, confidence across all markets
GET /intel/:id Single-market intelligence snapshot
GET /intel/history/:id 8-week historical III and volatility series
GET /intel/export Full B2B data export for all markets

POST /price/submit

Request body:

{
  "market_id": "lagos",
  "item_name": "Imported Rice (50kg bag)",
  "submitted_price": 45000,
  "quality": 7,
  "amount": "50kg",
  "reporter_type": "local",
  "neighborhood": "Balogun",
  "dry_run": false
}

POST /identify

Request body:

{
  "image_base64": "<base64-encoded image>",
  "market_id": "lagos"
}

External Data Sources

FAO Producer Prices

CSV files sourced from the FAO STAT database covering producer prices for West Africa, India, and France. These files live in backend/data/raw/ and provide the historical price floor used to anchor baselines.

World Bank API

Fetches annual CPI (FP.CPI.TOTL.ZG) and food price inflation (FP.FPI.TOTL.ZG) for Nigeria, India, and France. This inflation multiplier adjusts FAO baselines to account for macroeconomic conditions. Results are cached locally to avoid hitting rate limits.

ReliefWeb API

Live humanitarian alert feed from ReliefWeb. The backend queries for active disaster events in each market's country and maps disaster types (drought, flood, cyclone, epidemic) to price category multipliers. Example: a drought raises staple food baselines by 35%.

Anthropic Claude

Used for three distinct tasks:

  1. Item identification - given a base64 image and market context, returns the identified item name and its expected price range
  2. Price analysis - given a submitted price and baseline data, returns a fairness score, severity label, deviation percentage, and a culturally-adapted negotiation script
  3. Market summaries - given a market's current deviation rate and flagged items, returns a paragraph of contextual analysis displayed on the market detail screen

Environment Variables

Backend (backend/.env)

Variable Description
DATABASE_URL PostgreSQL connection string
ANTHROPIC_API_KEY Anthropic API key for Claude

Client (client/app/constants.ts)

Constant Description
API_BASE Base URL of the Flask backend
TUNNEL_HEADERS Headers required to bypass localtunnel browser warning

Tracked Markets

Market City Currency
Balogun Market Lagos, Nigeria NGN (Naira)
Chandni Chowk Delhi, India INR (Rupee)
Marche de Metz Metz, France EUR (Euro)

Each market tracks 8 items covering staple foods, street food, and local merchandise.


Built for Hackalytics 2026.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors