- Replace Clerk with self-hosted JWT auth (register/login/verify, bcrypt passwords, Gmail OTP with console fallback) - Add lib/db.ts pg pool + transaction helpers; seed script migrates legacy Clerk-era schema (drop clerk_id, enforce UUID ids and unique email) - Add owner-gated admin API: stats, users, drivers CRUD, rides - Add dashboard/ Vite React owner dashboard (login, overview, users, fleet, rides) with dev-server proxy to avoid Expo CORS middleware - Add scripts/set-owner.mjs for role management
71 lines
1.9 KiB
TypeScript
71 lines
1.9 KiB
TypeScript
import { requireOwner, withCors, preflight } from "@/lib/admin";
|
|
import { sql } from "@/lib/db";
|
|
|
|
export async function OPTIONS() {
|
|
return preflight();
|
|
}
|
|
|
|
export async function GET(request: Request) {
|
|
const auth = await requireOwner(request);
|
|
if ("error" in auth) return withCors(auth.error);
|
|
|
|
try {
|
|
const url = new URL(request.url);
|
|
const status = url.searchParams.get("status")?.trim().toLowerCase() ?? "";
|
|
|
|
const rows = status
|
|
? await sql`
|
|
SELECT
|
|
r.ride_id,
|
|
r.origin_address,
|
|
r.destination_address,
|
|
r.ride_time,
|
|
r.fare_price,
|
|
r.payment_status,
|
|
r.created_at,
|
|
u.id AS user_id,
|
|
u.email AS user_email,
|
|
json_build_object(
|
|
'driver_id', d.id,
|
|
'name', d.first_name || ' ' || d.last_name,
|
|
'rating', d.rating
|
|
) AS driver
|
|
FROM rides r
|
|
INNER JOIN drivers d ON d.id = r.driver_id
|
|
INNER JOIN users u ON u.id = r.user_id
|
|
WHERE LOWER(r.payment_status) = ${status}
|
|
ORDER BY r.created_at DESC
|
|
LIMIT 500
|
|
`
|
|
: await sql`
|
|
SELECT
|
|
r.ride_id,
|
|
r.origin_address,
|
|
r.destination_address,
|
|
r.ride_time,
|
|
r.fare_price,
|
|
r.payment_status,
|
|
r.created_at,
|
|
u.id AS user_id,
|
|
u.email AS user_email,
|
|
json_build_object(
|
|
'driver_id', d.id,
|
|
'name', d.first_name || ' ' || d.last_name,
|
|
'rating', d.rating
|
|
) AS driver
|
|
FROM rides r
|
|
INNER JOIN drivers d ON d.id = r.driver_id
|
|
INNER JOIN users u ON u.id = r.user_id
|
|
ORDER BY r.created_at DESC
|
|
LIMIT 500
|
|
`;
|
|
|
|
return withCors(Response.json({ data: rows }));
|
|
} catch (error) {
|
|
console.error("[ADMIN_RIDES]: ", error);
|
|
return withCors(
|
|
Response.json({ error: "Internal Server Error" }, { status: 500 }),
|
|
);
|
|
}
|
|
}
|