Pharmacy Price Tracker App EN - WR134/Knowledge-Base GitHub Wiki

🏥 Georgian Pharmacy Price Tracker

App Specification & Business Plan

Version: 1.0
Date: February 2, 2026
Status: Planning Phase


1. Executive Summary

A multi-platform price comparison app for the Georgian pharmaceutical market. It aggregates real-time pricing data from major Georgian pharmacies (PSP, Aversi, GPC, PharmaDepot), enabling users to find the best prices on medications, track price changes over time, and receive alerts when prices drop on products they care about.

The app targets Georgian consumers who want to save money on pharmaceutical purchases — a universal need in a price-sensitive market of ~3.7 million people.


2. Problem Statement

Georgian consumers currently have no easy way to compare pharmaceutical prices across pharmacies. To find the best deal, a person must manually visit multiple pharmacy websites or physical locations. This leads to overpaying for medications, wasted time comparing prices manually, no visibility into price trends or upcoming drops, and a lack of awareness about which pharmacy offers the best overall value.


3. Solution

A centralized platform that automatically scrapes, normalizes, and presents pricing data from Georgia's top pharmacies. Users can search for any product, instantly see who sells it cheapest, track prices over time, and get notified when prices drop.


4. Target Pharmacies (MVP)

Pharmacy Website Market Position
PSP psp.ge Major chain
Aversi aversi.ge Largest chain
GPC gpc.ge Major chain
PharmaDepot pharmadepot.ge Growing chain

Future expansion candidates: Pharmhouse, Natali Pharm, ABC Pharma, and regional pharmacies.


5. Core Features

5.1 Product Search & Comparison

  • Search by product name (Georgian and English)
  • Search by active ingredient
  • Filter by dosage, form (tablet, capsule, syrup), quantity
  • Side-by-side price comparison across all pharmacies
  • Sort by price, pharmacy, availability
  • Direct link to product on pharmacy website

5.2 Price History & Trends

  • 7-day price history chart for every product
  • Extended history (90 days, 1 year) for premium users
  • Price trend indicators (rising, falling, stable)
  • Average price calculations
  • Best time to buy insights

5.3 Watchlist & Notifications

  • Add products to a personal watchlist
  • Set target price thresholds per product
  • Push notifications when price drops below target
  • Notification when any price drop occurs on watchlist items
  • Daily/weekly digest option for watchlist changes
  • Free tier: 5 watchlist items, 1 notification per day
  • Premium tier: Unlimited watchlist, instant notifications

5.4 User Accounts

  • Email/password registration
  • Google sign-in
  • Watchlist sync across devices
  • Notification preferences
  • Search history

5.5 Product Catalog

  • Normalized product database with canonical names
  • Product categories (pain relief, antibiotics, vitamins, etc.)
  • Active ingredient cross-referencing
  • Brand vs. generic identification
  • Product images where available

6. Technical Architecture

6.1 Tech Stack Overview

Component Technology Reasoning
Frontend (Web) React + Next.js Industry standard, Vercel deployment, SEO benefits
Frontend (Mobile) React Native + Expo Code sharing with web, official Convex SDK
Backend/Database Convex Managed backend, real-time sync, TypeScript, generous free tier
Scraper Python (Playwright/Scrapy) Best scraping ecosystem, runs separately
Scraper Hosting Railway or Render Simple, affordable ($5-10/month)
Push Notifications Firebase Cloud Messaging (FCM) Free, unlimited, cross-platform
Web Hosting Vercel Free tier, perfect for Next.js
Auth Convex Auth (built-in) Integrated with backend
Language TypeScript (everywhere except scraper) Type safety, code sharing

6.2 Architecture Diagram

┌─────────────────────────────────────────────────────────────────────┐
│                                                                     │
│   SCRAPER SERVICE (Railway/Render, $5-10/month)                    │
│   ┌─────────────────────────────────────────────────────┐          │
│   │  Python + Playwright                                 │          │
│   │  • Visits pharmacy websites every 2-3 hours         │          │
│   │  • Parses product names, prices, availability       │          │
│   │  • Normalizes data                                  │          │
│   │  • Writes to Convex via HTTP API                    │          │
│   │  • Runs on cron schedule                            │          │
│   └─────────────────────────┬───────────────────────────┘          │
│                              │                                      │
└──────────────────────────────┼──────────────────────────────────────┘
                               │ writes data
                               ▼
