alepha
Version:
Easy-to-use modern TypeScript framework for building many kind of applications.
108 lines (93 loc) • 3 kB
text/typescript
import { $inject } from "alepha";
import { $logger } from "alepha/logger";
import type { Page } from "alepha/orm";
import type { SessionEntity } from "../entities/sessions.ts";
import { users } from "../entities/users.ts";
import { RealmProvider } from "../providers/RealmProvider.ts";
import type { SessionQuery } from "../schemas/sessionQuerySchema.ts";
/**
* Relation map embedding a slim user summary on every session row, so the
* admin UI can render `user.email`/`user.username` instead of a bare UUID.
* Left-join (default) so sessions whose owner was deleted still come back
* with `user: undefined`.
*/
const withUser = {
user: {
join: users,
on: ["userId", users.cols.id] as ["userId", { name: string }],
},
};
export class SessionCrudService {
protected readonly log = $logger();
protected readonly realmProvider = $inject(RealmProvider);
public sessions(userRealmName?: string) {
return this.realmProvider.sessionRepository(userRealmName);
}
/**
* Find sessions with pagination and filtering.
*/
public async findSessions(
q: SessionQuery = {},
userRealmName?: string,
): Promise<Page<SessionEntity>> {
this.log.trace("Finding sessions", { query: q, userRealmName });
q.sort ??= "-createdAt";
const where = this.sessions(userRealmName).createQueryWhere();
if (q.userId) {
where.userId = { eq: q.userId };
}
const result = await this.sessions(userRealmName).paginate(
q,
{ where, with: withUser },
{ count: true },
);
this.log.debug("Sessions found", {
count: result.content.length,
total: result.page.totalElements,
});
return result;
}
/**
* Get a session by ID.
*/
public async getSessionById(
id: string,
userRealmName?: string,
): Promise<SessionEntity> {
this.log.trace("Getting session by ID", { id, userRealmName });
const session = await this.sessions(userRealmName).getOne({
where: { id: { eq: id } },
with: withUser,
});
this.log.debug("Session retrieved", { id, userId: session.userId });
return session;
}
/**
* Delete a session by ID.
*/
public async deleteSession(
id: string,
userRealmName?: string,
): Promise<void> {
this.log.trace("Deleting session", { id, userRealmName });
// Verify session exists
await this.getSessionById(id, userRealmName);
await this.sessions(userRealmName).deleteById(id);
this.log.info("Session deleted", { id });
}
/**
* Delete many sessions by ID in one repository call.
*/
public async deleteSessions(
ids: string[],
userRealmName?: string,
): Promise<string[]> {
if (ids.length === 0) return [];
this.log.trace("Deleting sessions", { count: ids.length, userRealmName });
const deleted = await this.sessions(userRealmName).deleteMany({
id: { inArray: ids },
});
this.log.info("Sessions deleted", { count: deleted.length });
return deleted.map(String);
}
}