From 46c3fc728680a7337e0270bf61ec38844b037076 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:49:42 +0000 Subject: [PATCH 1/8] Initial plan From 91b43b6985eecb542b406b77135a253b3b30f056 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 18:54:30 +0000 Subject: [PATCH 2/8] #16 add seed data implementation Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- .github/workflows/migrate.yml | 8 + package-lock.json | 539 +++++++++++++++++++++++++++++++++- package.json | 4 +- prisma.config.ts | 3 + prisma/seed.ts | 168 +++++++++++ 5 files changed, 720 insertions(+), 2 deletions(-) create mode 100644 prisma/seed.ts diff --git a/.github/workflows/migrate.yml b/.github/workflows/migrate.yml index cdf466d..3e24e7f 100644 --- a/.github/workflows/migrate.yml +++ b/.github/workflows/migrate.yml @@ -29,3 +29,11 @@ jobs: DATABASE_URL: ${{ secrets.DATABASE_URL }} DIRECT_URL: ${{ secrets.DIRECT_URL }} run: npx prisma migrate deploy + + - name: Seed database + if: github.ref == 'refs/heads/dev' + env: + DATABASE_URL: ${{ secrets.DATABASE_URL }} + DIRECT_URL: ${{ secrets.DIRECT_URL }} + NODE_ENV: development + run: npm run prisma:seed diff --git a/package-lock.json b/package-lock.json index 01c9e6f..482bd9b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -44,6 +44,7 @@ "postcss": "^8.5.6", "prettier": "^3.8.1", "tailwindcss": "^4.1.16", + "tsx": "^4.21.0", "typescript": "^5.9.3" } }, @@ -90,6 +91,7 @@ "integrity": "sha512-e7jT4DxYvIDLk1ZHmU/m/mB19rex9sv0c2ftBtjSBv+kVM/902eh0fINUzD7UwLLNR+jU585GxUJ8/EBfAM5fw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@babel/code-frame": "^7.27.1", "@babel/generator": "^7.28.5", @@ -359,6 +361,448 @@ "tslib": "^2.4.0" } }, + "node_modules/@esbuild/aix-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.27.3.tgz", + "integrity": "sha512-9fJMTNFTWZMh5qwrBItuziu834eOCUcEqymSH7pY+zoMVEZg3gcPuBNxH1EvfVYe9h0x/Ptw8KBzv7qxb7l8dg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "aix" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.27.3.tgz", + "integrity": "sha512-i5D1hPY7GIQmXlXhs2w8AWHhenb00+GxjxRncS2ZM7YNVGNfaMxgzSGuO8o8SJzRc/oZwU2bcScvVERk03QhzA==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.27.3.tgz", + "integrity": "sha512-YdghPYUmj/FX2SYKJ0OZxf+iaKgMsKHVPF1MAq/P8WirnSpCStzKJFjOjzsW0QQ7oIAiccHdcqjbHmJxRb/dmg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/android-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.27.3.tgz", + "integrity": "sha512-IN/0BNTkHtk8lkOM8JWAYFg4ORxBkZQf9zXiEOfERX/CzxW3Vg1ewAhU7QSWQpVIzTW+b8Xy+lGzdYXV6UZObQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.27.3.tgz", + "integrity": "sha512-Re491k7ByTVRy0t3EKWajdLIr0gz2kKKfzafkth4Q8A5n1xTHrkqZgLLjFEHVD+AXdUGgQMq+Godfq45mGpCKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/darwin-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.27.3.tgz", + "integrity": "sha512-vHk/hA7/1AckjGzRqi6wbo+jaShzRowYip6rt6q7VYEDX4LEy1pZfDpdxCBnGtl+A5zq8iXDcyuxwtv3hNtHFg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.27.3.tgz", + "integrity": "sha512-ipTYM2fjt3kQAYOvo6vcxJx3nBYAzPjgTCk7QEgZG8AUO3ydUhvelmhrbOheMnGOlaSFUoHXB6un+A7q4ygY9w==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/freebsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.27.3.tgz", + "integrity": "sha512-dDk0X87T7mI6U3K9VjWtHOXqwAMJBNN2r7bejDsc+j03SEjtD9HrOl8gVFByeM0aJksoUuUVU9TBaZa2rgj0oA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.27.3.tgz", + "integrity": "sha512-s6nPv2QkSupJwLYyfS+gwdirm0ukyTFNl3KTgZEAiJDd+iHZcbTPPcWCcRYH+WlNbwChgH2QkE9NSlNrMT8Gfw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.27.3.tgz", + "integrity": "sha512-sZOuFz/xWnZ4KH3YfFrKCf1WyPZHakVzTiqji3WDc0BCl2kBwiJLCXpzLzUBLgmp4veFZdvN5ChW4Eq/8Fc2Fg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.27.3.tgz", + "integrity": "sha512-yGlQYjdxtLdh0a3jHjuwOrxQjOZYD/C9PfdbgJJF3TIZWnm/tMd/RcNiLngiu4iwcBAOezdnSLAwQDPqTmtTYg==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-loong64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.27.3.tgz", + "integrity": "sha512-WO60Sn8ly3gtzhyjATDgieJNet/KqsDlX5nRC5Y3oTFcS1l0KWba+SEa9Ja1GfDqSF1z6hif/SkpQJbL63cgOA==", + "cpu": [ + "loong64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-mips64el": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.27.3.tgz", + "integrity": "sha512-APsymYA6sGcZ4pD6k+UxbDjOFSvPWyZhjaiPyl/f79xKxwTnrn5QUnXR5prvetuaSMsb4jgeHewIDCIWljrSxw==", + "cpu": [ + "mips64el" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-ppc64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.27.3.tgz", + "integrity": "sha512-eizBnTeBefojtDb9nSh4vvVQ3V9Qf9Df01PfawPcRzJH4gFSgrObw+LveUyDoKU3kxi5+9RJTCWlj4FjYXVPEA==", + "cpu": [ + "ppc64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-riscv64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.27.3.tgz", + "integrity": "sha512-3Emwh0r5wmfm3ssTWRQSyVhbOHvqegUDRd0WhmXKX2mkHJe1SFCMJhagUleMq+Uci34wLSipf8Lagt4LlpRFWQ==", + "cpu": [ + "riscv64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-s390x": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.27.3.tgz", + "integrity": "sha512-pBHUx9LzXWBc7MFIEEL0yD/ZVtNgLytvx60gES28GcWMqil8ElCYR4kvbV2BDqsHOvVDRrOxGySBM9Fcv744hw==", + "cpu": [ + "s390x" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/linux-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.27.3.tgz", + "integrity": "sha512-Czi8yzXUWIQYAtL/2y6vogER8pvcsOsk5cpwL4Gk5nJqH5UZiVByIY8Eorm5R13gq+DQKYg0+JyQoytLQas4dA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.27.3.tgz", + "integrity": "sha512-sDpk0RgmTCR/5HguIZa9n9u+HVKf40fbEUt+iTzSnCaGvY9kFP0YKBWZtJaraonFnqef5SlJ8/TiPAxzyS+UoA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/netbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.27.3.tgz", + "integrity": "sha512-P14lFKJl/DdaE00LItAukUdZO5iqNH7+PjoBm+fLQjtxfcfFE20Xf5CrLsmZdq5LFFZzb5JMZ9grUwvtVYzjiA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "netbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.27.3.tgz", + "integrity": "sha512-AIcMP77AvirGbRl/UZFTq5hjXK+2wC7qFRGoHSDrZ5v5b8DK/GYpXW3CPRL53NkvDqb9D+alBiC/dV0Fb7eJcw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openbsd-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.27.3.tgz", + "integrity": "sha512-DnW2sRrBzA+YnE70LKqnM3P+z8vehfJWHXECbwBmH/CU51z6FiqTQTHFenPlHmo3a8UgpLyH3PT+87OViOh1AQ==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openbsd" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/openharmony-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/openharmony-arm64/-/openharmony-arm64-0.27.3.tgz", + "integrity": "sha512-NinAEgr/etERPTsZJ7aEZQvvg/A6IsZG/LgZy+81wON2huV7SrK3e63dU0XhyZP4RKGyTm7aOgmQk0bGp0fy2g==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/sunos-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.27.3.tgz", + "integrity": "sha512-PanZ+nEz+eWoBJ8/f8HKxTTD172SKwdXebZ0ndd953gt1HRBbhMsaNqjTyYLGLPdoWHy4zLU7bDVJztF5f3BHA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "sunos" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-arm64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.27.3.tgz", + "integrity": "sha512-B2t59lWWYrbRDw/tjiWOuzSsFh1Y/E95ofKz7rIVYSQkUYBjfSgf6oeYPNWHToFRr2zx52JKApIcAS/D5TUBnA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-ia32": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.27.3.tgz", + "integrity": "sha512-QLKSFeXNS8+tHW7tZpMtjlNb7HKau0QDpwm49u0vUp9y1WOF+PEzkU84y9GqYaAVW8aH8f3GcBck26jh54cX4Q==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, + "node_modules/@esbuild/win32-x64": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.27.3.tgz", + "integrity": "sha512-4uJGhsxuptu3OcpVAzli+/gWusVGwZZHTlS63hh++ehExkVT8SgiEf7/uC/PclrPPkLhZqGgCTjd0VWLo6xMqA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=18" + } + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.9.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.9.0.tgz", @@ -2157,6 +2601,7 @@ "resolved": "https://registry.npmjs.org/@supabase/supabase-js/-/supabase-js-2.95.3.tgz", "integrity": "sha512-Fukw1cUTQ6xdLiHDJhKKPu6svEPaCEDvThqCne3OaQyZvuq2qjhJAd91kJu3PXLG18aooCgYBaB6qQz35hhABg==", "license": "MIT", + "peer": true, "dependencies": { "@supabase/auth-js": "2.95.3", "@supabase/functions-js": "2.95.3", @@ -2550,6 +2995,7 @@ "integrity": "sha512-ilcTH/UniCkMdtexkoCN0bI7pMcJDvmQFPvuPvmEaYA/NSfFTAgdUSLAoVjaRJm7+6PvcM+q1zYOwS4wTYMF9w==", "devOptional": true, "license": "MIT", + "peer": true, "dependencies": { "csstype": "^3.2.2" } @@ -2560,6 +3006,7 @@ "integrity": "sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==", "devOptional": true, "license": "MIT", + "peer": true, "peerDependencies": { "@types/react": "^19.2.0" } @@ -2631,6 +3078,7 @@ "integrity": "sha512-BnOroVl1SgrPLywqxyqdJ4l3S2MsKVLDVxZvjI1Eoe8ev2r3kGDo+PcMihNmDE+6/KjkTubSJnmqGZZjQSBq/g==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.2", "@typescript-eslint/types": "8.46.2", @@ -3148,6 +3596,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -3500,6 +3949,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.19", "caniuse-lite": "^1.0.30001751", @@ -4225,6 +4675,48 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/esbuild": { + "version": "0.27.3", + "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.27.3.tgz", + "integrity": "sha512-8VwMnyGCONIs6cWue2IdpHxHnAjzxnw2Zr7MkVxB2vjmQ2ivqGFb4LEG3SMnv0Gb2F/G/2yA8zUaiL1gywDCCg==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "bin": { + "esbuild": "bin/esbuild" + }, + "engines": { + "node": ">=18" + }, + "optionalDependencies": { + "@esbuild/aix-ppc64": "0.27.3", + "@esbuild/android-arm": "0.27.3", + "@esbuild/android-arm64": "0.27.3", + "@esbuild/android-x64": "0.27.3", + "@esbuild/darwin-arm64": "0.27.3", + "@esbuild/darwin-x64": "0.27.3", + "@esbuild/freebsd-arm64": "0.27.3", + "@esbuild/freebsd-x64": "0.27.3", + "@esbuild/linux-arm": "0.27.3", + "@esbuild/linux-arm64": "0.27.3", + "@esbuild/linux-ia32": "0.27.3", + "@esbuild/linux-loong64": "0.27.3", + "@esbuild/linux-mips64el": "0.27.3", + "@esbuild/linux-ppc64": "0.27.3", + "@esbuild/linux-riscv64": "0.27.3", + "@esbuild/linux-s390x": "0.27.3", + "@esbuild/linux-x64": "0.27.3", + "@esbuild/netbsd-arm64": "0.27.3", + "@esbuild/netbsd-x64": "0.27.3", + "@esbuild/openbsd-arm64": "0.27.3", + "@esbuild/openbsd-x64": "0.27.3", + "@esbuild/openharmony-arm64": "0.27.3", + "@esbuild/sunos-x64": "0.27.3", + "@esbuild/win32-arm64": "0.27.3", + "@esbuild/win32-ia32": "0.27.3", + "@esbuild/win32-x64": "0.27.3" + } + }, "node_modules/escalade": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.2.0.tgz", @@ -4253,6 +4745,7 @@ "integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4438,6 +4931,7 @@ "integrity": "sha512-whOE1HFo/qJDyX4SnXzP4N6zOWn79WhnCUY/iDR0mPfQZO8wcYE4JClzI2oZrhBnnMUCBCHZhO6VQyoBU95mZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@rtsao/scc": "^1.1.0", "array-includes": "^3.1.9", @@ -4878,6 +5372,21 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/fsevents": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", + "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", + "dev": true, + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^8.16.0 || ^10.6.0 || >=11.0.0" + } + }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -6701,6 +7210,7 @@ "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==", "dev": true, "license": "MIT", + "peer": true, "engines": { "node": ">=12" }, @@ -6778,6 +7288,7 @@ "integrity": "sha512-bXWy3vTk8mnRmT+SLyZBQoC2vtV9Z8u7OHvEu+aULYxwiop/CPiFZ+F56KsNRNf35jw+8wcu8pmLsjxpBxAO9g==", "hasInstallScript": true, "license": "Apache-2.0", + "peer": true, "dependencies": { "@prisma/config": "6.18.0", "@prisma/engines": "6.18.0" @@ -6876,6 +7387,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-19.2.4.tgz", "integrity": "sha512-9nfp2hYpCwOjAN+8TZFGhtWEwgvWHXqESH8qT89AT/lWklpLON22Lc8pEtnpsZz7VmawabSU0gCjnj8aC0euHQ==", "license": "MIT", + "peer": true, "engines": { "node": ">=0.10.0" } @@ -6885,6 +7397,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.2.4.tgz", "integrity": "sha512-AXJdLo8kgMbimY95O2aKQqsz2iWi9jMgKJhRBAxECE4IFxfcazB2LmzloIoibJI3C12IlY20+KFaLv+71bUJeQ==", "license": "MIT", + "peer": true, "dependencies": { "scheduler": "^0.27.0" }, @@ -6897,6 +7410,7 @@ "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.71.1.tgz", "integrity": "sha512-9SUJKCGKo8HUSsCO+y0CtqkqI5nNuaDqTxyqPsZPqIwudpj4rCrAz/jZV+jn57bx5gtZKOh3neQu94DXMc+w5w==", "license": "MIT", + "peer": true, "engines": { "node": ">=18.0.0" }, @@ -7586,7 +8100,8 @@ "version": "4.1.18", "resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.18.tgz", "integrity": "sha512-4+Z+0yiYyEtUVCScyfHCxOYP06L5Ne+JiHhY2IjR2KWMIWhJOYZKLSGZaP5HkZ8+bY0cxfzwDE5uOmzFXyIwxw==", - "license": "MIT" + "license": "MIT", + "peer": true }, "node_modules/tailwindcss-animate": { "version": "1.0.7", @@ -7691,6 +8206,26 @@ "integrity": "sha512-oJFu94HQb+KVduSUQL7wnpmqnfmLsOA/nAh6b6EH0wCEoK0/mPeXU6c3wKDV83MkOuHPRHtSXKKU99IBazS/2w==", "license": "0BSD" }, + "node_modules/tsx": { + "version": "4.21.0", + "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.21.0.tgz", + "integrity": "sha512-5C1sg4USs1lfG0GFb2RLXsdpXqBSEhAaA/0kPL01wxzpMqLILNxIxIOKiILz+cdg/pLnOUxFYOR5yhHU666wbw==", + "dev": true, + "license": "MIT", + "dependencies": { + "esbuild": "~0.27.0", + "get-tsconfig": "^4.7.5" + }, + "bin": { + "tsx": "dist/cli.mjs" + }, + "engines": { + "node": ">=18.0.0" + }, + "optionalDependencies": { + "fsevents": "~2.3.3" + } + }, "node_modules/type-check": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz", @@ -7788,6 +8323,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "devOptional": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" @@ -8125,6 +8661,7 @@ "resolved": "https://registry.npmjs.org/zod/-/zod-4.3.6.tgz", "integrity": "sha512-rftlrkhHZOcjDwkGlnUtZZkvaPHCsDATp4pGpuOOMDaTdDDXF91wuVDJoWoPsKX/3YPQ5fHuF3STjcYyKr+Qhg==", "license": "MIT", + "peer": true, "funding": { "url": "https://github.com/sponsors/colinhacks" } diff --git a/package.json b/package.json index a49b4ab..fa3dcc7 100644 --- a/package.json +++ b/package.json @@ -9,9 +9,10 @@ "lint": "next lint", "db:start": "docker compose up -d", "db:stop": "docker compose down", - "db:reset": "docker compose down -v && docker compose up -d --wait && npm run prisma:migrate", + "db:reset": "docker compose down -v && docker compose up -d --wait && npm run prisma:migrate && npm run prisma:seed", "prisma:generate": "prisma generate", "prisma:migrate": "prisma migrate dev", + "prisma:seed": "prisma db seed", "prisma:studio": "prisma studio", "postinstall": "prisma generate" }, @@ -51,6 +52,7 @@ "postcss": "^8.5.6", "prettier": "^3.8.1", "tailwindcss": "^4.1.16", + "tsx": "^4.21.0", "typescript": "^5.9.3" } } diff --git a/prisma.config.ts b/prisma.config.ts index 030de16..ab6c5f2 100644 --- a/prisma.config.ts +++ b/prisma.config.ts @@ -11,4 +11,7 @@ export default defineConfig({ url: env("DATABASE_URL"), directUrl: env("DIRECT_URL"), }, + seed: { + command: "tsx prisma/seed.ts", + }, }); diff --git a/prisma/seed.ts b/prisma/seed.ts new file mode 100644 index 0000000..de43553 --- /dev/null +++ b/prisma/seed.ts @@ -0,0 +1,168 @@ +import { PrismaClient } from '@prisma/client' + +const prisma = new PrismaClient() + +// Predefined data arrays +const FIRST_NAMES = ['Alex', 'Jordan', 'Taylor', 'Morgan', 'Casey'] +const LAST_NAMES = ['Smith', 'Johnson', 'Williams', 'Brown', 'Davis'] +const COLLEGES = ['Khoury College of Computer Sciences', 'College of Engineering', 'College of Science', 'D\'Amore-McKim School of Business', 'College of Social Sciences and Humanities'] +const MAJORS = ['Computer Science', 'Data Science', 'Business Administration', 'Political Science', 'Biology'] +const MINORS = ['Mathematics', 'Economics', 'Psychology', '', 'Philosophy'] +const YEARS = [1, 2, 3, 4, 5] +const SEMESTERS = ['Fall 2024', 'Spring 2025', 'Fall 2025', 'Spring 2026', 'Fall 2026'] +const CONSTITUENCIES = ['Khoury', 'Engineering', 'Science', 'Business', 'CSSH'] +const PRONOUNS = ['he/him', 'she/her', 'they/them', 'she/they', 'he/they'] + +const randomItem = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)] + +async function main() { + if (process.env.NODE_ENV === 'production') { + console.log('Seeding disabled in production') + return + } + + const existingData = await prisma.communityConstituency.findFirst() + if (existingData) { + console.log('Already seeded, skipping...') + return + } + + console.log('Seeding database...') + + // Seed CommunityConstituency + console.log('Seeding community constituencies...') + const constituencies = await Promise.all([ + prisma.communityConstituency.create({ + data: { + name: 'International Students', + isActive: true, + }, + }), + prisma.communityConstituency.create({ + data: { + name: 'First Generation Students', + isActive: true, + }, + }), + prisma.communityConstituency.create({ + data: { + name: 'Transfer Students', + isActive: true, + }, + }), + prisma.communityConstituency.create({ + data: { + name: 'Veterans and Military Affiliated', + isActive: true, + }, + }), + prisma.communityConstituency.create({ + data: { + name: 'LGBTQ+ Community', + isActive: false, + }, + }), + ]) + + // Seed Settings (singleton) + console.log('Seeding settings...') + await prisma.settings.create({ + data: { + requiredNominations: 15, + maxCommunityNominations: 7, + endorsementRequired: false, + endorsementsOpen: true, + applicationDeadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now + applicationsOpen: true, + nominationsOpen: true, + customMessage: 'Welcome to the Student Senate Application System!', + }, + }) + + // Seed Applications + console.log('Seeding applications...') + for (let i = 0; i < 5; i++) { + const firstName = FIRST_NAMES[i] + const lastName = LAST_NAMES[i] + const fullName = `${firstName} ${lastName}` + + await prisma.application.create({ + data: { + nuid: `00100000${i}`, + fullName, + preferredFullName: fullName, + phoneticPronunciation: fullName, + pronunciationAudioUrl: `https://example.com/audio/${i}.mp3`, + pronouns: PRONOUNS[i], + email: `user${i + 1}@northeastern.edu`, + phoneNumber: `617-555-010${i}`, + college: COLLEGES[i], + major: MAJORS[i], + minors: MINORS[i], + year: YEARS[i], + semester: SEMESTERS[i], + constituency: CONSTITUENCIES[i], + communityConstituencyId: i < 3 ? constituencies[i].id : null, + whySenateLongAnswer: `I am passionate about representing ${CONSTITUENCIES[i]} students and making a positive impact on campus. I believe my experience and dedication make me a strong candidate for student senate.`, + constituencyIssueLongAnswer: `The main issues facing ${CONSTITUENCIES[i]} students include access to resources, representation in decision-making, and building community. I plan to address these by working closely with administration and advocating for student needs.`, + diversityEquityInclusionLongAnswer: 'I am committed to creating an inclusive environment where all students feel valued and heard. I will work to ensure diverse perspectives are represented in all discussions and decisions.', + conflictSituationLongAnswer: 'In conflict situations, I believe in listening to all parties, finding common ground, and working collaboratively toward solutions that benefit everyone involved.', + campaignBlurb: `Vote ${firstName} ${lastName} for Student Senate - Committed to representing your voice!`, + nominationFormPdfUrl: `https://example.com/nominations/${i}.pdf`, + }, + }) + } + + // Seed Nominations + console.log('Seeding nominations...') + const statuses = ['PENDING', 'APPROVED', 'REJECTED', 'PENDING', 'APPROVED'] as const + + for (let i = 0; i < 5; i++) { + const firstName = randomItem(FIRST_NAMES) + const lastName = randomItem(LAST_NAMES) + + await prisma.nomination.create({ + data: { + nominee: `${firstName} ${lastName}`, + fullName: `Nominator ${i + 1}`, + email: `nominator${i + 1}@northeastern.edu`, + college: randomItem(COLLEGES), + major: randomItem(MAJORS), + status: statuses[i], + constituencyType: i % 2 === 0 ? 'academic' : 'community', + communityConstituencyId: i % 2 === 1 && i < 4 ? constituencies[Math.floor(i / 2)].id : null, + }, + }) + } + + // Seed Endorsements + console.log('Seeding endorsements...') + for (let i = 0; i < 5; i++) { + const endorserFirst = randomItem(FIRST_NAMES) + const endorserLast = randomItem(LAST_NAMES) + const applicantFirst = FIRST_NAMES[i] + const applicantLast = LAST_NAMES[i] + + await prisma.endorsement.create({ + data: { + endorserName: `${endorserFirst} ${endorserLast}`, + endorserEmail: `endorser${i + 1}@northeastern.edu`, + applicantName: `${applicantFirst} ${applicantLast}`, + definingTraits: 'Dedicated, passionate, and committed to student advocacy. Shows strong leadership potential and genuine care for the student body.', + leadershipQualities: 'Excellent communication skills, ability to work collaboratively, strategic thinking, and proven track record of initiative.', + areasForDevelopment: 'Could benefit from more experience in formal governance processes and public speaking in large settings.', + }, + }) + } + + console.log('Seeding complete!') +} + +main() + .catch((e) => { + console.error('Seeding error:', e) + process.exit(1) + }) + .finally(async () => { + await prisma.$disconnect() + }) From 0457c414b3ca21c0f51b2194bdd574a7388573a7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 19:00:59 +0000 Subject: [PATCH 3/8] #16 fix seed configuration and improve production safety Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- package.json | 3 +++ prisma.config.ts | 3 --- prisma/seed.ts | 4 +++- 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/package.json b/package.json index fa3dcc7..c25db33 100644 --- a/package.json +++ b/package.json @@ -16,6 +16,9 @@ "prisma:studio": "prisma studio", "postinstall": "prisma generate" }, + "prisma": { + "seed": "tsx prisma/seed.ts" + }, "private": true, "dependencies": { "@hookform/resolvers": "^5.2.2", diff --git a/prisma.config.ts b/prisma.config.ts index ab6c5f2..030de16 100644 --- a/prisma.config.ts +++ b/prisma.config.ts @@ -11,7 +11,4 @@ export default defineConfig({ url: env("DATABASE_URL"), directUrl: env("DIRECT_URL"), }, - seed: { - command: "tsx prisma/seed.ts", - }, }); diff --git a/prisma/seed.ts b/prisma/seed.ts index de43553..4b5871c 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -16,7 +16,9 @@ const PRONOUNS = ['he/him', 'she/her', 'they/them', 'she/they', 'he/they'] const randomItem = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)] async function main() { - if (process.env.NODE_ENV === 'production') { + const nodeEnv = process.env.NODE_ENV || 'development' + + if (nodeEnv === 'production') { console.log('Seeding disabled in production') return } From adc4a2fb92a6b832a67400f6fc39534179050a68 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 14 Feb 2026 20:08:01 +0000 Subject: [PATCH 4/8] #16 refactor seed data into modular structure with randomization Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- prisma/seed.ts | 156 ++---------------------- prisma/seed/applications.ts | 56 +++++++++ prisma/seed/community-constituencies.ts | 11 ++ prisma/seed/constants.ts | 81 ++++++++++++ prisma/seed/endorsements.ts | 27 ++++ prisma/seed/nominations.ts | 34 ++++++ prisma/seed/settings.ts | 16 +++ 7 files changed, 236 insertions(+), 145 deletions(-) create mode 100644 prisma/seed/applications.ts create mode 100644 prisma/seed/community-constituencies.ts create mode 100644 prisma/seed/constants.ts create mode 100644 prisma/seed/endorsements.ts create mode 100644 prisma/seed/nominations.ts create mode 100644 prisma/seed/settings.ts diff --git a/prisma/seed.ts b/prisma/seed.ts index 4b5871c..2ce76c3 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,163 +1,29 @@ import { PrismaClient } from '@prisma/client' +import { seedCommunityConstituencies } from './seed/community-constituencies' +import { seedSettings } from './seed/settings' +import { seedApplications } from './seed/applications' +import { seedNominations } from './seed/nominations' +import { seedEndorsements } from './seed/endorsements' const prisma = new PrismaClient() -// Predefined data arrays -const FIRST_NAMES = ['Alex', 'Jordan', 'Taylor', 'Morgan', 'Casey'] -const LAST_NAMES = ['Smith', 'Johnson', 'Williams', 'Brown', 'Davis'] -const COLLEGES = ['Khoury College of Computer Sciences', 'College of Engineering', 'College of Science', 'D\'Amore-McKim School of Business', 'College of Social Sciences and Humanities'] -const MAJORS = ['Computer Science', 'Data Science', 'Business Administration', 'Political Science', 'Biology'] -const MINORS = ['Mathematics', 'Economics', 'Psychology', '', 'Philosophy'] -const YEARS = [1, 2, 3, 4, 5] -const SEMESTERS = ['Fall 2024', 'Spring 2025', 'Fall 2025', 'Spring 2026', 'Fall 2026'] -const CONSTITUENCIES = ['Khoury', 'Engineering', 'Science', 'Business', 'CSSH'] -const PRONOUNS = ['he/him', 'she/her', 'they/them', 'she/they', 'he/they'] - -const randomItem = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)] - async function main() { const nodeEnv = process.env.NODE_ENV || 'development' - + if (nodeEnv === 'production') { - console.log('Seeding disabled in production') return } const existingData = await prisma.communityConstituency.findFirst() if (existingData) { - console.log('Already seeded, skipping...') return } - console.log('Seeding database...') - - // Seed CommunityConstituency - console.log('Seeding community constituencies...') - const constituencies = await Promise.all([ - prisma.communityConstituency.create({ - data: { - name: 'International Students', - isActive: true, - }, - }), - prisma.communityConstituency.create({ - data: { - name: 'First Generation Students', - isActive: true, - }, - }), - prisma.communityConstituency.create({ - data: { - name: 'Transfer Students', - isActive: true, - }, - }), - prisma.communityConstituency.create({ - data: { - name: 'Veterans and Military Affiliated', - isActive: true, - }, - }), - prisma.communityConstituency.create({ - data: { - name: 'LGBTQ+ Community', - isActive: false, - }, - }), - ]) - - // Seed Settings (singleton) - console.log('Seeding settings...') - await prisma.settings.create({ - data: { - requiredNominations: 15, - maxCommunityNominations: 7, - endorsementRequired: false, - endorsementsOpen: true, - applicationDeadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now - applicationsOpen: true, - nominationsOpen: true, - customMessage: 'Welcome to the Student Senate Application System!', - }, - }) - - // Seed Applications - console.log('Seeding applications...') - for (let i = 0; i < 5; i++) { - const firstName = FIRST_NAMES[i] - const lastName = LAST_NAMES[i] - const fullName = `${firstName} ${lastName}` - - await prisma.application.create({ - data: { - nuid: `00100000${i}`, - fullName, - preferredFullName: fullName, - phoneticPronunciation: fullName, - pronunciationAudioUrl: `https://example.com/audio/${i}.mp3`, - pronouns: PRONOUNS[i], - email: `user${i + 1}@northeastern.edu`, - phoneNumber: `617-555-010${i}`, - college: COLLEGES[i], - major: MAJORS[i], - minors: MINORS[i], - year: YEARS[i], - semester: SEMESTERS[i], - constituency: CONSTITUENCIES[i], - communityConstituencyId: i < 3 ? constituencies[i].id : null, - whySenateLongAnswer: `I am passionate about representing ${CONSTITUENCIES[i]} students and making a positive impact on campus. I believe my experience and dedication make me a strong candidate for student senate.`, - constituencyIssueLongAnswer: `The main issues facing ${CONSTITUENCIES[i]} students include access to resources, representation in decision-making, and building community. I plan to address these by working closely with administration and advocating for student needs.`, - diversityEquityInclusionLongAnswer: 'I am committed to creating an inclusive environment where all students feel valued and heard. I will work to ensure diverse perspectives are represented in all discussions and decisions.', - conflictSituationLongAnswer: 'In conflict situations, I believe in listening to all parties, finding common ground, and working collaboratively toward solutions that benefit everyone involved.', - campaignBlurb: `Vote ${firstName} ${lastName} for Student Senate - Committed to representing your voice!`, - nominationFormPdfUrl: `https://example.com/nominations/${i}.pdf`, - }, - }) - } - - // Seed Nominations - console.log('Seeding nominations...') - const statuses = ['PENDING', 'APPROVED', 'REJECTED', 'PENDING', 'APPROVED'] as const - - for (let i = 0; i < 5; i++) { - const firstName = randomItem(FIRST_NAMES) - const lastName = randomItem(LAST_NAMES) - - await prisma.nomination.create({ - data: { - nominee: `${firstName} ${lastName}`, - fullName: `Nominator ${i + 1}`, - email: `nominator${i + 1}@northeastern.edu`, - college: randomItem(COLLEGES), - major: randomItem(MAJORS), - status: statuses[i], - constituencyType: i % 2 === 0 ? 'academic' : 'community', - communityConstituencyId: i % 2 === 1 && i < 4 ? constituencies[Math.floor(i / 2)].id : null, - }, - }) - } - - // Seed Endorsements - console.log('Seeding endorsements...') - for (let i = 0; i < 5; i++) { - const endorserFirst = randomItem(FIRST_NAMES) - const endorserLast = randomItem(LAST_NAMES) - const applicantFirst = FIRST_NAMES[i] - const applicantLast = LAST_NAMES[i] - - await prisma.endorsement.create({ - data: { - endorserName: `${endorserFirst} ${endorserLast}`, - endorserEmail: `endorser${i + 1}@northeastern.edu`, - applicantName: `${applicantFirst} ${applicantLast}`, - definingTraits: 'Dedicated, passionate, and committed to student advocacy. Shows strong leadership potential and genuine care for the student body.', - leadershipQualities: 'Excellent communication skills, ability to work collaboratively, strategic thinking, and proven track record of initiative.', - areasForDevelopment: 'Could benefit from more experience in formal governance processes and public speaking in large settings.', - }, - }) - } - - console.log('Seeding complete!') + const constituencies = await seedCommunityConstituencies(prisma) + await seedSettings(prisma) + await seedApplications(prisma, constituencies) + await seedNominations(prisma, constituencies) + await seedEndorsements(prisma) } main() diff --git a/prisma/seed/applications.ts b/prisma/seed/applications.ts new file mode 100644 index 0000000..1984ca6 --- /dev/null +++ b/prisma/seed/applications.ts @@ -0,0 +1,56 @@ +import { PrismaClient, CommunityConstituency } from '@prisma/client' +import { + FIRST_NAMES, + LAST_NAMES, + COLLEGES, + MAJORS, + MINORS, + YEARS, + SEMESTERS, + CONSTITUENCIES, + PRONOUNS, + LONG_ANSWERS, + randomItem, +} from './constants' + +export async function seedApplications( + prisma: PrismaClient, + constituencies: CommunityConstituency[] +) { + const applications = [] + + for (let i = 0; i < 5; i++) { + const firstName = randomItem(FIRST_NAMES) + const lastName = randomItem(LAST_NAMES) + const fullName = `${firstName} ${lastName}` + + applications.push({ + nuid: `00100000${i}`, + fullName, + preferredFullName: fullName, + phoneticPronunciation: fullName, + pronunciationAudioUrl: `https://example.com/audio/${i}.mp3`, + pronouns: randomItem(PRONOUNS), + email: `user${i + 1}@northeastern.edu`, + phoneNumber: `617-555-010${i}`, + college: randomItem(COLLEGES), + major: randomItem(MAJORS), + minors: randomItem(MINORS), + year: randomItem(YEARS), + semester: randomItem(SEMESTERS), + constituency: randomItem(CONSTITUENCIES), + communityConstituencyId: i < 3 ? constituencies[i].id : null, + whySenateLongAnswer: randomItem(LONG_ANSWERS.whySenate), + constituencyIssueLongAnswer: randomItem(LONG_ANSWERS.constituencyIssue), + diversityEquityInclusionLongAnswer: randomItem(LONG_ANSWERS.diversityEquityInclusion), + conflictSituationLongAnswer: randomItem(LONG_ANSWERS.conflictSituation), + campaignBlurb: `Vote ${firstName} ${lastName} for Student Senate - Committed to representing your voice!`, + nominationFormPdfUrl: `https://example.com/nominations/${i}.pdf`, + }) + } + + await prisma.application.createMany({ + data: applications, + skipDuplicates: true, + }) +} diff --git a/prisma/seed/community-constituencies.ts b/prisma/seed/community-constituencies.ts new file mode 100644 index 0000000..b1d0414 --- /dev/null +++ b/prisma/seed/community-constituencies.ts @@ -0,0 +1,11 @@ +import { PrismaClient } from '@prisma/client' +import { COMMUNITY_CONSTITUENCIES } from './constants' + +export async function seedCommunityConstituencies(prisma: PrismaClient) { + const constituencies = await prisma.communityConstituency.createMany({ + data: COMMUNITY_CONSTITUENCIES, + skipDuplicates: true, + }) + + return prisma.communityConstituency.findMany() +} diff --git a/prisma/seed/constants.ts b/prisma/seed/constants.ts new file mode 100644 index 0000000..7c172da --- /dev/null +++ b/prisma/seed/constants.ts @@ -0,0 +1,81 @@ +// Predefined data arrays +export const FIRST_NAMES = ['Alex', 'Jordan', 'Taylor', 'Morgan', 'Casey'] +export const LAST_NAMES = ['Smith', 'Johnson', 'Williams', 'Brown', 'Davis'] +export const COLLEGES = [ + 'Khoury College of Computer Sciences', + 'College of Engineering', + 'College of Science', + 'D\'Amore-McKim School of Business', + 'College of Social Sciences and Humanities' +] +export const MAJORS = ['Computer Science', 'Data Science', 'Business Administration', 'Political Science', 'Biology'] +export const MINORS = ['Mathematics', 'Economics', 'Psychology', '', 'Philosophy'] +export const YEARS = [1, 2, 3, 4, 5] +export const SEMESTERS = ['Fall 2024', 'Spring 2025', 'Fall 2025', 'Spring 2026', 'Fall 2026'] +export const CONSTITUENCIES = ['Khoury', 'Engineering', 'Science', 'Business', 'CSSH'] +export const PRONOUNS = ['he/him', 'she/her', 'they/them', 'she/they', 'he/they'] + +export const COMMUNITY_CONSTITUENCIES = [ + { name: 'International Students', isActive: true }, + { name: 'First Generation Students', isActive: true }, + { name: 'Transfer Students', isActive: true }, + { name: 'Veterans and Military Affiliated', isActive: true }, + { name: 'LGBTQ+ Community', isActive: false } +] + +export const LONG_ANSWERS = { + whySenate: [ + 'I am passionate about representing students and making a positive impact on campus. I believe my experience and dedication make me a strong candidate for student senate.', + 'Student government has always been important to me as a way to create meaningful change. I want to ensure every voice is heard in decision-making processes.', + 'My goal is to bridge the gap between students and administration, advocating for policies that improve campus life and academic experiences.', + 'I have a track record of leadership and want to use those skills to serve the student body and address pressing issues facing our community.', + 'Being part of student senate would allow me to work on initiatives I care about while representing the diverse perspectives of my fellow students.' + ], + constituencyIssue: [ + 'The main issues include access to resources, representation in decision-making, and building community. I plan to address these by working closely with administration and advocating for student needs.', + 'Students face challenges with academic support, mental health resources, and campus engagement. I will work to expand services and create more inclusive programs.', + 'Key concerns are affordability, career preparation, and campus safety. I will collaborate with stakeholders to develop comprehensive solutions.', + 'We need better communication between students and faculty, improved facilities, and more opportunities for student involvement in governance.', + 'The biggest issues are accessibility, equity in resource distribution, and creating a welcoming environment for all students regardless of background.' + ], + diversityEquityInclusion: [ + 'I am committed to creating an inclusive environment where all students feel valued and heard. I will work to ensure diverse perspectives are represented in all discussions and decisions.', + 'Diversity strengthens our community. I will advocate for programs that celebrate different cultures and create spaces for meaningful dialogue across differences.', + 'Equity means ensuring everyone has access to the resources they need. I will push for policies that address systemic barriers and promote equal opportunity.', + 'Inclusion requires active effort. I will work to amplify marginalized voices and ensure decision-making processes reflect the full diversity of our student body.', + 'I believe in proactive measures to create belonging, from inclusive events to equitable policies that support students from all backgrounds.' + ], + conflictSituation: [ + 'In conflict situations, I believe in listening to all parties, finding common ground, and working collaboratively toward solutions that benefit everyone involved.', + 'I approach conflicts with empathy and patience, seeking to understand different perspectives before proposing resolutions that address root causes.', + 'My strategy is to facilitate open dialogue, mediate disputes fairly, and find creative compromises that respect everyone\'s needs and concerns.', + 'I handle conflicts by staying calm, gathering all relevant information, and working with stakeholders to develop mutually beneficial solutions.', + 'Conflict resolution requires active listening, clear communication, and a commitment to fairness. I focus on building consensus and maintaining relationships.' + ] +} + +export const ENDORSEMENT_CONTENT = { + definingTraits: [ + 'Dedicated, passionate, and committed to student advocacy. Shows strong leadership potential and genuine care for the student body.', + 'Innovative thinker with excellent interpersonal skills. Demonstrates reliability, integrity, and a collaborative approach to problem-solving.', + 'Empathetic listener who builds consensus. Shows resilience, creativity, and dedication to making positive change on campus.', + 'Natural leader with strong communication abilities. Displays initiative, responsibility, and genuine commitment to serving others.', + 'Strategic and thoughtful with a proven track record. Combines vision with practical action and inspires others through example.' + ], + leadershipQualities: [ + 'Excellent communication skills, ability to work collaboratively, strategic thinking, and proven track record of initiative.', + 'Strong organizational abilities, empowers team members, thinks critically under pressure, and maintains ethical standards.', + 'Builds inclusive teams, delegates effectively, stays focused on goals, and adapts well to changing circumstances.', + 'Inspires trust and confidence, makes thoughtful decisions, takes accountability, and demonstrates emotional intelligence.', + 'Motivates others toward shared vision, balances multiple priorities, communicates clearly, and leads by example.' + ], + areasForDevelopment: [ + 'Could benefit from more experience in formal governance processes and public speaking in large settings.', + 'Would grow from additional exposure to budget management and long-term strategic planning.', + 'Could develop skills in conflict mediation and navigating complex organizational structures.', + 'Would benefit from experience managing larger teams and coordinating multi-stakeholder initiatives.', + 'Could strengthen abilities in data analysis and evidence-based policy development.' + ] +} + +export const randomItem = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)] diff --git a/prisma/seed/endorsements.ts b/prisma/seed/endorsements.ts new file mode 100644 index 0000000..c2dd2e8 --- /dev/null +++ b/prisma/seed/endorsements.ts @@ -0,0 +1,27 @@ +import { PrismaClient } from '@prisma/client' +import { FIRST_NAMES, LAST_NAMES, ENDORSEMENT_CONTENT, randomItem } from './constants' + +export async function seedEndorsements(prisma: PrismaClient) { + const endorsements = [] + + for (let i = 0; i < 5; i++) { + const endorserFirst = randomItem(FIRST_NAMES) + const endorserLast = randomItem(LAST_NAMES) + const applicantFirst = randomItem(FIRST_NAMES) + const applicantLast = randomItem(LAST_NAMES) + + endorsements.push({ + endorserName: `${endorserFirst} ${endorserLast}`, + endorserEmail: `endorser${i + 1}@northeastern.edu`, + applicantName: `${applicantFirst} ${applicantLast}`, + definingTraits: randomItem(ENDORSEMENT_CONTENT.definingTraits), + leadershipQualities: randomItem(ENDORSEMENT_CONTENT.leadershipQualities), + areasForDevelopment: randomItem(ENDORSEMENT_CONTENT.areasForDevelopment), + }) + } + + await prisma.endorsement.createMany({ + data: endorsements, + skipDuplicates: true, + }) +} diff --git a/prisma/seed/nominations.ts b/prisma/seed/nominations.ts new file mode 100644 index 0000000..a21a088 --- /dev/null +++ b/prisma/seed/nominations.ts @@ -0,0 +1,34 @@ +import { PrismaClient, CommunityConstituency } from '@prisma/client' +import { FIRST_NAMES, LAST_NAMES, COLLEGES, MAJORS, randomItem } from './constants' + +const STATUSES = ['PENDING', 'APPROVED', 'REJECTED', 'PENDING', 'APPROVED'] as const + +export async function seedNominations( + prisma: PrismaClient, + constituencies: CommunityConstituency[] +) { + const nominations = [] + + for (let i = 0; i < 5; i++) { + const firstName = randomItem(FIRST_NAMES) + const lastName = randomItem(LAST_NAMES) + const nominatorFirst = randomItem(FIRST_NAMES) + const nominatorLast = randomItem(LAST_NAMES) + + nominations.push({ + nominee: `${firstName} ${lastName}`, + fullName: `${nominatorFirst} ${nominatorLast}`, + email: `nominator${i + 1}@northeastern.edu`, + college: randomItem(COLLEGES), + major: randomItem(MAJORS), + status: STATUSES[i], + constituencyType: i % 2 === 0 ? 'academic' : 'community', + communityConstituencyId: i % 2 === 1 && i < 4 ? constituencies[Math.floor(i / 2)].id : null, + }) + } + + await prisma.nomination.createMany({ + data: nominations, + skipDuplicates: true, + }) +} diff --git a/prisma/seed/settings.ts b/prisma/seed/settings.ts new file mode 100644 index 0000000..d3250a5 --- /dev/null +++ b/prisma/seed/settings.ts @@ -0,0 +1,16 @@ +import { PrismaClient } from '@prisma/client' + +export async function seedSettings(prisma: PrismaClient) { + await prisma.settings.create({ + data: { + requiredNominations: 15, + maxCommunityNominations: 7, + endorsementRequired: false, + endorsementsOpen: true, + applicationDeadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now + applicationsOpen: true, + nominationsOpen: true, + customMessage: 'Welcome to the Student Senate Application System!', + }, + }) +} From a4c6c3fdeeb16131e93b935c8b0ba4fcfd9534d6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 01:54:48 +0000 Subject: [PATCH 5/8] #16 add global prisma client and randomize all numbers and emails Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- prisma/seed.ts | 16 ++++++------- prisma/seed/applications.ts | 17 ++++++------- prisma/seed/community-constituencies.ts | 6 ++--- prisma/seed/constants.ts | 32 ++++++++++++++++++++++++- prisma/seed/endorsements.ts | 14 +++++++---- prisma/seed/nominations.ts | 22 ++++++++++------- prisma/seed/settings.ts | 6 ++--- 7 files changed, 77 insertions(+), 36 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index 2ce76c3..b1fc08e 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -5,7 +5,7 @@ import { seedApplications } from './seed/applications' import { seedNominations } from './seed/nominations' import { seedEndorsements } from './seed/endorsements' -const prisma = new PrismaClient() +export const prisma = new PrismaClient() async function main() { const nodeEnv = process.env.NODE_ENV || 'development' @@ -15,15 +15,13 @@ async function main() { } const existingData = await prisma.communityConstituency.findFirst() - if (existingData) { - return - } + if (existingData) return - const constituencies = await seedCommunityConstituencies(prisma) - await seedSettings(prisma) - await seedApplications(prisma, constituencies) - await seedNominations(prisma, constituencies) - await seedEndorsements(prisma) + const constituencies = await seedCommunityConstituencies() + await seedSettings() + await seedApplications(constituencies) + await seedNominations(constituencies) + await seedEndorsements() } main() diff --git a/prisma/seed/applications.ts b/prisma/seed/applications.ts index 1984ca6..436f332 100644 --- a/prisma/seed/applications.ts +++ b/prisma/seed/applications.ts @@ -1,4 +1,5 @@ -import { PrismaClient, CommunityConstituency } from '@prisma/client' +import { CommunityConstituency } from '@prisma/client' +import { prisma } from '../seed' import { FIRST_NAMES, LAST_NAMES, @@ -11,12 +12,12 @@ import { PRONOUNS, LONG_ANSWERS, randomItem, + generateNUID, + generateEmail, + generatePhoneNumber, } from './constants' -export async function seedApplications( - prisma: PrismaClient, - constituencies: CommunityConstituency[] -) { +export async function seedApplications(constituencies: CommunityConstituency[]) { const applications = [] for (let i = 0; i < 5; i++) { @@ -25,14 +26,14 @@ export async function seedApplications( const fullName = `${firstName} ${lastName}` applications.push({ - nuid: `00100000${i}`, + nuid: generateNUID(), fullName, preferredFullName: fullName, phoneticPronunciation: fullName, pronunciationAudioUrl: `https://example.com/audio/${i}.mp3`, pronouns: randomItem(PRONOUNS), - email: `user${i + 1}@northeastern.edu`, - phoneNumber: `617-555-010${i}`, + email: generateEmail(firstName, lastName), + phoneNumber: generatePhoneNumber(), college: randomItem(COLLEGES), major: randomItem(MAJORS), minors: randomItem(MINORS), diff --git a/prisma/seed/community-constituencies.ts b/prisma/seed/community-constituencies.ts index b1d0414..7e84d56 100644 --- a/prisma/seed/community-constituencies.ts +++ b/prisma/seed/community-constituencies.ts @@ -1,8 +1,8 @@ -import { PrismaClient } from '@prisma/client' +import { prisma } from '../seed' import { COMMUNITY_CONSTITUENCIES } from './constants' -export async function seedCommunityConstituencies(prisma: PrismaClient) { - const constituencies = await prisma.communityConstituency.createMany({ +export async function seedCommunityConstituencies() { + await prisma.communityConstituency.createMany({ data: COMMUNITY_CONSTITUENCIES, skipDuplicates: true, }) diff --git a/prisma/seed/constants.ts b/prisma/seed/constants.ts index 7c172da..8809c3b 100644 --- a/prisma/seed/constants.ts +++ b/prisma/seed/constants.ts @@ -1,4 +1,3 @@ -// Predefined data arrays export const FIRST_NAMES = ['Alex', 'Jordan', 'Taylor', 'Morgan', 'Casey'] export const LAST_NAMES = ['Smith', 'Johnson', 'Williams', 'Brown', 'Davis'] export const COLLEGES = [ @@ -79,3 +78,34 @@ export const ENDORSEMENT_CONTENT = { } export const randomItem = (arr: T[]): T => arr[Math.floor(Math.random() * arr.length)] + +export const randomInt = (min: number, max: number): number => + Math.floor(Math.random() * (max - min + 1)) + min + +export const generateNUID = (): string => { + const randomDigits = randomInt(100000, 999999) + return `001${randomDigits}` +} + +export const generateEmail = (firstName: string, lastName: string): string => { + const randomNum = randomInt(1, 9999) + const cleanFirst = firstName.toLowerCase().replace(/[^a-z]/g, '') + const cleanLast = lastName.toLowerCase().replace(/[^a-z]/g, '') + return `${cleanFirst}.${cleanLast}${randomNum}@northeastern.edu` +} + +export const generatePhoneNumber = (): string => { + const areaCode = randomInt(200, 999) + const prefix = randomInt(200, 999) + const lineNumber = randomInt(1000, 9999) + return `${areaCode}-${prefix}-${lineNumber}` +} + +export const getRandomConstituencyId = ( + index: number, + constituencies: Array<{ id: string }> +): string | null => { + if (index % 2 === 0) return null + if (index >= 4) return null + return constituencies[Math.floor(index / 2)].id +} diff --git a/prisma/seed/endorsements.ts b/prisma/seed/endorsements.ts index c2dd2e8..bde54c9 100644 --- a/prisma/seed/endorsements.ts +++ b/prisma/seed/endorsements.ts @@ -1,7 +1,13 @@ -import { PrismaClient } from '@prisma/client' -import { FIRST_NAMES, LAST_NAMES, ENDORSEMENT_CONTENT, randomItem } from './constants' +import { prisma } from '../seed' +import { + FIRST_NAMES, + LAST_NAMES, + ENDORSEMENT_CONTENT, + randomItem, + generateEmail, +} from './constants' -export async function seedEndorsements(prisma: PrismaClient) { +export async function seedEndorsements() { const endorsements = [] for (let i = 0; i < 5; i++) { @@ -12,7 +18,7 @@ export async function seedEndorsements(prisma: PrismaClient) { endorsements.push({ endorserName: `${endorserFirst} ${endorserLast}`, - endorserEmail: `endorser${i + 1}@northeastern.edu`, + endorserEmail: generateEmail(endorserFirst, endorserLast), applicantName: `${applicantFirst} ${applicantLast}`, definingTraits: randomItem(ENDORSEMENT_CONTENT.definingTraits), leadershipQualities: randomItem(ENDORSEMENT_CONTENT.leadershipQualities), diff --git a/prisma/seed/nominations.ts b/prisma/seed/nominations.ts index a21a088..e1db745 100644 --- a/prisma/seed/nominations.ts +++ b/prisma/seed/nominations.ts @@ -1,12 +1,18 @@ -import { PrismaClient, CommunityConstituency } from '@prisma/client' -import { FIRST_NAMES, LAST_NAMES, COLLEGES, MAJORS, randomItem } from './constants' +import { CommunityConstituency } from '@prisma/client' +import { prisma } from '../seed' +import { + FIRST_NAMES, + LAST_NAMES, + COLLEGES, + MAJORS, + randomItem, + generateEmail, + getRandomConstituencyId, +} from './constants' const STATUSES = ['PENDING', 'APPROVED', 'REJECTED', 'PENDING', 'APPROVED'] as const -export async function seedNominations( - prisma: PrismaClient, - constituencies: CommunityConstituency[] -) { +export async function seedNominations(constituencies: CommunityConstituency[]) { const nominations = [] for (let i = 0; i < 5; i++) { @@ -18,12 +24,12 @@ export async function seedNominations( nominations.push({ nominee: `${firstName} ${lastName}`, fullName: `${nominatorFirst} ${nominatorLast}`, - email: `nominator${i + 1}@northeastern.edu`, + email: generateEmail(nominatorFirst, nominatorLast), college: randomItem(COLLEGES), major: randomItem(MAJORS), status: STATUSES[i], constituencyType: i % 2 === 0 ? 'academic' : 'community', - communityConstituencyId: i % 2 === 1 && i < 4 ? constituencies[Math.floor(i / 2)].id : null, + communityConstituencyId: getRandomConstituencyId(i, constituencies), }) } diff --git a/prisma/seed/settings.ts b/prisma/seed/settings.ts index d3250a5..b4b617a 100644 --- a/prisma/seed/settings.ts +++ b/prisma/seed/settings.ts @@ -1,13 +1,13 @@ -import { PrismaClient } from '@prisma/client' +import { prisma } from '../seed' -export async function seedSettings(prisma: PrismaClient) { +export async function seedSettings() { await prisma.settings.create({ data: { requiredNominations: 15, maxCommunityNominations: 7, endorsementRequired: false, endorsementsOpen: true, - applicationDeadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), // 30 days from now + applicationDeadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000), applicationsOpen: true, nominationsOpen: true, customMessage: 'Welcome to the Student Senate Application System!', From 2b0cb8524486c0b795ca5aef2862ff47f195c5d6 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 02:08:28 +0000 Subject: [PATCH 6/8] #16 use existing db client from lib/db and remove error handling Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- prisma/seed.ts | 13 ++----------- prisma/seed/applications.ts | 4 ++-- prisma/seed/community-constituencies.ts | 6 +++--- prisma/seed/endorsements.ts | 4 ++-- prisma/seed/nominations.ts | 4 ++-- prisma/seed/settings.ts | 4 ++-- 6 files changed, 13 insertions(+), 22 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index b1fc08e..a3c8eea 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,11 +1,9 @@ -import { PrismaClient } from '@prisma/client' import { seedCommunityConstituencies } from './seed/community-constituencies' import { seedSettings } from './seed/settings' import { seedApplications } from './seed/applications' import { seedNominations } from './seed/nominations' import { seedEndorsements } from './seed/endorsements' - -export const prisma = new PrismaClient() +import { db } from '../lib/db' async function main() { const nodeEnv = process.env.NODE_ENV || 'development' @@ -14,7 +12,7 @@ async function main() { return } - const existingData = await prisma.communityConstituency.findFirst() + const existingData = await db.communityConstituency.findFirst() if (existingData) return const constituencies = await seedCommunityConstituencies() @@ -25,10 +23,3 @@ async function main() { } main() - .catch((e) => { - console.error('Seeding error:', e) - process.exit(1) - }) - .finally(async () => { - await prisma.$disconnect() - }) diff --git a/prisma/seed/applications.ts b/prisma/seed/applications.ts index 436f332..fb5b4f3 100644 --- a/prisma/seed/applications.ts +++ b/prisma/seed/applications.ts @@ -1,5 +1,5 @@ import { CommunityConstituency } from '@prisma/client' -import { prisma } from '../seed' +import { db } from '../../lib/db' import { FIRST_NAMES, LAST_NAMES, @@ -50,7 +50,7 @@ export async function seedApplications(constituencies: CommunityConstituency[]) }) } - await prisma.application.createMany({ + await db.application.createMany({ data: applications, skipDuplicates: true, }) diff --git a/prisma/seed/community-constituencies.ts b/prisma/seed/community-constituencies.ts index 7e84d56..370e4cd 100644 --- a/prisma/seed/community-constituencies.ts +++ b/prisma/seed/community-constituencies.ts @@ -1,11 +1,11 @@ -import { prisma } from '../seed' +import { db } from '../../lib/db' import { COMMUNITY_CONSTITUENCIES } from './constants' export async function seedCommunityConstituencies() { - await prisma.communityConstituency.createMany({ + await db.communityConstituency.createMany({ data: COMMUNITY_CONSTITUENCIES, skipDuplicates: true, }) - return prisma.communityConstituency.findMany() + return db.communityConstituency.findMany() } diff --git a/prisma/seed/endorsements.ts b/prisma/seed/endorsements.ts index bde54c9..3ecb9cb 100644 --- a/prisma/seed/endorsements.ts +++ b/prisma/seed/endorsements.ts @@ -1,4 +1,4 @@ -import { prisma } from '../seed' +import { db } from '../../lib/db' import { FIRST_NAMES, LAST_NAMES, @@ -26,7 +26,7 @@ export async function seedEndorsements() { }) } - await prisma.endorsement.createMany({ + await db.endorsement.createMany({ data: endorsements, skipDuplicates: true, }) diff --git a/prisma/seed/nominations.ts b/prisma/seed/nominations.ts index e1db745..751582c 100644 --- a/prisma/seed/nominations.ts +++ b/prisma/seed/nominations.ts @@ -1,5 +1,5 @@ import { CommunityConstituency } from '@prisma/client' -import { prisma } from '../seed' +import { db } from '../../lib/db' import { FIRST_NAMES, LAST_NAMES, @@ -33,7 +33,7 @@ export async function seedNominations(constituencies: CommunityConstituency[]) { }) } - await prisma.nomination.createMany({ + await db.nomination.createMany({ data: nominations, skipDuplicates: true, }) diff --git a/prisma/seed/settings.ts b/prisma/seed/settings.ts index b4b617a..9aad118 100644 --- a/prisma/seed/settings.ts +++ b/prisma/seed/settings.ts @@ -1,7 +1,7 @@ -import { prisma } from '../seed' +import { db } from '../../lib/db' export async function seedSettings() { - await prisma.settings.create({ + await db.settings.create({ data: { requiredNominations: 15, maxCommunityNominations: 7, From 73a81213a800975a5c9e38a64bf080b1aa09b2ed Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 02:34:09 +0000 Subject: [PATCH 7/8] #16 convert all seed imports to absolute paths Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- prisma/seed.ts | 12 ++++++------ prisma/seed/applications.ts | 4 ++-- prisma/seed/community-constituencies.ts | 4 ++-- prisma/seed/endorsements.ts | 4 ++-- prisma/seed/nominations.ts | 4 ++-- prisma/seed/settings.ts | 2 +- 6 files changed, 15 insertions(+), 15 deletions(-) diff --git a/prisma/seed.ts b/prisma/seed.ts index a3c8eea..a2efb4e 100644 --- a/prisma/seed.ts +++ b/prisma/seed.ts @@ -1,9 +1,9 @@ -import { seedCommunityConstituencies } from './seed/community-constituencies' -import { seedSettings } from './seed/settings' -import { seedApplications } from './seed/applications' -import { seedNominations } from './seed/nominations' -import { seedEndorsements } from './seed/endorsements' -import { db } from '../lib/db' +import { seedCommunityConstituencies } from '@/prisma/seed/community-constituencies' +import { seedSettings } from '@/prisma/seed/settings' +import { seedApplications } from '@/prisma/seed/applications' +import { seedNominations } from '@/prisma/seed/nominations' +import { seedEndorsements } from '@/prisma/seed/endorsements' +import { db } from '@/lib/db' async function main() { const nodeEnv = process.env.NODE_ENV || 'development' diff --git a/prisma/seed/applications.ts b/prisma/seed/applications.ts index fb5b4f3..d395f9d 100644 --- a/prisma/seed/applications.ts +++ b/prisma/seed/applications.ts @@ -1,5 +1,5 @@ import { CommunityConstituency } from '@prisma/client' -import { db } from '../../lib/db' +import { db } from '@/lib/db' import { FIRST_NAMES, LAST_NAMES, @@ -15,7 +15,7 @@ import { generateNUID, generateEmail, generatePhoneNumber, -} from './constants' +} from '@/prisma/seed/constants' export async function seedApplications(constituencies: CommunityConstituency[]) { const applications = [] diff --git a/prisma/seed/community-constituencies.ts b/prisma/seed/community-constituencies.ts index 370e4cd..ad748f7 100644 --- a/prisma/seed/community-constituencies.ts +++ b/prisma/seed/community-constituencies.ts @@ -1,5 +1,5 @@ -import { db } from '../../lib/db' -import { COMMUNITY_CONSTITUENCIES } from './constants' +import { db } from '@/lib/db' +import { COMMUNITY_CONSTITUENCIES } from '@/prisma/seed/constants' export async function seedCommunityConstituencies() { await db.communityConstituency.createMany({ diff --git a/prisma/seed/endorsements.ts b/prisma/seed/endorsements.ts index 3ecb9cb..333920d 100644 --- a/prisma/seed/endorsements.ts +++ b/prisma/seed/endorsements.ts @@ -1,11 +1,11 @@ -import { db } from '../../lib/db' +import { db } from '@/lib/db' import { FIRST_NAMES, LAST_NAMES, ENDORSEMENT_CONTENT, randomItem, generateEmail, -} from './constants' +} from '@/prisma/seed/constants' export async function seedEndorsements() { const endorsements = [] diff --git a/prisma/seed/nominations.ts b/prisma/seed/nominations.ts index 751582c..1aae531 100644 --- a/prisma/seed/nominations.ts +++ b/prisma/seed/nominations.ts @@ -1,5 +1,5 @@ import { CommunityConstituency } from '@prisma/client' -import { db } from '../../lib/db' +import { db } from '@/lib/db' import { FIRST_NAMES, LAST_NAMES, @@ -8,7 +8,7 @@ import { randomItem, generateEmail, getRandomConstituencyId, -} from './constants' +} from '@/prisma/seed/constants' const STATUSES = ['PENDING', 'APPROVED', 'REJECTED', 'PENDING', 'APPROVED'] as const diff --git a/prisma/seed/settings.ts b/prisma/seed/settings.ts index 9aad118..5340b85 100644 --- a/prisma/seed/settings.ts +++ b/prisma/seed/settings.ts @@ -1,4 +1,4 @@ -import { db } from '../../lib/db' +import { db } from '@/lib/db' export async function seedSettings() { await db.settings.create({ From f0f99929aec8cf939ad1fa3a0c894d5244433d7b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 16 Feb 2026 02:36:48 +0000 Subject: [PATCH 8/8] #16 update seed command to use tsconfig for path aliases Co-authored-by: b-at-neu <144247685+b-at-neu@users.noreply.github.com> --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c25db33..926eaba 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "postinstall": "prisma generate" }, "prisma": { - "seed": "tsx prisma/seed.ts" + "seed": "tsx --tsconfig tsconfig.json prisma/seed.ts" }, "private": true, "dependencies": {