import { Context, Effect, Layer } from "effect"; import { AuthService } from "../services/AuthService.js"; import { AuthError, AuthResponse, DatabaseError, LoginRequest, RegisterRequest, User, ValidationError, } from "../../../shared/types.js"; export interface RegisterResult { user: { id: string; username: string; email: string; emailVerified: boolean; }; } export interface LoginResult extends AuthResponse {} export interface MeResult { user: { id: string; username: string; email: string; emailVerified: boolean; createdAt: number; lastLoginAt: number | null; }; } export class AuthController extends Context.Tag("AuthController")< AuthController, { readonly register: ( data: RegisterRequest, ipAddress?: string | null, userAgent?: string | null ) => Effect.Effect; readonly login: ( data: LoginRequest, ipAddress?: string | null, userAgent?: string | null ) => Effect.Effect; readonly logout: ( sessionId: string, userId: string ) => Effect.Effect; readonly me: (user: User) => Effect.Effect; } >() { static Live = Layer.effect( this, Effect.gen(function* () { const authService = yield* AuthService; const register = ( data: RegisterRequest, ipAddress?: string | null, userAgent?: string | null ): Effect.Effect => Effect.gen(function* () { const user = yield* authService.register( data.username, data.email, data.password, ipAddress, userAgent ); return { user: { id: user.id, username: user.username, email: user.email, emailVerified: user.emailVerified, }, }; }); const login = ( data: LoginRequest, ipAddress?: string | null, userAgent?: string | null ): Effect.Effect => Effect.gen(function* () { const result = yield* authService.login( data.email, data.password, ipAddress, userAgent ); return { user: { id: result.user.id, username: result.user.username, email: result.user.email, emailVerified: result.user.emailVerified, }, token: result.token, }; }); const logout = ( sessionId: string, userId: string ): Effect.Effect => authService.logout(sessionId, userId); const me = (user: User): Effect.Effect => Effect.succeed({ user: { id: user.id, username: user.username, email: user.email, emailVerified: user.emailVerified, createdAt: user.createdAt, lastLoginAt: user.lastLoginAt, }, }); return { register, login, logout, me }; }) ); }