Admin Dashboard UI
Relevant source files
The following files were used as context for generating this wiki page:
The Admin Dashboard UI is a restricted management interface designed for system administrators to oversee and maintain the core data operations of the price comparison system. Its primary functions include managing product-to-canonical mappings, monitoring the "freshness" of scraped data, and controlling the execution of web scrapers across multiple countries and supermarkets.
The interface is built using React and TailwindCSS, relying on a set of administrative REST API endpoints protected by Google OAuth 2.0 authentication. It ensures that cross-country price comparisons remain accurate by allowing manual intervention in product matching and providing visibility into the time-series data health.
Sources: README.md:11-20, frontend/src/i18n/locales/en.json:115-125, src/api/server.ts:80-95
Core Administrative Modules
The dashboard is divided into several specialized modules, each targeting a specific aspect of the data lifecycle.
Product Mapping and Canonical Management
This module allows administrators to link disparate products from various supermarkets to a single "Canonical Product." This linking is essential for the cross-country comparison engine to recognize that a product in Turkey is the same as one in Spain.
- Linking Logic: Administrators can search for products by country and link them to existing canonical identifiers or create new ones.
- Per-Unit Configuration: Admins can toggle whether a product should be compared by total price or per-unit price (e.g., price per kg).
- Status Control: Canonical products can be disabled or hidden from the public comparison table if the data is deemed unreliable.
Sources: frontend/src/i18n/locales/en.json:126-150, src/api/routes/canonical.ts:150-185, frontend/src/services/api.ts:75-90
Canonical Freshness Tracking
The Freshness module provides a data-health view of mapped products. It detects "stale" links by tracking the last date a product's price was successfully scanned.
- Stale Threshold: By default, products not updated within 7 days are marked as stale.
- Coverage Analysis: Displays how many countries and markets are currently covered by a specific canonical mapping.
- Scan Monitoring: Tracks
last_price_updated_atto identify scrapers that may be failing or supermarkets that have changed their site structure.
Sources: frontend/src/pages/admin/CanonicalFreshness.tsx:10-35, src/api/routes/canonical.ts:55-75, frontend/src/i18n/locales/en.json:151-170
Scraper Control and Monitoring
The Scraper module provides manual overrides and real-time status for the automated data collection system.
- Manual Trigger: Allows administrators to force-run a specific scraper or target specific categories for immediate updates.
- Statistics: Tracks success/failure rates and the total volume of products scraped within a 24-hour window.
- Audit Logs: Provides access to detailed
scrape_logsincluding start times, durations, and specific error messages encountered during browser automation.
Sources: frontend/src/services/api.ts:165-185, frontend/src/i18n/locales/en.json:106-125, README.md:75-85
System Architecture and Data Flow
The Admin Dashboard operates as a Single Page Application (SPA) that interacts with a Node.js Express backend. The following diagram illustrates the interaction between the UI components and the backend services.
The diagram shows the flow of an administrative request, from the user interface through the isAdmin authentication middleware to the data repositories.
Sources: src/api/server.ts:40-60, src/api/routes/canonical.ts:1-15, frontend/src/services/api.ts:5-15
Administrative API Endpoints
The dashboard consumes specific protected routes under the /api prefix.
| Method | Endpoint | Description | Required Payload |
|---|---|---|---|
GET | /api/canonical/mapped-products | List mapped products with stale status | stale_only, stale_days |
POST | /api/canonical | Create new canonical product | name, category_id |
PUT | /api/canonical/link | Link/Unlink product to canonical | product_id, canonical_product_id |
POST | /api/scraper/trigger | Manually run a scraper | supermarket_id, categories |
GET | /api/scraper/status | Real-time scraper stats | N/A |
Sources: src/api/routes/canonical.ts:25-50, frontend/src/services/api.ts:165-175, README.md:95-110
Implementation Details
Freshness Calculation Logic
The "Age" of a mapping is calculated in the frontend using the stale_days field returned by the API. The UI applies conditional styling (e.g., bg-amber-50 for stale, bg-red-50 for never scanned) to alert administrators.
// Sample logic from CanonicalFreshness.tsx
const isNeverScanned = row.last_price_updated_at == null;
const isStale = !isNeverScanned && (row.stale_days ?? 0) >= staleThreshold;
const rowClass = isNeverScanned
? 'bg-red-50/70 hover:bg-red-50'
: isStale
? 'bg-amber-50/70 hover:bg-amber-50'
: 'hover:bg-slate-50';
Sources: frontend/src/pages/admin/CanonicalFreshness.tsx:100-110
Scraper Interaction Sequence
When an administrator triggers a scraper manually, the system follows a specific sequence to ensure the request is authorized and correctly logged.
Sequence of events when a manual scraper trigger is initiated from the Admin Dashboard.
Sources: frontend/src/services/api.ts:167-172, src/api/server.ts:85-90, frontend/src/i18n/locales/en.json:115-120
Conclusion
The Admin Dashboard UI serves as the central control plane for the "WhereIsLifeCheaper" project. By centralizing product mapping, freshness monitoring, and scraper control, it enables administrators to maintain a high-quality dataset across multiple international markets, ensuring the end-user comparison tools remain accurate and up-to-date.