Implement PostgreSQL support and update database configuration: Migrate from SQLite to PostgreSQL by updating the Prisma schema, Docker configuration, and environment variables. Add PostgreSQL dependencies and adjust the database connection logic in the application. Enhance .gitignore to exclude PostgreSQL-related files and directories.
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled
Some checks failed
Deploy with Docker Compose / deploy (push) Has been cancelled
This commit is contained in:
6
.gitignore
vendored
6
.gitignore
vendored
@@ -41,3 +41,9 @@ dev.db*
|
||||
|
||||
# prisma
|
||||
/app/generated/prisma
|
||||
prisma/generated/
|
||||
|
||||
# database data
|
||||
data/postgres/
|
||||
data/*.db
|
||||
data/*.db-journal
|
||||
|
||||
16
Dockerfile
16
Dockerfile
@@ -19,7 +19,7 @@ RUN corepack enable && corepack prepare pnpm@latest --activate
|
||||
COPY --from=deps /app/node_modules ./node_modules
|
||||
COPY . .
|
||||
|
||||
ENV DATABASE_URL="file:/tmp/build.db"
|
||||
ENV DATABASE_URL="postgresql://user:pass@localhost:5432/db"
|
||||
RUN pnpm prisma generate
|
||||
|
||||
ENV NEXT_TELEMETRY_DISABLED=1
|
||||
@@ -47,27 +47,24 @@ COPY --from=builder /app/pnpm-lock.yaml ./pnpm-lock.yaml
|
||||
COPY --from=builder /app/next.config.js ./next.config.js
|
||||
COPY --from=builder /app/prisma ./prisma
|
||||
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
||||
COPY --from=builder /app/scripts ./scripts
|
||||
|
||||
ENV DATABASE_URL="file:/tmp/build.db"
|
||||
ENV DATABASE_URL="postgresql://user:pass@localhost:5432/db"
|
||||
|
||||
# Installer seulement les dépendances de production puis générer Prisma Client
|
||||
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store \
|
||||
pnpm install --frozen-lockfile --prod && \
|
||||
pnpm dlx prisma generate
|
||||
|
||||
ENV DATABASE_URL="file:/app/data/dev.db"
|
||||
|
||||
# Create data directory for SQLite database and uploads directories
|
||||
RUN mkdir -p /app/data /app/public/uploads /app/public/uploads/backgrounds && \
|
||||
chown -R nextjs:nodejs /app/data /app/public/uploads
|
||||
# Create uploads directories
|
||||
RUN mkdir -p /app/public/uploads /app/public/uploads/backgrounds && \
|
||||
chown -R nextjs:nodejs /app/public/uploads
|
||||
|
||||
RUN echo '#!/bin/sh' > /app/entrypoint.sh && \
|
||||
echo 'set -e' >> /app/entrypoint.sh && \
|
||||
echo 'mkdir -p /app/data' >> /app/entrypoint.sh && \
|
||||
echo 'mkdir -p /app/public/uploads' >> /app/entrypoint.sh && \
|
||||
echo 'mkdir -p /app/public/uploads/backgrounds' >> /app/entrypoint.sh && \
|
||||
echo 'pnpm dlx prisma migrate deploy || true' >> /app/entrypoint.sh && \
|
||||
echo 'pnpm dlx prisma db push || true' >> /app/entrypoint.sh && \
|
||||
echo 'exec pnpm start' >> /app/entrypoint.sh && \
|
||||
chmod +x /app/entrypoint.sh && \
|
||||
chown nextjs:nodejs /app/entrypoint.sh
|
||||
@@ -77,6 +74,5 @@ USER nextjs
|
||||
EXPOSE 3000
|
||||
ENV PORT=3000
|
||||
ENV HOSTNAME="0.0.0.0"
|
||||
ENV DATABASE_URL="file:/app/data/dev.db"
|
||||
|
||||
ENTRYPOINT ["./entrypoint.sh"]
|
||||
82
MIGRATION_POSTGRES.md
Normal file
82
MIGRATION_POSTGRES.md
Normal file
@@ -0,0 +1,82 @@
|
||||
# Migration vers PostgreSQL
|
||||
|
||||
## Changements effectués
|
||||
|
||||
✅ Schema Prisma modifié pour PostgreSQL
|
||||
✅ Code retiré Better SQLite adapter
|
||||
✅ Docker Compose configuré avec service PostgreSQL
|
||||
✅ Dockerfile mis à jour
|
||||
✅ Dépendances retirées (better-sqlite3)
|
||||
|
||||
## Prochaines étapes
|
||||
|
||||
### 1. Démarrer PostgreSQL en local (pour dev)
|
||||
|
||||
```bash
|
||||
# Option 1: Docker Compose
|
||||
docker-compose up postgres -d
|
||||
|
||||
# Option 2: PostgreSQL local
|
||||
# Installer PostgreSQL puis créer la DB
|
||||
createdb gotgaming
|
||||
```
|
||||
|
||||
### 2. Configurer DATABASE_URL
|
||||
|
||||
Créer un fichier `.env.local` avec :
|
||||
```
|
||||
DATABASE_URL="postgresql://gotgaming:password@localhost:5432/gotgaming?schema=public"
|
||||
```
|
||||
|
||||
### 3. Créer la migration initiale
|
||||
|
||||
```bash
|
||||
pnpm prisma migrate dev --name init_postgres
|
||||
```
|
||||
|
||||
### 4. Migrer les données SQLite → PostgreSQL (si nécessaire)
|
||||
|
||||
Si tu as des données existantes dans SQLite :
|
||||
|
||||
```bash
|
||||
# Exporter SQLite
|
||||
sqlite3 data/dev.db .dump > sqlite_dump.sql
|
||||
|
||||
# Adapter le dump pour PostgreSQL (changer les types, syntaxe)
|
||||
# Puis importer dans PostgreSQL
|
||||
psql gotgaming < adapted_dump.sql
|
||||
```
|
||||
|
||||
Ou utiliser un outil comme `pgloader` :
|
||||
```bash
|
||||
pgloader sqlite://data/dev.db postgresql://gotgaming:password@localhost:5432/gotgaming
|
||||
```
|
||||
|
||||
### 5. En production (Docker Compose)
|
||||
|
||||
```bash
|
||||
# Démarrer tous les services
|
||||
docker-compose up -d
|
||||
|
||||
# Les migrations seront appliquées automatiquement au démarrage via entrypoint.sh
|
||||
```
|
||||
|
||||
## Variables d'environnement Docker
|
||||
|
||||
Ajouter dans ton `.env` ou docker-compose.yml :
|
||||
|
||||
```env
|
||||
POSTGRES_USER=gotgaming
|
||||
POSTGRES_PASSWORD=change-this-in-production
|
||||
POSTGRES_DB=gotgaming
|
||||
POSTGRES_DATA_PATH=./data/postgres
|
||||
```
|
||||
|
||||
## Avantages de PostgreSQL
|
||||
|
||||
- ✅ Pool de connexions natif (plus de timeout après inactivité)
|
||||
- ✅ Concurrence réelle (pas de verrous de fichier)
|
||||
- ✅ Meilleures performances en production
|
||||
- ✅ Backups plus simples (`pg_dump`)
|
||||
- ✅ Scaling horizontal possible
|
||||
|
||||
@@ -1,6 +1,31 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
got-postgres:
|
||||
image: postgres:15-alpine
|
||||
container_name: got-mc-postgres
|
||||
environment:
|
||||
POSTGRES_USER: ${POSTGRES_USER:-gotgaming}
|
||||
POSTGRES_PASSWORD: ${POSTGRES_PASSWORD:-change-this-in-production}
|
||||
POSTGRES_DB: ${POSTGRES_DB:-gotgaming}
|
||||
POSTGRES_INITDB_ARGS: "-E UTF8 --locale=C"
|
||||
volumes:
|
||||
- ${POSTGRES_DATA_PATH:-./data/postgres}:/var/lib/postgresql/data
|
||||
ports:
|
||||
- "5433:5432"
|
||||
restart: unless-stopped
|
||||
command: postgres -c max_connections=100 -c shared_buffers=256MB -c effective_cache_size=1GB
|
||||
healthcheck:
|
||||
test:
|
||||
[
|
||||
"CMD-SHELL",
|
||||
"pg_isready -U ${POSTGRES_USER:-gotgaming} -d ${POSTGRES_DB:-gotgaming}",
|
||||
]
|
||||
interval: 5s
|
||||
timeout: 3s
|
||||
retries: 10
|
||||
start_period: 10s
|
||||
|
||||
got-app:
|
||||
build:
|
||||
context: .
|
||||
@@ -10,15 +35,18 @@ services:
|
||||
- "3040:3000"
|
||||
environment:
|
||||
- NODE_ENV=production
|
||||
- DATABASE_URL=file:/app/data/dev.db
|
||||
- DATABASE_URL=postgresql://${POSTGRES_USER:-gotgaming}:${POSTGRES_PASSWORD:-change-this-in-production}@got-postgres:5432/${POSTGRES_DB:-gotgaming}?schema=public
|
||||
- NEXTAUTH_URL=${NEXTAUTH_URL:-http://localhost:3000}
|
||||
- NEXTAUTH_SECRET=${NEXTAUTH_SECRET:-change-this-secret-in-production}
|
||||
volumes:
|
||||
# Persist database (override DATA_PATH env var to change location)
|
||||
- ${PRISMA_DATA_PATH:-/Volumes/EXTERNAL_USB/sites/got-gaming/data}:/app/data
|
||||
# Persist SQLite database (pour migration)
|
||||
- ${PRISMA_DATA_PATH:-./data}:/app/data
|
||||
# Persist uploaded images (avatars and backgrounds)
|
||||
- ${UPLOADS_PATH:-./public/uploads}:/app/public/uploads
|
||||
- ./prisma/migrations:/app/prisma/migrations
|
||||
depends_on:
|
||||
got-postgres:
|
||||
condition: service_healthy
|
||||
restart: unless-stopped
|
||||
labels:
|
||||
- "com.centurylinklabs.watchtower.enable=false"
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { PrismaClient } from "@/prisma/generated/prisma/client";
|
||||
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
|
||||
import { PrismaPg } from "@prisma/adapter-pg";
|
||||
import { Pool } from "pg";
|
||||
|
||||
const adapter = new PrismaBetterSqlite3({
|
||||
url: process.env.DATABASE_URL || "file:./data/dev.db",
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
});
|
||||
|
||||
const adapter = new PrismaPg(pool);
|
||||
|
||||
const globalForPrisma = globalThis as unknown as {
|
||||
prisma: PrismaClient | undefined;
|
||||
};
|
||||
|
||||
@@ -22,12 +22,14 @@
|
||||
]
|
||||
},
|
||||
"dependencies": {
|
||||
"@prisma/adapter-pg": "^7.1.0",
|
||||
"@prisma/adapter-better-sqlite3": "^7.1.0",
|
||||
"@prisma/client": "^7.1.0",
|
||||
"bcryptjs": "^3.0.3",
|
||||
"better-sqlite3": "^12.5.0",
|
||||
"next": "15.5.9",
|
||||
"next-auth": "5.0.0-beta.30",
|
||||
"pg": "^8.16.3",
|
||||
"react": "^19.0.0",
|
||||
"react-dom": "^19.0.0"
|
||||
},
|
||||
@@ -36,6 +38,7 @@
|
||||
"@types/bcryptjs": "^3.0.0",
|
||||
"@types/better-sqlite3": "^7.6.13",
|
||||
"@types/node": "^22.0.0",
|
||||
"@types/pg": "^8.16.0",
|
||||
"@types/react": "^19.0.0",
|
||||
"@types/react-dom": "^19.0.0",
|
||||
"@typescript-eslint/eslint-plugin": "^8.49.0",
|
||||
|
||||
142
pnpm-lock.yaml
generated
142
pnpm-lock.yaml
generated
@@ -11,6 +11,9 @@ importers:
|
||||
'@prisma/adapter-better-sqlite3':
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
'@prisma/adapter-pg':
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0
|
||||
'@prisma/client':
|
||||
specifier: ^7.1.0
|
||||
version: 7.1.0(prisma@7.1.0(@types/react@19.2.7)(better-sqlite3@12.5.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3))(typescript@5.9.3)
|
||||
@@ -26,6 +29,9 @@ importers:
|
||||
next-auth:
|
||||
specifier: 5.0.0-beta.30
|
||||
version: 5.0.0-beta.30(next@15.5.9(@babel/core@7.28.5)(react-dom@19.2.1(react@19.2.1))(react@19.2.1))(react@19.2.1)
|
||||
pg:
|
||||
specifier: ^8.16.3
|
||||
version: 8.16.3
|
||||
react:
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.1
|
||||
@@ -45,6 +51,9 @@ importers:
|
||||
'@types/node':
|
||||
specifier: ^22.0.0
|
||||
version: 22.19.1
|
||||
'@types/pg':
|
||||
specifier: ^8.16.0
|
||||
version: 8.16.0
|
||||
'@types/react':
|
||||
specifier: ^19.0.0
|
||||
version: 19.2.7
|
||||
@@ -671,6 +680,9 @@ packages:
|
||||
'@prisma/adapter-better-sqlite3@7.1.0':
|
||||
resolution: {integrity: sha512-Ex4CimAONWMoUrhU27lpGXb4MdX/59qj+4PBTIuPVJLXZfTxSWuU8KowlRtq1w5iE91WiwMgU1KgeBOKJ81nEA==}
|
||||
|
||||
'@prisma/adapter-pg@7.1.0':
|
||||
resolution: {integrity: sha512-DSAnUwkKfX4bUzhkrjGN4IBQzwg0nvFw2W17H0Oa532I5w9nLtTJ9mAEGDs1nUBEGRAsa0c7qsf8CSgfJ4DsBQ==}
|
||||
|
||||
'@prisma/client-runtime-utils@7.1.0':
|
||||
resolution: {integrity: sha512-39xmeBrNTN40FzF34aJMjfX1PowVCqoT3UKUWBBSP3aXV05NRqGBC3x2wCDs96ti6ZgdiVzqnRDHtbzU8X+lPQ==}
|
||||
|
||||
@@ -757,6 +769,9 @@ packages:
|
||||
'@types/node@22.19.1':
|
||||
resolution: {integrity: sha512-LCCV0HdSZZZb34qifBsyWlUmok6W7ouER+oQIGBScS8EsZsQbrtFTUrDX4hOl+CS6p7cnNC4td+qrSVGSCTUfQ==}
|
||||
|
||||
'@types/pg@8.16.0':
|
||||
resolution: {integrity: sha512-RmhMd/wD+CF8Dfo+cVIy3RR5cl8CyfXQ0tGgW6XBL8L4LM/UTEbNXYRbLwU6w+CgrKBNbrQWt4FUtTfaU5jSYQ==}
|
||||
|
||||
'@types/react-dom@19.2.3':
|
||||
resolution: {integrity: sha512-jp2L/eY6fn+KgVVQAOqYItbF0VY/YApe5Mz2F0aykSO8gx31bYCZyvSeYxCHKvzHG5eZjc+zyaS5BrBWya2+kQ==}
|
||||
peerDependencies:
|
||||
@@ -2072,6 +2087,40 @@ packages:
|
||||
perfect-debounce@1.0.0:
|
||||
resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==}
|
||||
|
||||
pg-cloudflare@1.2.7:
|
||||
resolution: {integrity: sha512-YgCtzMH0ptvZJslLM1ffsY4EuGaU0cx4XSdXLRFae8bPP4dS5xL1tNB3k2o/N64cHJpwU7dxKli/nZ2lUa5fLg==}
|
||||
|
||||
pg-connection-string@2.9.1:
|
||||
resolution: {integrity: sha512-nkc6NpDcvPVpZXxrreI/FOtX3XemeLl8E0qFr6F2Lrm/I8WOnaWNhIPK2Z7OHpw7gh5XJThi6j6ppgNoaT1w4w==}
|
||||
|
||||
pg-int8@1.0.1:
|
||||
resolution: {integrity: sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==}
|
||||
engines: {node: '>=4.0.0'}
|
||||
|
||||
pg-pool@3.10.1:
|
||||
resolution: {integrity: sha512-Tu8jMlcX+9d8+QVzKIvM/uJtp07PKr82IUOYEphaWcoBhIYkoHpLXN3qO59nAI11ripznDsEzEv8nUxBVWajGg==}
|
||||
peerDependencies:
|
||||
pg: '>=8.0'
|
||||
|
||||
pg-protocol@1.10.3:
|
||||
resolution: {integrity: sha512-6DIBgBQaTKDJyxnXaLiLR8wBpQQcGWuAESkRBX/t6OwA8YsqP+iVSiond2EDy6Y/dsGk8rh/jtax3js5NeV7JQ==}
|
||||
|
||||
pg-types@2.2.0:
|
||||
resolution: {integrity: sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
pg@8.16.3:
|
||||
resolution: {integrity: sha512-enxc1h0jA/aq5oSDMvqyW3q89ra6XIIDZgCX9vkMrnz5DFTw/Ny3Li2lFQ+pt3L6MCgm/5o2o8HW9hiJji+xvw==}
|
||||
engines: {node: '>= 16.0.0'}
|
||||
peerDependencies:
|
||||
pg-native: '>=3.0.1'
|
||||
peerDependenciesMeta:
|
||||
pg-native:
|
||||
optional: true
|
||||
|
||||
pgpass@1.0.5:
|
||||
resolution: {integrity: sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==}
|
||||
|
||||
picocolors@1.1.1:
|
||||
resolution: {integrity: sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==}
|
||||
|
||||
@@ -2149,6 +2198,26 @@ packages:
|
||||
resolution: {integrity: sha512-3Ybi1tAuwAP9s0r1UQ2J4n5Y0G05bJkpUIO0/bI9MhwmD70S5aTWbXGBwxHrelT+XM1k6dM0pk+SwNkpTRN7Pg==}
|
||||
engines: {node: ^10 || ^12 || >=14}
|
||||
|
||||
postgres-array@2.0.0:
|
||||
resolution: {integrity: sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==}
|
||||
engines: {node: '>=4'}
|
||||
|
||||
postgres-array@3.0.4:
|
||||
resolution: {integrity: sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
postgres-bytea@1.0.1:
|
||||
resolution: {integrity: sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-date@1.0.7:
|
||||
resolution: {integrity: sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres-interval@1.2.0:
|
||||
resolution: {integrity: sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
postgres@3.4.7:
|
||||
resolution: {integrity: sha512-Jtc2612XINuBjIl/QTWsV5UvE8UHuNblcO3vVADSrKsrc6RqGX6lOW1cEo3CM2v0XG4Nat8nI+YM7/f26VxXLw==}
|
||||
engines: {node: '>=12'}
|
||||
@@ -2372,6 +2441,10 @@ packages:
|
||||
resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
|
||||
engines: {node: '>=0.10.0'}
|
||||
|
||||
split2@4.2.0:
|
||||
resolution: {integrity: sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==}
|
||||
engines: {node: '>= 10.x'}
|
||||
|
||||
sqlstring@2.3.3:
|
||||
resolution: {integrity: sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==}
|
||||
engines: {node: '>= 0.6'}
|
||||
@@ -2598,6 +2671,10 @@ packages:
|
||||
wrappy@1.0.2:
|
||||
resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
|
||||
|
||||
xtend@4.0.2:
|
||||
resolution: {integrity: sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==}
|
||||
engines: {node: '>=0.4'}
|
||||
|
||||
yallist@3.1.1:
|
||||
resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
|
||||
|
||||
@@ -3088,6 +3165,14 @@ snapshots:
|
||||
'@prisma/driver-adapter-utils': 7.1.0
|
||||
better-sqlite3: 12.5.0
|
||||
|
||||
'@prisma/adapter-pg@7.1.0':
|
||||
dependencies:
|
||||
'@prisma/driver-adapter-utils': 7.1.0
|
||||
pg: 8.16.3
|
||||
postgres-array: 3.0.4
|
||||
transitivePeerDependencies:
|
||||
- pg-native
|
||||
|
||||
'@prisma/client-runtime-utils@7.1.0': {}
|
||||
|
||||
'@prisma/client@7.1.0(prisma@7.1.0(@types/react@19.2.7)(better-sqlite3@12.5.0)(react-dom@19.2.1(react@19.2.1))(react@19.2.1)(typescript@5.9.3))(typescript@5.9.3)':
|
||||
@@ -3198,6 +3283,12 @@ snapshots:
|
||||
dependencies:
|
||||
undici-types: 6.21.0
|
||||
|
||||
'@types/pg@8.16.0':
|
||||
dependencies:
|
||||
'@types/node': 22.19.1
|
||||
pg-protocol: 1.10.3
|
||||
pg-types: 2.2.0
|
||||
|
||||
'@types/react-dom@19.2.3(@types/react@19.2.7)':
|
||||
dependencies:
|
||||
'@types/react': 19.2.7
|
||||
@@ -4680,6 +4771,41 @@ snapshots:
|
||||
|
||||
perfect-debounce@1.0.0: {}
|
||||
|
||||
pg-cloudflare@1.2.7:
|
||||
optional: true
|
||||
|
||||
pg-connection-string@2.9.1: {}
|
||||
|
||||
pg-int8@1.0.1: {}
|
||||
|
||||
pg-pool@3.10.1(pg@8.16.3):
|
||||
dependencies:
|
||||
pg: 8.16.3
|
||||
|
||||
pg-protocol@1.10.3: {}
|
||||
|
||||
pg-types@2.2.0:
|
||||
dependencies:
|
||||
pg-int8: 1.0.1
|
||||
postgres-array: 2.0.0
|
||||
postgres-bytea: 1.0.1
|
||||
postgres-date: 1.0.7
|
||||
postgres-interval: 1.2.0
|
||||
|
||||
pg@8.16.3:
|
||||
dependencies:
|
||||
pg-connection-string: 2.9.1
|
||||
pg-pool: 3.10.1(pg@8.16.3)
|
||||
pg-protocol: 1.10.3
|
||||
pg-types: 2.2.0
|
||||
pgpass: 1.0.5
|
||||
optionalDependencies:
|
||||
pg-cloudflare: 1.2.7
|
||||
|
||||
pgpass@1.0.5:
|
||||
dependencies:
|
||||
split2: 4.2.0
|
||||
|
||||
picocolors@1.1.1: {}
|
||||
|
||||
picomatch@2.3.1: {}
|
||||
@@ -4742,6 +4868,18 @@ snapshots:
|
||||
picocolors: 1.1.1
|
||||
source-map-js: 1.2.1
|
||||
|
||||
postgres-array@2.0.0: {}
|
||||
|
||||
postgres-array@3.0.4: {}
|
||||
|
||||
postgres-bytea@1.0.1: {}
|
||||
|
||||
postgres-date@1.0.7: {}
|
||||
|
||||
postgres-interval@1.2.0:
|
||||
dependencies:
|
||||
xtend: 4.0.2
|
||||
|
||||
postgres@3.4.7: {}
|
||||
|
||||
preact-render-to-string@6.5.11(preact@10.24.3):
|
||||
@@ -5029,6 +5167,8 @@ snapshots:
|
||||
|
||||
source-map-js@1.2.1: {}
|
||||
|
||||
split2@4.2.0: {}
|
||||
|
||||
sqlstring@2.3.3: {}
|
||||
|
||||
stable-hash@0.0.5: {}
|
||||
@@ -5361,6 +5501,8 @@ snapshots:
|
||||
|
||||
wrappy@1.0.2: {}
|
||||
|
||||
xtend@4.0.2: {}
|
||||
|
||||
yallist@3.1.1: {}
|
||||
|
||||
yocto-queue@0.1.0: {}
|
||||
|
||||
@@ -16,8 +16,8 @@ import type * as Prisma from "./internal/prismaNamespace"
|
||||
|
||||
export type StringFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -25,20 +25,21 @@ export type StringFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringFilter<$PrismaModel> | string
|
||||
}
|
||||
|
||||
export type EnumRoleFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.Role | Prisma.EnumRoleFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.Role[]
|
||||
notIn?: $Enums.Role[]
|
||||
in?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumRoleFilter<$PrismaModel> | $Enums.Role
|
||||
}
|
||||
|
||||
export type IntFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -48,8 +49,8 @@ export type IntFilter<$PrismaModel = never> = {
|
||||
|
||||
export type StringNullableFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -57,13 +58,14 @@ export type StringNullableFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringNullableFilter<$PrismaModel> | string | null
|
||||
}
|
||||
|
||||
export type DateTimeFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -73,8 +75,8 @@ export type DateTimeFilter<$PrismaModel = never> = {
|
||||
|
||||
export type EnumCharacterClassNullableFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CharacterClass | Prisma.EnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.CharacterClass[] | null
|
||||
notIn?: $Enums.CharacterClass[] | null
|
||||
in?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
notIn?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
not?: Prisma.NestedEnumCharacterClassNullableFilter<$PrismaModel> | $Enums.CharacterClass | null
|
||||
}
|
||||
|
||||
@@ -85,8 +87,8 @@ export type SortOrderInput = {
|
||||
|
||||
export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -94,6 +96,7 @@ export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringWithAggregatesFilter<$PrismaModel> | string
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedStringFilter<$PrismaModel>
|
||||
@@ -102,8 +105,8 @@ export type StringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type EnumRoleWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.Role | Prisma.EnumRoleFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.Role[]
|
||||
notIn?: $Enums.Role[]
|
||||
in?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumRoleWithAggregatesFilter<$PrismaModel> | $Enums.Role
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumRoleFilter<$PrismaModel>
|
||||
@@ -112,8 +115,8 @@ export type EnumRoleWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -128,8 +131,8 @@ export type IntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -137,6 +140,7 @@ export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
contains?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
startsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
endsWith?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
mode?: Prisma.QueryMode
|
||||
not?: Prisma.NestedStringNullableWithAggregatesFilter<$PrismaModel> | string | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedStringNullableFilter<$PrismaModel>
|
||||
@@ -145,8 +149,8 @@ export type StringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -159,8 +163,8 @@ export type DateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type EnumCharacterClassNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CharacterClass | Prisma.EnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.CharacterClass[] | null
|
||||
notIn?: $Enums.CharacterClass[] | null
|
||||
in?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
notIn?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
not?: Prisma.NestedEnumCharacterClassNullableWithAggregatesFilter<$PrismaModel> | $Enums.CharacterClass | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumCharacterClassNullableFilter<$PrismaModel>
|
||||
@@ -169,15 +173,15 @@ export type EnumCharacterClassNullableWithAggregatesFilter<$PrismaModel = never>
|
||||
|
||||
export type EnumEventTypeFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.EventType | Prisma.EnumEventTypeFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.EventType[]
|
||||
notIn?: $Enums.EventType[]
|
||||
in?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumEventTypeFilter<$PrismaModel> | $Enums.EventType
|
||||
}
|
||||
|
||||
export type IntNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -187,8 +191,8 @@ export type IntNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type EnumEventTypeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.EventType | Prisma.EnumEventTypeFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.EventType[]
|
||||
notIn?: $Enums.EventType[]
|
||||
in?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumEventTypeWithAggregatesFilter<$PrismaModel> | $Enums.EventType
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumEventTypeFilter<$PrismaModel>
|
||||
@@ -197,8 +201,8 @@ export type EnumEventTypeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type IntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -226,15 +230,15 @@ export type BoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type EnumChallengeStatusFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.ChallengeStatus | Prisma.EnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.ChallengeStatus[]
|
||||
notIn?: $Enums.ChallengeStatus[]
|
||||
in?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumChallengeStatusFilter<$PrismaModel> | $Enums.ChallengeStatus
|
||||
}
|
||||
|
||||
export type DateTimeNullableFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -244,8 +248,8 @@ export type DateTimeNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type EnumChallengeStatusWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.ChallengeStatus | Prisma.EnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.ChallengeStatus[]
|
||||
notIn?: $Enums.ChallengeStatus[]
|
||||
in?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumChallengeStatusWithAggregatesFilter<$PrismaModel> | $Enums.ChallengeStatus
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumChallengeStatusFilter<$PrismaModel>
|
||||
@@ -254,8 +258,8 @@ export type EnumChallengeStatusWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -268,8 +272,8 @@ export type DateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedStringFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -282,15 +286,15 @@ export type NestedStringFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedEnumRoleFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.Role | Prisma.EnumRoleFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.Role[]
|
||||
notIn?: $Enums.Role[]
|
||||
in?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumRoleFilter<$PrismaModel> | $Enums.Role
|
||||
}
|
||||
|
||||
export type NestedIntFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -300,8 +304,8 @@ export type NestedIntFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -314,8 +318,8 @@ export type NestedStringNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -325,15 +329,15 @@ export type NestedDateTimeFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedEnumCharacterClassNullableFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CharacterClass | Prisma.EnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.CharacterClass[] | null
|
||||
notIn?: $Enums.CharacterClass[] | null
|
||||
in?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
notIn?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
not?: Prisma.NestedEnumCharacterClassNullableFilter<$PrismaModel> | $Enums.CharacterClass | null
|
||||
}
|
||||
|
||||
export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
in?: string[]
|
||||
notIn?: string[]
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel>
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -349,8 +353,8 @@ export type NestedStringWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedEnumRoleWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.Role | Prisma.EnumRoleFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.Role[]
|
||||
notIn?: $Enums.Role[]
|
||||
in?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.Role[] | Prisma.ListEnumRoleFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumRoleWithAggregatesFilter<$PrismaModel> | $Enums.Role
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumRoleFilter<$PrismaModel>
|
||||
@@ -359,8 +363,8 @@ export type NestedEnumRoleWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -375,8 +379,8 @@ export type NestedIntWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedFloatFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
in?: number[]
|
||||
notIn?: number[]
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel>
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -386,8 +390,8 @@ export type NestedFloatFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: string | Prisma.StringFieldRefInput<$PrismaModel> | null
|
||||
in?: string[] | null
|
||||
notIn?: string[] | null
|
||||
in?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
notIn?: string[] | Prisma.ListStringFieldRefInput<$PrismaModel> | null
|
||||
lt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
lte?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
gt?: string | Prisma.StringFieldRefInput<$PrismaModel>
|
||||
@@ -403,8 +407,8 @@ export type NestedStringNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -414,8 +418,8 @@ export type NestedIntNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
in?: Date[] | string[]
|
||||
notIn?: Date[] | string[]
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel>
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -428,8 +432,8 @@ export type NestedDateTimeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedEnumCharacterClassNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.CharacterClass | Prisma.EnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
in?: $Enums.CharacterClass[] | null
|
||||
notIn?: $Enums.CharacterClass[] | null
|
||||
in?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
notIn?: $Enums.CharacterClass[] | Prisma.ListEnumCharacterClassFieldRefInput<$PrismaModel> | null
|
||||
not?: Prisma.NestedEnumCharacterClassNullableWithAggregatesFilter<$PrismaModel> | $Enums.CharacterClass | null
|
||||
_count?: Prisma.NestedIntNullableFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumCharacterClassNullableFilter<$PrismaModel>
|
||||
@@ -438,15 +442,15 @@ export type NestedEnumCharacterClassNullableWithAggregatesFilter<$PrismaModel =
|
||||
|
||||
export type NestedEnumEventTypeFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.EventType | Prisma.EnumEventTypeFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.EventType[]
|
||||
notIn?: $Enums.EventType[]
|
||||
in?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumEventTypeFilter<$PrismaModel> | $Enums.EventType
|
||||
}
|
||||
|
||||
export type NestedEnumEventTypeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.EventType | Prisma.EnumEventTypeFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.EventType[]
|
||||
notIn?: $Enums.EventType[]
|
||||
in?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.EventType[] | Prisma.ListEnumEventTypeFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumEventTypeWithAggregatesFilter<$PrismaModel> | $Enums.EventType
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumEventTypeFilter<$PrismaModel>
|
||||
@@ -455,8 +459,8 @@ export type NestedEnumEventTypeWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.IntFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListIntFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.IntFieldRefInput<$PrismaModel>
|
||||
@@ -471,8 +475,8 @@ export type NestedIntNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedFloatNullableFilter<$PrismaModel = never> = {
|
||||
equals?: number | Prisma.FloatFieldRefInput<$PrismaModel> | null
|
||||
in?: number[] | null
|
||||
notIn?: number[] | null
|
||||
in?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
notIn?: number[] | Prisma.ListFloatFieldRefInput<$PrismaModel> | null
|
||||
lt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
lte?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
gt?: number | Prisma.FloatFieldRefInput<$PrismaModel>
|
||||
@@ -495,15 +499,15 @@ export type NestedBoolWithAggregatesFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedEnumChallengeStatusFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.ChallengeStatus | Prisma.EnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.ChallengeStatus[]
|
||||
notIn?: $Enums.ChallengeStatus[]
|
||||
in?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumChallengeStatusFilter<$PrismaModel> | $Enums.ChallengeStatus
|
||||
}
|
||||
|
||||
export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
@@ -513,8 +517,8 @@ export type NestedDateTimeNullableFilter<$PrismaModel = never> = {
|
||||
|
||||
export type NestedEnumChallengeStatusWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: $Enums.ChallengeStatus | Prisma.EnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
in?: $Enums.ChallengeStatus[]
|
||||
notIn?: $Enums.ChallengeStatus[]
|
||||
in?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
notIn?: $Enums.ChallengeStatus[] | Prisma.ListEnumChallengeStatusFieldRefInput<$PrismaModel>
|
||||
not?: Prisma.NestedEnumChallengeStatusWithAggregatesFilter<$PrismaModel> | $Enums.ChallengeStatus
|
||||
_count?: Prisma.NestedIntFilter<$PrismaModel>
|
||||
_min?: Prisma.NestedEnumChallengeStatusFilter<$PrismaModel>
|
||||
@@ -523,8 +527,8 @@ export type NestedEnumChallengeStatusWithAggregatesFilter<$PrismaModel = never>
|
||||
|
||||
export type NestedDateTimeNullableWithAggregatesFilter<$PrismaModel = never> = {
|
||||
equals?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel> | null
|
||||
in?: Date[] | string[] | null
|
||||
notIn?: Date[] | string[] | null
|
||||
in?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
notIn?: Date[] | string[] | Prisma.ListDateTimeFieldRefInput<$PrismaModel> | null
|
||||
lt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
lte?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
gt?: Date | string | Prisma.DateTimeFieldRefInput<$PrismaModel>
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -958,6 +958,9 @@ export type TypeMap<ExtArgs extends runtime.Types.Extensions.InternalArgs = runt
|
||||
*/
|
||||
|
||||
export const TransactionIsolationLevel = runtime.makeStrictEnum({
|
||||
ReadUncommitted: 'ReadUncommitted',
|
||||
ReadCommitted: 'ReadCommitted',
|
||||
RepeatableRead: 'RepeatableRead',
|
||||
Serializable: 'Serializable'
|
||||
} as const)
|
||||
|
||||
@@ -1083,6 +1086,14 @@ export const SortOrder = {
|
||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
||||
|
||||
|
||||
export const QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
} as const
|
||||
|
||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
||||
|
||||
|
||||
export const NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
@@ -1104,6 +1115,13 @@ export type StringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel,
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'String[]'
|
||||
*/
|
||||
export type ListStringFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'String[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Role'
|
||||
*/
|
||||
@@ -1111,6 +1129,13 @@ export type EnumRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Role[]'
|
||||
*/
|
||||
export type ListEnumRoleFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Role[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Int'
|
||||
*/
|
||||
@@ -1118,6 +1143,13 @@ export type IntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'In
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Int[]'
|
||||
*/
|
||||
export type ListIntFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Int[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'DateTime'
|
||||
*/
|
||||
@@ -1125,6 +1157,13 @@ export type DateTimeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'DateTime[]'
|
||||
*/
|
||||
export type ListDateTimeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'DateTime[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'CharacterClass'
|
||||
*/
|
||||
@@ -1132,6 +1171,13 @@ export type EnumCharacterClassFieldRefInput<$PrismaModel> = FieldRefInputType<$P
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'CharacterClass[]'
|
||||
*/
|
||||
export type ListEnumCharacterClassFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'CharacterClass[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'EventType'
|
||||
*/
|
||||
@@ -1139,6 +1185,13 @@ export type EnumEventTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$Prisma
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'EventType[]'
|
||||
*/
|
||||
export type ListEnumEventTypeFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'EventType[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Boolean'
|
||||
*/
|
||||
@@ -1153,12 +1206,26 @@ export type EnumChallengeStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'ChallengeStatus[]'
|
||||
*/
|
||||
export type ListEnumChallengeStatusFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'ChallengeStatus[]'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Float'
|
||||
*/
|
||||
export type FloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float'>
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Reference to a field of type 'Float[]'
|
||||
*/
|
||||
export type ListFloatFieldRefInput<$PrismaModel> = FieldRefInputType<$PrismaModel, 'Float[]'>
|
||||
|
||||
|
||||
/**
|
||||
* Batch Payload for updateMany & deleteMany & createMany
|
||||
*/
|
||||
|
||||
@@ -67,6 +67,9 @@ export type ModelName = (typeof ModelName)[keyof typeof ModelName]
|
||||
*/
|
||||
|
||||
export const TransactionIsolationLevel = {
|
||||
ReadUncommitted: 'ReadUncommitted',
|
||||
ReadCommitted: 'ReadCommitted',
|
||||
RepeatableRead: 'RepeatableRead',
|
||||
Serializable: 'Serializable'
|
||||
} as const
|
||||
|
||||
@@ -192,6 +195,14 @@ export const SortOrder = {
|
||||
export type SortOrder = (typeof SortOrder)[keyof typeof SortOrder]
|
||||
|
||||
|
||||
export const QueryMode = {
|
||||
default: 'default',
|
||||
insensitive: 'insensitive'
|
||||
} as const
|
||||
|
||||
export type QueryMode = (typeof QueryMode)[keyof typeof QueryMode]
|
||||
|
||||
|
||||
export const NullsOrder = {
|
||||
first: 'first',
|
||||
last: 'last'
|
||||
|
||||
@@ -780,6 +780,7 @@ export type ChallengeCreateOrConnectWithoutChallengerInput = {
|
||||
|
||||
export type ChallengeCreateManyChallengerInputEnvelope = {
|
||||
data: Prisma.ChallengeCreateManyChallengerInput | Prisma.ChallengeCreateManyChallengerInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type ChallengeCreateWithoutChallengedInput = {
|
||||
@@ -821,6 +822,7 @@ export type ChallengeCreateOrConnectWithoutChallengedInput = {
|
||||
|
||||
export type ChallengeCreateManyChallengedInputEnvelope = {
|
||||
data: Prisma.ChallengeCreateManyChallengedInput | Prisma.ChallengeCreateManyChallengedInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type ChallengeCreateWithoutAdminInput = {
|
||||
@@ -862,6 +864,7 @@ export type ChallengeCreateOrConnectWithoutAdminInput = {
|
||||
|
||||
export type ChallengeCreateManyAdminInputEnvelope = {
|
||||
data: Prisma.ChallengeCreateManyAdminInput | Prisma.ChallengeCreateManyAdminInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type ChallengeCreateWithoutWinnerInput = {
|
||||
@@ -903,6 +906,7 @@ export type ChallengeCreateOrConnectWithoutWinnerInput = {
|
||||
|
||||
export type ChallengeCreateManyWinnerInputEnvelope = {
|
||||
data: Prisma.ChallengeCreateManyWinnerInput | Prisma.ChallengeCreateManyWinnerInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type ChallengeUpsertWithWhereUniqueWithoutChallengerInput = {
|
||||
@@ -2040,6 +2044,7 @@ export type ChallengeCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Int
|
||||
* The data used to create many Challenges.
|
||||
*/
|
||||
data: Prisma.ChallengeCreateManyInput | Prisma.ChallengeCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2058,6 +2063,7 @@ export type ChallengeCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Exten
|
||||
* The data used to create many Challenges.
|
||||
*/
|
||||
data: Prisma.ChallengeCreateManyInput | Prisma.ChallengeCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
|
||||
@@ -1447,6 +1447,7 @@ export type EventCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Interna
|
||||
* The data used to create many Events.
|
||||
*/
|
||||
data: Prisma.EventCreateManyInput | Prisma.EventCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1465,6 +1466,7 @@ export type EventCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extension
|
||||
* The data used to create many Events.
|
||||
*/
|
||||
data: Prisma.EventCreateManyInput | Prisma.EventCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -550,6 +550,7 @@ export type EventFeedbackCreateOrConnectWithoutUserInput = {
|
||||
|
||||
export type EventFeedbackCreateManyUserInputEnvelope = {
|
||||
data: Prisma.EventFeedbackCreateManyUserInput | Prisma.EventFeedbackCreateManyUserInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type EventFeedbackUpsertWithWhereUniqueWithoutUserInput = {
|
||||
@@ -609,6 +610,7 @@ export type EventFeedbackCreateOrConnectWithoutEventInput = {
|
||||
|
||||
export type EventFeedbackCreateManyEventInputEnvelope = {
|
||||
data: Prisma.EventFeedbackCreateManyEventInput | Prisma.EventFeedbackCreateManyEventInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type EventFeedbackUpsertWithWhereUniqueWithoutEventInput = {
|
||||
@@ -1450,6 +1452,7 @@ export type EventFeedbackCreateManyArgs<ExtArgs extends runtime.Types.Extensions
|
||||
* The data used to create many EventFeedbacks.
|
||||
*/
|
||||
data: Prisma.EventFeedbackCreateManyInput | Prisma.EventFeedbackCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1468,6 +1471,7 @@ export type EventFeedbackCreateManyAndReturnArgs<ExtArgs extends runtime.Types.E
|
||||
* The data used to create many EventFeedbacks.
|
||||
*/
|
||||
data: Prisma.EventFeedbackCreateManyInput | Prisma.EventFeedbackCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
|
||||
@@ -406,6 +406,7 @@ export type EventRegistrationCreateOrConnectWithoutUserInput = {
|
||||
|
||||
export type EventRegistrationCreateManyUserInputEnvelope = {
|
||||
data: Prisma.EventRegistrationCreateManyUserInput | Prisma.EventRegistrationCreateManyUserInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type EventRegistrationUpsertWithWhereUniqueWithoutUserInput = {
|
||||
@@ -453,6 +454,7 @@ export type EventRegistrationCreateOrConnectWithoutEventInput = {
|
||||
|
||||
export type EventRegistrationCreateManyEventInputEnvelope = {
|
||||
data: Prisma.EventRegistrationCreateManyEventInput | Prisma.EventRegistrationCreateManyEventInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
export type EventRegistrationUpsertWithWhereUniqueWithoutEventInput = {
|
||||
@@ -1238,6 +1240,7 @@ export type EventRegistrationCreateManyArgs<ExtArgs extends runtime.Types.Extens
|
||||
* The data used to create many EventRegistrations.
|
||||
*/
|
||||
data: Prisma.EventRegistrationCreateManyInput | Prisma.EventRegistrationCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1256,6 +1259,7 @@ export type EventRegistrationCreateManyAndReturnArgs<ExtArgs extends runtime.Typ
|
||||
* The data used to create many EventRegistrations.
|
||||
*/
|
||||
data: Prisma.EventRegistrationCreateManyInput | Prisma.EventRegistrationCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
|
||||
@@ -1145,6 +1145,7 @@ export type SitePreferencesCreateManyArgs<ExtArgs extends runtime.Types.Extensio
|
||||
* The data used to create many SitePreferences.
|
||||
*/
|
||||
data: Prisma.SitePreferencesCreateManyInput | Prisma.SitePreferencesCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1163,6 +1164,7 @@ export type SitePreferencesCreateManyAndReturnArgs<ExtArgs extends runtime.Types
|
||||
* The data used to create many SitePreferences.
|
||||
*/
|
||||
data: Prisma.SitePreferencesCreateManyInput | Prisma.SitePreferencesCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -2499,6 +2499,7 @@ export type UserCreateManyArgs<ExtArgs extends runtime.Types.Extensions.Internal
|
||||
* The data used to create many Users.
|
||||
*/
|
||||
data: Prisma.UserCreateManyInput | Prisma.UserCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -2517,6 +2518,7 @@ export type UserCreateManyAndReturnArgs<ExtArgs extends runtime.Types.Extensions
|
||||
* The data used to create many Users.
|
||||
*/
|
||||
data: Prisma.UserCreateManyInput | Prisma.UserCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -1201,6 +1201,7 @@ export type UserPreferencesCreateManyArgs<ExtArgs extends runtime.Types.Extensio
|
||||
* The data used to create many UserPreferences.
|
||||
*/
|
||||
data: Prisma.UserPreferencesCreateManyInput | Prisma.UserPreferencesCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1219,6 +1220,7 @@ export type UserPreferencesCreateManyAndReturnArgs<ExtArgs extends runtime.Types
|
||||
* The data used to create many UserPreferences.
|
||||
*/
|
||||
data: Prisma.UserPreferencesCreateManyInput | Prisma.UserPreferencesCreateManyInput[]
|
||||
skipDuplicates?: boolean
|
||||
/**
|
||||
* Choose, which related nodes to fetch as well
|
||||
*/
|
||||
|
||||
3
prisma/migrations.sqlite.backup/migration_lock.toml
Normal file
3
prisma/migrations.sqlite.backup/migration_lock.toml
Normal file
@@ -0,0 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "postgresql"
|
||||
200
prisma/migrations/20251217101717_init_postgres/migration.sql
Normal file
200
prisma/migrations/20251217101717_init_postgres/migration.sql
Normal file
@@ -0,0 +1,200 @@
|
||||
-- CreateEnum
|
||||
CREATE TYPE "Role" AS ENUM ('USER', 'ADMIN');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "EventType" AS ENUM ('ATELIER', 'KATA', 'PRESENTATION', 'LEARNING_HOUR');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "CharacterClass" AS ENUM ('WARRIOR', 'MAGE', 'ROGUE', 'RANGER', 'PALADIN', 'ENGINEER', 'MERCHANT', 'SCHOLAR', 'BERSERKER', 'NECROMANCER');
|
||||
|
||||
-- CreateEnum
|
||||
CREATE TYPE "ChallengeStatus" AS ENUM ('PENDING', 'ACCEPTED', 'COMPLETED', 'REJECTED', 'CANCELLED');
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "User" (
|
||||
"id" TEXT NOT NULL,
|
||||
"email" TEXT NOT NULL,
|
||||
"password" TEXT NOT NULL,
|
||||
"username" TEXT NOT NULL,
|
||||
"role" "Role" NOT NULL DEFAULT 'USER',
|
||||
"score" INTEGER NOT NULL DEFAULT 0,
|
||||
"level" INTEGER NOT NULL DEFAULT 1,
|
||||
"hp" INTEGER NOT NULL DEFAULT 1000,
|
||||
"maxHp" INTEGER NOT NULL DEFAULT 1000,
|
||||
"xp" INTEGER NOT NULL DEFAULT 0,
|
||||
"maxXp" INTEGER NOT NULL DEFAULT 5000,
|
||||
"avatar" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
"bio" TEXT,
|
||||
"characterClass" "CharacterClass",
|
||||
|
||||
CONSTRAINT "User_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "UserPreferences" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"homeBackground" TEXT,
|
||||
"eventsBackground" TEXT,
|
||||
"leaderboardBackground" TEXT,
|
||||
"theme" TEXT DEFAULT 'default',
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "UserPreferences_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Event" (
|
||||
"id" TEXT NOT NULL,
|
||||
"date" TIMESTAMP(3) NOT NULL,
|
||||
"name" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"type" "EventType" NOT NULL,
|
||||
"room" TEXT,
|
||||
"time" TEXT,
|
||||
"maxPlaces" INTEGER,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Event_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EventRegistration" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"eventId" TEXT NOT NULL,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
|
||||
CONSTRAINT "EventRegistration_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "EventFeedback" (
|
||||
"id" TEXT NOT NULL,
|
||||
"userId" TEXT NOT NULL,
|
||||
"eventId" TEXT NOT NULL,
|
||||
"rating" INTEGER NOT NULL,
|
||||
"comment" TEXT,
|
||||
"isRead" BOOLEAN NOT NULL DEFAULT false,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "EventFeedback_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "SitePreferences" (
|
||||
"id" TEXT NOT NULL DEFAULT 'global',
|
||||
"homeBackground" TEXT,
|
||||
"eventsBackground" TEXT,
|
||||
"leaderboardBackground" TEXT,
|
||||
"challengesBackground" TEXT,
|
||||
"eventRegistrationPoints" INTEGER NOT NULL DEFAULT 100,
|
||||
"eventFeedbackPoints" INTEGER NOT NULL DEFAULT 100,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "SitePreferences_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE "Challenge" (
|
||||
"id" TEXT NOT NULL,
|
||||
"challengerId" TEXT NOT NULL,
|
||||
"challengedId" TEXT NOT NULL,
|
||||
"title" TEXT NOT NULL,
|
||||
"description" TEXT NOT NULL,
|
||||
"pointsReward" INTEGER NOT NULL DEFAULT 100,
|
||||
"status" "ChallengeStatus" NOT NULL DEFAULT 'PENDING',
|
||||
"adminId" TEXT,
|
||||
"adminComment" TEXT,
|
||||
"winnerId" TEXT,
|
||||
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
"acceptedAt" TIMESTAMP(3),
|
||||
"completedAt" TIMESTAMP(3),
|
||||
"updatedAt" TIMESTAMP(3) NOT NULL,
|
||||
|
||||
CONSTRAINT "Challenge_pkey" PRIMARY KEY ("id")
|
||||
);
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "User_username_key" ON "User"("username");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "User_score_idx" ON "User"("score");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "User_email_idx" ON "User"("email");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "UserPreferences_userId_key" ON "UserPreferences"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Event_date_idx" ON "Event"("date");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EventRegistration_userId_idx" ON "EventRegistration"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EventRegistration_eventId_idx" ON "EventRegistration"("eventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "EventRegistration_userId_eventId_key" ON "EventRegistration"("userId", "eventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EventFeedback_userId_idx" ON "EventFeedback"("userId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EventFeedback_eventId_idx" ON "EventFeedback"("eventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "EventFeedback_isRead_idx" ON "EventFeedback"("isRead");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE UNIQUE INDEX "EventFeedback_userId_eventId_key" ON "EventFeedback"("userId", "eventId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Challenge_challengerId_idx" ON "Challenge"("challengerId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Challenge_challengedId_idx" ON "Challenge"("challengedId");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Challenge_status_idx" ON "Challenge"("status");
|
||||
|
||||
-- CreateIndex
|
||||
CREATE INDEX "Challenge_adminId_idx" ON "Challenge"("adminId");
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "UserPreferences" ADD CONSTRAINT "UserPreferences_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EventRegistration" ADD CONSTRAINT "EventRegistration_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EventRegistration" ADD CONSTRAINT "EventRegistration_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EventFeedback" ADD CONSTRAINT "EventFeedback_eventId_fkey" FOREIGN KEY ("eventId") REFERENCES "Event"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "EventFeedback" ADD CONSTRAINT "EventFeedback_userId_fkey" FOREIGN KEY ("userId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Challenge" ADD CONSTRAINT "Challenge_challengerId_fkey" FOREIGN KEY ("challengerId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Challenge" ADD CONSTRAINT "Challenge_challengedId_fkey" FOREIGN KEY ("challengedId") REFERENCES "User"("id") ON DELETE CASCADE ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Challenge" ADD CONSTRAINT "Challenge_adminId_fkey" FOREIGN KEY ("adminId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE "Challenge" ADD CONSTRAINT "Challenge_winnerId_fkey" FOREIGN KEY ("winnerId") REFERENCES "User"("id") ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -1,3 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "sqlite"
|
||||
provider = "postgresql"
|
||||
|
||||
@@ -4,7 +4,7 @@ generator client {
|
||||
}
|
||||
|
||||
datasource db {
|
||||
provider = "sqlite"
|
||||
provider = "postgresql"
|
||||
}
|
||||
|
||||
model User {
|
||||
|
||||
@@ -3,12 +3,15 @@ import {
|
||||
EventType,
|
||||
CharacterClass,
|
||||
} from "@/prisma/generated/prisma/client";
|
||||
import { PrismaBetterSqlite3 } from "@prisma/adapter-better-sqlite3";
|
||||
import { PrismaPg } from "@prisma/adapter-pg";
|
||||
import { Pool } from "pg";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const adapter = new PrismaBetterSqlite3({
|
||||
url: process.env.DATABASE_URL || "file:./data/dev.db",
|
||||
const pool = new Pool({
|
||||
connectionString: process.env.DATABASE_URL,
|
||||
});
|
||||
|
||||
const adapter = new PrismaPg(pool);
|
||||
const prisma = new PrismaClient({ adapter });
|
||||
|
||||
async function main() {
|
||||
|
||||
70
scripts/README-MIGRATION.md
Normal file
70
scripts/README-MIGRATION.md
Normal file
@@ -0,0 +1,70 @@
|
||||
# Migration SQLite → PostgreSQL
|
||||
|
||||
Script pour migrer les données de SQLite vers PostgreSQL.
|
||||
|
||||
## Prérequis
|
||||
|
||||
1. Le container `got-app` doit être démarré
|
||||
2. Le container `got-postgres` doit être démarré et accessible
|
||||
3. Le fichier SQLite doit être accessible dans le container (par défaut: `/app/data/dev.db`)
|
||||
|
||||
## Utilisation
|
||||
|
||||
### Dans le container Docker
|
||||
|
||||
```bash
|
||||
# IMPORTANT: Le script doit être exécuté depuis la racine du projet (/app)
|
||||
|
||||
# Option 1: Exécuter directement depuis l'extérieur du container
|
||||
docker-compose exec got-app sh -c "cd /app && pnpm dlx tsx scripts/migrate-sqlite-to-postgres.ts"
|
||||
|
||||
# Option 2: Se connecter au container puis exécuter
|
||||
docker-compose exec got-app sh
|
||||
# Dans le container:
|
||||
cd /app
|
||||
pnpm dlx tsx scripts/migrate-sqlite-to-postgres.ts
|
||||
```
|
||||
|
||||
### Variables d'environnement
|
||||
|
||||
Le script utilise les variables d'environnement suivantes :
|
||||
|
||||
- `SQLITE_DB_PATH` : Chemin vers le fichier SQLite (défaut: `/app/data/dev.db`)
|
||||
- `DATABASE_URL` : URL de connexion PostgreSQL (défaut: depuis les variables d'env du container)
|
||||
|
||||
### Exemple avec variables personnalisées
|
||||
|
||||
```bash
|
||||
docker-compose exec -e SQLITE_DB_PATH=/app/data/old.db got-app sh -c "cd /app && pnpm dlx tsx scripts/migrate-sqlite-to-postgres.ts"
|
||||
```
|
||||
|
||||
## Ce que fait le script
|
||||
|
||||
1. **Se connecte** à SQLite (lecture seule) et PostgreSQL
|
||||
2. **Migre les données** dans l'ordre des dépendances :
|
||||
- Users
|
||||
- UserPreferences
|
||||
- Events
|
||||
- EventRegistrations
|
||||
- EventFeedbacks
|
||||
- SitePreferences
|
||||
- Challenges
|
||||
3. **Utilise `upsert`** pour éviter les doublons (idempotent)
|
||||
4. **Affiche la progression** en temps réel
|
||||
5. **Affiche un résumé** à la fin avec les statistiques
|
||||
|
||||
## Notes importantes
|
||||
|
||||
- Le script est **idempotent** : tu peux le relancer plusieurs fois sans problème
|
||||
- Les données existantes dans PostgreSQL seront **mises à jour** si elles existent déjà
|
||||
- Les **erreurs** sont affichées mais n'arrêtent pas la migration
|
||||
- Le script utilise `better-sqlite3` en **lecture seule** pour SQLite
|
||||
|
||||
## En cas d'erreur
|
||||
|
||||
Si le script échoue :
|
||||
|
||||
1. Vérifie que les containers sont démarrés : `docker-compose ps`
|
||||
2. Vérifie que le fichier SQLite existe : `docker-compose exec got-app ls -la /app/data/dev.db`
|
||||
3. Vérifie les logs PostgreSQL : `docker-compose logs got-postgres`
|
||||
4. Vérifie la connexion PostgreSQL : `docker-compose exec got-app pnpm prisma db pull`
|
||||
489
scripts/migrate-sqlite-to-postgres.ts
Normal file
489
scripts/migrate-sqlite-to-postgres.ts
Normal file
@@ -0,0 +1,489 @@
|
||||
#!/usr/bin/env tsx
|
||||
/* eslint-disable @typescript-eslint/no-explicit-any */
|
||||
/**
|
||||
* Script de migration des données SQLite vers PostgreSQL
|
||||
*
|
||||
* Usage dans le container:
|
||||
* docker-compose exec got-app sh -c "cd /app && pnpm dlx tsx scripts/migrate-sqlite-to-postgres.ts"
|
||||
*
|
||||
* Variables d'environnement:
|
||||
* SQLITE_DB_PATH - Chemin vers le fichier SQLite (défaut: /app/data/dev.db)
|
||||
* DATABASE_URL - URL de connexion PostgreSQL (défaut: depuis env)
|
||||
*/
|
||||
|
||||
import { PrismaPg } from "@prisma/adapter-pg";
|
||||
import { Pool } from "pg";
|
||||
import Database from "better-sqlite3";
|
||||
import { fileURLToPath } from "url";
|
||||
import { dirname, join } from "path";
|
||||
import { existsSync } from "fs";
|
||||
|
||||
// Résoudre le chemin vers le module Prisma
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = dirname(__filename);
|
||||
const projectRoot = join(__dirname, "..");
|
||||
|
||||
const SQLITE_DB_PATH = process.env.SQLITE_DB_PATH || "/app/data/dev.db";
|
||||
const POSTGRES_URL = process.env.DATABASE_URL;
|
||||
|
||||
if (!POSTGRES_URL) {
|
||||
console.error("❌ DATABASE_URL est requis");
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
// Variables globales pour les clients (initialisées dans main)
|
||||
let sqliteDb: Database.Database;
|
||||
let pgPool: Pool;
|
||||
let prismaPG: any; // PrismaClient - typé dynamiquement
|
||||
|
||||
interface MigrationStats {
|
||||
users: number;
|
||||
userPreferences: number;
|
||||
events: number;
|
||||
eventRegistrations: number;
|
||||
eventFeedbacks: number;
|
||||
sitePreferences: number;
|
||||
challenges: number;
|
||||
errors: number;
|
||||
}
|
||||
|
||||
const stats: MigrationStats = {
|
||||
users: 0,
|
||||
userPreferences: 0,
|
||||
events: 0,
|
||||
eventRegistrations: 0,
|
||||
eventFeedbacks: 0,
|
||||
sitePreferences: 0,
|
||||
challenges: 0,
|
||||
errors: 0,
|
||||
};
|
||||
|
||||
function readSQLite(table: string): any[] {
|
||||
try {
|
||||
const rows = sqliteDb.prepare(`SELECT * FROM "${table}"`).all() as any[];
|
||||
return rows;
|
||||
} catch (error) {
|
||||
console.error(`Erreur lecture table ${table}:`, error);
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
async function migrateUsers() {
|
||||
console.log("\n📦 Migration des Users...");
|
||||
const users = readSQLite("User");
|
||||
|
||||
for (const user of users) {
|
||||
try {
|
||||
await prismaPG.user.upsert({
|
||||
where: { id: user.id },
|
||||
update: {
|
||||
email: user.email,
|
||||
password: user.password,
|
||||
username: user.username,
|
||||
role: user.role,
|
||||
score: user.score,
|
||||
level: user.level,
|
||||
hp: user.hp,
|
||||
maxHp: user.maxHp,
|
||||
xp: user.xp,
|
||||
maxXp: user.maxXp,
|
||||
avatar: user.avatar,
|
||||
bio: user.bio,
|
||||
characterClass: user.characterClass,
|
||||
createdAt: new Date(user.createdAt),
|
||||
updatedAt: new Date(user.updatedAt),
|
||||
},
|
||||
create: {
|
||||
id: user.id,
|
||||
email: user.email,
|
||||
password: user.password,
|
||||
username: user.username,
|
||||
role: user.role,
|
||||
score: user.score,
|
||||
level: user.level,
|
||||
hp: user.hp,
|
||||
maxHp: user.maxHp,
|
||||
xp: user.xp,
|
||||
maxXp: user.maxXp,
|
||||
avatar: user.avatar,
|
||||
bio: user.bio,
|
||||
characterClass: user.characterClass,
|
||||
createdAt: new Date(user.createdAt),
|
||||
updatedAt: new Date(user.updatedAt),
|
||||
},
|
||||
});
|
||||
stats.users++;
|
||||
process.stdout.write(
|
||||
`\r ✅ ${stats.users}/${users.length} users migrés`
|
||||
);
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur user ${user.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(`\n ✅ ${stats.users} users migrés avec succès`);
|
||||
}
|
||||
|
||||
async function migrateUserPreferences() {
|
||||
console.log("\n📦 Migration des UserPreferences...");
|
||||
const preferences = readSQLite("UserPreferences");
|
||||
|
||||
for (const pref of preferences) {
|
||||
try {
|
||||
await prismaPG.userPreferences.upsert({
|
||||
where: { id: pref.id },
|
||||
update: {
|
||||
userId: pref.userId,
|
||||
homeBackground: pref.homeBackground,
|
||||
eventsBackground: pref.eventsBackground,
|
||||
leaderboardBackground: pref.leaderboardBackground,
|
||||
theme: pref.theme,
|
||||
createdAt: new Date(pref.createdAt),
|
||||
updatedAt: new Date(pref.updatedAt),
|
||||
},
|
||||
create: {
|
||||
id: pref.id,
|
||||
userId: pref.userId,
|
||||
homeBackground: pref.homeBackground,
|
||||
eventsBackground: pref.eventsBackground,
|
||||
leaderboardBackground: pref.leaderboardBackground,
|
||||
theme: pref.theme,
|
||||
createdAt: new Date(pref.createdAt),
|
||||
updatedAt: new Date(pref.updatedAt),
|
||||
},
|
||||
});
|
||||
stats.userPreferences++;
|
||||
process.stdout.write(
|
||||
`\r ✅ ${stats.userPreferences}/${preferences.length} préférences migrées`
|
||||
);
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur préférence ${pref.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
`\n ✅ ${stats.userPreferences} préférences migrées avec succès`
|
||||
);
|
||||
}
|
||||
|
||||
async function migrateEvents() {
|
||||
console.log("\n📦 Migration des Events...");
|
||||
const events = readSQLite("Event");
|
||||
|
||||
for (const event of events) {
|
||||
try {
|
||||
await prismaPG.event.upsert({
|
||||
where: { id: event.id },
|
||||
update: {
|
||||
date: new Date(event.date),
|
||||
name: event.name,
|
||||
description: event.description,
|
||||
type: event.type,
|
||||
room: event.room,
|
||||
time: event.time,
|
||||
maxPlaces: event.maxPlaces,
|
||||
createdAt: new Date(event.createdAt),
|
||||
updatedAt: new Date(event.updatedAt),
|
||||
},
|
||||
create: {
|
||||
id: event.id,
|
||||
date: new Date(event.date),
|
||||
name: event.name,
|
||||
description: event.description,
|
||||
type: event.type,
|
||||
room: event.room,
|
||||
time: event.time,
|
||||
maxPlaces: event.maxPlaces,
|
||||
createdAt: new Date(event.createdAt),
|
||||
updatedAt: new Date(event.updatedAt),
|
||||
},
|
||||
});
|
||||
stats.events++;
|
||||
process.stdout.write(
|
||||
`\r ✅ ${stats.events}/${events.length} événements migrés`
|
||||
);
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur event ${event.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(`\n ✅ ${stats.events} événements migrés avec succès`);
|
||||
}
|
||||
|
||||
async function migrateEventRegistrations() {
|
||||
console.log("\n📦 Migration des EventRegistrations...");
|
||||
const registrations = readSQLite("EventRegistration");
|
||||
|
||||
for (const reg of registrations) {
|
||||
try {
|
||||
await prismaPG.eventRegistration.upsert({
|
||||
where: {
|
||||
userId_eventId: {
|
||||
userId: reg.userId,
|
||||
eventId: reg.eventId,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
createdAt: new Date(reg.createdAt),
|
||||
},
|
||||
create: {
|
||||
id: reg.id,
|
||||
userId: reg.userId,
|
||||
eventId: reg.eventId,
|
||||
createdAt: new Date(reg.createdAt),
|
||||
},
|
||||
});
|
||||
stats.eventRegistrations++;
|
||||
process.stdout.write(
|
||||
`\r ✅ ${stats.eventRegistrations}/${registrations.length} inscriptions migrées`
|
||||
);
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur registration ${reg.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
`\n ✅ ${stats.eventRegistrations} inscriptions migrées avec succès`
|
||||
);
|
||||
}
|
||||
|
||||
async function migrateEventFeedbacks() {
|
||||
console.log("\n📦 Migration des EventFeedbacks...");
|
||||
const feedbacks = readSQLite("EventFeedback");
|
||||
|
||||
for (const feedback of feedbacks) {
|
||||
try {
|
||||
await prismaPG.eventFeedback.upsert({
|
||||
where: {
|
||||
userId_eventId: {
|
||||
userId: feedback.userId,
|
||||
eventId: feedback.eventId,
|
||||
},
|
||||
},
|
||||
update: {
|
||||
rating: feedback.rating,
|
||||
comment: feedback.comment,
|
||||
isRead: feedback.isRead ? true : false,
|
||||
createdAt: new Date(feedback.createdAt),
|
||||
updatedAt: new Date(feedback.updatedAt),
|
||||
},
|
||||
create: {
|
||||
id: feedback.id,
|
||||
userId: feedback.userId,
|
||||
eventId: feedback.eventId,
|
||||
rating: feedback.rating,
|
||||
comment: feedback.comment,
|
||||
isRead: feedback.isRead ? true : false,
|
||||
createdAt: new Date(feedback.createdAt),
|
||||
updatedAt: new Date(feedback.updatedAt),
|
||||
},
|
||||
});
|
||||
stats.eventFeedbacks++;
|
||||
process.stdout.write(
|
||||
`\r ✅ ${stats.eventFeedbacks}/${feedbacks.length} feedbacks migrés`
|
||||
);
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur feedback ${feedback.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(`\n ✅ ${stats.eventFeedbacks} feedbacks migrés avec succès`);
|
||||
}
|
||||
|
||||
async function migrateSitePreferences() {
|
||||
console.log("\n📦 Migration des SitePreferences...");
|
||||
const sitePrefs = readSQLite("SitePreferences");
|
||||
|
||||
for (const pref of sitePrefs) {
|
||||
try {
|
||||
await prismaPG.sitePreferences.upsert({
|
||||
where: { id: pref.id },
|
||||
update: {
|
||||
homeBackground: pref.homeBackground,
|
||||
eventsBackground: pref.eventsBackground,
|
||||
leaderboardBackground: pref.leaderboardBackground,
|
||||
challengesBackground: pref.challengesBackground,
|
||||
eventRegistrationPoints: pref.eventRegistrationPoints,
|
||||
eventFeedbackPoints: pref.eventFeedbackPoints,
|
||||
createdAt: new Date(pref.createdAt),
|
||||
updatedAt: new Date(pref.updatedAt),
|
||||
},
|
||||
create: {
|
||||
id: pref.id,
|
||||
homeBackground: pref.homeBackground,
|
||||
eventsBackground: pref.eventsBackground,
|
||||
leaderboardBackground: pref.leaderboardBackground,
|
||||
challengesBackground: pref.challengesBackground,
|
||||
eventRegistrationPoints: pref.eventRegistrationPoints,
|
||||
eventFeedbackPoints: pref.eventFeedbackPoints,
|
||||
createdAt: new Date(pref.createdAt),
|
||||
updatedAt: new Date(pref.updatedAt),
|
||||
},
|
||||
});
|
||||
stats.sitePreferences++;
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur site preferences ${pref.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(
|
||||
` ✅ ${stats.sitePreferences} préférences site migrées avec succès`
|
||||
);
|
||||
}
|
||||
|
||||
async function migrateChallenges() {
|
||||
console.log("\n📦 Migration des Challenges...");
|
||||
const challenges = readSQLite("Challenge");
|
||||
|
||||
for (const challenge of challenges) {
|
||||
try {
|
||||
await prismaPG.challenge.upsert({
|
||||
where: { id: challenge.id },
|
||||
update: {
|
||||
challengerId: challenge.challengerId,
|
||||
challengedId: challenge.challengedId,
|
||||
title: challenge.title,
|
||||
description: challenge.description,
|
||||
pointsReward: challenge.pointsReward,
|
||||
status: challenge.status,
|
||||
adminId: challenge.adminId,
|
||||
adminComment: challenge.adminComment,
|
||||
winnerId: challenge.winnerId,
|
||||
createdAt: new Date(challenge.createdAt),
|
||||
acceptedAt: challenge.acceptedAt
|
||||
? new Date(challenge.acceptedAt)
|
||||
: null,
|
||||
completedAt: challenge.completedAt
|
||||
? new Date(challenge.completedAt)
|
||||
: null,
|
||||
updatedAt: new Date(challenge.updatedAt),
|
||||
},
|
||||
create: {
|
||||
id: challenge.id,
|
||||
challengerId: challenge.challengerId,
|
||||
challengedId: challenge.challengedId,
|
||||
title: challenge.title,
|
||||
description: challenge.description,
|
||||
pointsReward: challenge.pointsReward,
|
||||
status: challenge.status,
|
||||
adminId: challenge.adminId,
|
||||
adminComment: challenge.adminComment,
|
||||
winnerId: challenge.winnerId,
|
||||
createdAt: new Date(challenge.createdAt),
|
||||
acceptedAt: challenge.acceptedAt
|
||||
? new Date(challenge.acceptedAt)
|
||||
: null,
|
||||
completedAt: challenge.completedAt
|
||||
? new Date(challenge.completedAt)
|
||||
: null,
|
||||
updatedAt: new Date(challenge.updatedAt),
|
||||
},
|
||||
});
|
||||
stats.challenges++;
|
||||
process.stdout.write(
|
||||
`\r ✅ ${stats.challenges}/${challenges.length} défis migrés`
|
||||
);
|
||||
} catch (error) {
|
||||
stats.errors++;
|
||||
console.error(`\n ❌ Erreur sur challenge ${challenge.id}:`, error);
|
||||
}
|
||||
}
|
||||
console.log(`\n ✅ ${stats.challenges} défis migrés avec succès`);
|
||||
}
|
||||
|
||||
async function main() {
|
||||
console.log("🚀 Démarrage de la migration SQLite → PostgreSQL");
|
||||
console.log(`📂 SQLite: ${SQLITE_DB_PATH}`);
|
||||
console.log(`🐘 PostgreSQL: ${POSTGRES_URL?.replace(/:[^:@]+@/, ":****@")}`);
|
||||
|
||||
try {
|
||||
// Import dynamique du PrismaClient depuis la racine du projet
|
||||
const prismaModule = await import(
|
||||
join(projectRoot, "prisma/generated/prisma/client")
|
||||
);
|
||||
const { PrismaClient } = prismaModule;
|
||||
|
||||
// Vérifier que le fichier SQLite existe
|
||||
if (!existsSync(SQLITE_DB_PATH)) {
|
||||
console.error(`\n❌ Le fichier SQLite n'existe pas: ${SQLITE_DB_PATH}`);
|
||||
console.error(`\n💡 Vérifications:`);
|
||||
console.error(` 1. Le volume est-il monté dans docker-compose.yml ?`);
|
||||
console.error(` 2. Le fichier existe-t-il sur l'hôte ?`);
|
||||
console.error(` 3. Le chemin est-il correct ?`);
|
||||
console.error(`\n Pour vérifier dans le container:`);
|
||||
console.error(` docker-compose exec got-app ls -la /app/data/`);
|
||||
throw new Error(`Fichier SQLite introuvable: ${SQLITE_DB_PATH}`);
|
||||
}
|
||||
|
||||
console.log(` ✅ Fichier SQLite trouvé: ${SQLITE_DB_PATH}`);
|
||||
|
||||
// Initialiser les clients
|
||||
sqliteDb = new Database(SQLITE_DB_PATH, { readonly: true });
|
||||
|
||||
pgPool = new Pool({
|
||||
connectionString: POSTGRES_URL,
|
||||
});
|
||||
const pgAdapter = new PrismaPg(pgPool);
|
||||
prismaPG = new PrismaClient({
|
||||
adapter: pgAdapter,
|
||||
log: ["error"],
|
||||
});
|
||||
|
||||
// Vérifier les connexions
|
||||
console.log("\n🔍 Vérification des connexions...");
|
||||
if (!sqliteDb.open) {
|
||||
throw new Error("Impossible d'ouvrir la base SQLite");
|
||||
}
|
||||
console.log(" ✅ SQLite connecté");
|
||||
|
||||
await prismaPG.$connect();
|
||||
console.log(" ✅ PostgreSQL connecté");
|
||||
|
||||
// Migration dans l'ordre des dépendances
|
||||
await migrateUsers();
|
||||
await migrateUserPreferences();
|
||||
await migrateEvents();
|
||||
await migrateEventRegistrations();
|
||||
await migrateEventFeedbacks();
|
||||
await migrateSitePreferences();
|
||||
await migrateChallenges();
|
||||
|
||||
// Résumé
|
||||
console.log("\n" + "=".repeat(50));
|
||||
console.log("📊 Résumé de la migration:");
|
||||
console.log("=".repeat(50));
|
||||
console.log(` Users: ${stats.users}`);
|
||||
console.log(` UserPreferences: ${stats.userPreferences}`);
|
||||
console.log(` Events: ${stats.events}`);
|
||||
console.log(` EventRegistrations: ${stats.eventRegistrations}`);
|
||||
console.log(` EventFeedbacks: ${stats.eventFeedbacks}`);
|
||||
console.log(` SitePreferences: ${stats.sitePreferences}`);
|
||||
console.log(` Challenges: ${stats.challenges}`);
|
||||
console.log(` Erreurs: ${stats.errors}`);
|
||||
console.log("=".repeat(50));
|
||||
|
||||
if (stats.errors > 0) {
|
||||
console.log(
|
||||
"\n⚠️ Certaines erreurs sont survenues. Vérifiez les logs ci-dessus."
|
||||
);
|
||||
process.exit(1);
|
||||
} else {
|
||||
console.log("\n✅ Migration terminée avec succès!");
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("\n❌ Erreur fatale:", error);
|
||||
process.exit(1);
|
||||
} finally {
|
||||
if (prismaPG) {
|
||||
await prismaPG.$disconnect();
|
||||
}
|
||||
if (sqliteDb) {
|
||||
sqliteDb.close();
|
||||
}
|
||||
if (pgPool) {
|
||||
await pgPool.end();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
Reference in New Issue
Block a user