89b24d4c34
- Add tsconfig.json (server) + client/tsconfig.{json,app.json,node.json}
so typecheck and tsc -b actually work.
- Fix npm test to run Playwright (was running vitest on Playwright specs);
typecheck now covers both server and client.
- Mount routes before app.listen, add error handler, mount optional
@tonycodes/auth-express middleware when AUTH_SECRET is set.
- Add /api/trips (GET/POST/PATCH/DELETE) backed by an in-memory store
that gracefully degrades when DATABASE_URL is unset.
- Add prisma/seed.ts skeleton and server/types/express.d.ts for req.auth.
- Rewrite Grok prompt for combo-aware planning: charge+eat,
stay+destination-charging, eat+viewpoint, etc., with amenities,
cuisine, priceLevel, duration, day titles and trip highlights.
- Extend Stop schema + normalization to preserve all enrichment fields.
- New StopCard component renders combo pill, description, meta row
(charge / stop / battery / cuisine / £-level) and amenity icons;
map popups show the same enriched detail; timeline gains day titles
and a HIGHLIGHTS sidebar.
- Fix server TS errors (vehicle accepted as string | {name,rangeKm},
JSON parse results typed).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
63 lines
1.8 KiB
TypeScript
63 lines
1.8 KiB
TypeScript
/**
|
|
* Tesla Roadtrip seed
|
|
*
|
|
* Generates a small demo trip so the API has something to return after a fresh setup.
|
|
* Requires DATABASE_URL and a Prisma client generated from prisma/schema.prisma.
|
|
*
|
|
* Run: npm run db:seed
|
|
*/
|
|
import { PrismaClient } from './generated/prisma/index.js';
|
|
|
|
const prisma = new PrismaClient();
|
|
|
|
async function main() {
|
|
const demoUserId = 'demo-user';
|
|
|
|
const existing = await prisma.trip.findFirst({ where: { userId: demoUserId } });
|
|
if (existing) {
|
|
console.log('Seed skipped — demo trip already exists:', existing.id);
|
|
return;
|
|
}
|
|
|
|
const trip = await prisma.trip.create({
|
|
data: {
|
|
userId: demoUserId,
|
|
title: 'London → Edinburgh (demo)',
|
|
vehicleModel: 'Model Y Long Range',
|
|
rangeMi: 320,
|
|
status: 'planning',
|
|
isPublic: false,
|
|
itinerary: {
|
|
days: [
|
|
{
|
|
day: 1,
|
|
stops: [
|
|
{ id: 'london', name: 'London', type: 'custom', lat: 51.5074, lng: -0.1278, day: 1, order: 1 },
|
|
{ id: 'mk-sc', name: 'Milton Keynes Supercharger', type: 'supercharger', lat: 52.0406, lng: -0.7594, day: 1, order: 2, chargeMinutes: 25 },
|
|
{ id: 'leeds-sc', name: 'Leeds Supercharger', type: 'supercharger', lat: 53.8008, lng: -1.5491, day: 1, order: 3, chargeMinutes: 30 },
|
|
],
|
|
},
|
|
{
|
|
day: 2,
|
|
stops: [
|
|
{ id: 'edi', name: 'Edinburgh', type: 'attraction', lat: 55.9533, lng: -3.1883, day: 2, order: 1 },
|
|
],
|
|
},
|
|
],
|
|
summary: { totalDistanceKm: 670, estDriveHours: 8, estChargeHours: 1.2, superchargers: 2, hotels: 0 },
|
|
},
|
|
},
|
|
});
|
|
|
|
console.log('Seed created demo trip:', trip.id);
|
|
}
|
|
|
|
main()
|
|
.catch((err) => {
|
|
console.error('Seed failed:', err);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|