update: packages,operations,lua (2 files)

This commit is contained in:
Richard Ward
2025-12-30 21:43:42 +00:00
parent 986352d07b
commit bfce6f6f84
2 changed files with 479 additions and 0 deletions

View File

@@ -0,0 +1,238 @@
-- audit_log/seed/scripts/db/operations.lua
-- DBAL operations for AuditLog entity
-- @module audit_log.db.operations
local M = {}
---@class AuditLogCreateParams
---@field tenantId string
---@field userId string|nil
---@field username string|nil
---@field action string
---@field entity string
---@field entityId string|nil
---@field oldValue table|nil
---@field newValue table|nil
---@field ipAddress string|nil
---@field userAgent string|nil
---@field details table|nil
---Create a new audit log entry
---@param dbal table DBAL client instance
---@param params AuditLogCreateParams
---@return table Created audit log record
function M.create(dbal, params)
local json = require('json')
return dbal:create('AuditLog', {
tenantId = params.tenantId,
userId = params.userId,
username = params.username,
action = params.action,
entity = params.entity,
entityId = params.entityId,
oldValue = params.oldValue and json.encode(params.oldValue) or nil,
newValue = params.newValue and json.encode(params.newValue) or nil,
ipAddress = params.ipAddress,
userAgent = params.userAgent,
details = params.details and json.encode(params.details) or nil,
timestamp = os.time() * 1000,
})
end
---@class AuditLogListParams
---@field tenantId string
---@field userId string|nil
---@field action string|nil
---@field entity string|nil
---@field entityId string|nil
---@field startTime number|nil Unix timestamp
---@field endTime number|nil Unix timestamp
---@field take number|nil
---@field skip number|nil
---List audit logs with filters
---@param dbal table DBAL client instance
---@param params AuditLogListParams
---@return table[] List of audit log records
function M.list(dbal, params)
local where = { tenantId = params.tenantId }
if params.userId then
where.userId = params.userId
end
if params.action then
where.action = params.action
end
if params.entity then
where.entity = params.entity
end
if params.entityId then
where.entityId = params.entityId
end
-- Time range filtering would need DBAL support for comparison operators
-- For now, return all and filter in Lua
local result = dbal:list('AuditLog', {
where = where,
orderBy = { timestamp = 'desc' },
take = params.take or 50,
skip = params.skip or 0,
})
-- Filter by time range if specified
if params.startTime or params.endTime then
local filtered = {}
for _, log in ipairs(result.items or {}) do
local ts = log.timestamp
local inRange = true
if params.startTime and ts < (params.startTime * 1000) then
inRange = false
end
if params.endTime and ts > (params.endTime * 1000) then
inRange = false
end
if inRange then
table.insert(filtered, log)
end
end
result.items = filtered
end
return result
end
---Get audit logs for a specific entity
---@param dbal table DBAL client instance
---@param tenantId string
---@param entity string Entity type
---@param entityId string Entity ID
---@return table[] Audit history for entity
function M.getEntityHistory(dbal, tenantId, entity, entityId)
return M.list(dbal, {
tenantId = tenantId,
entity = entity,
entityId = entityId,
take = 100,
})
end
---Get audit logs for a specific user
---@param dbal table DBAL client instance
---@param tenantId string
---@param userId string
---@param take number|nil
---@return table[] User's audit history
function M.getUserHistory(dbal, tenantId, userId, take)
return M.list(dbal, {
tenantId = tenantId,
userId = userId,
take = take or 50,
})
end
---Log a create action
---@param dbal table DBAL client instance
---@param tenantId string
---@param userId string
---@param entity string
---@param entityId string
---@param newValue table Created record
---@param context table|nil Additional context
function M.logCreate(dbal, tenantId, userId, entity, entityId, newValue, context)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
action = 'create',
entity = entity,
entityId = entityId,
newValue = newValue,
details = context,
})
end
---Log an update action
---@param dbal table DBAL client instance
---@param tenantId string
---@param userId string
---@param entity string
---@param entityId string
---@param oldValue table Previous state
---@param newValue table New state
---@param context table|nil Additional context
function M.logUpdate(dbal, tenantId, userId, entity, entityId, oldValue, newValue, context)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
action = 'update',
entity = entity,
entityId = entityId,
oldValue = oldValue,
newValue = newValue,
details = context,
})
end
---Log a delete action
---@param dbal table DBAL client instance
---@param tenantId string
---@param userId string
---@param entity string
---@param entityId string
---@param oldValue table Deleted record
---@param context table|nil Additional context
function M.logDelete(dbal, tenantId, userId, entity, entityId, oldValue, context)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
action = 'delete',
entity = entity,
entityId = entityId,
oldValue = oldValue,
details = context,
})
end
---Log a login action
---@param dbal table DBAL client instance
---@param tenantId string
---@param userId string
---@param username string
---@param ipAddress string|nil
---@param userAgent string|nil
function M.logLogin(dbal, tenantId, userId, username, ipAddress, userAgent)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
username = username,
action = 'login',
entity = 'User',
entityId = userId,
ipAddress = ipAddress,
userAgent = userAgent,
})
end
---Log a logout action
---@param dbal table DBAL client instance
---@param tenantId string
---@param userId string
---@param username string
function M.logLogout(dbal, tenantId, userId, username)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
username = username,
action = 'logout',
entity = 'User',
entityId = userId,
})
end
return M

