Files
petfeed/prisma/seed.ts
T
admin 4b17537a9a feat(i18n): add EN/DE language support with next-intl
- Install next-intl@4 with cookie-based locale switching (NEXT_LOCALE)
- Add LanguageSwitcher component in Sidebar footer
- Translate Nav, PostTypeSheet, Feed, Explore, WelcomeCard, PetForm,
  AvatarUpload, and Onboarding pages (EN + DE)
- Add SpeciesTranslation and BreedTranslation DB models for locale-aware
  taxonomy; listSpecies and listBreeds accept optional locale param
- Seed German translations for all 3 species and 45 breeds
- Add SQL migration script for Supabase (add_i18n_translations.sql)
- fix(invite): secure cookie flag and set-invite route for HTTPS
2026-06-22 14:01:16 +02:00

204 lines
5.2 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 SPECIES_DE: Record<string, string> = {
"Dog": "Hund",
"Cat": "Katze",
"Bird": "Vogel",
};
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 BREED_DE_BY_SPECIES: Record<string, Record<string, string>> = {
"Dog": DOG_BREEDS_DE,
"Cat": CAT_BREEDS_DE,
"Bird": BIRD_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 },
];
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();
});