┌─────────────────────────────────────────────────────────────────────┐
│                                                                     │
│   CONVEX (Managed Backend)                                         │
│   ┌─────────────────────────────────────────────────────┐          │
│   │                                                      │          │
│   │   Database                                           │          │
│   │   ├── products (canonical product catalog)          │          │
│   │   ├── pharmacyListings (per-pharmacy prices)        │          │
│   │   ├── priceHistory (historical price records)       │          │
│   │   ├── users (accounts, preferences)                 │          │
│   │   └── watchlistItems (user watchlists + targets)    │          │
│   │                                                      │          │
│   │   Functions                                          │          │
│   │   ├── queries: search, getPrices, getHistory...     │          │
│   │   ├── mutations: addToWatchlist, updatePrefs...     │          │
│   │   └── actions: triggerNotifications, cleanup...     │          │
│   │                                                      │          │
│   │   Real-time Sync                                     │          │
│   │   └── Automatic UI updates when prices change       │          │
│   │                                                      │          │
│   └─────────────────────────┬───────────────────────────┘          │
│                              │                                      │
└──────────────────────────────┼──────────────────────────────────────┘
                               │ real-time connection
                               │
              ┌────────────────┼────────────────┐
              │                │                │
              ▼                ▼                ▼
     ┌──────────────┐ ┌──────────────┐ ┌──────────────┐
     │   Web App    │ │  Android     │ │    iOS       │
     │  (Next.js)   │ │  (React     │ │  (React      │
     │   Vercel     │ │   Native)   │ │   Native)    │
     └──────────────┘ └──────────────┘ └──────────────┘

6.3 Database Schema

// products — Canonical product catalog
{
  canonicalName: string,       // "Paracetamol 500mg Tablets"
  nameKa: string,             // "პარაცეტამოლი 500მგ ტაბლეტები"
  activeIngredient: string,    // "Paracetamol"
  dosage: string,             // "500mg"
  form: string,               // "tablet" | "capsule" | "syrup" | "injection"
  quantity: number,           // 20
  category: string,           // "pain_relief"
  isBrand: boolean,           // true/false
  imageUrl?: string,
}

// pharmacyListings — Current prices per pharmacy
{
  pharmacyId: string,          // "psp" | "aversi" | "gpc" | "pharmadepot"
  productId: Id,   // reference to product
  originalName: string,        // name as scraped from pharmacy
  currentPrice: number,        // 4.50
  currency: string,            // "GEL"
  inStock: boolean,
  productUrl: string,          // direct link to pharmacy page
  lastScrapedAt: number,       // timestamp
}

// priceHistory — Historical price records
{
  listingId: Id,
  productId: Id,
  pharmacyId: string,
  price: number,
  recordedAt: number,          // timestamp
}

// users — User accounts
{
  email: string,
  name: string,
  authProvider: string,        // "email" | "google"
  isPremium: boolean,
  notificationPreferences: {
    pushEnabled: boolean,
    digestFrequency: string,   // "instant" | "daily" | "weekly"
  },
  createdAt: number,
}

// watchlistItems — User watchlists
{
  userId: Id,
  productId: Id,
  targetPrice?: number,        // notify when below this
  notifyOnAnyDrop: boolean,
  addedAt: number,
}

6.4 Monorepo Structure (for code sharing)

pharma-ge/
├── packages/
│   ├── shared/                 # Shared code (used by web & mobile)
│   │   ├── hooks/              # Business logic hooks
│   │   │   ├── useProductSearch.ts
│   │   │   ├── usePriceHistory.ts
│   │   │   ├── useWatchlist.ts
│   │   │   └── usePriceComparison.ts
│   │   ├── types/              # TypeScript interfaces
│   │   │   ├── product.ts
│   │   │   ├── pharmacy.ts
│   │   │   └── user.ts
│   │   └── utils/              # Helper functions
│   │       ├── priceFormatting.ts
│   │       ├── productMatching.ts
│   │       └── dateHelpers.ts
│   │
│   ├── web/                    # Next.js web app (Phase 1)
│   │   ├── app/                # Next.js app router pages
│   │   ├── components/         # Web-specific UI components
│   │   └── styles/
│   │
│   └── mobile/                 # React Native app (Phase 2)
│       ├── screens/            # Mobile screens
│       ├── components/         # Mobile-specific UI components
│       └── navigation/
│
├── convex/                     # Backend functions & schema
│   ├── schema.ts
│   ├── products.ts
│   ├── prices.ts
│   ├── watchlist.ts
│   ├── users.ts
│   └── notifications.ts
│
├── scraper/                    # Python scraper (separate service)
│   ├── scrapers/
│   │   ├── psp_scraper.py
│   │   ├── aversi_scraper.py
│   │   ├── gpc_scraper.py
│   │   └── pharmadepot_scraper.py
│   ├── normalizer.py           # Product name normalization
│   ├── matcher.py              # Cross-pharmacy product matching
│   ├── scheduler.py            # Cron scheduling
│   └── convex_client.py        # Writes data to Convex
│
└── docs/
    ├── spec.md                 # This document
    └── product-matching.md     # Product matching algorithm docs

