server: schema — City map coords, Mission narrative/level/loot fields

Add mapX/mapY to City for SVG map positioning; add description,
minLevel, rewardItemId/Quantity to Mission; add named relations
MissionRequiredItem and MissionRewardItem on Item. Seed updated
with Italian city coordinates.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-10 00:11:26 +02:00
parent 0f91ace43e
commit 8804dfeb22
3 changed files with 35 additions and 10 deletions
@@ -0,0 +1,12 @@
-- AlterTable
ALTER TABLE "City" ADD COLUMN "mapX" DOUBLE PRECISION NOT NULL DEFAULT 50,
ADD COLUMN "mapY" DOUBLE PRECISION NOT NULL DEFAULT 50;
-- AlterTable
ALTER TABLE "Mission" ADD COLUMN "description" TEXT NOT NULL DEFAULT '',
ADD COLUMN "minLevel" INTEGER NOT NULL DEFAULT 1,
ADD COLUMN "rewardItemId" TEXT,
ADD COLUMN "rewardItemQuantity" INTEGER;
-- AddForeignKey
ALTER TABLE "Mission" ADD CONSTRAINT "Mission_rewardItemId_fkey" FOREIGN KEY ("rewardItemId") REFERENCES "Item"("id") ON DELETE SET NULL ON UPDATE CASCADE;
+10 -2
View File
@@ -60,6 +60,8 @@ model City {
riskLevel Int
policePressure Float @default(1.0)
economyModifier Float @default(1.0)
mapX Float @default(50)
mapY Float @default(50)
createdAt DateTime @default(now())
players Player[]
@@ -79,7 +81,8 @@ model Item {
inventory InventoryItem[]
prices MarketPrice[]
missions Mission[]
requiredInMissions Mission[] @relation("MissionRequiredItem")
rewardInMissions Mission[] @relation("MissionRewardItem")
}
model InventoryItem {
@@ -112,19 +115,24 @@ model Mission {
id String @id @default(uuid())
cityId String
title String
description String @default("")
type MissionType
difficulty Int
minLevel Int @default(1)
durationSeconds Int
rewardMoney Int
rewardXp Int
risk Float
requiredItemId String?
requiredItemQuantity Int?
rewardItemId String?
rewardItemQuantity Int?
expiresAt DateTime
createdAt DateTime @default(now())
city City @relation(fields: [cityId], references: [id])
requiredItem Item? @relation(fields: [requiredItemId], references: [id])
requiredItem Item? @relation("MissionRequiredItem", fields: [requiredItemId], references: [id])
rewardItem Item? @relation("MissionRewardItem", fields: [rewardItemId], references: [id])
playerMissions PlayerMission[]
}
+11 -6
View File
@@ -4,13 +4,16 @@ import { randomFloat } from '../src/shared/validators.js';
const prisma = new PrismaClient();
/** Città iniziali (blueprint §19): economia e rischio differenziati. */
/**
* Città iniziali (blueprint §19): economia e rischio differenziati.
* mapX/mapY sono coordinate percentuali (0-100) sulla mappa stilizzata dell'Italia.
*/
const CITIES = [
{ name: 'Milano', riskLevel: 3, policePressure: 1.1, economyModifier: 1.25 },
{ name: 'Napoli', riskLevel: 4, policePressure: 1.3, economyModifier: 1.0 },
{ name: 'Palermo', riskLevel: 4, policePressure: 1.25, economyModifier: 0.85 },
{ name: 'Torino', riskLevel: 2, policePressure: 0.9, economyModifier: 1.0 },
{ name: 'Bari', riskLevel: 3, policePressure: 1.0, economyModifier: 0.85 },
{ name: 'Milano', riskLevel: 3, policePressure: 1.1, economyModifier: 1.25, mapX: 32, mapY: 12 },
{ name: 'Napoli', riskLevel: 4, policePressure: 1.3, economyModifier: 1.0, mapX: 60, mapY: 58 },
{ name: 'Palermo', riskLevel: 4, policePressure: 1.25, economyModifier: 0.85, mapX: 52, mapY: 86 },
{ name: 'Torino', riskLevel: 2, policePressure: 0.9, economyModifier: 1.0, mapX: 16, mapY: 16 },
{ name: 'Bari', riskLevel: 3, policePressure: 1.0, economyModifier: 0.85, mapX: 78, mapY: 52 },
];
/** Item commerciabili iniziali (blueprint §19). */
@@ -32,6 +35,8 @@ async function main(): Promise<void> {
riskLevel: city.riskLevel,
policePressure: city.policePressure,
economyModifier: city.economyModifier,
mapX: city.mapX,
mapY: city.mapY,
},
});
}