feat: How to create a session

This commit is contained in:
Wanjohi
2025-11-04 00:09:31 +03:00
parent 6947230a1d
commit 86959f93d9
4 changed files with 104 additions and 27 deletions

Binary file not shown.

View File

@@ -1,5 +1,7 @@
import { z } from "zod/v4"; import { z } from "zod/v4";
import { fn } from "../utils/fn.js"; import { fn } from "../utils/fn.js";
import { Identifier } from "../id.js";
import { and, eq, isNull } from "drizzle-orm";
import { sessionTable } from "./session.sql.js"; import { sessionTable } from "./session.sql.js";
import { import {
MachinePresetName, MachinePresetName,
@@ -12,6 +14,8 @@ import {
type Session as SessionInterface, type Session as SessionInterface,
type Config as SessionConfig, type Config as SessionConfig,
} from "./types.js"; } from "./types.js";
import { Actor } from "../actor.js";
import { Database } from "../drizzle/index.js";
// Re-export all types and schemas from types.ts // Re-export all types and schemas from types.ts
export { export {
@@ -49,10 +53,44 @@ export namespace Session {
run: (ctx: any) => Promise<any>; run: (ctx: any) => Promise<any>;
}; };
export const list = fn(z.void(), () => { export const create = fn(Info.partial({ id: true }), (input) =>
// Placeholder implementation Database.transaction(async (tx) => {
const id = Identifier.descending("session", input.id); // Placeholder for Identifier.ascending
await tx
.insert(sessionTable)
.values({
id,
ownerID: Actor.userID(),
...input,
})
.onConflictDoUpdate({
target: sessionTable.id,
set: {
timeDeleted: null,
},
}); });
return id;
}),
);
export const list = fn(z.void(), () =>
Database.use((tx) =>
tx
.select()
.from(sessionTable)
.where(
and(
eq(sessionTable.ownerID, Actor.userID()),
isNull(sessionTable.timeDeleted),
),
)
.limit(100)
.then((rows) => rows.map(serialize)),
),
);
export function serialize( export function serialize(
input: typeof sessionTable.$inferSelect, input: typeof sessionTable.$inferSelect,
): z.infer<typeof SessionInfo> { ): z.infer<typeof SessionInfo> {

View File

@@ -1,4 +1,4 @@
import { id, timestamps } from "../drizzle/types.js"; import { id, timestamps, ulid } from "../drizzle/types.js";
import { import {
pgTable, pgTable,
varchar, varchar,
@@ -20,11 +20,17 @@ import {
AudioRateControl, AudioRateControl,
VideoBitDepth, VideoBitDepth,
} from "./types.js"; } from "./types.js";
import { userTable } from "../user/user.sql.js";
export const sessionTable = pgTable("sessions", { export const sessionTable = pgTable("sessions", {
...id, ...id,
...timestamps, ...timestamps,
description: text("description"), description: text("description"),
ownerID: ulid("owner_id")
.references(() => userTable.id, {
onDelete: "cascade",
})
.notNull(),
retry: jsonb("retry").$type<RetryOptions>(), retry: jsonb("retry").$type<RetryOptions>(),
queue: jsonb("queue").$type<Queue>(), queue: jsonb("queue").$type<Queue>(),
machine: varchar("machine", { length: 200 }).$type<MachinePresetName>(), machine: varchar("machine", { length: 200 }).$type<MachinePresetName>(),

View File

@@ -2,16 +2,18 @@ import { Hono } from "hono";
import { notPublic } from "../utils/auth.js"; import { notPublic } from "../utils/auth.js";
import { ErrorResponses } from "../utils/error.js"; import { ErrorResponses } from "../utils/error.js";
import { Session } from "@nestri/core/session/index"; import { Session } from "@nestri/core/session/index";
import { describeRoute, resolver } from "hono-openapi"; import { describeRoute, resolver, validator } from "hono-openapi";
export namespace SessionRoute { export namespace SessionRoute {
export const route = new Hono().use(notPublic).get( export const route = new Hono()
.use(notPublic)
.get(
"/", "/",
describeRoute({ describeRoute({
tags: ["Session"], tags: ["Session"],
operationId: "session.list", operationId: "session.list",
summary: "List all active sessions", summary: "List all sessions",
description: "List all the current user's active sessions", description: "List all the current user's sessions",
responses: { responses: {
200: { 200: {
description: "List of sessions", description: "List of sessions",
@@ -30,5 +32,36 @@ export namespace SessionRoute {
const sessions = await Session.list(); const sessions = await Session.list();
return c.json(sessions); return c.json(sessions);
}, },
)
.post(
"/",
describeRoute({
tags: ["Session"],
operationId: "session.create",
summary: "Create a new session",
description: "Create a new session for the current user",
responses: {
201: {
description: "The created session",
content: {
"application/json": {
schema: resolver(Session.Info),
},
},
},
400: ErrorResponses[400],
401: ErrorResponses[401],
403: ErrorResponses[403],
429: ErrorResponses[429],
},
}),
validator("json", Session.Info.omit({ id: true })),
async (c) => {
const sessionData = c.req.valid("json");
const id = await Session.create(sessionData);
return c.json({ ...sessionData, id }, 201);
},
); );
} }