7. Development Approach

7.1 AI-Assisted Development

Tool Purpose
Claude Code Primary AI coding agent for writing code
Vercel agent-browser Auto-verification of web UI during development
Mobile MCP (claude-in-mobile) Auto-verification on Android/iOS emulator

7.2 Development Phases

Phase 1: Web MVP (Weeks 1-2)

Goal: Functional web app with core features, deployed and testable.

Week Focus Deliverables
1 Setup & learning Project scaffolding, Convex setup, Next.js basics
2 Scraper MVP PSP + Aversi scrapers working, data in Convex
3 Product search Search page, price comparison UI
4 Price history Charts, trend indicators
5 User accounts & watchlist Auth, watchlist, basic notifications
6 Polish & deploy UI polish, Vercel deployment, testing

MVP scope:

  • 2 pharmacies (PSP, Aversi)
  • product matching logic finalized
  • Product search and price comparison
  • 7-day price history
  • Basic watchlist (no notifications yet)
  • Web only

Phase 2: Full Web App (Week 3)

Week Focus Deliverables
7 Add GPC + PharmaDepot scrapers 4 pharmacies covered
8 Push notifications FCM integration, watchlist alerts
9 Premium features Extended history, unlimited watchlist

Phase 3: Mobile App (Weeks 4-5)

Week Focus Deliverables
11-12 React Native setup Project setup, shared code integration
13-14 Mobile UI Rebuild screens for mobile UX
15 Mobile-specific features Push notifications, offline basics
16 App store launch Play Store + App Store submission

Phase 4: Growth (Ongoing)

  • Expand product catalog (1,000+ products)
  • Add more pharmacies
  • Pharmacy partnerships
  • Ads integration
  • Regional expansion considerations

8. Key Technical Challenges

8.1 Product Matching (Highest Risk)

The Problem: The same medication is listed with different names across pharmacies.

Pharmacy How They List It
PSP "პარაცეტამოლი ტაბ. 500მგ N20"
Aversi "Paracetamol 500mg tablets #20"
GPC "PARACETAMOL TAB 500MG №20"
PharmaDepot "პარაცეტამოლი 500 მგ 20 ტაბლეტი"

Approach:

  1. Start with manual curation for top 200 products
  2. Build normalization pipeline (lowercase, strip units, parse dosage)
  3. Match by active ingredient + dosage + form + quantity
  4. Fuzzy matching for names (Levenshtein distance)
  5. Manual review queue for uncertain matches
  6. Gradually automate as patterns emerge

8.2 Scraping Reliability

Risk Mitigation
Website structure changes Modular scrapers, easy to update per pharmacy
Rate limiting / blocking Respectful scraping intervals (2-3 hours), random delays
Legal / ToS issues Consider reaching out for official partnerships
JavaScript-rendered content Use Playwright (handles JS rendering)
Monitoring Alerts when scrape fails or returns unexpected data

8.3 Georgian Language Support

  • Full Georgian (ქართული) language support in UI
  • Bilingual search (Georgian and English product names)
  • Georgian Lari (₾ / GEL) currency formatting
  • Right text direction is not needed (Georgian is LTR)

9. Monetization Strategy

9.1 Revenue Streams

Stream 1: Advertising (Low effort, low revenue)

  • Banner ads on search results page
  • Interstitial ads between searches (non-intrusive)
  • Provider: Google AdMob (mobile), Google AdSense (web)
  • Expected CPM for Georgian market: $0.50-1.00

Stream 2: Premium Subscription (Medium effort, moderate revenue)

Feature Free Tier Premium (₾5/month)
Price comparison
Search
Price history 7 days 90 days+
Watchlist items 5 Unlimited
Price drop alerts 1/day Instant, unlimited
Ads Yes No ads

Stream 3: Pharmacy Partnerships (High effort, highest revenue)

Offering Price Range
Featured badge on listings $50-200/month
Priority placement in results $100-300/month
Competitor pricing analytics $100-500/month
Exclusive deals/coupons through app Revenue share
Sponsored product placements $50-150/month

9.2 Payment Integration

  • BOG iPay or TBC Pay for Georgian card payments
  • Google Play Billing for Android subscriptions
  • Apple In-App Purchase for iOS subscriptions

10. Financial Projections

10.1 Running Costs by Stage

