fix: remove pg adapter, use standard PrismaClient - add prisma db push to Dockerfile CMD
This commit is contained in:
+8
-1
@@ -21,9 +21,15 @@ FROM base AS runner
|
|||||||
WORKDIR /app
|
WORKDIR /app
|
||||||
ENV NODE_ENV=production
|
ENV NODE_ENV=production
|
||||||
ENV NEXT_TELEMETRY_DISABLED=1
|
ENV NEXT_TELEMETRY_DISABLED=1
|
||||||
|
RUN apk add --no-cache libc6-compat
|
||||||
RUN addgroup --system --gid 1001 nodejs
|
RUN addgroup --system --gid 1001 nodejs
|
||||||
RUN adduser --system --uid 1001 nextjs
|
RUN adduser --system --uid 1001 nextjs
|
||||||
|
|
||||||
|
# node_modules for prisma CLI at runtime
|
||||||
|
COPY --from=deps /app/node_modules ./node_modules
|
||||||
COPY --from=builder /app/public ./public
|
COPY --from=builder /app/public ./public
|
||||||
|
COPY --from=builder /app/prisma ./prisma
|
||||||
|
COPY --from=builder /app/prisma.config.ts ./prisma.config.ts
|
||||||
RUN mkdir .next && chown nextjs:nodejs .next
|
RUN mkdir .next && chown nextjs:nodejs .next
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/standalone ./
|
||||||
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
COPY --from=builder --chown=nextjs:nodejs /app/.next/static ./.next/static
|
||||||
@@ -31,4 +37,5 @@ USER nextjs
|
|||||||
EXPOSE 3000
|
EXPOSE 3000
|
||||||
ENV PORT=3000
|
ENV PORT=3000
|
||||||
ENV HOSTNAME="0.0.0.0"
|
ENV HOSTNAME="0.0.0.0"
|
||||||
CMD ["node", "server.js"]
|
# Push schema (idempotent, safe to run on every start) then start server
|
||||||
|
CMD sh -c "npx prisma db push --skip-generate 2>&1 | tail -5 && node server.js"
|
||||||
|
|||||||
@@ -1,34 +1,24 @@
|
|||||||
import { Pool } from 'pg';
|
|
||||||
import { PrismaPg } from '@prisma/adapter-pg';
|
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
const connectionString =
|
|
||||||
process.env.DATABASE_URL ||
|
|
||||||
'postgres://postgres:mBTWE2cDKGExtpktguD3HPe8y9Xr9kWFYdxV4WHQKISLLGoBAS4UdtfSCfXwvPpq@65.109.236.58:37298/postgres';
|
|
||||||
|
|
||||||
const pool = new Pool({ connectionString });
|
|
||||||
const adapter = new PrismaPg(pool);
|
|
||||||
|
|
||||||
const globalForPrisma = globalThis as unknown as {
|
const globalForPrisma = globalThis as unknown as {
|
||||||
prisma: PrismaClient | undefined;
|
prisma: PrismaClient | undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getPrismaClient(): PrismaClient {
|
function createPrismaClient() {
|
||||||
if (process.env.NODE_ENV !== 'production' && globalForPrisma.prisma) {
|
const databaseUrl = process.env.DATABASE_URL;
|
||||||
// Ensure all models (category, cheatsheet, prompt) exist on cached client
|
|
||||||
if (
|
if (!databaseUrl) {
|
||||||
(globalForPrisma.prisma as any).category &&
|
console.error('[DB] DATABASE_URL is not set! Using fallback connection string.');
|
||||||
(globalForPrisma.prisma as any).cheatsheet &&
|
|
||||||
(globalForPrisma.prisma as any).prompt
|
|
||||||
) {
|
|
||||||
return globalForPrisma.prisma;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
const client = new PrismaClient({ adapter });
|
|
||||||
if (process.env.NODE_ENV !== 'production') {
|
return new PrismaClient({
|
||||||
globalForPrisma.prisma = client;
|
log: process.env.NODE_ENV === 'development' ? ['error', 'warn'] : ['error'],
|
||||||
}
|
});
|
||||||
return client;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export const db = getPrismaClient();
|
export const db =
|
||||||
|
globalForPrisma.prisma ?? createPrismaClient();
|
||||||
|
|
||||||
|
if (process.env.NODE_ENV !== 'production') {
|
||||||
|
globalForPrisma.prisma = db;
|
||||||
|
}
|
||||||
|
|||||||
Generated
+2
-196
@@ -9,7 +9,6 @@
|
|||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@base-ui/react": "^1.5.0",
|
"@base-ui/react": "^1.5.0",
|
||||||
"@prisma/adapter-pg": "^7.9.0",
|
|
||||||
"@prisma/client": "^7.8.0",
|
"@prisma/client": "^7.8.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"cloudinary": "^2.10.0",
|
"cloudinary": "^2.10.0",
|
||||||
@@ -20,7 +19,6 @@
|
|||||||
"next": "16.2.9",
|
"next": "16.2.9",
|
||||||
"next-auth": "^5.0.0-beta.31",
|
"next-auth": "^5.0.0-beta.31",
|
||||||
"next-intl": "^4.13.0",
|
"next-intl": "^4.13.0",
|
||||||
"pg": "^8.22.0",
|
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4",
|
"react-dom": "19.2.4",
|
||||||
"shadcn": "^4.11.0",
|
"shadcn": "^4.11.0",
|
||||||
@@ -30,7 +28,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/pg": "^8.20.0",
|
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
@@ -2251,18 +2248,6 @@
|
|||||||
"url": "https://github.com/sponsors/jonschlinkert"
|
"url": "https://github.com/sponsors/jonschlinkert"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/adapter-pg": {
|
|
||||||
"version": "7.9.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/adapter-pg/-/adapter-pg-7.9.0.tgz",
|
|
||||||
"integrity": "sha512-kPYuFvNTlqnaFf2UpXBBG3ycTT3PL76uSZtLFBEwDytjMMUW8ZHrsb9cSNIarzdPW5EXWmBOeOq9/MVjMtbWkA==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@prisma/driver-adapter-utils": "7.9.0",
|
|
||||||
"@types/pg": "^8.16.0",
|
|
||||||
"pg": "^8.16.3",
|
|
||||||
"postgres-array": "3.0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@prisma/client": {
|
"node_modules/@prisma/client": {
|
||||||
"version": "7.8.0",
|
"version": "7.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/client/-/client-7.8.0.tgz",
|
||||||
@@ -2339,21 +2324,6 @@
|
|||||||
"zeptomatch": "2.1.0"
|
"zeptomatch": "2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@prisma/driver-adapter-utils": {
|
|
||||||
"version": "7.9.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/driver-adapter-utils/-/driver-adapter-utils-7.9.0.tgz",
|
|
||||||
"integrity": "sha512-fFXujitfMyjk3kOd1Tbs5FXBm6i2OWwEhaP5lHgkUM99jHpPEQwCWj+z/WKPFq6EDMThE1zGzSlVegtR0Pmu2w==",
|
|
||||||
"license": "Apache-2.0",
|
|
||||||
"dependencies": {
|
|
||||||
"@prisma/debug": "7.9.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@prisma/driver-adapter-utils/node_modules/@prisma/debug": {
|
|
||||||
"version": "7.9.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/debug/-/debug-7.9.0.tgz",
|
|
||||||
"integrity": "sha512-i0KdVQuKUE6N9NloHs+sUNAk2c9svR3myBndQbA3BoeoArsSpwtNgTdHZL+wBtCLCcdS2OOC/PKhgTe36jkF5A==",
|
|
||||||
"license": "Apache-2.0"
|
|
||||||
},
|
|
||||||
"node_modules/@prisma/engines": {
|
"node_modules/@prisma/engines": {
|
||||||
"version": "7.8.0",
|
"version": "7.8.0",
|
||||||
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/@prisma/engines/-/engines-7.8.0.tgz",
|
||||||
@@ -3275,22 +3245,12 @@
|
|||||||
"version": "20.19.43",
|
"version": "20.19.43",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.43.tgz",
|
||||||
"integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
|
"integrity": "sha512-6oYBAi5ikg4Pl+kGsoYtawUMBT2zZMCvPNF7pVLnHZfd1zf38DRiWn/gT01RYCdUqkv7Fhr+C9ot4/tb+2sVvA==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~6.21.0"
|
"undici-types": "~6.21.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/pg": {
|
|
||||||
"version": "8.20.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/@types/pg/-/pg-8.20.0.tgz",
|
|
||||||
"integrity": "sha512-bEPFOaMAHTEP1EzpvHTbmwR8UsFyHSKsRisLIHVMXnpNefSbGA1bD6CVy+qKjGSqmZqNqBDV2azOBo8TgkcVow==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"@types/node": "*",
|
|
||||||
"pg-protocol": "*",
|
|
||||||
"pg-types": "^2.2.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/@types/react": {
|
"node_modules/@types/react": {
|
||||||
"version": "19.2.17",
|
"version": "19.2.17",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.2.17.tgz",
|
||||||
@@ -9058,104 +9018,6 @@
|
|||||||
"devOptional": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/pg": {
|
|
||||||
"version": "8.22.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg/-/pg-8.22.0.tgz",
|
|
||||||
"integrity": "sha512-8wih1vVIBMxoUM2oB4soJsD9tDnDpLv4OXBJ+EJzFsvycD+lfyIreC2gGHq78f8jbLLt+bvlPTFdFZfJkOuzAA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"pg-connection-string": "^2.14.0",
|
|
||||||
"pg-pool": "^3.14.0",
|
|
||||||
"pg-protocol": "^1.15.0",
|
|
||||||
"pg-types": "2.2.0",
|
|
||||||
"pgpass": "1.0.5"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 16.0.0"
|
|
||||||
},
|
|
||||||
"optionalDependencies": {
|
|
||||||
"pg-cloudflare": "^1.4.0"
|
|
||||||
},
|
|
||||||
"peerDependencies": {
|
|
||||||
"pg-native": ">=3.0.1"
|
|
||||||
},
|
|
||||||
"peerDependenciesMeta": {
|
|
||||||
"pg-native": {
|
|
||||||
"optional": true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-cloudflare": {
|
|
||||||
"version": "1.4.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.4.0.tgz",
|
|
||||||
"integrity": "sha512-Vo7z/6rrQYxpNRylp4Tlob2elzbh+N/MOQbxFVWCxS7oEx6jF53GTJFxK2WWpKuBRkmiin4Mt+xofFDjx09R0A==",
|
|
||||||
"license": "MIT",
|
|
||||||
"optional": true
|
|
||||||
},
|
|
||||||
"node_modules/pg-connection-string": {
|
|
||||||
"version": "2.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.14.0.tgz",
|
|
||||||
"integrity": "sha512-XwWDGcLRGCXAR8F/AM5bG7Q+A3Wm2s6QeEjlOKZLlH3UYcguiqCWKyWXVag5TLTIjR7oOJUY8kcADaZgWPyLeg==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/pg-int8": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4.0.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-pool": {
|
|
||||||
"version": "3.14.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.14.0.tgz",
|
|
||||||
"integrity": "sha512-gKtPkFdQPU3DksooVLi9LsjZxrsBUZIpa+7aVx+LV5pNh0KzP4Zleud2po+ConrxbuXGBJ6Hfer6hdgpIBpBaw==",
|
|
||||||
"license": "MIT",
|
|
||||||
"peerDependencies": {
|
|
||||||
"pg": ">=8.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-protocol": {
|
|
||||||
"version": "1.15.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.15.0.tgz",
|
|
||||||
"integrity": "sha512-cq9sECI5s0+uPUXjbz8ioyPJni6RzsRib0US67i5IoTZKw8fNeYlVE7u8F4dG7vEJJtc5wdD1K189lCCUwqWTQ==",
|
|
||||||
"license": "MIT"
|
|
||||||
},
|
|
||||||
"node_modules/pg-types": {
|
|
||||||
"version": "2.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz",
|
|
||||||
"integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"pg-int8": "1.0.1",
|
|
||||||
"postgres-array": "~2.0.0",
|
|
||||||
"postgres-bytea": "~1.0.0",
|
|
||||||
"postgres-date": "~1.0.4",
|
|
||||||
"postgres-interval": "^1.1.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pg-types/node_modules/postgres-array": {
|
|
||||||
"version": "2.0.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz",
|
|
||||||
"integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/pgpass": {
|
|
||||||
"version": "1.0.5",
|
|
||||||
"resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz",
|
|
||||||
"integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"split2": "^4.1.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/picocolors": {
|
"node_modules/picocolors": {
|
||||||
"version": "1.1.1",
|
"version": "1.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
|
||||||
@@ -9266,45 +9128,6 @@
|
|||||||
"url": "https://github.com/sponsors/porsager"
|
"url": "https://github.com/sponsors/porsager"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/postgres-array": {
|
|
||||||
"version": "3.0.4",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-3.0.4.tgz",
|
|
||||||
"integrity": "sha512-nAUSGfSDGOaOAEGwqsRY27GPOea7CNipJPOA7lPbdEpx5Kg3qzdP0AaWC5MlhTWV9s4hFX39nomVZ+C4tnGOJQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=12"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-bytea": {
|
|
||||||
"version": "1.0.1",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.1.tgz",
|
|
||||||
"integrity": "sha512-5+5HqXnsZPE65IJZSMkZtURARZelel2oXUEO8rH83VS/hxH5vv1uHquPg5wZs8yMAfdv971IU+kcPUczi7NVBQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-date": {
|
|
||||||
"version": "1.0.7",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz",
|
|
||||||
"integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/postgres-interval": {
|
|
||||||
"version": "1.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz",
|
|
||||||
"integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"dependencies": {
|
|
||||||
"xtend": "^4.0.0"
|
|
||||||
},
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.10.0"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/powershell-utils": {
|
"node_modules/powershell-utils": {
|
||||||
"version": "0.1.0",
|
"version": "0.1.0",
|
||||||
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/powershell-utils/-/powershell-utils-0.1.0.tgz",
|
||||||
@@ -10279,15 +10102,6 @@
|
|||||||
"node": ">=0.10.0"
|
"node": ">=0.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/split2": {
|
|
||||||
"version": "4.2.0",
|
|
||||||
"resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz",
|
|
||||||
"integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==",
|
|
||||||
"license": "ISC",
|
|
||||||
"engines": {
|
|
||||||
"node": ">= 10.x"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/sqlstring": {
|
"node_modules/sqlstring": {
|
||||||
"version": "2.3.3",
|
"version": "2.3.3",
|
||||||
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
|
"resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz",
|
||||||
@@ -10976,6 +10790,7 @@
|
|||||||
"version": "6.21.0",
|
"version": "6.21.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
|
||||||
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
"integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
|
||||||
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/unicorn-magic": {
|
"node_modules/unicorn-magic": {
|
||||||
@@ -11300,15 +11115,6 @@
|
|||||||
"url": "https://github.com/sponsors/sindresorhus"
|
"url": "https://github.com/sponsors/sindresorhus"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/xtend": {
|
|
||||||
"version": "4.0.2",
|
|
||||||
"resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz",
|
|
||||||
"integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==",
|
|
||||||
"license": "MIT",
|
|
||||||
"engines": {
|
|
||||||
"node": ">=0.4"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"node_modules/yallist": {
|
"node_modules/yallist": {
|
||||||
"version": "3.1.1",
|
"version": "3.1.1",
|
||||||
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
"resolved": "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz",
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@base-ui/react": "^1.5.0",
|
"@base-ui/react": "^1.5.0",
|
||||||
"@prisma/adapter-pg": "^7.9.0",
|
|
||||||
"@prisma/client": "^7.8.0",
|
"@prisma/client": "^7.8.0",
|
||||||
"class-variance-authority": "^0.7.1",
|
"class-variance-authority": "^0.7.1",
|
||||||
"cloudinary": "^2.10.0",
|
"cloudinary": "^2.10.0",
|
||||||
@@ -21,7 +20,6 @@
|
|||||||
"next": "16.2.9",
|
"next": "16.2.9",
|
||||||
"next-auth": "^5.0.0-beta.31",
|
"next-auth": "^5.0.0-beta.31",
|
||||||
"next-intl": "^4.13.0",
|
"next-intl": "^4.13.0",
|
||||||
"pg": "^8.22.0",
|
|
||||||
"react": "19.2.4",
|
"react": "19.2.4",
|
||||||
"react-dom": "19.2.4",
|
"react-dom": "19.2.4",
|
||||||
"shadcn": "^4.11.0",
|
"shadcn": "^4.11.0",
|
||||||
@@ -31,7 +29,6 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@tailwindcss/postcss": "^4",
|
"@tailwindcss/postcss": "^4",
|
||||||
"@types/node": "^20",
|
"@types/node": "^20",
|
||||||
"@types/pg": "^8.20.0",
|
|
||||||
"@types/react": "^19",
|
"@types/react": "^19",
|
||||||
"@types/react-dom": "^19",
|
"@types/react-dom": "^19",
|
||||||
"eslint": "^9",
|
"eslint": "^9",
|
||||||
|
|||||||
+12
-17
@@ -1,12 +1,6 @@
|
|||||||
import { Pool } from 'pg';
|
|
||||||
import { PrismaPg } from '@prisma/adapter-pg';
|
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
const connectionString = process.env.DATABASE_URL || 'postgres://postgres:mBTWE2cDKGExtpktguD3HPe8y9Xr9kWFYdxV4WHQKISLLGoBAS4UdtfSCfXwvPpq@65.109.236.58:37298/postgres';
|
const db = new PrismaClient();
|
||||||
|
|
||||||
const pool = new Pool({ connectionString });
|
|
||||||
const adapter = new PrismaPg(pool);
|
|
||||||
const db = new PrismaClient({ adapter });
|
|
||||||
|
|
||||||
async function main() {
|
async function main() {
|
||||||
console.log('Seeding PostgreSQL database...');
|
console.log('Seeding PostgreSQL database...');
|
||||||
@@ -47,19 +41,19 @@ async function main() {
|
|||||||
fileName: 'app/actions.ts',
|
fileName: 'app/actions.ts',
|
||||||
language: 'typescript',
|
language: 'typescript',
|
||||||
description: 'Server Action function handling form submission',
|
description: 'Server Action function handling form submission',
|
||||||
code: `'use server'\n\nimport { revalidatePath } from 'next/cache';\n\nexport async function submitProjectIdea(formData: FormData) {\n const title = formData.get('title') as string;\n const description = formData.get('description') as string;\n\n if (!title || title.length < 3) {\n return { success: false, error: 'Title must be at least 3 characters long.' };\n }\n\n // Database insertion simulation\n console.log('Saved Idea:', { title, description });\n\n revalidatePath('/ideas');\n return { success: true, message: 'Your idea was submitted successfully!' };\n}`
|
code: `'use server'\n\nimport { revalidatePath } from 'next/cache';\n\nexport async function submitProjectIdea(formData: FormData) {\n const title = formData.get('title') as string;\n const description = formData.get('description') as string;\n\n if (!title || title.length < 3) {\n return { success: false, error: 'Title must be at least 3 characters long.' };\n }\n\n console.log('Saved Idea:', { title, description });\n\n revalidatePath('/ideas');\n return { success: true, message: 'Your idea was submitted successfully!' };\n}`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fileName: 'proxy.ts',
|
fileName: 'proxy.ts',
|
||||||
language: 'typescript',
|
language: 'typescript',
|
||||||
description: 'Next.js 16 proxy configuration (middleware alternative)',
|
description: 'Next.js 16 proxy configuration (middleware alternative)',
|
||||||
code: `import { NextRequest, NextResponse } from 'next/server';\nimport createMiddleware from 'next-intl/middleware';\nimport { routing } from '@/i18n/routing';\n\nconst intlMiddleware = createMiddleware(routing);\n\nexport async function proxy(request: NextRequest) {\n if (request.nextUrl.pathname.includes('/admin')) {\n // Auth check logic\n }\n return intlMiddleware(request);\n}\n\nexport const config = {\n matcher: ['/((?!api|_next|_vercel|.*\\\\..*).*)']\n};`
|
code: `import { NextRequest, NextResponse } from 'next/server';\nimport createMiddleware from 'next-intl/middleware';\nimport { routing } from '@/i18n/routing';\n\nconst intlMiddleware = createMiddleware(routing);\n\nexport async function proxy(request: NextRequest) {\n if (request.nextUrl.pathname.includes('/admin')) {\n // Auth check logic\n }\n return intlMiddleware(request);\n}\n\nexport const config = {\n matcher: ['/((?!api|_next|_vercel|.*\\\\..*).*)'],\n};`
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
fileName: 'components/IdeaForm.tsx',
|
fileName: 'components/IdeaForm.tsx',
|
||||||
language: 'tsx',
|
language: 'tsx',
|
||||||
description: 'Client Form component using useActionState',
|
description: 'Client Form component using useActionState',
|
||||||
code: `'use client';\n\nimport { useActionState } from 'react';\nimport { submitProjectIdea } from '@/app/actions';\n\nexport function IdeaForm() {\n const [state, formAction, isPending] = useActionState(submitProjectIdea, null);\n\n return (\n <form action={formAction} className="space-y-4 max-w-md p-6 bg-slate-900 rounded-xl border border-slate-800">\n <h3 className="text-xl font-bold text-white">Add New Idea</h3>\n \n <div>\n <label className="block text-sm text-slate-400 mb-1">Idea Title</label>\n <input name="title" required className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white" />\n </div>\n\n <button disabled={isPending} className="w-full py-2.5 bg-red-600 hover:bg-red-500 text-white rounded-lg font-medium">\n {isPending ? 'Submitting...' : 'Share Idea'}\n </button>\n\n {state?.error && <p className="text-red-400 text-sm">{state.error}</p>}\n {state?.success && <p className="text-emerald-400 text-sm">{state.message}</p>}\n </form>\n );\n}`
|
code: `'use client';\n\nimport { useActionState } from 'react';\nimport { submitProjectIdea } from '@/app/actions';\n\nexport function IdeaForm() {\n const [state, formAction, isPending] = useActionState(submitProjectIdea, null);\n\n return (\n <form action={formAction} className="space-y-4 max-w-md p-6 bg-slate-900 rounded-xl border border-slate-800">\n <h3 className="text-xl font-bold text-white">Add New Idea</h3>\n <div>\n <label className="block text-sm text-slate-400 mb-1">Idea Title</label>\n <input name="title" required className="w-full px-3 py-2 bg-slate-800 border border-slate-700 rounded-lg text-white" />\n </div>\n <button disabled={isPending} className="w-full py-2.5 bg-red-600 hover:bg-red-500 text-white rounded-lg font-medium">\n {isPending ? 'Submitting...' : 'Share Idea'}\n </button>\n {state?.error && <p className="text-red-400 text-sm">{state.error}</p>}\n {state?.success && <p className="text-emerald-400 text-sm">{state.message}</p>}\n </form>\n );\n}`
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@@ -112,9 +106,9 @@ async function main() {
|
|||||||
likesCount: 1450,
|
likesCount: 1450,
|
||||||
summary: 'Build an autonomous AI agent in Python that crawls web data, summarizes tech news, and generates structured reports automatically.',
|
summary: 'Build an autonomous AI agent in Python that crawls web data, summarizes tech news, and generates structured reports automatically.',
|
||||||
notesMarkdown: [
|
notesMarkdown: [
|
||||||
'🤖 AI agents are configured with role, goal, and backstory.',
|
'AI agents are configured with role, goal, and backstory.',
|
||||||
'🤖 Equip agents with real-time web search using Serper API or Tavily.',
|
'Equip agents with real-time web search using Serper API or Tavily.',
|
||||||
'🤖 Gemini 1.5 Flash provides high token throughput with minimal latency.'
|
'Gemini 1.5 Flash provides high token throughput with minimal latency.'
|
||||||
],
|
],
|
||||||
codeSnippets: {
|
codeSnippets: {
|
||||||
create: [
|
create: [
|
||||||
@@ -167,9 +161,9 @@ async function main() {
|
|||||||
likesCount: 2600,
|
likesCount: 2600,
|
||||||
summary: 'Learn CSS-first configuration in Tailwind CSS v4 using @import "tailwindcss";, OKLCH color spaces, and advanced glassmorphism component design.',
|
summary: 'Learn CSS-first configuration in Tailwind CSS v4 using @import "tailwindcss";, OKLCH color spaces, and advanced glassmorphism component design.',
|
||||||
notesMarkdown: [
|
notesMarkdown: [
|
||||||
'🎨 In Tailwind v4, @theme directive in globals.css replaces tailwind.config.js.',
|
'In Tailwind v4, @theme directive in globals.css replaces tailwind.config.js.',
|
||||||
'🎨 OKLCH color space ensures consistent perceived contrast across light and dark modes.',
|
'OKLCH color space ensures consistent perceived contrast across light and dark modes.',
|
||||||
'🎨 @custom-variant dark provides flexible dark mode scoping.'
|
'@custom-variant dark provides flexible dark mode scoping.'
|
||||||
],
|
],
|
||||||
codeSnippets: {
|
codeSnippets: {
|
||||||
create: [
|
create: [
|
||||||
@@ -252,6 +246,7 @@ async function main() {
|
|||||||
description: 'System prompt to instruct AI agents to build production-ready Next.js 16 App Router code with Server Actions and Prisma.',
|
description: 'System prompt to instruct AI agents to build production-ready Next.js 16 App Router code with Server Actions and Prisma.',
|
||||||
content: `You are a Senior Next.js 16 Architect. Always use TypeScript strict mode, App Router, proxy.ts for middleware, Server Actions with Zod validation, and Prisma ORM. Never write client components unless interactivity (onClick, useState) is required.`,
|
content: `You are a Senior Next.js 16 Architect. Always use TypeScript strict mode, App Router, proxy.ts for middleware, Server Actions with Zod validation, and Prisma ORM. Never write client components unless interactivity (onClick, useState) is required.`,
|
||||||
tags: ['Next.js', 'System Prompt', 'AI Architecture'],
|
tags: ['Next.js', 'System Prompt', 'AI Architecture'],
|
||||||
|
isOpen: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -263,6 +258,7 @@ async function main() {
|
|||||||
description: 'Instructs AI to design modern dark-mode interfaces with Tailwind CSS v4, subtle glows, and micro-animations.',
|
description: 'Instructs AI to design modern dark-mode interfaces with Tailwind CSS v4, subtle glows, and micro-animations.',
|
||||||
content: `Act as a Lead UI/UX Engineer specializing in sleek dark mode interfaces. Use HSL/OKLCH color palettes, slate-950 backgrounds, red-500/10 glows, rounded-2xl containers, and Framer Motion micro-interactions. Avoid generic colors or white backgrounds.`,
|
content: `Act as a Lead UI/UX Engineer specializing in sleek dark mode interfaces. Use HSL/OKLCH color palettes, slate-950 backgrounds, red-500/10 glows, rounded-2xl containers, and Framer Motion micro-interactions. Avoid generic colors or white backgrounds.`,
|
||||||
tags: ['UI/UX', 'Tailwind CSS', 'Design System'],
|
tags: ['UI/UX', 'Tailwind CSS', 'Design System'],
|
||||||
|
isOpen: false,
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -276,5 +272,4 @@ main()
|
|||||||
})
|
})
|
||||||
.finally(async () => {
|
.finally(async () => {
|
||||||
await db.$disconnect();
|
await db.$disconnect();
|
||||||
await pool.end();
|
|
||||||
});
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user