Files
stream.graff.tech-new/server/src/controllers/session.ts
T

209 lines
6.1 KiB
TypeScript

import { Elysia, t } from "elysia";
import { authMiddleware } from "../middlewares/auth";
import { eq } from "drizzle-orm";
import db from "../db";
import { apps } from "../db/schema/apps";
import { serverSessionService } from "../services/serverSession";
export const sessionController = new Elysia({ prefix: "/sessions" })
// Все роуты требуют авторизации
.use(authMiddleware)
// GET /sessions - получить список сессий пользователя
.get("/", async ({ currentUser, query }) => {
const { status, mode } = query as {
status?: "starting" | "started" | "ending" | "ended";
mode?: "stream" | "local";
};
const sessions = await serverSessionService.findByUserId(currentUser.id, {
status,
mode,
});
return { sessions };
})
// GET /sessions/:id - получить информацию о конкретной сессии
.get("/:id", async ({ params, currentUser, status }) => {
const { id } = params;
const session = await serverSessionService.findByIdForUser(
id,
currentUser.id
);
if (!session) {
return status(404, "Session not found");
}
return { session };
})
// POST /sessions - создать новую сессию
.post(
"/",
async ({ body, currentUser, status }) => {
const { appId, mode, serverId } = body as {
appId: string;
mode: "stream" | "local";
serverId?: string;
};
// Проверить, что приложение существует
const app = await db.query.apps.findFirst({
where: eq(apps.id, appId),
});
if (!app) {
return status(404, "App not found");
}
// Проверить, что пользователь не имеет активных сессий этого приложения
const hasActive = await serverSessionService.hasActiveSession(
currentUser.id,
appId
);
if (hasActive) {
return status(409, "User already has an active session for this app");
}
// Создать сессию
try {
const newSession = await serverSessionService.create({
appId,
userId: currentUser.id,
mode,
serverId,
});
return { session: newSession };
} catch (error) {
if (error instanceof Error) {
return status(503, error.message);
}
return status(500, "Failed to create session");
}
},
{
body: t.Object({
appId: t.String({ format: "uuid" }),
mode: t.Union([t.Literal("stream"), t.Literal("local")]),
serverId: t.Optional(t.String({ format: "uuid" })),
}),
}
)
// PATCH /sessions/:id - обновить статус сессии
.patch(
"/:id",
async ({ params, body, currentUser, status }) => {
const { id } = params;
const {
status: sessionStatus,
appPid,
cirrusPid,
endAt,
} = body as {
status?: "starting" | "started" | "ending" | "ended";
appPid?: number;
cirrusPid?: number;
endAt?: string;
};
// Проверить, что сессия существует и принадлежит пользователю
const session = await serverSessionService.findByIdForUser(
id,
currentUser.id
);
if (!session) {
return status(404, "Session not found");
}
// Обновить сессию
const updatedSession = await serverSessionService.update(id, {
status: sessionStatus,
appPid,
cirrusPid,
endAt: endAt ? new Date(endAt) : undefined,
});
return { session: updatedSession };
},
{
body: t.Object({
status: t.Optional(
t.Union([
t.Literal("starting"),
t.Literal("started"),
t.Literal("ending"),
t.Literal("ended"),
])
),
appPid: t.Optional(t.Number()),
cirrusPid: t.Optional(t.Number()),
endAt: t.Optional(t.String({ format: "date-time" })),
}),
}
)
// DELETE /sessions/:id - удалить (завершить) сессию
.delete("/:id", async ({ params, currentUser, status }) => {
const { id } = params;
// Проверить, что сессия существует и принадлежит пользователю
const session = await serverSessionService.findByIdForUser(
id,
currentUser.id
);
if (!session) {
return status(404, "Session not found");
}
// Если сессия активна, изменить статус на "ending"
if (session.status === "started" || session.status === "starting") {
await serverSessionService.end(id);
return { message: "Session is ending" };
}
// Если сессия уже завершена или завершается
return { message: "Session already ended or ending" };
})
// POST /sessions/:id/extend - продлить сессию
.post(
"/:id/extend",
async ({ params, body, currentUser, status }) => {
const { id } = params;
const { minutes } = body as { minutes: number };
// Проверить, что сессия существует и принадлежит пользователю
const session = await serverSessionService.findByIdForUser(
id,
currentUser.id
);
if (!session) {
return status(404, "Session not found");
}
// Проверить, что сессия активна
if (session.status !== "started") {
return status(400, "Can only extend active sessions");
}
// Продлить сессию
try {
const updatedSession = await serverSessionService.extend(id, minutes);
return { session: updatedSession };
} catch (error) {
if (error instanceof Error) {
return status(400, error.message);
}
return status(500, "Failed to extend session");
}
},
{
body: t.Object({
minutes: t.Number({ minimum: 1, maximum: 120 }),
}),
}
);