fix: Resolve linting and TypeScript errors
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m19s
CI / lint-and-type-check (pull_request) Failing after 1m41s
CI / test (pull_request) Successful in 1m46s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m22s
CI / workflow-summary (pull_request) Successful in 1m18s
Some checks failed
CI / skip-ci-check (pull_request) Successful in 1m19s
CI / lint-and-type-check (pull_request) Failing after 1m41s
CI / test (pull_request) Successful in 1m46s
CI / build (pull_request) Failing after 1m46s
CI / secret-scanning (pull_request) Successful in 1m20s
CI / dependency-scan (pull_request) Successful in 1m25s
CI / sast-scan (pull_request) Successful in 2m22s
CI / workflow-summary (pull_request) Successful in 1m18s
- Replace 'any' types with proper Prisma types - Use PhotoUncheckedCreateInput for photo creation - Use Prisma.PhotoWhereInput for where clauses - Add proper type assertions for photo fields - Fix Photo import error by using Prisma namespace
This commit is contained in:
parent
9640627972
commit
90c5a9a4df
@ -2,6 +2,7 @@ import { NextRequest, NextResponse } from "next/server"
|
|||||||
import { auth } from "@/lib/auth"
|
import { auth } from "@/lib/auth"
|
||||||
import { prisma } from "@/lib/prisma"
|
import { prisma } from "@/lib/prisma"
|
||||||
import { sendNewPhotoEmail } from "@/lib/email"
|
import { sendNewPhotoEmail } from "@/lib/email"
|
||||||
|
import type { Prisma } from "@prisma/client"
|
||||||
|
|
||||||
// Legacy endpoint for URL-based uploads (kept for backward compatibility)
|
// Legacy endpoint for URL-based uploads (kept for backward compatibility)
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
@ -46,7 +47,7 @@ export async function POST(req: NextRequest) {
|
|||||||
answerName: answerName.trim(),
|
answerName: answerName.trim(),
|
||||||
points: pointsValue,
|
points: pointsValue,
|
||||||
maxAttempts: maxAttemptsValue,
|
maxAttempts: maxAttemptsValue,
|
||||||
} as any,
|
} as Prisma.PhotoUncheckedCreateInput,
|
||||||
include: {
|
include: {
|
||||||
uploader: {
|
uploader: {
|
||||||
select: {
|
select: {
|
||||||
|
|||||||
@ -6,7 +6,7 @@ import { writeFile } from "fs/promises"
|
|||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
import { existsSync, mkdirSync } from "fs"
|
import { existsSync, mkdirSync } from "fs"
|
||||||
import { createHash } from "crypto"
|
import { createHash } from "crypto"
|
||||||
import type { Photo } from "@prisma/client"
|
import type { Prisma } from "@prisma/client"
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -44,9 +44,9 @@ export async function POST(req: NextRequest) {
|
|||||||
mkdirSync(uploadsDir, { recursive: true })
|
mkdirSync(uploadsDir, { recursive: true })
|
||||||
}
|
}
|
||||||
|
|
||||||
type PhotoWithUploader = Photo & {
|
type PhotoWithUploader = Prisma.PhotoGetPayload<{
|
||||||
uploader: { name: string }
|
include: { uploader: { select: { name: true } } }
|
||||||
}
|
}>
|
||||||
|
|
||||||
const createdPhotos: PhotoWithUploader[] = []
|
const createdPhotos: PhotoWithUploader[] = []
|
||||||
|
|
||||||
@ -106,7 +106,7 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
// Check for duplicate file
|
// Check for duplicate file
|
||||||
const existingPhoto = await prisma.photo.findFirst({
|
const existingPhoto = await prisma.photo.findFirst({
|
||||||
where: { fileHash } as any,
|
where: { fileHash } as Prisma.PhotoWhereInput,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (existingPhoto) {
|
if (existingPhoto) {
|
||||||
@ -158,7 +158,7 @@ export async function POST(req: NextRequest) {
|
|||||||
penaltyEnabled: penaltyEnabled,
|
penaltyEnabled: penaltyEnabled,
|
||||||
penaltyPoints: penaltyPointsValue,
|
penaltyPoints: penaltyPointsValue,
|
||||||
maxAttempts: maxAttemptsValue,
|
maxAttempts: maxAttemptsValue,
|
||||||
} as any,
|
} as Prisma.PhotoUncheckedCreateInput,
|
||||||
include: {
|
include: {
|
||||||
uploader: {
|
uploader: {
|
||||||
select: {
|
select: {
|
||||||
@ -168,7 +168,7 @@ export async function POST(req: NextRequest) {
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
createdPhotos.push(photo as PhotoWithUploader)
|
createdPhotos.push(photo)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send emails to all other users for all photos
|
// Send emails to all other users for all photos
|
||||||
|
|||||||
@ -6,6 +6,7 @@ import { writeFile } from "fs/promises"
|
|||||||
import { join } from "path"
|
import { join } from "path"
|
||||||
import { existsSync, mkdirSync } from "fs"
|
import { existsSync, mkdirSync } from "fs"
|
||||||
import { createHash } from "crypto"
|
import { createHash } from "crypto"
|
||||||
|
import type { Prisma } from "@prisma/client"
|
||||||
|
|
||||||
export async function POST(req: NextRequest) {
|
export async function POST(req: NextRequest) {
|
||||||
try {
|
try {
|
||||||
@ -62,7 +63,7 @@ export async function POST(req: NextRequest) {
|
|||||||
|
|
||||||
// Check for duplicate file
|
// Check for duplicate file
|
||||||
const existingPhoto = await prisma.photo.findFirst({
|
const existingPhoto = await prisma.photo.findFirst({
|
||||||
where: { fileHash } as any,
|
where: { fileHash } as Prisma.PhotoWhereInput,
|
||||||
})
|
})
|
||||||
|
|
||||||
if (existingPhoto) {
|
if (existingPhoto) {
|
||||||
@ -122,7 +123,7 @@ export async function POST(req: NextRequest) {
|
|||||||
answerName: answerName.trim(),
|
answerName: answerName.trim(),
|
||||||
points: pointsValue,
|
points: pointsValue,
|
||||||
maxAttempts: maxAttemptsValue,
|
maxAttempts: maxAttemptsValue,
|
||||||
} as any,
|
} as Prisma.PhotoUncheckedCreateInput,
|
||||||
include: {
|
include: {
|
||||||
uploader: {
|
uploader: {
|
||||||
select: {
|
select: {
|
||||||
|
|||||||
@ -49,10 +49,17 @@ export default async function PhotoPage({ params }: { params: Promise<{ id: stri
|
|||||||
const hasCorrectGuess = userGuess?.correct || false
|
const hasCorrectGuess = userGuess?.correct || false
|
||||||
const isOwner = photo.uploaderId === session.user.id
|
const isOwner = photo.uploaderId === session.user.id
|
||||||
|
|
||||||
|
// Type assertion for new fields (penaltyEnabled, penaltyPoints, maxAttempts)
|
||||||
|
type PhotoWithNewFields = typeof photo & {
|
||||||
|
penaltyEnabled: boolean
|
||||||
|
penaltyPoints: number
|
||||||
|
maxAttempts: number | null
|
||||||
|
}
|
||||||
|
const photoWithFields = photo as PhotoWithNewFields
|
||||||
|
|
||||||
// Calculate remaining attempts
|
// Calculate remaining attempts
|
||||||
const photoWithMaxAttempts = photo as typeof photo & { maxAttempts: number | null | undefined }
|
|
||||||
const userGuessCount = photo.guesses.length
|
const userGuessCount = photo.guesses.length
|
||||||
const maxAttempts = photoWithMaxAttempts.maxAttempts ?? null
|
const maxAttempts = photoWithFields.maxAttempts ?? null
|
||||||
const remainingAttempts = maxAttempts !== null && maxAttempts > 0
|
const remainingAttempts = maxAttempts !== null && maxAttempts > 0
|
||||||
? Math.max(0, maxAttempts - userGuessCount)
|
? Math.max(0, maxAttempts - userGuessCount)
|
||||||
: null
|
: null
|
||||||
@ -77,9 +84,9 @@ export default async function PhotoPage({ params }: { params: Promise<{ id: stri
|
|||||||
<span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-purple-100 text-purple-800">
|
<span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-purple-100 text-purple-800">
|
||||||
+{photo.points} {photo.points === 1 ? "point" : "points"} if correct
|
+{photo.points} {photo.points === 1 ? "point" : "points"} if correct
|
||||||
</span>
|
</span>
|
||||||
{(photo as any).penaltyEnabled && (photo as any).penaltyPoints > 0 && (
|
{photoWithFields.penaltyEnabled && photoWithFields.penaltyPoints > 0 && (
|
||||||
<span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
|
<span className="inline-flex items-center px-3 py-1 rounded-full text-sm font-medium bg-red-100 text-red-800">
|
||||||
-{(photo as any).penaltyPoints} {(photo as any).penaltyPoints === 1 ? "point" : "points"} if wrong
|
-{photoWithFields.penaltyPoints} {photoWithFields.penaltyPoints === 1 ? "point" : "points"} if wrong
|
||||||
</span>
|
</span>
|
||||||
)}
|
)}
|
||||||
{maxAttempts !== null && maxAttempts > 0 && (
|
{maxAttempts !== null && maxAttempts > 0 && (
|
||||||
@ -117,9 +124,9 @@ export default async function PhotoPage({ params }: { params: Promise<{ id: stri
|
|||||||
<p className="text-sm text-red-700 mt-1">
|
<p className="text-sm text-red-700 mt-1">
|
||||||
Your last guess: <strong>{userGuess.guessText}</strong>
|
Your last guess: <strong>{userGuess.guessText}</strong>
|
||||||
</p>
|
</p>
|
||||||
{(photo as any).penaltyEnabled && (photo as any).penaltyPoints > 0 && (
|
{photoWithFields.penaltyEnabled && photoWithFields.penaltyPoints > 0 && (
|
||||||
<p className="text-sm text-red-700 mt-1">
|
<p className="text-sm text-red-700 mt-1">
|
||||||
You lost <strong>{(photo as any).penaltyPoints} {(photo as any).penaltyPoints === 1 ? "point" : "points"}</strong> for this wrong guess.
|
You lost <strong>{photoWithFields.penaltyPoints} {photoWithFields.penaltyPoints === 1 ? "point" : "points"}</strong> for this wrong guess.
|
||||||
</p>
|
</p>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user