Consolidated round management, AI filtering enhancements, MinIO storage restructure
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
All checks were successful
Build and Push Docker Image / build (push) Successful in 7m45s
- Fix STAGE_ACTIVE bug in assignment router (now ROUND_ACTIVE)
- Add evaluation form CRUD (getForm + upsertForm endpoints)
- Add advanceProjects mutation for manual project advancement
- Rewrite round detail page: 7-tab consolidated interface
- Add filtering rules UI with full CRUD (field-based, document check, AI screening)
- Add pageCount field to ProjectFile for document page limit filtering
- Enhance AI filtering: per-file page limits, category/region-aware guidelines
- Restructure MinIO paths: {ProjectName}/{RoundName}/{timestamp}-{file}
- Update dashboard and pool page links from /admin/competitions to /admin/rounds
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -149,20 +149,27 @@ export const fileRouter = router({
|
||||
})
|
||||
}
|
||||
|
||||
let isLate = false
|
||||
if (input.roundId) {
|
||||
const stage = await ctx.prisma.round.findUnique({
|
||||
where: { id: input.roundId },
|
||||
select: { windowCloseAt: true },
|
||||
})
|
||||
// Fetch project title and optional round name for storage path
|
||||
const [project, roundInfo] = await Promise.all([
|
||||
ctx.prisma.project.findUniqueOrThrow({
|
||||
where: { id: input.projectId },
|
||||
select: { title: true },
|
||||
}),
|
||||
input.roundId
|
||||
? ctx.prisma.round.findUnique({
|
||||
where: { id: input.roundId },
|
||||
select: { name: true, windowCloseAt: true },
|
||||
})
|
||||
: null,
|
||||
])
|
||||
|
||||
if (stage?.windowCloseAt) {
|
||||
isLate = new Date() > stage.windowCloseAt
|
||||
}
|
||||
let isLate = false
|
||||
if (roundInfo?.windowCloseAt) {
|
||||
isLate = new Date() > roundInfo.windowCloseAt
|
||||
}
|
||||
|
||||
const bucket = BUCKET_NAME
|
||||
const objectKey = generateObjectKey(input.projectId, input.fileName)
|
||||
const objectKey = generateObjectKey(project.title, input.fileName, roundInfo?.name)
|
||||
|
||||
const uploadUrl = await getPresignedUrl(bucket, objectKey, 'PUT', 3600) // 1 hour
|
||||
|
||||
@@ -1122,8 +1129,20 @@ export const fileRouter = router({
|
||||
else if (input.mimeType.includes('presentation') || input.mimeType.includes('powerpoint'))
|
||||
fileType = 'PRESENTATION'
|
||||
|
||||
// Fetch project title and window name for storage path
|
||||
const [project, submissionWindow] = await Promise.all([
|
||||
ctx.prisma.project.findUniqueOrThrow({
|
||||
where: { id: input.projectId },
|
||||
select: { title: true },
|
||||
}),
|
||||
ctx.prisma.submissionWindow.findUniqueOrThrow({
|
||||
where: { id: input.submissionWindowId },
|
||||
select: { name: true },
|
||||
}),
|
||||
])
|
||||
|
||||
const bucket = BUCKET_NAME
|
||||
const objectKey = generateObjectKey(input.projectId, input.fileName)
|
||||
const objectKey = generateObjectKey(project.title, input.fileName, submissionWindow.name)
|
||||
const uploadUrl = await getPresignedUrl(bucket, objectKey, 'PUT', 3600)
|
||||
|
||||
// Remove any existing file for this project+requirement combo (replace)
|
||||
|
||||
Reference in New Issue
Block a user