View File

@@ -0,0 +1,241 @@
-- notification_center/seed/scripts/db/operations.lua
-- DBAL operations for Notification entity
-- @module notification_center.db.operations
local M = {}
---@class NotificationCreateParams
---@field tenantId string
---@field userId string
---@field type string info|warning|success|error|mention|reply|follow|like|system
---@field title string
---@field message string
---@field icon string|nil
---@field data table|nil
---@field expiresAt number|nil Unix timestamp
---Create a new notification
---@param dbal table DBAL client instance
---@param params NotificationCreateParams
---@return table Created notification
function M.create(dbal, params)
local json = require('json')
return dbal:create('Notification', {
tenantId = params.tenantId,
userId = params.userId,
type = params.type,
title = params.title,
message = params.message,
icon = params.icon,
read = false,
data = params.data and json.encode(params.data) or nil,
createdAt = os.time() * 1000,
expiresAt = params.expiresAt and (params.expiresAt * 1000) or nil,
})
end
---List notifications for a user
---@param dbal table DBAL client instance
---@param userId string
---@param unreadOnly boolean|nil Only return unread notifications
---@param take number|nil
---@param skip number|nil
---@return table List result with items and total
function M.list(dbal, userId, unreadOnly, take, skip)
local where = { userId = userId }
if unreadOnly then
where.read = false
end
return dbal:list('Notification', {
where = where,
orderBy = { createdAt = 'desc' },
take = take or 20,
skip = skip or 0,
})
end
---Get unread notification count
---@param dbal table DBAL client instance
---@param userId string
---@return number Unread count
function M.getUnreadCount(dbal, userId)
local result = M.list(dbal, userId, true, 1000, 0)
return result.total or #(result.items or {})
end
---Mark a notification as read
---@param dbal table DBAL client instance
---@param notificationId string
---@return table Updated notification
function M.markAsRead(dbal, notificationId)
return dbal:update('Notification', notificationId, {
read = true,
})
end
---Mark all notifications as read for a user
---@param dbal table DBAL client instance
---@param userId string
---@return number Number of notifications updated
function M.markAllAsRead(dbal, userId)
local unread = M.list(dbal, userId, true, 1000, 0)
local count = 0
for _, notification in ipairs(unread.items or {}) do
dbal:update('Notification', notification.id, { read = true })
count = count + 1
end
return count
end
---Delete a notification
---@param dbal table DBAL client instance
---@param notificationId string
---@return boolean Success
function M.delete(dbal, notificationId)
return dbal:delete('Notification', notificationId)
end
---Delete all read notifications for a user
---@param dbal table DBAL client instance
---@param userId string
---@return number Number deleted
function M.deleteRead(dbal, userId)
local result = dbal:list('Notification', {
where = { userId = userId, read = true },
take = 1000,
})
local count = 0
for _, notification in ipairs(result.items or {}) do
dbal:delete('Notification', notification.id)
count = count + 1
end
return count
end
---Delete expired notifications
---@param dbal table DBAL client instance
---@param tenantId string
---@return number Number deleted
function M.deleteExpired(dbal, tenantId)
local now = os.time() * 1000
local result = dbal:list('Notification', {
where = { tenantId = tenantId },
take = 1000,
})
local count = 0
for _, notification in ipairs(result.items or {}) do
if notification.expiresAt and notification.expiresAt < now then
dbal:delete('Notification', notification.id)
count = count + 1
end
end
return count
end
-- Convenience functions for creating typed notifications
---Send an info notification
---@param dbal table
---@param tenantId string
---@param userId string
---@param title string
---@param message string
---@param data table|nil
function M.sendInfo(dbal, tenantId, userId, title, message, data)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
type = 'info',
title = title,
message = message,
icon = 'Info',
data = data,
})
end
---Send a success notification
---@param dbal table
---@param tenantId string
---@param userId string
---@param title string
---@param message string
---@param data table|nil
function M.sendSuccess(dbal, tenantId, userId, title, message, data)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
type = 'success',
title = title,
message = message,
icon = 'CheckCircle',
data = data,
})
end
---Send a warning notification
---@param dbal table
---@param tenantId string
---@param userId string
---@param title string
---@param message string
---@param data table|nil
function M.sendWarning(dbal, tenantId, userId, title, message, data)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
type = 'warning',
title = title,
message = message,
icon = 'Warning',
data = data,
})
end
---Send an error notification
---@param dbal table
---@param tenantId string
---@param userId string
---@param title string
---@param message string
---@param data table|nil
function M.sendError(dbal, tenantId, userId, title, message, data)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
type = 'error',
title = title,
message = message,
icon = 'Error',
data = data,
})
end
---Send a mention notification
---@param dbal table
---@param tenantId string
---@param userId string
---@param mentionedBy string Username who mentioned
---@param context string Where they were mentioned
---@param link string|nil Link to the mention
function M.sendMention(dbal, tenantId, userId, mentionedBy, context, link)
return M.create(dbal, {
tenantId = tenantId,
userId = userId,
type = 'mention',
title = 'You were mentioned',
message = mentionedBy .. ' mentioned you in ' .. context,
icon = 'AlternateEmail',
data = { mentionedBy = mentionedBy, link = link },
})
end
return M