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 riskLevel Int
policePressure Float @default(1.0) policePressure Float @default(1.0)
economyModifier Float @default(1.0) economyModifier Float @default(1.0)
mapX Float @default(50)
mapY Float @default(50)
createdAt DateTime @default(now()) createdAt DateTime @default(now())
players Player[] players Player[]
@@ -79,7 +81,8 @@ model Item {
inventory InventoryItem[] inventory InventoryItem[]
prices MarketPrice[] prices MarketPrice[]
missions Mission[] requiredInMissions Mission[] @relation("MissionRequiredItem")
rewardInMissions Mission[] @relation("MissionRewardItem")
} }
model InventoryItem { model InventoryItem {
@@ -112,19 +115,24 @@ model Mission {
id String @id @default(uuid()) id String @id @default(uuid())
cityId String cityId String
title String title String
description String @default("")
type MissionType type MissionType
difficulty Int difficulty Int
minLevel Int @default(1)
durationSeconds Int durationSeconds Int
rewardMoney Int rewardMoney Int
rewardXp Int rewardXp Int
risk Float risk Float
requiredItemId String? requiredItemId String?
requiredItemQuantity Int? requiredItemQuantity Int?
rewardItemId String?
rewardItemQuantity Int?
expiresAt DateTime expiresAt DateTime
createdAt DateTime @default(now()) createdAt DateTime @default(now())
city City @relation(fields: [cityId], references: [id]) 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[] playerMissions PlayerMission[]
} }
+11 -6
View File
@@ -4,13 +4,16 @@ import { randomFloat } from '../src/shared/validators.js';
const prisma = new PrismaClient(); 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 = [ const CITIES = [
{ name: 'Milano', riskLevel: 3, policePressure: 1.1, economyModifier: 1.25 }, { name: 'Milano', riskLevel: 3, policePressure: 1.1, economyModifier: 1.25, mapX: 32, mapY: 12 },
{ name: 'Napoli', riskLevel: 4, policePressure: 1.3, economyModifier: 1.0 }, { name: 'Napoli', riskLevel: 4, policePressure: 1.3, economyModifier: 1.0, mapX: 60, mapY: 58 },
{ name: 'Palermo', riskLevel: 4, policePressure: 1.25, economyModifier: 0.85 }, { name: 'Palermo', riskLevel: 4, policePressure: 1.25, economyModifier: 0.85, mapX: 52, mapY: 86 },
{ name: 'Torino', riskLevel: 2, policePressure: 0.9, economyModifier: 1.0 }, { name: 'Torino', riskLevel: 2, policePressure: 0.9, economyModifier: 1.0, mapX: 16, mapY: 16 },
{ name: 'Bari', riskLevel: 3, policePressure: 1.0, economyModifier: 0.85 }, { name: 'Bari', riskLevel: 3, policePressure: 1.0, economyModifier: 0.85, mapX: 78, mapY: 52 },
]; ];
/** Item commerciabili iniziali (blueprint §19). */ /** Item commerciabili iniziali (blueprint §19). */
@@ -32,6 +35,8 @@ async function main(): Promise<void> {
riskLevel: city.riskLevel, riskLevel: city.riskLevel,
policePressure: city.policePressure, policePressure: city.policePressure,
economyModifier: city.economyModifier, economyModifier: city.economyModifier,
mapX: city.mapX,
mapY: city.mapY,
}, },
}); });
} }