update: studio,packages,operations (1 files)

This commit is contained in:
Richard Ward
2025-12-30 21:59:59 +00:00
parent b807de3f34
commit 93af08b8f1

View File

@@ -0,0 +1,367 @@
-- codegen_studio/seed/scripts/db/operations.lua
-- DBAL operations for Codegen entities (Project, Blueprint, Template)
-- @module codegen_studio.db.operations
local M = {}
local json = require('json')
---------------------------------------------------------------------------
-- PROJECT OPERATIONS
---------------------------------------------------------------------------
---@class CodegenProjectCreateParams
---@field tenantId string
---@field name string
---@field description string|nil
---@field framework string react|vue|svelte|angular|etc
---@field settings table|nil
---@field createdBy string
---Create a new codegen project
---@param dbal table DBAL client instance
---@param params CodegenProjectCreateParams
---@return table Created project
function M.createProject(dbal, params)
return dbal:create('CodegenProject', {
tenantId = params.tenantId,
name = params.name,
description = params.description,
framework = params.framework,
settings = params.settings and json.encode(params.settings) or '{}',
status = 'active',
createdBy = params.createdBy,
createdAt = os.time() * 1000,
updatedAt = os.time() * 1000,
})
end
---Get project by ID
---@param dbal table
---@param projectId string
---@return table|nil Project
function M.getProject(dbal, projectId)
local project = dbal:read('CodegenProject', projectId)
if project and project.settings then
project.settings = json.decode(project.settings)
end
return project
end
---List projects
---@param dbal table
---@param tenantId string
---@param framework string|nil Filter by framework
---@param take number|nil
---@param skip number|nil
---@return table List result
function M.listProjects(dbal, tenantId, framework, take, skip)
local where = { tenantId = tenantId, status = 'active' }
if framework then
where.framework = framework
end
return dbal:list('CodegenProject', {
where = where,
orderBy = { updatedAt = 'desc' },
take = take or 20,
skip = skip or 0,
})
end
---Update project
---@param dbal table
---@param projectId string
---@param updates table
---@return table Updated project
function M.updateProject(dbal, projectId, updates)
if updates.settings and type(updates.settings) == 'table' then
updates.settings = json.encode(updates.settings)
end
updates.updatedAt = os.time() * 1000
return dbal:update('CodegenProject', projectId, updates)
end
---Archive project
---@param dbal table
---@param projectId string
function M.archiveProject(dbal, projectId)
return M.updateProject(dbal, projectId, { status = 'archived' })
end
---Delete project
---@param dbal table
---@param projectId string
---@return boolean Success
function M.deleteProject(dbal, projectId)
return dbal:delete('CodegenProject', projectId)
end
---------------------------------------------------------------------------
-- BLUEPRINT OPERATIONS
---------------------------------------------------------------------------
---@class CodegenBlueprintCreateParams
---@field tenantId string
---@field projectId string
---@field name string
---@field type string component|page|api|model|etc
---@field spec table Blueprint specification
---@field createdBy string
---Create a new blueprint
---@param dbal table
---@param params CodegenBlueprintCreateParams
---@return table Created blueprint
function M.createBlueprint(dbal, params)
return dbal:create('CodegenBlueprint', {
tenantId = params.tenantId,
projectId = params.projectId,
name = params.name,
type = params.type,
spec = json.encode(params.spec or {}),
version = 1,
status = 'draft',
createdBy = params.createdBy,
createdAt = os.time() * 1000,
updatedAt = os.time() * 1000,
})
end
---Get blueprint by ID
---@param dbal table
---@param blueprintId string
---@return table|nil Blueprint
function M.getBlueprint(dbal, blueprintId)
local blueprint = dbal:read('CodegenBlueprint', blueprintId)
if blueprint and blueprint.spec then
blueprint.spec = json.decode(blueprint.spec)
end
return blueprint
end
---List blueprints for a project
---@param dbal table
---@param projectId string
---@param type string|nil Filter by type
---@param take number|nil
---@return table List result
function M.listBlueprints(dbal, projectId, type, take)
local where = { projectId = projectId }
if type then
where.type = type
end
return dbal:list('CodegenBlueprint', {
where = where,
orderBy = { name = 'asc' },
take = take or 50,
})
end
---Update blueprint spec
---@param dbal table
---@param blueprintId string
---@param spec table
---@return table Updated blueprint
function M.updateBlueprintSpec(dbal, blueprintId, spec)
local blueprint = M.getBlueprint(dbal, blueprintId)
if not blueprint then
error('Blueprint not found: ' .. blueprintId)
end
return dbal:update('CodegenBlueprint', blueprintId, {
spec = json.encode(spec),
version = (blueprint.version or 0) + 1,
updatedAt = os.time() * 1000,
})
end
---Publish blueprint
---@param dbal table
---@param blueprintId string
function M.publishBlueprint(dbal, blueprintId)
return dbal:update('CodegenBlueprint', blueprintId, {
status = 'published',
publishedAt = os.time() * 1000,
updatedAt = os.time() * 1000,
})
end
---Delete blueprint
---@param dbal table
---@param blueprintId string
---@return boolean Success
function M.deleteBlueprint(dbal, blueprintId)
return dbal:delete('CodegenBlueprint', blueprintId)
end
---------------------------------------------------------------------------
-- TEMPLATE OPERATIONS
---------------------------------------------------------------------------
---@class CodegenTemplateCreateParams
---@field tenantId string
---@field name string
---@field type string component|page|api|model|hook|etc
---@field framework string
---@field content string Template content with placeholders
---@field variables table[] Variable definitions
---@field isPublic boolean|nil
---Create a new template
---@param dbal table
---@param params CodegenTemplateCreateParams
---@return table Created template
function M.createTemplate(dbal, params)
return dbal:create('CodegenTemplate', {
tenantId = params.tenantId,
name = params.name,
type = params.type,
framework = params.framework,
content = params.content,
variables = json.encode(params.variables or {}),
isPublic = params.isPublic or false,
usageCount = 0,
createdAt = os.time() * 1000,
updatedAt = os.time() * 1000,
})
end
---Get template by ID
---@param dbal table
---@param templateId string
---@return table|nil Template
function M.getTemplate(dbal, templateId)
local template = dbal:read('CodegenTemplate', templateId)
if template and template.variables then
template.variables = json.decode(template.variables)
end
return template
end
---List templates
---@param dbal table
---@param tenantId string
---@param framework string|nil
---@param type string|nil
---@param take number|nil
---@return table[] Templates
function M.listTemplates(dbal, tenantId, framework, type, take)
-- Get tenant templates
local where = { tenantId = tenantId }
local result = dbal:list('CodegenTemplate', {
where = where,
orderBy = { usageCount = 'desc' },
take = take or 50,
})
local templates = result.items or {}
-- Filter by framework and type
if framework or type then
local filtered = {}
for _, t in ipairs(templates) do
local matchFramework = not framework or t.framework == framework
local matchType = not type or t.type == type
if matchFramework and matchType then
table.insert(filtered, t)
end
end
templates = filtered
end
-- Parse variables
for _, t in ipairs(templates) do
if t.variables and type(t.variables) == 'string' then
t.variables = json.decode(t.variables)
end
end
return templates
end
---Update template
---@param dbal table
---@param templateId string
---@param updates table
---@return table Updated template
function M.updateTemplate(dbal, templateId, updates)
if updates.variables and type(updates.variables) == 'table' then
updates.variables = json.encode(updates.variables)
end
updates.updatedAt = os.time() * 1000
return dbal:update('CodegenTemplate', templateId, updates)
end
---Increment template usage
---@param dbal table
---@param templateId string
function M.incrementUsage(dbal, templateId)
local template = M.getTemplate(dbal, templateId)
if template then
dbal:update('CodegenTemplate', templateId, {
usageCount = (template.usageCount or 0) + 1,
})
end
end
---Delete template
---@param dbal table
---@param templateId string
---@return boolean Success
function M.deleteTemplate(dbal, templateId)
return dbal:delete('CodegenTemplate', templateId)
end
---------------------------------------------------------------------------
-- GENERATION OPERATIONS
---------------------------------------------------------------------------
---Generate code from template
---@param dbal table
---@param templateId string
---@param variables table Variable values
---@return string Generated code
function M.generateFromTemplate(dbal, templateId, variables)
local template = M.getTemplate(dbal, templateId)
if not template then
error('Template not found: ' .. templateId)
end
M.incrementUsage(dbal, templateId)
local code = template.content
-- Replace variables
for key, value in pairs(variables) do
code = code:gsub('{{' .. key .. '}}', tostring(value))
code = code:gsub('{%% ' .. key .. ' %%}', tostring(value))
end
return code
end
---Log a generation event
---@param dbal table
---@param tenantId string
---@param projectId string
---@param templateId string|nil
---@param blueprintId string|nil
---@param output table Generated files
---@param userId string
function M.logGeneration(dbal, tenantId, projectId, templateId, blueprintId, output, userId)
return dbal:create('CodegenHistory', {
tenantId = tenantId,
projectId = projectId,
templateId = templateId,
blueprintId = blueprintId,
output = json.encode(output),
generatedBy = userId,
generatedAt = os.time() * 1000,
})
end
return M