Stage Users Convex Scraper Notifications Total/Month
MVP / Testing 0-500 $0 $0-5 $0 $0-5
Early Growth 500-5,000 $0-25 $5-7 $0 $5-32
Traction 5,000-20,000 $25-55 $7-15 $0 $32-70
Scale 20,000+ $55-150 $15-30 $0 $70-180

10.2 One-Time Launch Costs

Item Cost
Google Play Developer Account $25 (one-time)
Apple Developer Account $99/year
Domain name (pharmage.ge) $10-15/year
Total to launch ~$135

10.3 Revenue Projections (Ads + Premium Only, No Partnerships)

Users Ads Revenue Premium Revenue (1-2% conversion) Total Revenue Costs Profit
1,000 $5-10 $10-20 $15-30 $0-5 $10-30
5,000 $25-50 $50-100 $75-150 $5-32 $45-120
10,000 $50-100 $100-200 $150-300 $32-55 $95-265
50,000 $250-500 $500-1,000 $750-1,500 $70-180 $570-1,320

10.4 Revenue Projections (With Pharmacy Partnerships)

Users Ads + Premium Partnerships Total Revenue Costs Profit
10,000 $150-300 $200-500 $350-800 $32-55 $295-765
50,000 $750-1,500 $500-2,000 $1,250-3,500 $70-180 $1,070-3,320

10.5 Break-Even Analysis

With minimal costs ($0-5/month at start), the app is profitable from its very first ad impressions. There is effectively no break-even point to worry about — infrastructure costs are negligible until significant scale.


11. Market Analysis

11.1 Target Market

Metric Value
Georgia population ~3.7 million
Smartphone penetration ~70%
Internet users ~2.8 million
Addressable market (adults who buy medications) ~2 million
Realistic app users (niche utility app) 10,000-50,000

11.2 Competition

Competitor Status Notes
Direct competitor (pharmacy price comparison) None known Blue ocean opportunity
Individual pharmacy apps Exist (Aversi, PSP) Only show their own prices
Google search Indirect No real-time price comparison
Glovo & Wolt shows all pharmacy prices for given product Unreliable search, no price alerts

11.3 Growth Timeline Expectations

Milestone Expected Timeline
First 100 users 1 month after launch
First 1,000 users 3-6 months
First 10,000 users 6-18 months
First 50,000 users 18-36 months

12. Risks & Mitigations

Risk Severity Probability Mitigation
Pharmacies block scraping 🔴 High Medium Rotate IPs, respectful intervals, pursue API partnerships
Product matching too complex 🔴 High High Start small (200 products), manual curation, iterate
Low user adoption 🟡 Medium Medium Focus on solving real pain point, social media marketing
Legal/ToS issues 🟡 Medium Low Consult lawyer, pursue official partnerships
Scraper breaks frequently 🟡 Medium High Monitoring, modular design, quick fix workflow
Scaling costs 🟢 Low Low Costs grow slowly, revenue should outpace

13. Future Expansion Opportunities

Opportunity Description Potential
More pharmacies Add Pharmhouse, Natali Pharm, regional chains Medium
Electronics/retail Price tracking for other product categories High
Regional expansion Armenia, Azerbaijan — similar markets High
B2B analytics Sell pricing intelligence to pharmacies/distributors Medium-High
Chrome extension Show prices while browsing pharmacy websites Low-Medium

14. Success Metrics (KPIs)

Metric Target (6 months) Target (12 months)
Monthly Active Users 2,000 10,000
Daily Active Users 500 2,500
Products in database 500 2,000
Pharmacies covered 3 5+
Watchlist items created 5,000 30,000
Premium conversion rate 1% 2%
Monthly revenue $50-100 $300-800
App store rating 4.0+ 4.5+
Scraper uptime 95% 99%

15. Development Tools & Workflow

Tool Purpose
VS Code Code editor
Claude Code AI-assisted development (primary)
Vercel agent-browser Web UI auto-verification during development
claude-in-mobile MCP Mobile UI auto-verification
Git + GitHub Version control
Vercel Web app hosting & deployment
Railway Scraper hosting
Android Studio Android emulator management

Development Verification Flow

Claude Code writes/edits code
         │
         ├── Web: agent-browser opens localhost
         │    ├── Takes snapshot
         │    ├── Interacts with UI
         │    ├── Verifies behavior
         │    └── Iterates if needed
         │
         └── Mobile: MCP controls emulator
              ├── Takes screenshot
              ├── Taps, swipes, types
              ├── Verifies behavior
              └── Iterates if needed

This spec is a living document and should be updated as decisions are made and the project evolves.