import { authPool } from '../db/authDb.js' interface InsertAuditLogInput { userId: string actionCd: string actionDtl?: string httpMethod?: string crudType?: string reqUrl?: string resStatus?: number resSize?: number ipAddr?: string userAgent?: string extra?: Record } interface AuditLogItem { logSn: number userId: string userName: string | null userAccount: string | null actionCd: string actionDtl: string | null httpMethod: string | null crudType: string | null reqUrl: string | null reqDtm: string resDtm: string | null resStatus: number | null resSize: number | null ipAddr: string | null userAgent: string | null extra: Record | null } interface AuditLogListResult { items: AuditLogItem[] total: number page: number size: number } export async function insertAuditLog(input: InsertAuditLogInput): Promise { await authPool.query( `INSERT INTO AUTH_AUDIT_LOG (USER_ID, ACTION_CD, ACTION_DTL, HTTP_METHOD, CRUD_TYPE, REQ_URL, RES_STATUS, RES_SIZE, IP_ADDR, USER_AGENT, EXTRA) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11)`, [ input.userId, input.actionCd, input.actionDtl || null, input.httpMethod || null, input.crudType || null, input.reqUrl || null, input.resStatus || null, input.resSize || null, input.ipAddr || null, input.userAgent || null, input.extra ? JSON.stringify(input.extra) : null, ] ) } export async function listAuditLogs(filters?: { page?: number size?: number userId?: string actionCd?: string from?: string to?: string }): Promise { const page = filters?.page || 1 const size = Math.min(filters?.size || 50, 200) const offset = (page - 1) * size let whereClause = 'WHERE 1=1' const params: (string | number)[] = [] let paramIdx = 1 if (filters?.userId) { whereClause += ` AND a.USER_ID = $${paramIdx++}` params.push(filters.userId) } if (filters?.actionCd) { whereClause += ` AND a.ACTION_CD = $${paramIdx++}` params.push(filters.actionCd) } if (filters?.from) { whereClause += ` AND a.REQ_DTM >= $${paramIdx++}` params.push(filters.from) } if (filters?.to) { whereClause += ` AND a.REQ_DTM <= $${paramIdx++}` params.push(filters.to) } const countResult = await authPool.query( `SELECT COUNT(*) as cnt FROM AUTH_AUDIT_LOG a ${whereClause}`, params ) const total = parseInt(countResult.rows[0].cnt, 10) const dataParams = [...params, size, offset] const result = await authPool.query( `SELECT a.LOG_SN, a.USER_ID, u.USER_NM, u.USER_ACNT, a.ACTION_CD, a.ACTION_DTL, a.HTTP_METHOD, a.CRUD_TYPE, a.REQ_URL, a.REQ_DTM, a.RES_DTM, a.RES_STATUS, a.RES_SIZE, a.IP_ADDR, a.USER_AGENT, a.EXTRA FROM AUTH_AUDIT_LOG a LEFT JOIN AUTH_USER u ON a.USER_ID = u.USER_ID ${whereClause} ORDER BY a.REQ_DTM DESC LIMIT $${paramIdx++} OFFSET $${paramIdx}`, dataParams ) const items: AuditLogItem[] = result.rows.map((row: Record) => ({ logSn: row.log_sn as number, userId: row.user_id as string, userName: row.user_nm as string | null, userAccount: row.user_acnt as string | null, actionCd: row.action_cd as string, actionDtl: row.action_dtl as string | null, httpMethod: row.http_method as string | null, crudType: row.crud_type as string | null, reqUrl: row.req_url as string | null, reqDtm: row.req_dtm as string, resDtm: row.res_dtm as string | null, resStatus: row.res_status as number | null, resSize: row.res_size as number | null, ipAddr: row.ip_addr as string | null, userAgent: row.user_agent as string | null, extra: row.extra as Record | null, })) return { items, total, page, size } }