Update: 2026-06-30 21:12:26
This commit is contained in:
@@ -37,7 +37,7 @@ try {
|
|||||||
$anomalies = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
$anomalies = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
||||||
|
|
||||||
// Fetch some recent competitor prices for context
|
// Fetch some recent competitor prices for context
|
||||||
$sqlPrices = "SELECT * FROM competitor_prices";
|
$sqlPrices = "SELECT * FROM scraped_competitor_prices";
|
||||||
$paramsPrices = [];
|
$paramsPrices = [];
|
||||||
if ($countryCode) {
|
if ($countryCode) {
|
||||||
$sqlPrices .= " WHERE country_code = :country";
|
$sqlPrices .= " WHERE country_code = :country";
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ try {
|
|||||||
DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') AS hour_bucket,
|
DATE_FORMAT(created_at, '%Y-%m-%d %H:00:00') AS hour_bucket,
|
||||||
AVG(price_per_km) AS avg_price_per_km,
|
AVG(price_per_km) AS avg_price_per_km,
|
||||||
COUNT(*) AS sample_count
|
COUNT(*) AS sample_count
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)";
|
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)";
|
||||||
$compParams = [];
|
$compParams = [];
|
||||||
if ($countryCode) {
|
if ($countryCode) {
|
||||||
@@ -33,12 +33,12 @@ try {
|
|||||||
|
|
||||||
// 2. PCI by region — group competitor prices by ~0.02° grid cells
|
// 2. PCI by region — group competitor prices by ~0.02° grid cells
|
||||||
$pciSql = "SELECT
|
$pciSql = "SELECT
|
||||||
ROUND(from_latitude * 50, 0) / 50 AS lat_group,
|
ROUND(start_lat * 50, 0) / 50 AS lat_group,
|
||||||
ROUND(from_longitude * 50, 0) / 50 AS lng_group,
|
ROUND(start_lng * 50, 0) / 50 AS lng_group,
|
||||||
competitor_name,
|
competitor_name,
|
||||||
AVG(price_per_km) AS avg_price_per_km,
|
AVG(price_per_km) AS avg_price_per_km,
|
||||||
COUNT(*) AS samples
|
COUNT(*) AS samples
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
|
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
|
||||||
$pciParams = [];
|
$pciParams = [];
|
||||||
if ($countryCode) {
|
if ($countryCode) {
|
||||||
|
|||||||
@@ -35,13 +35,13 @@ try {
|
|||||||
|
|
||||||
// Aggregate competitor data by geographical grid (approx 1.5km x 1.5km)
|
// Aggregate competitor data by geographical grid (approx 1.5km x 1.5km)
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
ROUND(from_latitude * 74, 0) / 74 AS lat_group,
|
ROUND(start_lat * 74, 0) / 74 AS lat_group,
|
||||||
ROUND(from_longitude * 74, 0) / 74 AS lng_group,
|
ROUND(start_lng * 74, 0) / 74 AS lng_group,
|
||||||
AVG(price_per_km) as avg_competitor_price_per_km,
|
AVG(price_per_km) as avg_competitor_price_per_km,
|
||||||
COUNT(*) as trip_count
|
COUNT(*) as trip_count
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :country
|
WHERE country_code = :country
|
||||||
AND distance_km > 0
|
AND price_per_km > 0
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||||
GROUP BY lat_group, lng_group
|
GROUP BY lat_group, lng_group
|
||||||
HAVING trip_count >= 3"; // Require at least 3 trips for a reliable heatmap point
|
HAVING trip_count >= 3"; // Require at least 3 trips for a reliable heatmap point
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ try {
|
|||||||
// 1. حساب الـ baseline (آخر 7 أيام، بدون آخر 6 ساعات)
|
// 1. حساب الـ baseline (آخر 7 أيام، بدون آخر 6 ساعات)
|
||||||
// و current (آخر ساعتين) لكل منافس في كل خلية grid
|
// و current (آخر ساعتين) لكل منافس في كل خلية grid
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
ROUND(cp.from_latitude * 74, 0) / 74 AS lat_group,
|
ROUND(cp.start_lat * 74, 0) / 74 AS lat_group,
|
||||||
ROUND(cp.from_longitude * 74, 0) / 74 AS lng_group,
|
ROUND(cp.start_lng * 74, 0) / 74 AS lng_group,
|
||||||
cp.competitor_name,
|
cp.competitor_name,
|
||||||
cp.country_code,
|
cp.country_code,
|
||||||
AVG(CASE WHEN cp.created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)
|
AVG(CASE WHEN cp.created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)
|
||||||
@@ -42,7 +42,7 @@ try {
|
|||||||
THEN cp.price_per_km END) AS current_avg,
|
THEN cp.price_per_km END) AS current_avg,
|
||||||
COUNT(*) AS total_samples,
|
COUNT(*) AS total_samples,
|
||||||
SUM(CASE WHEN cp.created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR) THEN 1 ELSE 0 END) AS recent_samples
|
SUM(CASE WHEN cp.created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR) THEN 1 ELSE 0 END) AS recent_samples
|
||||||
FROM competitor_prices cp
|
FROM scraped_competitor_prices cp
|
||||||
WHERE cp.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
WHERE cp.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||||
AND cp.price_per_km > 0
|
AND cp.price_per_km > 0
|
||||||
$where
|
$where
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ $siroBasePrice = filterRequest('siro_base_price', 'float') ?? 10000.0;
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
// 3. Fetch recent competitor prices for this region to supply context to Gemini
|
// 3. Fetch recent competitor prices for this region to supply context to Gemini
|
||||||
$sqlPrices = "SELECT competitor_name, total_price, distance_km
|
$sqlPrices = "SELECT competitor_name, price_amount AS total_price, (price_amount / price_per_km) AS distance_km
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :country
|
WHERE country_code = :country AND price_per_km > 0
|
||||||
ORDER BY created_at DESC LIMIT 10";
|
ORDER BY created_at DESC LIMIT 10";
|
||||||
$stmtPrices = $con->prepare($sqlPrices);
|
$stmtPrices = $con->prepare($sqlPrices);
|
||||||
$stmtPrices->execute([':country' => strtoupper($countryCode)]);
|
$stmtPrices->execute([':country' => strtoupper($countryCode)]);
|
||||||
|
|||||||
@@ -22,10 +22,10 @@ try {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 1. Fetch recent competitor trips (last 7 days, limit 500 for fast simulation)
|
// 1. Fetch recent competitor trips (last 7 days, limit 500 for fast simulation)
|
||||||
$sql = "SELECT distance_km, total_price, competitor_name
|
$sql = "SELECT (price_amount / price_per_km) AS distance_km, price_amount AS total_price, competitor_name
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :country
|
WHERE country_code = :country
|
||||||
AND distance_km > 0
|
AND price_per_km > 0
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||||
ORDER BY created_at DESC
|
ORDER BY created_at DESC
|
||||||
LIMIT 500";
|
LIMIT 500";
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ if (empty($data) || !is_array($data)) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
$insertedCount = 0;
|
$insertedCount = 0;
|
||||||
$stmt = $con->prepare("INSERT INTO scraped_competitor_prices (task_id, app_name, start_location, end_location, price_amount, currency) VALUES (?, ?, ?, ?, ?, ?)");
|
$stmt = $con->prepare("INSERT INTO scraped_competitor_prices (task_id, app_name, competitor_name, start_location, end_location, start_lat, start_lng, end_lat, end_lng, price_amount, price_per_km, currency, country_code) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)");
|
||||||
|
|
||||||
foreach ($data as $row) {
|
foreach ($data as $row) {
|
||||||
if (isset($row['status']) && $row['status'] !== 'success') {
|
if (isset($row['status']) && $row['status'] !== 'success') {
|
||||||
@@ -83,7 +83,21 @@ foreach ($data as $row) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($stmt->execute([$taskId, $appName, $startLoc, $endLoc, $amount, $currency])) {
|
$distanceKm = (float)($resultData['distance_km'] ?? 1);
|
||||||
|
if ($distanceKm <= 0) $distanceKm = 1;
|
||||||
|
$pricePerKm = $amount / $distanceKm;
|
||||||
|
|
||||||
|
$startLat = $resultData['start_lat'] ?? null;
|
||||||
|
$startLng = $resultData['start_lng'] ?? null;
|
||||||
|
$endLat = $resultData['end_lat'] ?? null;
|
||||||
|
$endLng = $resultData['end_lng'] ?? null;
|
||||||
|
$countryCode = 'JO'; // Default for now, as scraping is in Jordan
|
||||||
|
|
||||||
|
if ($stmt->execute([
|
||||||
|
$taskId, $appName, $appName, $startLoc, $endLoc,
|
||||||
|
$startLat, $startLng, $endLat, $endLng,
|
||||||
|
$amount, $pricePerKm, $currency, $countryCode
|
||||||
|
])) {
|
||||||
$insertedCount++;
|
$insertedCount++;
|
||||||
} else {
|
} else {
|
||||||
echo "Failed to insert task_id: $taskId. Error: " . implode(" ", $stmt->errorInfo()) . "\n";
|
echo "Failed to insert task_id: $taskId. Error: " . implode(" ", $stmt->errorInfo()) . "\n";
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ echo "[".date('Y-m-d H:i:s')."] Starting cron_surge_opportunity...\n";
|
|||||||
try {
|
try {
|
||||||
// 1. حساب الـ baseline و current
|
// 1. حساب الـ baseline و current
|
||||||
$sql = "SELECT
|
$sql = "SELECT
|
||||||
ROUND(cp.from_latitude * 74, 0) / 74 AS lat_group,
|
ROUND(cp.start_lat * 74, 0) / 74 AS lat_group,
|
||||||
ROUND(cp.from_longitude * 74, 0) / 74 AS lng_group,
|
ROUND(cp.start_lng * 74, 0) / 74 AS lng_group,
|
||||||
cp.competitor_name,
|
cp.competitor_name,
|
||||||
cp.country_code,
|
cp.country_code,
|
||||||
AVG(CASE WHEN cp.created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)
|
AVG(CASE WHEN cp.created_at < DATE_SUB(NOW(), INTERVAL 6 HOUR)
|
||||||
@@ -40,7 +40,7 @@ try {
|
|||||||
THEN cp.price_per_km END) AS current_avg,
|
THEN cp.price_per_km END) AS current_avg,
|
||||||
COUNT(*) AS total_samples,
|
COUNT(*) AS total_samples,
|
||||||
SUM(CASE WHEN cp.created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR) THEN 1 ELSE 0 END) AS recent_samples
|
SUM(CASE WHEN cp.created_at >= DATE_SUB(NOW(), INTERVAL 2 HOUR) THEN 1 ELSE 0 END) AS recent_samples
|
||||||
FROM competitor_prices cp
|
FROM scraped_competitor_prices cp
|
||||||
WHERE cp.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
WHERE cp.created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)
|
||||||
AND cp.price_per_km > 0
|
AND cp.price_per_km > 0
|
||||||
GROUP BY lat_group, lng_group, cp.competitor_name, cp.country_code
|
GROUP BY lat_group, lng_group, cp.competitor_name, cp.country_code
|
||||||
|
|||||||
@@ -26,10 +26,10 @@ try {
|
|||||||
foreach ($countries as $countryCode) {
|
foreach ($countries as $countryCode) {
|
||||||
|
|
||||||
// 1. Calculate Average PCI and Market Share
|
// 1. Calculate Average PCI and Market Share
|
||||||
$sql = "SELECT distance_km, total_price
|
$sql = "SELECT (price_amount / price_per_km) AS distance_km, price_amount AS total_price
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :country
|
WHERE country_code = :country
|
||||||
AND distance_km > 0
|
AND price_per_km > 0
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY)";
|
||||||
$stmt = $con->prepare($sql);
|
$stmt = $con->prepare($sql);
|
||||||
$stmt->execute([':country' => $countryCode]);
|
$stmt->execute([':country' => $countryCode]);
|
||||||
|
|||||||
@@ -17,19 +17,27 @@ try {
|
|||||||
|
|
||||||
// 1. Ensure Table Exists
|
// 1. Ensure Table Exists
|
||||||
$sql = "
|
$sql = "
|
||||||
CREATE TABLE IF NOT EXISTS competitor_prices (
|
CREATE TABLE IF NOT EXISTS `scraped_competitor_prices` (
|
||||||
id INT AUTO_INCREMENT PRIMARY KEY,
|
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||||
competitor_name VARCHAR(50) NOT NULL,
|
`task_id` varchar(100) DEFAULT NULL,
|
||||||
from_latitude VARCHAR(30) NOT NULL,
|
`app_name` varchar(100) NOT NULL,
|
||||||
from_longitude VARCHAR(30) NOT NULL,
|
`competitor_name` varchar(100) NOT NULL,
|
||||||
to_latitude VARCHAR(30) NOT NULL,
|
`start_location` varchar(255) NOT NULL,
|
||||||
to_longitude VARCHAR(30) NOT NULL,
|
`end_location` varchar(255) NOT NULL,
|
||||||
distance_km DECIMAL(8,2) NOT NULL,
|
`start_lat` decimal(10,7) DEFAULT NULL,
|
||||||
total_price DECIMAL(10,2) NOT NULL,
|
`start_lng` decimal(10,7) DEFAULT NULL,
|
||||||
price_per_km DECIMAL(8,2) NOT NULL,
|
`end_lat` decimal(10,7) DEFAULT NULL,
|
||||||
country_code VARCHAR(5) NOT NULL DEFAULT 'SY',
|
`end_lng` decimal(10,7) DEFAULT NULL,
|
||||||
created_at TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`price_amount` decimal(8,2) NOT NULL,
|
||||||
INDEX idx_competitor_country (competitor_name, country_code)
|
`price_per_km` decimal(8,2) NOT NULL,
|
||||||
|
`currency` varchar(10) NOT NULL DEFAULT 'JOD',
|
||||||
|
`country_code` varchar(10) NOT NULL DEFAULT 'JO',
|
||||||
|
`scraped_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
KEY `idx_app_name` (`app_name`),
|
||||||
|
KEY `idx_competitor_name` (`competitor_name`),
|
||||||
|
KEY `idx_start_location` (`start_location`),
|
||||||
|
KEY `idx_country_code` (`country_code`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
";
|
";
|
||||||
$con->exec($sql);
|
$con->exec($sql);
|
||||||
|
|||||||
@@ -133,11 +133,13 @@ if ($method === 'GET') {
|
|||||||
|
|
||||||
// 1. Save to MySQL
|
// 1. Save to MySQL
|
||||||
$stmt = $con->prepare("
|
$stmt = $con->prepare("
|
||||||
INSERT INTO competitor_prices
|
INSERT INTO scraped_competitor_prices
|
||||||
(competitor_name, from_latitude, from_longitude, to_latitude, to_longitude, distance_km, total_price, price_per_km, country_code)
|
(task_id, app_name, competitor_name, start_location, end_location, start_lat, start_lng, end_lat, end_lng, price_amount, price_per_km, currency, country_code)
|
||||||
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)
|
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
|
||||||
");
|
");
|
||||||
$stmt->execute([$app_name, (string)$start_lat, (string)$start_lng, (string)$end_lat, (string)$end_lng, $distance_km, $price, $pricePerKm, $country_code]);
|
$start_loc = "Lat: $start_lat, Lng: $start_lng";
|
||||||
|
$end_loc = "Lat: $end_lat, Lng: $end_lng";
|
||||||
|
$stmt->execute([$task_id, $app_name, $app_name, $start_loc, $end_loc, (string)$start_lat, (string)$start_lng, (string)$end_lat, (string)$end_lng, $price, $pricePerKm, 'JOD', $country_code]);
|
||||||
|
|
||||||
// 2. Save to Redis (Calculate Price Per KM)
|
// 2. Save to Redis (Calculate Price Per KM)
|
||||||
if ($distance_km > 0 && $price > 0) {
|
if ($distance_km > 0 && $price > 0) {
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ $logEntries = [];
|
|||||||
foreach ($countries as $country => $cc) {
|
foreach ($countries as $country => $cc) {
|
||||||
// 1. متوسط سعر الكيلو لكل منافس (آخر 24 ساعة)
|
// 1. متوسط سعر الكيلو لكل منافس (آخر 24 ساعة)
|
||||||
$sql = "SELECT competitor_name, AVG(price_per_km) AS avg_ppm
|
$sql = "SELECT competitor_name, AVG(price_per_km) AS avg_ppm
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :cc
|
WHERE country_code = :cc
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
||||||
AND price_per_km > 0
|
AND price_per_km > 0
|
||||||
|
|||||||
@@ -288,13 +288,14 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
|
|||||||
$maxTlng = $destLng + $lngDelta;
|
$maxTlng = $destLng + $lngDelta;
|
||||||
|
|
||||||
// Layer 1: Start and End match within bounding box
|
// Layer 1: Start and End match within bounding box
|
||||||
$sqlComp = "SELECT total_price, distance_km
|
$sqlComp = "SELECT price_amount AS total_price, (price_amount / price_per_km) AS distance_km
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :country_code
|
WHERE country_code = :country_code
|
||||||
AND (from_latitude + 0.0) BETWEEN :min_flat AND :max_flat
|
AND (start_lat + 0.0) BETWEEN :min_flat AND :max_flat
|
||||||
AND (from_longitude + 0.0) BETWEEN :min_flng AND :max_flng
|
AND (start_lng + 0.0) BETWEEN :min_flng AND :max_flng
|
||||||
AND (to_latitude + 0.0) BETWEEN :min_tlat AND :max_tlat
|
AND (end_lat + 0.0) BETWEEN :min_tlat AND :max_tlat
|
||||||
AND (to_longitude + 0.0) BETWEEN :min_tlng AND :max_tlng
|
AND (end_lng + 0.0) BETWEEN :min_tlng AND :max_tlng
|
||||||
|
AND price_per_km > 0
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
||||||
ORDER BY created_at DESC LIMIT 5";
|
ORDER BY created_at DESC LIMIT 5";
|
||||||
$stmtComp = $con->prepare($sqlComp);
|
$stmtComp = $con->prepare($sqlComp);
|
||||||
@@ -313,11 +314,12 @@ function calculateDynamicPrice($country, $minFare, $distance, $duration, $kazanR
|
|||||||
|
|
||||||
if (empty($matches)) {
|
if (empty($matches)) {
|
||||||
// Layer 2 Fallback: Start match only within bounding box
|
// Layer 2 Fallback: Start match only within bounding box
|
||||||
$sqlFallback = "SELECT total_price, distance_km
|
$sqlFallback = "SELECT price_amount AS total_price, (price_amount / price_per_km) AS distance_km
|
||||||
FROM competitor_prices
|
FROM scraped_competitor_prices
|
||||||
WHERE country_code = :country_code
|
WHERE country_code = :country_code
|
||||||
AND (from_latitude + 0.0) BETWEEN :min_flat AND :max_flat
|
AND (start_lat + 0.0) BETWEEN :min_flat AND :max_flat
|
||||||
AND (from_longitude + 0.0) BETWEEN :min_flng AND :max_flng
|
AND (start_lng + 0.0) BETWEEN :min_flng AND :max_flng
|
||||||
|
AND price_per_km > 0
|
||||||
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
AND created_at >= DATE_SUB(NOW(), INTERVAL 24 HOUR)
|
||||||
ORDER BY created_at DESC LIMIT 10";
|
ORDER BY created_at DESC LIMIT 10";
|
||||||
$stmtFallback = $con->prepare($sqlFallback);
|
$stmtFallback = $con->prepare($sqlFallback);
|
||||||
|
|||||||
@@ -1954,12 +1954,21 @@ CREATE TABLE IF NOT EXISTS `scraped_competitor_prices` (
|
|||||||
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
`id` BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
|
||||||
`task_id` varchar(100) DEFAULT NULL,
|
`task_id` varchar(100) DEFAULT NULL,
|
||||||
`app_name` varchar(100) NOT NULL,
|
`app_name` varchar(100) NOT NULL,
|
||||||
|
`competitor_name` varchar(100) NOT NULL,
|
||||||
`start_location` varchar(255) NOT NULL,
|
`start_location` varchar(255) NOT NULL,
|
||||||
`end_location` varchar(255) NOT NULL,
|
`end_location` varchar(255) NOT NULL,
|
||||||
|
`start_lat` decimal(10,7) DEFAULT NULL,
|
||||||
|
`start_lng` decimal(10,7) DEFAULT NULL,
|
||||||
|
`end_lat` decimal(10,7) DEFAULT NULL,
|
||||||
|
`end_lng` decimal(10,7) DEFAULT NULL,
|
||||||
`price_amount` decimal(8,2) NOT NULL,
|
`price_amount` decimal(8,2) NOT NULL,
|
||||||
|
`price_per_km` decimal(8,2) NOT NULL,
|
||||||
`currency` varchar(10) NOT NULL DEFAULT 'JOD',
|
`currency` varchar(10) NOT NULL DEFAULT 'JOD',
|
||||||
|
`country_code` varchar(10) NOT NULL DEFAULT 'JO',
|
||||||
`scraped_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`scraped_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
KEY `idx_app_name` (`app_name`),
|
KEY `idx_app_name` (`app_name`),
|
||||||
KEY `idx_start_location` (`start_location`)
|
KEY `idx_competitor_name` (`competitor_name`),
|
||||||
|
KEY `idx_start_location` (`start_location`),
|
||||||
|
KEY `idx_country_code` (`country_code`)
|
||||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||||
|
|||||||
Reference in New Issue
Block a user