Chinchilla joins the small-pet species as its own Species (breeds are color varieties: Standard Grey, Beige, Black Velvet, etc.). Aquarium models the tank/setup as the pet identity rather than an individual fish, matching how aquarists actually showcase their hobby — Breed is the predominant fish species kept (Betta, Guppy, Discus, Koi, etc.), same pattern as Bird covering many bird types via Breed. Pure seed-data addition, no schema/code changes needed.
497 lines
12 KiB
TypeScript
497 lines
12 KiB
TypeScript
import { PrismaClient } from "@prisma/client";
|
|
import { PrismaPg } from "@prisma/adapter-pg";
|
|
import { Pool } from "pg";
|
|
|
|
/**
|
|
* Seed script for the PawFeed database.
|
|
* Seeds Species (Dog, Cat, Bird) and Breed taxonomy idempotently.
|
|
* Uses upsert so it is safe to run multiple times.
|
|
*
|
|
* Run: npx tsx prisma/seed.ts
|
|
* Or: npx prisma db seed
|
|
*/
|
|
|
|
const databaseUrl = process.env.DATABASE_URL;
|
|
if (!databaseUrl) {
|
|
throw new Error(
|
|
"DATABASE_URL is not set. Please add it to .env.local first."
|
|
);
|
|
}
|
|
|
|
const adapter = new PrismaPg(new Pool({ connectionString: databaseUrl }));
|
|
const prisma = new PrismaClient({ adapter });
|
|
|
|
const DOG_BREEDS = [
|
|
"Labrador Retriever",
|
|
"Golden Retriever",
|
|
"German Shepherd",
|
|
"French Bulldog",
|
|
"Bulldog",
|
|
"Poodle",
|
|
"Beagle",
|
|
"Rottweiler",
|
|
"German Shorthaired Pointer",
|
|
"Dachshund",
|
|
"Pembroke Welsh Corgi",
|
|
"Australian Shepherd",
|
|
"Yorkshire Terrier",
|
|
"Boxer",
|
|
"Cavalier King Charles Spaniel",
|
|
"Doberman Pinscher",
|
|
"Great Dane",
|
|
"Miniature Schnauzer",
|
|
"Siberian Husky",
|
|
"Border Collie",
|
|
];
|
|
|
|
const CAT_BREEDS = [
|
|
"Domestic Shorthair",
|
|
"Domestic Longhair",
|
|
"Maine Coon",
|
|
"Ragdoll",
|
|
"Siamese",
|
|
"Persian",
|
|
"Bengal",
|
|
"British Shorthair",
|
|
"Sphynx",
|
|
"Scottish Fold",
|
|
"American Shorthair",
|
|
"Abyssinian",
|
|
"Norwegian Forest Cat",
|
|
"Birman",
|
|
"Russian Blue",
|
|
];
|
|
|
|
const BIRD_BREEDS = [
|
|
"Budgerigar (Budgie)",
|
|
"Cockatiel",
|
|
"Lovebird",
|
|
"African Grey Parrot",
|
|
"Cockatoo",
|
|
"Conure",
|
|
"Macaw",
|
|
"Canary",
|
|
"Finch",
|
|
"Amazon Parrot",
|
|
];
|
|
|
|
const HORSE_BREEDS = [
|
|
"Arabian Horse",
|
|
"Icelandic Horse",
|
|
"Shetland Pony",
|
|
"Haflinger",
|
|
"Friesian",
|
|
"Andalusian",
|
|
"Quarter Horse",
|
|
"Thoroughbred",
|
|
"Warmblood",
|
|
"Welsh Pony",
|
|
"Trakehner",
|
|
"Hanoverian",
|
|
];
|
|
|
|
const RABBIT_BREEDS = [
|
|
"Netherland Dwarf",
|
|
"Holland Lop",
|
|
"Lionhead Rabbit",
|
|
"Rex Rabbit",
|
|
"Angora Rabbit",
|
|
"Flemish Giant",
|
|
"Mini Rex",
|
|
"Dutch Rabbit",
|
|
];
|
|
|
|
const GUINEA_PIG_BREEDS = [
|
|
"American Guinea Pig",
|
|
"Abyssinian Guinea Pig",
|
|
"Peruvian Guinea Pig",
|
|
"Silkie Guinea Pig",
|
|
"Teddy Guinea Pig",
|
|
"Skinny Pig",
|
|
];
|
|
|
|
const HAMSTER_BREEDS = [
|
|
"Syrian Hamster",
|
|
"Roborovski Hamster",
|
|
"Campbell's Dwarf Hamster",
|
|
"Winter White Hamster",
|
|
"Chinese Hamster",
|
|
];
|
|
|
|
const MOUSE_BREEDS = [
|
|
"Fancy Mouse",
|
|
"Satin Mouse",
|
|
"Long-Haired Mouse",
|
|
"Hairless Mouse",
|
|
];
|
|
|
|
const RAT_BREEDS = [
|
|
"Standard Rat",
|
|
"Dumbo Rat",
|
|
"Hairless Rat",
|
|
"Rex Rat",
|
|
"Satin Rat",
|
|
];
|
|
|
|
const SNAKE_BREEDS = [
|
|
"Corn Snake",
|
|
"Ball Python",
|
|
"Boa Constrictor",
|
|
"King Snake",
|
|
"Milk Snake",
|
|
"Garter Snake",
|
|
];
|
|
|
|
const LIZARD_BREEDS = [
|
|
"Bearded Dragon",
|
|
"Green Iguana",
|
|
"Blue-Tongued Skink",
|
|
"Chameleon",
|
|
"Monitor Lizard",
|
|
];
|
|
|
|
const TURTLE_BREEDS = [
|
|
"Red-Eared Slider",
|
|
"Greek Tortoise",
|
|
"Hermann's Tortoise",
|
|
"Box Turtle",
|
|
"African Sulcata Tortoise",
|
|
];
|
|
|
|
const GECKO_BREEDS = [
|
|
"Leopard Gecko",
|
|
"Crested Gecko",
|
|
"Tokay Gecko",
|
|
"Day Gecko",
|
|
"Gargoyle Gecko",
|
|
];
|
|
|
|
const SPIDER_BREEDS = [
|
|
"Chilean Rose Tarantula",
|
|
"Mexican Red Knee Tarantula",
|
|
"Curly Hair Tarantula",
|
|
"Pink Toe Tarantula",
|
|
"Goliath Birdeater",
|
|
"Brazilian Black Tarantula",
|
|
];
|
|
|
|
const CHINCHILLA_BREEDS = [
|
|
"Standard Grey",
|
|
"Beige",
|
|
"White",
|
|
"Black Velvet",
|
|
"Violet",
|
|
"Sapphire",
|
|
"Ebony",
|
|
];
|
|
|
|
// The Species is the aquarium/tank as a whole (matches how aquarists
|
|
// actually showcase their hobby), not one profile per individual fish —
|
|
// "breed" here means the predominant fish species kept, same pattern as
|
|
// Bird covering many bird types via Breed.
|
|
const AQUARIUM_BREEDS = [
|
|
"Betta (Siamese Fighting Fish)",
|
|
"Guppy",
|
|
"Neon Tetra",
|
|
"Goldfish",
|
|
"Angelfish",
|
|
"Discus",
|
|
"Koi",
|
|
"Molly",
|
|
"Platy",
|
|
"Cichlid",
|
|
"Corydoras Catfish",
|
|
"Zebra Danio",
|
|
];
|
|
|
|
const SPECIES_DE: Record<string, string> = {
|
|
"Dog": "Hund",
|
|
"Cat": "Katze",
|
|
"Bird": "Vogel",
|
|
"Horse": "Pferd",
|
|
"Rabbit": "Kaninchen",
|
|
"Guinea Pig": "Meerschweinchen",
|
|
"Hamster": "Hamster",
|
|
"Mouse": "Maus",
|
|
"Rat": "Ratte",
|
|
"Snake": "Schlange",
|
|
"Lizard": "Echse",
|
|
"Turtle": "Schildkröte",
|
|
"Gecko": "Gecko",
|
|
"Spider": "Spinne",
|
|
"Chinchilla": "Chinchilla",
|
|
"Aquarium": "Aquarium",
|
|
};
|
|
|
|
const DOG_BREEDS_DE: Record<string, string> = {
|
|
"Labrador Retriever": "Labrador Retriever",
|
|
"Golden Retriever": "Golden Retriever",
|
|
"German Shepherd": "Deutscher Schäferhund",
|
|
"French Bulldog": "Französische Bulldogge",
|
|
"Bulldog": "Bulldogge",
|
|
"Poodle": "Pudel",
|
|
"Beagle": "Beagle",
|
|
"Rottweiler": "Rottweiler",
|
|
"German Shorthaired Pointer": "Deutsch Kurzhaar",
|
|
"Dachshund": "Dackel",
|
|
"Pembroke Welsh Corgi": "Pembroke Welsh Corgi",
|
|
"Australian Shepherd": "Australian Shepherd",
|
|
"Yorkshire Terrier": "Yorkshire Terrier",
|
|
"Boxer": "Boxer",
|
|
"Cavalier King Charles Spaniel": "Cavalier King Charles Spaniel",
|
|
"Doberman Pinscher": "Dobermann",
|
|
"Great Dane": "Deutsche Dogge",
|
|
"Miniature Schnauzer": "Zwergschnauzer",
|
|
"Siberian Husky": "Sibirischer Husky",
|
|
"Border Collie": "Border Collie",
|
|
};
|
|
|
|
const CAT_BREEDS_DE: Record<string, string> = {
|
|
"Domestic Shorthair": "Europäisch Kurzhaar",
|
|
"Domestic Longhair": "Europäisch Langhaar",
|
|
"Maine Coon": "Maine Coon",
|
|
"Ragdoll": "Ragdoll",
|
|
"Siamese": "Siamkatze",
|
|
"Persian": "Perserkatze",
|
|
"Bengal": "Bengalkatze",
|
|
"British Shorthair": "Britisch Kurzhaar",
|
|
"Sphynx": "Sphynx",
|
|
"Scottish Fold": "Scottish Fold",
|
|
"American Shorthair": "Amerikanisch Kurzhaar",
|
|
"Abyssinian": "Abessinier",
|
|
"Norwegian Forest Cat": "Norwegische Waldkatze",
|
|
"Birman": "Heilige Birma",
|
|
"Russian Blue": "Russisch Blau",
|
|
};
|
|
|
|
const BIRD_BREEDS_DE: Record<string, string> = {
|
|
"Budgerigar (Budgie)": "Wellensittich",
|
|
"Cockatiel": "Nymphensittich",
|
|
"Lovebird": "Unzertrennliche",
|
|
"African Grey Parrot": "Graupapagei",
|
|
"Cockatoo": "Kakadu",
|
|
"Conure": "Sittich",
|
|
"Macaw": "Ara",
|
|
"Canary": "Kanarienvogel",
|
|
"Finch": "Fink",
|
|
"Amazon Parrot": "Amazone",
|
|
};
|
|
|
|
const HORSE_BREEDS_DE: Record<string, string> = {
|
|
"Arabian Horse": "Araber",
|
|
"Icelandic Horse": "Islandpferd",
|
|
"Shetland Pony": "Shetlandpony",
|
|
"Haflinger": "Haflinger",
|
|
"Friesian": "Friese",
|
|
"Andalusian": "Andalusier",
|
|
"Quarter Horse": "Quarter Horse",
|
|
"Thoroughbred": "Englisches Vollblut",
|
|
"Warmblood": "Warmblut",
|
|
"Welsh Pony": "Welsh Pony",
|
|
"Trakehner": "Trakehner",
|
|
"Hanoverian": "Hannoveraner",
|
|
};
|
|
|
|
const RABBIT_BREEDS_DE: Record<string, string> = {
|
|
"Netherland Dwarf": "Hollandzwerg",
|
|
"Holland Lop": "Widderkaninchen",
|
|
"Lionhead Rabbit": "Löwenkopfkaninchen",
|
|
"Rex Rabbit": "Rex-Kaninchen",
|
|
"Angora Rabbit": "Angorakaninchen",
|
|
"Flemish Giant": "Deutscher Riese",
|
|
"Mini Rex": "Mini Rex",
|
|
"Dutch Rabbit": "Holländer",
|
|
};
|
|
|
|
const GUINEA_PIG_BREEDS_DE: Record<string, string> = {
|
|
"American Guinea Pig": "Glatthaarmeerschweinchen",
|
|
"Abyssinian Guinea Pig": "Rosettenmeerschweinchen",
|
|
"Peruvian Guinea Pig": "Perumeerschweinchen",
|
|
"Silkie Guinea Pig": "Silkie",
|
|
"Teddy Guinea Pig": "Teddymeerschweinchen",
|
|
"Skinny Pig": "Skinny Pig",
|
|
};
|
|
|
|
const HAMSTER_BREEDS_DE: Record<string, string> = {
|
|
"Syrian Hamster": "Goldhamster",
|
|
"Roborovski Hamster": "Roborowski-Zwerghamster",
|
|
"Campbell's Dwarf Hamster": "Campbell-Zwerghamster",
|
|
"Winter White Hamster": "Dsungarischer Zwerghamster",
|
|
"Chinese Hamster": "Chinesischer Streifenhamster",
|
|
};
|
|
|
|
const MOUSE_BREEDS_DE: Record<string, string> = {
|
|
"Fancy Mouse": "Farbmaus",
|
|
"Satin Mouse": "Satinmaus",
|
|
"Long-Haired Mouse": "Langhaarmaus",
|
|
"Hairless Mouse": "Nacktmaus",
|
|
};
|
|
|
|
const RAT_BREEDS_DE: Record<string, string> = {
|
|
"Standard Rat": "Standardratte",
|
|
"Dumbo Rat": "Dumbo-Ratte",
|
|
"Hairless Rat": "Nacktratte",
|
|
"Rex Rat": "Rex-Ratte",
|
|
"Satin Rat": "Satin-Ratte",
|
|
};
|
|
|
|
const SNAKE_BREEDS_DE: Record<string, string> = {
|
|
"Corn Snake": "Kornnatter",
|
|
"Ball Python": "Königspython",
|
|
"Boa Constrictor": "Abgottschlange",
|
|
"King Snake": "Königsnatter",
|
|
"Milk Snake": "Milchschlange",
|
|
"Garter Snake": "Strumpfbandnatter",
|
|
};
|
|
|
|
const LIZARD_BREEDS_DE: Record<string, string> = {
|
|
"Bearded Dragon": "Bartagame",
|
|
"Green Iguana": "Grüner Leguan",
|
|
"Blue-Tongued Skink": "Blauzungenskink",
|
|
"Chameleon": "Chamäleon",
|
|
"Monitor Lizard": "Waran",
|
|
};
|
|
|
|
const TURTLE_BREEDS_DE: Record<string, string> = {
|
|
"Red-Eared Slider": "Rotwangen-Schmuckschildkröte",
|
|
"Greek Tortoise": "Griechische Landschildkröte",
|
|
"Hermann's Tortoise": "Griechische Landschildkröte (Testudo hermanni)",
|
|
"Box Turtle": "Dosenschildkröte",
|
|
"African Sulcata Tortoise": "Spornschildkröte",
|
|
};
|
|
|
|
const GECKO_BREEDS_DE: Record<string, string> = {
|
|
"Leopard Gecko": "Leopardgecko",
|
|
"Crested Gecko": "Kronengecko",
|
|
"Tokay Gecko": "Tokeh",
|
|
"Day Gecko": "Taggecko",
|
|
"Gargoyle Gecko": "Gargoyle-Gecko",
|
|
};
|
|
|
|
const SPIDER_BREEDS_DE: Record<string, string> = {
|
|
"Chilean Rose Tarantula": "Chilenische Rosenhaarvogelspinne",
|
|
"Mexican Red Knee Tarantula": "Mexikanische Rotknievogelspinne",
|
|
"Curly Hair Tarantula": "Lockenhaarvogelspinne",
|
|
"Pink Toe Tarantula": "Antillen-Baumvogelspinne",
|
|
"Goliath Birdeater": "Goliath-Vogelspinne",
|
|
"Brazilian Black Tarantula": "Brasilianische Schwarze Vogelspinne",
|
|
};
|
|
|
|
const CHINCHILLA_BREEDS_DE: Record<string, string> = {
|
|
"Standard Grey": "Standardgrau",
|
|
"Beige": "Beige",
|
|
"White": "Weiß",
|
|
"Black Velvet": "Black Velvet",
|
|
"Violet": "Violett",
|
|
"Sapphire": "Saphir",
|
|
"Ebony": "Ebony",
|
|
};
|
|
|
|
const AQUARIUM_BREEDS_DE: Record<string, string> = {
|
|
"Betta (Siamese Fighting Fish)": "Kampffisch",
|
|
"Guppy": "Guppy",
|
|
"Neon Tetra": "Neonsalmler",
|
|
"Goldfish": "Goldfisch",
|
|
"Angelfish": "Skalar",
|
|
"Discus": "Diskusfisch",
|
|
"Koi": "Koi",
|
|
"Molly": "Molly",
|
|
"Platy": "Platy",
|
|
"Cichlid": "Buntbarsch",
|
|
"Corydoras Catfish": "Panzerwels",
|
|
"Zebra Danio": "Zebrabärbling",
|
|
};
|
|
|
|
const BREED_DE_BY_SPECIES: Record<string, Record<string, string>> = {
|
|
"Dog": DOG_BREEDS_DE,
|
|
"Cat": CAT_BREEDS_DE,
|
|
"Bird": BIRD_BREEDS_DE,
|
|
"Horse": HORSE_BREEDS_DE,
|
|
"Rabbit": RABBIT_BREEDS_DE,
|
|
"Guinea Pig": GUINEA_PIG_BREEDS_DE,
|
|
"Hamster": HAMSTER_BREEDS_DE,
|
|
"Mouse": MOUSE_BREEDS_DE,
|
|
"Rat": RAT_BREEDS_DE,
|
|
"Snake": SNAKE_BREEDS_DE,
|
|
"Lizard": LIZARD_BREEDS_DE,
|
|
"Turtle": TURTLE_BREEDS_DE,
|
|
"Gecko": GECKO_BREEDS_DE,
|
|
"Spider": SPIDER_BREEDS_DE,
|
|
"Chinchilla": CHINCHILLA_BREEDS_DE,
|
|
"Aquarium": AQUARIUM_BREEDS_DE,
|
|
};
|
|
|
|
async function main() {
|
|
console.log("Seeding species...");
|
|
|
|
const speciesData = [
|
|
{ name: "Dog", breeds: DOG_BREEDS },
|
|
{ name: "Cat", breeds: CAT_BREEDS },
|
|
{ name: "Bird", breeds: BIRD_BREEDS },
|
|
{ name: "Horse", breeds: HORSE_BREEDS },
|
|
{ name: "Rabbit", breeds: RABBIT_BREEDS },
|
|
{ name: "Guinea Pig", breeds: GUINEA_PIG_BREEDS },
|
|
{ name: "Hamster", breeds: HAMSTER_BREEDS },
|
|
{ name: "Mouse", breeds: MOUSE_BREEDS },
|
|
{ name: "Rat", breeds: RAT_BREEDS },
|
|
{ name: "Snake", breeds: SNAKE_BREEDS },
|
|
{ name: "Lizard", breeds: LIZARD_BREEDS },
|
|
{ name: "Turtle", breeds: TURTLE_BREEDS },
|
|
{ name: "Gecko", breeds: GECKO_BREEDS },
|
|
{ name: "Spider", breeds: SPIDER_BREEDS },
|
|
{ name: "Chinchilla", breeds: CHINCHILLA_BREEDS },
|
|
{ name: "Aquarium", breeds: AQUARIUM_BREEDS },
|
|
];
|
|
|
|
for (const s of speciesData) {
|
|
const species = await prisma.species.upsert({
|
|
where: { name: s.name },
|
|
update: {},
|
|
create: { name: s.name },
|
|
});
|
|
console.log(` Upserted species: ${species.name} (${species.id})`);
|
|
|
|
const deSpeciesName = SPECIES_DE[s.name];
|
|
if (deSpeciesName) {
|
|
await prisma.speciesTranslation.upsert({
|
|
where: { speciesId_locale: { speciesId: species.id, locale: "de" } },
|
|
update: { name: deSpeciesName },
|
|
create: { speciesId: species.id, locale: "de", name: deSpeciesName },
|
|
});
|
|
}
|
|
|
|
console.log(` Seeding ${s.breeds.length} breeds for ${species.name}...`);
|
|
const breedDeMap = BREED_DE_BY_SPECIES[s.name] ?? {};
|
|
|
|
for (const breedName of s.breeds) {
|
|
const breed = await prisma.breed.upsert({
|
|
where: { speciesId_name: { speciesId: species.id, name: breedName } },
|
|
update: {},
|
|
create: { speciesId: species.id, name: breedName },
|
|
});
|
|
|
|
const deBreedName = breedDeMap[breedName];
|
|
if (deBreedName) {
|
|
await prisma.breedTranslation.upsert({
|
|
where: { breedId_locale: { breedId: breed.id, locale: "de" } },
|
|
update: { name: deBreedName },
|
|
create: { breedId: breed.id, locale: "de", name: deBreedName },
|
|
});
|
|
}
|
|
|
|
console.log(` Upserted breed: ${breed.name}`);
|
|
}
|
|
}
|
|
|
|
console.log("Seeding complete.");
|
|
}
|
|
|
|
main()
|
|
.catch((e) => {
|
|
console.error(e);
|
|
process.exit(1);
|
|
})
|
|
.finally(async () => {
|
|
await prisma.$disconnect();
|
|
});
|