+61
-17
@@ -38,6 +38,8 @@ const createShotSchema = z.object({
|
||||
dueDate: z.string().optional(),
|
||||
thumbnailUrl: z.string().url().optional(),
|
||||
shotGroupName: z.string().max(100).optional(),
|
||||
// Optional explicit shot code — bypasses auto-generation
|
||||
shotCode: z.string().max(100).optional(),
|
||||
});
|
||||
|
||||
// ── POST /api/ext/shots ───────────────────────────────────────────────────────
|
||||
@@ -109,26 +111,46 @@ export async function POST(req: NextRequest) {
|
||||
);
|
||||
}
|
||||
|
||||
// Auto-increment shot number within scene (+ episode for episodic)
|
||||
const scopeWhere = {
|
||||
projectId: parsed.projectId,
|
||||
scene,
|
||||
...(project.projectType === "EPISODIC" ? { episode } : {}),
|
||||
};
|
||||
// Use explicit shotCode if provided, otherwise auto-increment
|
||||
let shotCode: string;
|
||||
let shotNumber: number;
|
||||
|
||||
const maxShot = await db.shot.findFirst({
|
||||
where: scopeWhere,
|
||||
orderBy: { shotNumber: "desc" },
|
||||
select: { shotNumber: true },
|
||||
});
|
||||
if (parsed.shotCode) {
|
||||
// Check uniqueness manually since we bypass auto-generation
|
||||
const existing = await db.shot.findUnique({
|
||||
where: { projectId_shotCode: { projectId: parsed.projectId, shotCode: parsed.shotCode } },
|
||||
select: { id: true },
|
||||
});
|
||||
if (existing) {
|
||||
return NextResponse.json(
|
||||
{ error: "A shot with that code already exists in this project", shotCode: parsed.shotCode },
|
||||
{ status: 409 }
|
||||
);
|
||||
}
|
||||
shotCode = parsed.shotCode;
|
||||
shotNumber = 0;
|
||||
} else {
|
||||
// Auto-increment shot number within scene (+ episode for episodic)
|
||||
const scopeWhere = {
|
||||
projectId: parsed.projectId,
|
||||
scene,
|
||||
...(project.projectType === "EPISODIC" ? { episode } : {}),
|
||||
};
|
||||
|
||||
const shotNumber = (maxShot?.shotNumber ?? 0) + 10;
|
||||
const paddedNumber = shotNumber.toString().padStart(4, "0");
|
||||
const maxShot = await db.shot.findFirst({
|
||||
where: scopeWhere,
|
||||
orderBy: { shotNumber: "desc" },
|
||||
select: { shotNumber: true },
|
||||
});
|
||||
|
||||
const shotCode =
|
||||
project.projectType === "EPISODIC" && episode
|
||||
? `${project.showId}_${episode}_${scene}_${paddedNumber}`
|
||||
: `${project.showId}_${scene}_${paddedNumber}`;
|
||||
shotNumber = (maxShot?.shotNumber ?? 0) + 10;
|
||||
const paddedNumber = shotNumber.toString().padStart(4, "0");
|
||||
|
||||
shotCode =
|
||||
project.projectType === "EPISODIC" && episode
|
||||
? `${project.showId}_${episode}_${scene}_${paddedNumber}`
|
||||
: `${project.showId}_${scene}_${paddedNumber}`;
|
||||
}
|
||||
|
||||
// Upload thumbnail if provided as a file
|
||||
let thumbnailUrl = parsed.thumbnailUrl;
|
||||
@@ -214,3 +236,25 @@ export async function POST(req: NextRequest) {
|
||||
return NextResponse.json({ error: "Internal server error" }, { status: 500 });
|
||||
}
|
||||
}
|
||||
|
||||
// ── GET /api/ext/shots?projectId=... ─────────────────────────────────────────
|
||||
|
||||
export async function GET(req: NextRequest) {
|
||||
if (!isAuthorized(req)) {
|
||||
return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
}
|
||||
|
||||
const { searchParams } = new URL(req.url);
|
||||
const projectId = searchParams.get("projectId");
|
||||
if (!projectId) {
|
||||
return NextResponse.json({ error: "projectId is required" }, { status: 400 });
|
||||
}
|
||||
|
||||
const shots = await db.shot.findMany({
|
||||
where: { projectId },
|
||||
orderBy: { createdAt: "asc" },
|
||||
select: { id: true, shotCode: true, scene: true, episode: true, status: true },
|
||||
});
|
||||
|
||||
return NextResponse.json({ shots });
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user