139 lines
3.8 KiB
TypeScript
139 lines
3.8 KiB
TypeScript
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<string, unknown>
|
|
}
|
|
|
|
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<string, unknown> | null
|
|
}
|
|
|
|
interface AuditLogListResult {
|
|
items: AuditLogItem[]
|
|
total: number
|
|
page: number
|
|
size: number
|
|
}
|
|
|
|
export async function insertAuditLog(input: InsertAuditLogInput): Promise<void> {
|
|
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<AuditLogListResult> {
|
|
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<string, unknown>) => ({
|
|
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<string, unknown> | null,
|
|
}))
|
|
|
|
return { items, total, page, size }
|
|
}
|