mappool API
This commit is contained in:
@@ -157,3 +157,56 @@ export const matchGameScore = pgTable(
|
|||||||
},
|
},
|
||||||
(t) => [index('idx_mgs_game').on(t.matchGameId)]
|
(t) => [index('idx_mgs_game').on(t.matchGameId)]
|
||||||
);
|
);
|
||||||
|
|
||||||
|
import { relations } from 'drizzle-orm';
|
||||||
|
|
||||||
|
// ── Relations ───────────────────────────────────────────────────────────
|
||||||
|
|
||||||
|
export const teamRelations = relations(team, ({ many }) => ({
|
||||||
|
members: many(teamMember)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const teamMemberRelations = relations(teamMember, ({ one }) => ({
|
||||||
|
team: one(team, { fields: [teamMember.teamId], references: [team.id] })
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const mappoolRelations = relations(mappool, ({ many }) => ({
|
||||||
|
slots: many(mappoolSlot)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const mappoolSlotRelations = relations(mappoolSlot, ({ one }) => ({
|
||||||
|
mappool: one(mappool, { fields: [mappoolSlot.mappoolId], references: [mappool.id] })
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const matchRelations = relations(match, ({ one, many }) => ({
|
||||||
|
mappool: one(mappool, { fields: [match.mappoolId], references: [mappool.id] }),
|
||||||
|
participants: many(matchParticipant),
|
||||||
|
games: many(matchGame)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const matchParticipantRelations = relations(matchParticipant, ({ one, many }) => ({
|
||||||
|
match: one(match, { fields: [matchParticipant.matchId], references: [match.id] }),
|
||||||
|
team: one(team, { fields: [matchParticipant.teamId], references: [team.id] }),
|
||||||
|
players: many(matchParticipantPlayer)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const matchParticipantPlayerRelations = relations(matchParticipantPlayer, ({ one }) => ({
|
||||||
|
participant: one(matchParticipant, {
|
||||||
|
fields: [matchParticipantPlayer.participantId],
|
||||||
|
references: [matchParticipant.id]
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const matchGameRelations = relations(matchGame, ({ one, many }) => ({
|
||||||
|
match: one(match, { fields: [matchGame.matchId], references: [match.id] }),
|
||||||
|
slot: one(mappoolSlot, { fields: [matchGame.mappoolSlotId], references: [mappoolSlot.id] }),
|
||||||
|
scores: many(matchGameScore)
|
||||||
|
}));
|
||||||
|
|
||||||
|
export const matchGameScoreRelations = relations(matchGameScore, ({ one }) => ({
|
||||||
|
game: one(matchGame, { fields: [matchGameScore.matchGameId], references: [matchGame.id] }),
|
||||||
|
player: one(matchParticipantPlayer, {
|
||||||
|
fields: [matchGameScore.playerId],
|
||||||
|
references: [matchParticipantPlayer.id]
|
||||||
|
})
|
||||||
|
}));
|
||||||
|
|||||||
33
src/routes/api/mappools/+server.ts
Normal file
33
src/routes/api/mappools/+server.ts
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
import { json, error } from '@sveltejs/kit';
|
||||||
|
import { db } from '$lib/server/db';
|
||||||
|
import { mappool } from '$lib/server/db/schema';
|
||||||
|
import type { RequestHandler } from './$types';
|
||||||
|
|
||||||
|
// List all mappools
|
||||||
|
export const GET: RequestHandler = async ({ locals }) => {
|
||||||
|
if (!locals.user) error(401, 'Not logged in');
|
||||||
|
|
||||||
|
const mappools = await db.query.mappool.findMany({
|
||||||
|
orderBy: (m, { desc }) => [desc(m.createdAt)]
|
||||||
|
});
|
||||||
|
|
||||||
|
return json(mappools);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Create a mappool
|
||||||
|
export const POST: RequestHandler = async ({ request, locals }) => {
|
||||||
|
if (!locals.user) error(401, 'Not logged in');
|
||||||
|
|
||||||
|
const { name } = await request.json();
|
||||||
|
if (!name?.trim()) error(400, 'Name is required');
|
||||||
|
|
||||||
|
const [created] = await db
|
||||||
|
.insert(mappool)
|
||||||
|
.values({
|
||||||
|
name: name.trim(),
|
||||||
|
createdBy: locals.user.id
|
||||||
|
})
|
||||||
|
.returning();
|
||||||
|
|
||||||
|
return json(created, { status: 201 });
|
||||||
|
};
|
||||||
31
src/routes/api/mappools/[id]/+server.ts
Normal file
31
src/routes/api/mappools/[id]/+server.ts
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
import { json, error } from '@sveltejs/kit';
|
||||||
|
import { db } from '$lib/server/db';
|
||||||
|
import { mappool, mappoolSlot } from '$lib/server/db/schema';
|
||||||
|
import { eq } from 'drizzle-orm';
|
||||||
|
import type { RequestHandler } from './$types';
|
||||||
|
|
||||||
|
// Get a mappool with its slots
|
||||||
|
export const GET: RequestHandler = async ({ params, locals }) => {
|
||||||
|
if (!locals.user) error(401, 'Not logged in');
|
||||||
|
|
||||||
|
const pool = await db.query.mappool.findFirst({
|
||||||
|
where: eq(mappool.id, params.id)
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!pool) error(404, 'Mappool not found');
|
||||||
|
|
||||||
|
const slots = await db.query.mappoolSlot.findMany({
|
||||||
|
where: eq(mappoolSlot.mappoolId, params.id),
|
||||||
|
orderBy: (s, { asc }) => [asc(s.category), asc(s.orderInCategory)]
|
||||||
|
});
|
||||||
|
|
||||||
|
return json({ ...pool, slots });
|
||||||
|
};
|
||||||
|
|
||||||
|
// Delete a mappool
|
||||||
|
export const DELETE: RequestHandler = async ({ params, locals }) => {
|
||||||
|
if (!locals.user) error(401, 'Not logged in');
|
||||||
|
|
||||||
|
await db.delete(mappool).where(eq(mappool.id, params.id));
|
||||||
|
return json({ ok: true });
|
||||||
|
};
|
||||||
38
src/routes/api/mappools/[id]/slots/+server.ts
Normal file
38
src/routes/api/mappools/[id]/slots/+server.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
import { json, error } from '@sveltejs/kit';
|
||||||
|
import { db } from '$lib/server/db';
|
||||||
|
import { mappoolSlot } from '$lib/server/db/schema';
|
||||||
|
import { eq, and } from 'drizzle-orm';
|
||||||
|
import { getBeatmap } from '$lib/server/osu/api';
|
||||||
|
import type { RequestHandler } from './$types';
|
||||||
|
|
||||||
|
// Add a slot to a mappool
|
||||||
|
export const POST: RequestHandler = async ({ params, request, locals }) => {
|
||||||
|
if (!locals.user) error(401, 'Not logged in');
|
||||||
|
|
||||||
|
const { beatmapId, category, mods } = await request.json();
|
||||||
|
|
||||||
|
if (!beatmapId || !category) {
|
||||||
|
error(400, 'beatmapId and category are required');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Count existing slots in this category to auto-increment order
|
||||||
|
const existing = await db.query.mappoolSlot.findMany({
|
||||||
|
where: and(
|
||||||
|
eq(mappoolSlot.mappoolId, params.id),
|
||||||
|
eq(mappoolSlot.category, category.toUpperCase())
|
||||||
|
)
|
||||||
|
});
|
||||||
|
|
||||||
|
const [created] = await db
|
||||||
|
.insert(mappoolSlot)
|
||||||
|
.values({
|
||||||
|
mappoolId: params.id,
|
||||||
|
beatmapId: String(beatmapId),
|
||||||
|
category: category.toUpperCase(),
|
||||||
|
orderInCategory: existing.length + 1,
|
||||||
|
mods: mods ?? []
|
||||||
|
})
|
||||||
|
.returning();
|
||||||
|
|
||||||
|
return json(created, { status: 201 });
|
||||||
|
};
|
||||||
12
src/routes/api/mappools/[id]/slots/[slotId]/+server.ts
Normal file
12
src/routes/api/mappools/[id]/slots/[slotId]/+server.ts
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
import { json, error } from '@sveltejs/kit';
|
||||||
|
import { db } from '$lib/server/db';
|
||||||
|
import { mappoolSlot } from '$lib/server/db/schema';
|
||||||
|
import { eq } from 'drizzle-orm';
|
||||||
|
import type { RequestHandler } from './$types';
|
||||||
|
|
||||||
|
export const DELETE: RequestHandler = async ({ params, locals }) => {
|
||||||
|
if (!locals.user) error(401, 'Not logged in');
|
||||||
|
|
||||||
|
await db.delete(mappoolSlot).where(eq(mappoolSlot.id, params.slotId));
|
||||||
|
return json({ ok: true });
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user