P1: drivers + trips(★state machine) + matching(Redis GEO) + tariff engine + maps + realtime + seed
- drivers: apply/approve/status/location (+Redis GEO presence) - trips: request→accept→status transitions + trip_events audit + offers via socket - matching: Redis GEO nearby drivers - tariff: JSON-rule engine (time_or_distance/window/rounding) + quote endpoint - maps: straight-line routing seam (انطلق later) - realtime: Socket.IO gateway (JWT auth, tenant rooms) - seed: demo tenant siro + default tariff on boot - migration InitP1 (drivers/tariffs/trips/trip_events) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,87 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
/**
|
||||
* جداول P1: drivers, tariffs, trips, trip_events (كلها ببادئة tripz_).
|
||||
*/
|
||||
export class InitP11721300000000 implements MigrationInterface {
|
||||
public async up(q: QueryRunner): Promise<void> {
|
||||
// drivers
|
||||
await q.query(`
|
||||
CREATE TABLE IF NOT EXISTS tripz_drivers (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL,
|
||||
user_id uuid NOT NULL,
|
||||
service_class varchar NOT NULL DEFAULT 'economy',
|
||||
vehicle_make varchar, vehicle_model varchar,
|
||||
vehicle_plate varchar, vehicle_color varchar,
|
||||
docs jsonb NOT NULL DEFAULT '{}',
|
||||
verification_status varchar NOT NULL DEFAULT 'pending',
|
||||
is_online boolean NOT NULL DEFAULT false,
|
||||
rating numeric(3,2) NOT NULL DEFAULT 5,
|
||||
last_lat double precision, last_lng double precision,
|
||||
created_at timestamptz NOT NULL DEFAULT now(),
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
)`);
|
||||
await q.query(`CREATE UNIQUE INDEX IF NOT EXISTS "UQ_tripz_drivers_tenant_user" ON tripz_drivers (tenant_id, user_id)`);
|
||||
|
||||
// tariffs
|
||||
await q.query(`
|
||||
CREATE TABLE IF NOT EXISTS tripz_tariffs (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL,
|
||||
city varchar NOT NULL,
|
||||
service_class varchar NOT NULL,
|
||||
definition jsonb NOT NULL,
|
||||
version int NOT NULL DEFAULT 1,
|
||||
active boolean NOT NULL DEFAULT true,
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
)`);
|
||||
await q.query(`CREATE INDEX IF NOT EXISTS "IDX_tripz_tariffs_lookup" ON tripz_tariffs (tenant_id, city, service_class, active)`);
|
||||
|
||||
// trips
|
||||
await q.query(`
|
||||
CREATE TABLE IF NOT EXISTS tripz_trips (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL,
|
||||
rider_id uuid NOT NULL,
|
||||
driver_id uuid,
|
||||
service_class varchar NOT NULL DEFAULT 'economy',
|
||||
city varchar,
|
||||
origin_lat double precision NOT NULL, origin_lng double precision NOT NULL,
|
||||
dest_lat double precision NOT NULL, dest_lng double precision NOT NULL,
|
||||
status varchar NOT NULL DEFAULT 'searching',
|
||||
distance_km numeric(8,3), duration_min numeric(8,1),
|
||||
tariff_id uuid, tariff_version int,
|
||||
quoted_fare numeric(12,3), final_fare numeric(12,3),
|
||||
currency varchar,
|
||||
payment_method varchar NOT NULL DEFAULT 'cash',
|
||||
requested_at timestamptz NOT NULL DEFAULT now(),
|
||||
assigned_at timestamptz, completed_at timestamptz,
|
||||
updated_at timestamptz NOT NULL DEFAULT now()
|
||||
)`);
|
||||
await q.query(`CREATE INDEX IF NOT EXISTS "IDX_tripz_trips_status" ON tripz_trips (tenant_id, status)`);
|
||||
await q.query(`CREATE INDEX IF NOT EXISTS "IDX_tripz_trips_rider" ON tripz_trips (tenant_id, rider_id)`);
|
||||
await q.query(`CREATE INDEX IF NOT EXISTS "IDX_tripz_trips_driver" ON tripz_trips (tenant_id, driver_id)`);
|
||||
|
||||
// trip_events
|
||||
await q.query(`
|
||||
CREATE TABLE IF NOT EXISTS tripz_trip_events (
|
||||
id uuid PRIMARY KEY DEFAULT uuid_generate_v4(),
|
||||
tenant_id uuid NOT NULL,
|
||||
trip_id uuid NOT NULL,
|
||||
from_status varchar,
|
||||
to_status varchar NOT NULL,
|
||||
source varchar NOT NULL DEFAULT 'system',
|
||||
payload jsonb NOT NULL DEFAULT '{}',
|
||||
created_at timestamptz NOT NULL DEFAULT now()
|
||||
)`);
|
||||
await q.query(`CREATE INDEX IF NOT EXISTS "IDX_tripz_trip_events_trip" ON tripz_trip_events (tenant_id, trip_id)`);
|
||||
}
|
||||
|
||||
public async down(q: QueryRunner): Promise<void> {
|
||||
await q.query(`DROP TABLE IF EXISTS tripz_trip_events`);
|
||||
await q.query(`DROP TABLE IF EXISTS tripz_trips`);
|
||||
await q.query(`DROP TABLE IF EXISTS tripz_tariffs`);
|
||||
await q.query(`DROP TABLE IF EXISTS tripz_drivers`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user