mirror of
https://github.com/certimate-go/certimate.git
synced 2026-09-21 12:43:46 +08:00
refactor: change database schemas
This commit is contained in:
@@ -54,7 +54,7 @@ func (s *CertificateService) InitSchedule(ctx context.Context) error {
|
||||
if settingsContent != nil && settingsContent.ExpiredCertificatesMaxDaysRetention != 0 {
|
||||
ret, err := s.certificateRepo.DeleteWhere(
|
||||
context.Background(),
|
||||
dbx.NewExp(fmt.Sprintf("expireAt<DATETIME('now', '-%d days')", settingsContent.ExpiredCertificatesMaxDaysRetention)),
|
||||
dbx.NewExp(fmt.Sprintf("validityNotAfter<DATETIME('now', '-%d days')", settingsContent.ExpiredCertificatesMaxDaysRetention)),
|
||||
)
|
||||
if err != nil {
|
||||
app.GetLogger().Error("failed to delete expired certificates", "err", err)
|
||||
|
||||
@@ -23,16 +23,16 @@ type Certificate struct {
|
||||
IssuerOrg string `json:"issuerOrg" db:"issuerOrg"`
|
||||
IssuerCertificate string `json:"issuerCertificate" db:"issuerCertificate"`
|
||||
KeyAlgorithm CertificateKeyAlgorithmType `json:"keyAlgorithm" db:"keyAlgorithm"`
|
||||
EffectAt time.Time `json:"effectAt" db:"effectAt"`
|
||||
ExpireAt time.Time `json:"expireAt" db:"expireAt"`
|
||||
ValidityNotBefore time.Time `json:"validityNotBefore" db:"validityNotBefore"`
|
||||
ValidityNotAfter time.Time `json:"validityNotAfter" db:"validityNotAfter"`
|
||||
ACMEAccountUrl string `json:"acmeAccountUrl" db:"acmeAccountUrl"`
|
||||
ACMECertUrl string `json:"acmeCertUrl" db:"acmeCertUrl"`
|
||||
ACMECertStableUrl string `json:"acmeCertStableUrl" db:"acmeCertStableUrl"`
|
||||
ACMERenewed bool `json:"acmeRenewed" db:"acmeRenewed"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowRef"`
|
||||
WorkflowRunId string `json:"workflowRunId" db:"workflowRunRef"`
|
||||
WorkflowOutputId string `json:"workflowOutputId" db:"workflowOutputRef"`
|
||||
WorkflowNodeId string `json:"workflowNodeId" db:"workflowNodeId"`
|
||||
WorkflowRunId string `json:"workflowRunId" db:"workflowRunId"`
|
||||
WorkflowOutputId string `json:"workflowOutputId" db:"workflowOutputId"`
|
||||
DeletedAt *time.Time `json:"deleted" db:"deleted"`
|
||||
}
|
||||
|
||||
@@ -40,8 +40,8 @@ func (c *Certificate) PopulateFromX509(certX509 *x509.Certificate) *Certificate
|
||||
c.SubjectAltNames = strings.Join(certX509.DNSNames, ";")
|
||||
c.SerialNumber = strings.ToUpper(certX509.SerialNumber.Text(16))
|
||||
c.IssuerOrg = strings.Join(certX509.Issuer.Organization, ";")
|
||||
c.EffectAt = certX509.NotBefore
|
||||
c.ExpireAt = certX509.NotAfter
|
||||
c.ValidityNotBefore = certX509.NotBefore
|
||||
c.ValidityNotAfter = certX509.NotAfter
|
||||
|
||||
switch certX509.PublicKeyAlgorithm {
|
||||
case x509.RSA:
|
||||
@@ -120,8 +120,8 @@ func (c *Certificate) PopulateFromPEM(certPEM, privkeyPEM string) *Certificate {
|
||||
type CertificateSourceType string
|
||||
|
||||
const (
|
||||
CertificateSourceTypeWorkflow = CertificateSourceType("workflow")
|
||||
CertificateSourceTypeUpload = CertificateSourceType("upload")
|
||||
CertificateSourceTypeRequest = CertificateSourceType("request")
|
||||
CertificateSourceTypeUpload = CertificateSourceType("upload")
|
||||
)
|
||||
|
||||
type CertificateKeyAlgorithmType string
|
||||
|
||||
@@ -20,7 +20,7 @@ type Workflow struct {
|
||||
Content *WorkflowNode `json:"content" db:"content"`
|
||||
Draft *WorkflowNode `json:"draft" db:"draft"`
|
||||
HasDraft bool `json:"hasDraft" db:"hasDraft"`
|
||||
LastRunId string `json:"lastRunId" db:"lastRunId"`
|
||||
LastRunId string `json:"lastRunId" db:"lastRunRef"`
|
||||
LastRunStatus WorkflowRunStatusType `json:"lastRunStatus" db:"lastRunStatus"`
|
||||
LastRunTime time.Time `json:"lastRunTime" db:"lastRunTime"`
|
||||
}
|
||||
@@ -45,8 +45,8 @@ const (
|
||||
type WorkflowTriggerType string
|
||||
|
||||
const (
|
||||
WorkflowTriggerTypeAuto = WorkflowTriggerType("auto")
|
||||
WorkflowTriggerTypeManual = WorkflowTriggerType("manual")
|
||||
WorkflowTriggerTypeScheduled = WorkflowTriggerType("scheduled")
|
||||
WorkflowTriggerTypeManual = WorkflowTriggerType("manual")
|
||||
)
|
||||
|
||||
type WorkflowNode struct {
|
||||
@@ -55,8 +55,8 @@ type WorkflowNode struct {
|
||||
Name string `json:"name"`
|
||||
|
||||
Config map[string]any `json:"config"`
|
||||
Inputs []WorkflowNodeIO `json:"inputs"`
|
||||
Outputs []WorkflowNodeIO `json:"outputs"`
|
||||
Inputs []WorkflowNodeIO `json:"inputs,omitempty"`
|
||||
Outputs []WorkflowNodeIO `json:"outputs,omitempty"`
|
||||
|
||||
Next *WorkflowNode `json:"next,omitempty"`
|
||||
Branches []WorkflowNode `json:"branches,omitempty"`
|
||||
|
||||
@@ -9,8 +9,8 @@ const CollectionNameWorkflowLog = "workflow_logs"
|
||||
|
||||
type WorkflowLog struct {
|
||||
Meta
|
||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||
RunId string `json:"workflorunIdwId" db:"runId"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowRef"`
|
||||
RunId string `json:"runId" db:"runRef"`
|
||||
NodeId string `json:"nodeId" db:"nodeId"`
|
||||
NodeName string `json:"nodeName" db:"nodeName"`
|
||||
Timestamp int64 `json:"timestamp" db:"timestamp"` // 毫秒级时间戳
|
||||
|
||||
@@ -4,8 +4,8 @@ const CollectionNameWorkflowOutput = "workflow_output"
|
||||
|
||||
type WorkflowOutput struct {
|
||||
Meta
|
||||
WorkflowId string `json:"workflowId" db:"workflow"`
|
||||
RunId string `json:"runId" db:"runId"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowRef"`
|
||||
RunId string `json:"runId" db:"runRef"`
|
||||
NodeId string `json:"nodeId" db:"nodeId"`
|
||||
Node *WorkflowNode `json:"node" db:"node"`
|
||||
Outputs []WorkflowNodeIO `json:"outputs" db:"outputs"`
|
||||
|
||||
@@ -8,7 +8,7 @@ const CollectionNameWorkflowRun = "workflow_run"
|
||||
|
||||
type WorkflowRun struct {
|
||||
Meta
|
||||
WorkflowId string `json:"workflowId" db:"workflowId"`
|
||||
WorkflowId string `json:"workflowId" db:"workflowRef"`
|
||||
Status WorkflowRunStatusType `json:"status" db:"status"`
|
||||
Trigger WorkflowTriggerType `json:"trigger" db:"trigger"`
|
||||
StartedAt time.Time `json:"startedAt" db:"startedAt"`
|
||||
|
||||
@@ -21,8 +21,8 @@ func NewCertificateRepository() *CertificateRepository {
|
||||
func (r *CertificateRepository) ListExpireSoon(ctx context.Context) ([]*domain.Certificate, error) {
|
||||
records, err := app.GetApp().FindAllRecords(
|
||||
domain.CollectionNameCertificate,
|
||||
dbx.NewExp("expireAt>DATETIME('now')"),
|
||||
dbx.NewExp("expireAt<DATETIME('now', '+20 days')"),
|
||||
dbx.NewExp("validityNotAfter>DATETIME('now')"),
|
||||
dbx.NewExp("validityNotAfter<DATETIME('now', '+20 days')"),
|
||||
dbx.NewExp("deleted=null"),
|
||||
)
|
||||
if err != nil {
|
||||
@@ -80,7 +80,7 @@ func (r *CertificateRepository) GetByWorkflowNodeId(ctx context.Context, workflo
|
||||
func (r *CertificateRepository) GetByWorkflowRunIdAndNodeId(ctx context.Context, workflowRunId string, workflowNodeId string) (*domain.Certificate, error) {
|
||||
records, err := app.GetApp().FindRecordsByFilter(
|
||||
domain.CollectionNameCertificate,
|
||||
"workflowRunId={:workflowRunId} && workflowNodeId={:workflowNodeId} && deleted=null",
|
||||
"workflowRunRef={:workflowRunId} && workflowNodeId={:workflowNodeId} && deleted=null",
|
||||
"-created",
|
||||
1, 0,
|
||||
dbx.Params{"workflowRunId": workflowRunId},
|
||||
@@ -124,16 +124,16 @@ func (r *CertificateRepository) Save(ctx context.Context, certificate *domain.Ce
|
||||
record.Set("issuerOrg", certificate.IssuerOrg)
|
||||
record.Set("issuerCertificate", certificate.IssuerCertificate)
|
||||
record.Set("keyAlgorithm", string(certificate.KeyAlgorithm))
|
||||
record.Set("effectAt", certificate.EffectAt)
|
||||
record.Set("expireAt", certificate.ExpireAt)
|
||||
record.Set("validityNotBefore", certificate.ValidityNotBefore)
|
||||
record.Set("validityNotAfter", certificate.ValidityNotAfter)
|
||||
record.Set("acmeAccountUrl", certificate.ACMEAccountUrl)
|
||||
record.Set("acmeCertUrl", certificate.ACMECertUrl)
|
||||
record.Set("acmeCertStableUrl", certificate.ACMECertStableUrl)
|
||||
record.Set("acmeRenewed", certificate.ACMERenewed)
|
||||
record.Set("workflowId", certificate.WorkflowId)
|
||||
record.Set("workflowRunId", certificate.WorkflowRunId)
|
||||
record.Set("workflowRef", certificate.WorkflowId)
|
||||
record.Set("workflowRunRef", certificate.WorkflowRunId)
|
||||
record.Set("workflowOutputRef", certificate.WorkflowOutputId)
|
||||
record.Set("workflowNodeId", certificate.WorkflowNodeId)
|
||||
record.Set("workflowOutputId", certificate.WorkflowOutputId)
|
||||
if err := app.GetApp().Save(record); err != nil {
|
||||
return certificate, err
|
||||
}
|
||||
@@ -186,16 +186,16 @@ func (r *CertificateRepository) castRecordToModel(record *core.Record) (*domain.
|
||||
IssuerOrg: record.GetString("issuerOrg"),
|
||||
IssuerCertificate: record.GetString("issuerCertificate"),
|
||||
KeyAlgorithm: domain.CertificateKeyAlgorithmType(record.GetString("keyAlgorithm")),
|
||||
EffectAt: record.GetDateTime("effectAt").Time(),
|
||||
ExpireAt: record.GetDateTime("expireAt").Time(),
|
||||
ValidityNotBefore: record.GetDateTime("validityNotBefore").Time(),
|
||||
ValidityNotAfter: record.GetDateTime("validityNotAfter").Time(),
|
||||
ACMEAccountUrl: record.GetString("acmeAccountUrl"),
|
||||
ACMECertUrl: record.GetString("acmeCertUrl"),
|
||||
ACMECertStableUrl: record.GetString("acmeCertStableUrl"),
|
||||
ACMERenewed: record.GetBool("acmeRenewed"),
|
||||
WorkflowId: record.GetString("workflowId"),
|
||||
WorkflowRunId: record.GetString("workflowRunId"),
|
||||
WorkflowId: record.GetString("workflowRef"),
|
||||
WorkflowRunId: record.GetString("workflowRunRef"),
|
||||
WorkflowOutputId: record.GetString("workflowOutputRef"),
|
||||
WorkflowNodeId: record.GetString("workflowNodeId"),
|
||||
WorkflowOutputId: record.GetString("workflowOutputId"),
|
||||
}
|
||||
return certificate, nil
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func (r *StatisticsRepository) Get(ctx context.Context) (*domain.Statistics, err
|
||||
Total int `db:"total"`
|
||||
}{}
|
||||
if err := app.GetDB().
|
||||
NewQuery("SELECT COUNT(*) AS total FROM certificate WHERE expireAt > DATETIME('now') and expireAt < DATETIME('now', '+20 days') AND deleted = ''").
|
||||
NewQuery("SELECT COUNT(*) AS total FROM certificate WHERE validityNotAfter > DATETIME('now') and validityNotAfter < DATETIME('now', '+20 days') AND deleted = ''").
|
||||
One(&certExpireSoonTotal); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -43,7 +43,7 @@ func (r *StatisticsRepository) Get(ctx context.Context) (*domain.Statistics, err
|
||||
Total int `db:"total"`
|
||||
}{}
|
||||
if err := app.GetDB().
|
||||
NewQuery("SELECT COUNT(*) AS total FROM certificate WHERE expireAt < DATETIME('now') AND deleted = ''").
|
||||
NewQuery("SELECT COUNT(*) AS total FROM certificate WHERE validityNotAfter < DATETIME('now') AND deleted = ''").
|
||||
One(&certExpiredTotal); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -18,13 +18,13 @@ func NewWorkflowRepository() *WorkflowRepository {
|
||||
return &WorkflowRepository{}
|
||||
}
|
||||
|
||||
func (r *WorkflowRepository) ListEnabledAuto(ctx context.Context) ([]*domain.Workflow, error) {
|
||||
func (r *WorkflowRepository) ListEnabledScheduled(ctx context.Context) ([]*domain.Workflow, error) {
|
||||
records, err := app.GetApp().FindRecordsByFilter(
|
||||
domain.CollectionNameWorkflow,
|
||||
"enabled={:enabled} && trigger={:trigger}",
|
||||
"-created",
|
||||
0, 0,
|
||||
dbx.Params{"enabled": true, "trigger": string(domain.WorkflowTriggerTypeAuto)},
|
||||
dbx.Params{"enabled": true, "trigger": string(domain.WorkflowTriggerTypeScheduled)},
|
||||
)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -82,7 +82,7 @@ func (r *WorkflowRepository) Save(ctx context.Context, workflow *domain.Workflow
|
||||
record.Set("content", workflow.Content)
|
||||
record.Set("draft", workflow.Draft)
|
||||
record.Set("hasDraft", workflow.HasDraft)
|
||||
record.Set("lastRunId", workflow.LastRunId)
|
||||
record.Set("lastRunRef", workflow.LastRunId)
|
||||
record.Set("lastRunStatus", string(workflow.LastRunStatus))
|
||||
record.Set("lastRunTime", workflow.LastRunTime)
|
||||
if err := app.GetApp().Save(record); err != nil {
|
||||
@@ -124,7 +124,7 @@ func (r *WorkflowRepository) castRecordToModel(record *core.Record) (*domain.Wor
|
||||
Content: content,
|
||||
Draft: draft,
|
||||
HasDraft: record.GetBool("hasDraft"),
|
||||
LastRunId: record.GetString("lastRunId"),
|
||||
LastRunId: record.GetString("lastRunRef"),
|
||||
LastRunStatus: domain.WorkflowRunStatusType(record.GetString("lastRunStatus")),
|
||||
LastRunTime: record.GetDateTime("lastRunTime").Time(),
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ func NewWorkflowLogRepository() *WorkflowLogRepository {
|
||||
func (r *WorkflowLogRepository) ListByWorkflowRunId(ctx context.Context, workflowRunId string) ([]*domain.WorkflowLog, error) {
|
||||
records, err := app.GetApp().FindRecordsByFilter(
|
||||
domain.CollectionNameWorkflowLog,
|
||||
"runId={:runId}",
|
||||
"runRef={:runId}",
|
||||
"timestamp",
|
||||
0, 0,
|
||||
dbx.Params{"runId": workflowRunId},
|
||||
@@ -62,8 +62,8 @@ func (r *WorkflowLogRepository) Save(ctx context.Context, workflowLog *domain.Wo
|
||||
}
|
||||
}
|
||||
|
||||
record.Set("workflowId", workflowLog.WorkflowId)
|
||||
record.Set("runId", workflowLog.RunId)
|
||||
record.Set("workflowRef", workflowLog.WorkflowId)
|
||||
record.Set("runRef", workflowLog.RunId)
|
||||
record.Set("nodeId", workflowLog.NodeId)
|
||||
record.Set("nodeName", workflowLog.NodeName)
|
||||
record.Set("timestamp", workflowLog.Timestamp)
|
||||
@@ -99,8 +99,8 @@ func (r *WorkflowLogRepository) castRecordToModel(record *core.Record) (*domain.
|
||||
CreatedAt: record.GetDateTime("created").Time(),
|
||||
UpdatedAt: record.GetDateTime("updated").Time(),
|
||||
},
|
||||
WorkflowId: record.GetString("workflowId"),
|
||||
RunId: record.GetString("runId"),
|
||||
WorkflowId: record.GetString("workflowRef"),
|
||||
RunId: record.GetString("runRef"),
|
||||
NodeId: record.GetString("nodeId"),
|
||||
NodeName: record.GetString("nodeName"),
|
||||
Timestamp: int64(record.GetInt("timestamp")),
|
||||
|
||||
@@ -123,8 +123,8 @@ func (r *WorkflowOutputRepository) castRecordToModel(record *core.Record) (*doma
|
||||
CreatedAt: record.GetDateTime("created").Time(),
|
||||
UpdatedAt: record.GetDateTime("updated").Time(),
|
||||
},
|
||||
WorkflowId: record.GetString("workflowId"),
|
||||
RunId: record.GetString("runId"),
|
||||
WorkflowId: record.GetString("workflowRef"),
|
||||
RunId: record.GetString("runRef"),
|
||||
NodeId: record.GetString("nodeId"),
|
||||
Node: node,
|
||||
Outputs: outputs,
|
||||
@@ -148,8 +148,8 @@ func (r *WorkflowOutputRepository) saveRecord(workflowOutput *domain.WorkflowOut
|
||||
return record, err
|
||||
}
|
||||
}
|
||||
record.Set("workflowId", workflowOutput.WorkflowId)
|
||||
record.Set("runId", workflowOutput.RunId)
|
||||
record.Set("workflowRef", workflowOutput.WorkflowId)
|
||||
record.Set("runRef", workflowOutput.RunId)
|
||||
record.Set("nodeId", workflowOutput.NodeId)
|
||||
record.Set("node", workflowOutput.Node)
|
||||
record.Set("outputs", workflowOutput.Outputs)
|
||||
|
||||
@@ -50,7 +50,7 @@ func (r *WorkflowRunRepository) Save(ctx context.Context, workflowRun *domain.Wo
|
||||
}
|
||||
|
||||
err = app.GetApp().RunInTransaction(func(txApp core.App) error {
|
||||
record.Set("workflowId", workflowRun.WorkflowId)
|
||||
record.Set("workflowRef", workflowRun.WorkflowId)
|
||||
record.Set("trigger", string(workflowRun.Trigger))
|
||||
record.Set("status", string(workflowRun.Status))
|
||||
record.Set("startedAt", workflowRun.StartedAt)
|
||||
@@ -70,7 +70,7 @@ func (r *WorkflowRunRepository) Save(ctx context.Context, workflowRun *domain.Wo
|
||||
workflowRecord, err := txApp.FindRecordById(domain.CollectionNameWorkflow, workflowRun.WorkflowId)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if workflowRun.Id == workflowRecord.GetString("lastRunId") {
|
||||
} else if workflowRun.Id == workflowRecord.GetString("lastRunRef") {
|
||||
workflowRecord.IgnoreUnchangedFields(true)
|
||||
workflowRecord.Set("lastRunStatus", record.GetString("status"))
|
||||
err = txApp.Save(workflowRecord)
|
||||
@@ -79,7 +79,7 @@ func (r *WorkflowRunRepository) Save(ctx context.Context, workflowRun *domain.Wo
|
||||
}
|
||||
} else if workflowRecord.GetDateTime("lastRunTime").Time().IsZero() || workflowRun.StartedAt.After(workflowRecord.GetDateTime("lastRunTime").Time()) {
|
||||
workflowRecord.IgnoreUnchangedFields(true)
|
||||
workflowRecord.Set("lastRunId", record.Id)
|
||||
workflowRecord.Set("lastRunRef", record.Id)
|
||||
workflowRecord.Set("lastRunStatus", record.GetString("status"))
|
||||
workflowRecord.Set("lastRunTime", record.GetString("startedAt"))
|
||||
err = txApp.Save(workflowRecord)
|
||||
@@ -136,7 +136,7 @@ func (r *WorkflowRunRepository) castRecordToModel(record *core.Record) (*domain.
|
||||
CreatedAt: record.GetDateTime("created").Time(),
|
||||
UpdatedAt: record.GetDateTime("updated").Time(),
|
||||
},
|
||||
WorkflowId: record.GetString("workflowId"),
|
||||
WorkflowId: record.GetString("workflowRef"),
|
||||
Status: domain.WorkflowRunStatusType(record.GetString("status")),
|
||||
Trigger: domain.WorkflowTriggerType(record.GetString("trigger")),
|
||||
StartedAt: record.GetDateTime("startedAt").Time(),
|
||||
|
||||
@@ -57,8 +57,8 @@ func onWorkflowRecordCreateOrUpdate(ctx context.Context, record *core.Record) er
|
||||
enabled := record.GetBool("enabled")
|
||||
trigger := record.GetString("trigger")
|
||||
|
||||
// 如果是手动触发或未启用,移除定时任务
|
||||
if !enabled || trigger == string(domain.WorkflowTriggerTypeManual) {
|
||||
// 如果非定时触发或未启用,移除定时任务
|
||||
if !enabled || trigger != string(domain.WorkflowTriggerTypeScheduled) {
|
||||
scheduler.Remove(fmt.Sprintf("workflow#%s", workflowId))
|
||||
return nil
|
||||
}
|
||||
@@ -68,7 +68,7 @@ func onWorkflowRecordCreateOrUpdate(ctx context.Context, record *core.Record) er
|
||||
workflowSrv := NewWorkflowService(repository.NewWorkflowRepository(), repository.NewWorkflowRunRepository(), repository.NewSettingsRepository())
|
||||
workflowSrv.StartRun(ctx, &dtos.WorkflowStartRunReq{
|
||||
WorkflowId: workflowId,
|
||||
RunTrigger: domain.WorkflowTriggerTypeAuto,
|
||||
RunTrigger: domain.WorkflowTriggerTypeScheduled,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -79,7 +79,7 @@ func (n *applyNode) Process(ctx context.Context) error {
|
||||
}
|
||||
|
||||
certificate := &domain.Certificate{
|
||||
Source: domain.CertificateSourceTypeWorkflow,
|
||||
Source: domain.CertificateSourceTypeRequest,
|
||||
Certificate: applyResult.FullChainCertificate,
|
||||
PrivateKey: applyResult.PrivateKey,
|
||||
IssuerCertificate: applyResult.IssuerCertificate,
|
||||
@@ -115,7 +115,7 @@ func (n *applyNode) Process(ctx context.Context) error {
|
||||
// 记录中间结果
|
||||
n.outputs[outputKeyForNodeSkipped] = strconv.FormatBool(false)
|
||||
n.outputs[outputKeyForCertificateValidity] = strconv.FormatBool(true)
|
||||
n.outputs[outputKeyForCertificateDaysLeft] = strconv.FormatInt(int64(time.Until(certificate.ExpireAt).Hours()/24), 10)
|
||||
n.outputs[outputKeyForCertificateDaysLeft] = strconv.FormatInt(int64(time.Until(certificate.ValidityNotAfter).Hours()/24), 10)
|
||||
|
||||
n.logger.Info("application completed")
|
||||
return nil
|
||||
@@ -158,7 +158,7 @@ func (n *applyNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workflo
|
||||
lastCertificate, _ := n.certRepo.GetByWorkflowRunIdAndNodeId(ctx, lastOutput.RunId, lastOutput.NodeId)
|
||||
if lastCertificate != nil {
|
||||
renewalInterval := time.Duration(thisNodeCfg.SkipBeforeExpiryDays) * time.Hour * 24
|
||||
expirationTime := time.Until(lastCertificate.ExpireAt)
|
||||
expirationTime := time.Until(lastCertificate.ValidityNotAfter)
|
||||
if expirationTime > renewalInterval {
|
||||
daysLeft := int(expirationTime.Hours() / 24)
|
||||
// TODO: 优化此处逻辑,[checkCanSkip] 方法不应该修改中间结果,违背单一职责
|
||||
|
||||
@@ -74,7 +74,7 @@ func (n *uploadNode) Process(ctx context.Context) error {
|
||||
// 记录中间结果
|
||||
n.outputs[outputKeyForNodeSkipped] = strconv.FormatBool(false)
|
||||
n.outputs[outputKeyForCertificateValidity] = strconv.FormatBool(true)
|
||||
n.outputs[outputKeyForCertificateDaysLeft] = strconv.FormatInt(int64(time.Until(certificate.ExpireAt).Hours()/24), 10)
|
||||
n.outputs[outputKeyForCertificateDaysLeft] = strconv.FormatInt(int64(time.Until(certificate.ValidityNotAfter).Hours()/24), 10)
|
||||
|
||||
n.logger.Info("uploading completed")
|
||||
return nil
|
||||
@@ -95,7 +95,7 @@ func (n *uploadNode) checkCanSkip(ctx context.Context, lastOutput *domain.Workfl
|
||||
|
||||
lastCertificate, _ := n.certRepo.GetByWorkflowRunIdAndNodeId(ctx, lastOutput.RunId, lastOutput.NodeId)
|
||||
if lastCertificate != nil {
|
||||
daysLeft := int(time.Until(lastCertificate.ExpireAt).Hours() / 24)
|
||||
daysLeft := int(time.Until(lastCertificate.ValidityNotAfter).Hours() / 24)
|
||||
n.outputs[outputKeyForCertificateValidity] = strconv.FormatBool(daysLeft > 0)
|
||||
n.outputs[outputKeyForCertificateDaysLeft] = strconv.FormatInt(int64(daysLeft), 10)
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
)
|
||||
|
||||
type workflowRepository interface {
|
||||
ListEnabledAuto(ctx context.Context) ([]*domain.Workflow, error)
|
||||
ListEnabledScheduled(ctx context.Context) ([]*domain.Workflow, error)
|
||||
GetById(ctx context.Context, id string) (*domain.Workflow, error)
|
||||
Save(ctx context.Context, workflow *domain.Workflow) (*domain.Workflow, error)
|
||||
}
|
||||
@@ -80,7 +80,7 @@ func (s *WorkflowService) InitSchedule(ctx context.Context) error {
|
||||
|
||||
// 工作流
|
||||
{
|
||||
workflows, err := s.workflowRepo.ListEnabledAuto(ctx)
|
||||
workflows, err := s.workflowRepo.ListEnabledScheduled(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -91,7 +91,7 @@ func (s *WorkflowService) InitSchedule(ctx context.Context) error {
|
||||
err := app.GetScheduler().Add(fmt.Sprintf("workflow#%s", workflow.Id), workflow.TriggerCron, func() {
|
||||
s.StartRun(ctx, &dtos.WorkflowStartRunReq{
|
||||
WorkflowId: workflow.Id,
|
||||
RunTrigger: domain.WorkflowTriggerTypeAuto,
|
||||
RunTrigger: domain.WorkflowTriggerTypeScheduled,
|
||||
})
|
||||
})
|
||||
if err != nil {
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
package migrations
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
|
||||
"github.com/pocketbase/pocketbase/core"
|
||||
m "github.com/pocketbase/pocketbase/migrations"
|
||||
)
|
||||
@@ -10,72 +12,203 @@ func init() {
|
||||
tracer := NewTracer("v0.4.0")
|
||||
tracer.Printf("go ...")
|
||||
|
||||
// update collection `workflow_logs`
|
||||
// update collection `access`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1682296116")
|
||||
collection, err := app.FindCollectionByNameOrId("4yzbv8urny5ja1e")
|
||||
if err != nil {
|
||||
return err
|
||||
} else if collection != nil {
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
provider := record.GetString("provider")
|
||||
config := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("config", &config); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch provider {
|
||||
case "discordbot", "mattermost", "slackbot":
|
||||
if _, ok := config["defaultChannelId"]; ok {
|
||||
config["channelId"] = config["defaultChannelId"]
|
||||
delete(config, "defaultChannelId")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
|
||||
case "email":
|
||||
if _, ok := config["defaultSenderAddress"]; ok {
|
||||
config["senderAddress"] = config["defaultSenderAddress"]
|
||||
delete(config, "defaultSenderAddress")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["defaultSenderName"]; ok {
|
||||
config["senderName"] = config["defaultSenderName"]
|
||||
delete(config, "defaultSenderName")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["defaultReceiverAddress"]; ok {
|
||||
config["receiverAddress"] = config["defaultReceiverAddress"]
|
||||
delete(config, "defaultReceiverAddress")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
|
||||
case "telegrambot":
|
||||
if _, ok := config["defaultChatId"]; ok {
|
||||
config["chatId"] = config["defaultChatId"]
|
||||
delete(config, "defaultChatId")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
|
||||
case "webhook":
|
||||
if _, ok := config["defaultDataForDeployment"]; ok {
|
||||
config["dataForDeployment"] = config["defaultDataForDeployment"]
|
||||
delete(config, "defaultDataForDeployment")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["defaultDataForNotification"]; ok {
|
||||
config["dataForNotification"] = config["defaultDataForNotification"]
|
||||
delete(config, "defaultDataForNotification")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
field := collection.Fields.GetByName("level")
|
||||
if field != nil && field.Type() == "text" {
|
||||
// add temp field `levelTmp`
|
||||
if err := collection.Fields.AddMarshaledJSONAt(7, []byte(`{
|
||||
// update collection `certificate`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("4szxr9x43tpj6np")
|
||||
if err != nil {
|
||||
return err
|
||||
} else if collection != nil {
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "number760395071",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "levelTmp",
|
||||
"onlyInt": false,
|
||||
"id": "by9hetqi",
|
||||
"maxSelect": 1,
|
||||
"name": "source",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
"type": "select",
|
||||
"values": [
|
||||
"request",
|
||||
"upload"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// copy `level` to `levelTmp`
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = -4 WHERE level = 'DEBUG'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = 4 WHERE level = 'WARN'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = 8 WHERE level = 'ERROR'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET levelTmp = 0 WHERE levelTmp IS NULL").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// remove old field `level`
|
||||
collection.Fields.RemoveById(field.GetId())
|
||||
if err := app.Save(collection); err != nil {
|
||||
println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
// rename field `levelTmp` to `level`
|
||||
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
|
||||
if err := collection.Fields.AddMarshaledJSONAt(9, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "number760395071",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "level",
|
||||
"onlyInt": false,
|
||||
"id": "v40aqzpd",
|
||||
"max": "",
|
||||
"min": "",
|
||||
"name": "validityNotBefore",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
"type": "date"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(10, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "zgpdby2k",
|
||||
"max": "",
|
||||
"min": "",
|
||||
"name": "validityNotAfter",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "date"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(15, []byte(`{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"hidden": false,
|
||||
"id": "uvqfamb1",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "workflowRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(16, []byte(`{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "qjp8lygssgwyqyz",
|
||||
"hidden": false,
|
||||
"id": "relation3917999135",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "workflowRunRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(17, []byte(`{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "bqnxb95f2cooowp",
|
||||
"hidden": false,
|
||||
"id": "2ohlr0yd",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "workflowOutputRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX `+"`"+`idx_Jx8TXzDCmw`+"`"+` ON `+"`"+`certificate`+"`"+` (`+"`"+`workflowRef`+"`"+`)",
|
||||
"CREATE INDEX `+"`"+`idx_2cRXqNDyyp`+"`"+` ON `+"`"+`certificate`+"`"+` (`+"`"+`workflowRunRef`+"`"+`)",
|
||||
"CREATE INDEX `+"`"+`idx_kcKpgAZapk`+"`"+` ON `+"`"+`certificate`+"`"+` (`+"`"+`workflowNodeId`+"`"+`)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := app.Save(collection); err != nil {
|
||||
println(err)
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := app.DB().NewQuery("UPDATE certificate SET source = 'request' WHERE source = 'workflow'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -83,86 +216,360 @@ func init() {
|
||||
}
|
||||
}
|
||||
|
||||
// update collection `access`
|
||||
// update collection `workflow`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("4yzbv8urny5ja1e")
|
||||
collection, err := app.FindCollectionByNameOrId("tovyif5ax6j62ur")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
provider := record.GetString("provider")
|
||||
config := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("config", &config); err != nil {
|
||||
} else if collection != nil {
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "vqoajwjq",
|
||||
"maxSelect": 1,
|
||||
"name": "trigger",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"manual",
|
||||
"scheduled"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch provider {
|
||||
case "discordbot", "mattermost", "slackbot":
|
||||
if _, ok := config["defaultChannelId"]; ok {
|
||||
config["channelId"] = config["defaultChannelId"]
|
||||
delete(config, "defaultChannelId")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
|
||||
case "email":
|
||||
if _, ok := config["defaultSenderAddress"]; ok {
|
||||
config["senderAddress"] = config["defaultSenderAddress"]
|
||||
delete(config, "defaultSenderAddress")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["defaultSenderName"]; ok {
|
||||
config["senderName"] = config["defaultSenderName"]
|
||||
delete(config, "defaultSenderName")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["defaultReceiverAddress"]; ok {
|
||||
config["receiverAddress"] = config["defaultReceiverAddress"]
|
||||
delete(config, "defaultReceiverAddress")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
|
||||
case "telegrambot":
|
||||
if _, ok := config["defaultChatId"]; ok {
|
||||
config["chatId"] = config["defaultChatId"]
|
||||
delete(config, "defaultChatId")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
|
||||
case "webhook":
|
||||
if _, ok := config["defaultDataForDeployment"]; ok {
|
||||
config["dataForDeployment"] = config["defaultDataForDeployment"]
|
||||
delete(config, "defaultDataForDeployment")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if _, ok := config["defaultDataForNotification"]; ok {
|
||||
config["dataForNotification"] = config["defaultDataForNotification"]
|
||||
delete(config, "defaultDataForNotification")
|
||||
record.Set("config", config)
|
||||
changed = true
|
||||
}
|
||||
if err := collection.Fields.AddMarshaledJSONAt(9, []byte(`{
|
||||
"cascadeDelete": false,
|
||||
"collectionId": "qjp8lygssgwyqyz",
|
||||
"hidden": false,
|
||||
"id": "a23wkj9x",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "lastRunRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow SET trigger = 'scheduled' WHERE trigger = 'auto'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("collection '%s' updated", collection.Name)
|
||||
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
draft := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("draft", &draft); err == nil {
|
||||
if _, ok := draft["config"]; ok {
|
||||
config := draft["config"].(map[string]any)
|
||||
if _, ok := config["trigger"]; ok {
|
||||
trigger := config["trigger"].(string)
|
||||
if trigger == "auto" {
|
||||
config["trigger"] = "scheduled"
|
||||
record.Set("draft", draft)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
content := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("content", &content); err == nil {
|
||||
if _, ok := content["config"]; ok {
|
||||
config := content["config"].(map[string]any)
|
||||
if _, ok := config["trigger"]; ok {
|
||||
trigger := config["trigger"].(string)
|
||||
if trigger == "auto" {
|
||||
config["trigger"] = "scheduled"
|
||||
record.Set("content", content)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update collection `workflow_run`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("qjp8lygssgwyqyz")
|
||||
if err != nil {
|
||||
return err
|
||||
} else if collection != nil {
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"hidden": false,
|
||||
"id": "m8xfsyyy",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "workflowRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(3, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "jlroa3fk",
|
||||
"maxSelect": 1,
|
||||
"name": "trigger",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "select",
|
||||
"values": [
|
||||
"manual",
|
||||
"scheduled"
|
||||
]
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX `+"`"+`idx_7ZpfjTFsD2`+"`"+` ON `+"`"+`workflow_run`+"`"+` (`+"`"+`workflowRef`+"`"+`)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_run SET trigger = 'scheduled' WHERE trigger = 'auto'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("collection '%s' updated", collection.Name)
|
||||
|
||||
records, err := app.FindAllRecords(collection)
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
for _, record := range records {
|
||||
changed := false
|
||||
|
||||
detail := make(map[string]any)
|
||||
if err := record.UnmarshalJSONField("detail", &detail); err == nil {
|
||||
if _, ok := detail["config"]; ok {
|
||||
config := detail["config"].(map[string]any)
|
||||
if _, ok := config["trigger"]; ok {
|
||||
trigger := config["trigger"].(string)
|
||||
if trigger == "auto" {
|
||||
config["trigger"] = "scheduled"
|
||||
record.Set("detail", detail)
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if changed {
|
||||
if err := app.Save(record); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// update collection `workflow_output`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("bqnxb95f2cooowp")
|
||||
if err != nil {
|
||||
return err
|
||||
} else if collection != nil {
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX `+"`"+`idx_BYoQPsz4my`+"`"+` ON `+"`"+`workflow_output`+"`"+` (`+"`"+`workflowRef`+"`"+`)",
|
||||
"CREATE INDEX `+"`"+`idx_O9zxLETuxJ`+"`"+` ON `+"`"+`workflow_output`+"`"+` (`+"`"+`runRef`+"`"+`)",
|
||||
"CREATE INDEX `+"`"+`idx_luac8Ul34G`+"`"+` ON `+"`"+`workflow_output`+"`"+` (`+"`"+`nodeId`+"`"+`)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"hidden": false,
|
||||
"id": "jka88auc",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "workflowRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "qjp8lygssgwyqyz",
|
||||
"hidden": false,
|
||||
"id": "relation821863227",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "runRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("collection '%s' updated", collection.Name)
|
||||
}
|
||||
}
|
||||
|
||||
// update collection `workflow_logs`
|
||||
{
|
||||
collection, err := app.FindCollectionByNameOrId("pbc_1682296116")
|
||||
if err != nil {
|
||||
return err
|
||||
} else if collection != nil {
|
||||
if field := collection.Fields.GetByName("level"); field != nil && field.Type() == "text" {
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET level = -4 WHERE level = 'DEBUG'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET level = 0 WHERE level = 'INFO'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET level = 4 WHERE level = 'WARN'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
if _, err := app.DB().NewQuery("UPDATE workflow_logs SET level = 8 WHERE level = 'ERROR'").Execute(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("record #%s in collection '%s' updated", record.Id, collection.Name)
|
||||
if err := collection.Fields.AddMarshaledJSONAt(7, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "number760395071",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "levelTmp",
|
||||
"onlyInt": false,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
collection.Fields.RemoveById(field.GetId())
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(6, []byte(`{
|
||||
"hidden": false,
|
||||
"id": "number760395071",
|
||||
"max": null,
|
||||
"min": null,
|
||||
"name": "level",
|
||||
"onlyInt": false,
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "number"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(1, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "tovyif5ax6j62ur",
|
||||
"hidden": false,
|
||||
"id": "relation3371272342",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "workflowRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := collection.Fields.AddMarshaledJSONAt(2, []byte(`{
|
||||
"cascadeDelete": true,
|
||||
"collectionId": "qjp8lygssgwyqyz",
|
||||
"hidden": false,
|
||||
"id": "relation821863227",
|
||||
"maxSelect": 1,
|
||||
"minSelect": 0,
|
||||
"name": "runRef",
|
||||
"presentable": false,
|
||||
"required": false,
|
||||
"system": false,
|
||||
"type": "relation"
|
||||
}`)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := json.Unmarshal([]byte(`{
|
||||
"indexes": [
|
||||
"CREATE INDEX `+"`"+`idx_IOlpy6XuJ2`+"`"+` ON `+"`"+`workflow_logs`+"`"+` (`+"`"+`workflowRef`+"`"+`)",
|
||||
"CREATE INDEX `+"`"+`idx_qVlTb2yl7v`+"`"+` ON `+"`"+`workflow_logs`+"`"+` (`+"`"+`runRef`+"`"+`)",
|
||||
"CREATE INDEX `+"`"+`idx_UL4tdCXNlA`+"`"+` ON `+"`"+`workflow_logs`+"`"+` (`+"`"+`nodeId`+"`"+`)"
|
||||
]
|
||||
}`), &collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := app.Save(collection); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
tracer.Printf("collection '%s' updated", collection.Name)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -45,7 +45,7 @@ const CertificateDetail = ({ data, ...props }: CertificateDetailProps) => {
|
||||
|
||||
<Form.Item label={t("certificate.props.validity")}>
|
||||
<Input
|
||||
value={`${dayjs(data.effectAt).format("YYYY-MM-DD HH:mm:ss")} ~ ${dayjs(data.expireAt).format("YYYY-MM-DD HH:mm:ss")}`}
|
||||
value={`${dayjs(data.validityNotBefore).format("YYYY-MM-DD HH:mm:ss")} ~ ${dayjs(data.validityNotAfter).format("YYYY-MM-DD HH:mm:ss")}`}
|
||||
variant="filled"
|
||||
placeholder=""
|
||||
/>
|
||||
|
||||
@@ -239,7 +239,7 @@ const WorkflowRunLogs = ({ runId, runStatus }: { runId: string; runStatus: strin
|
||||
style={{ color: "inherit" }}
|
||||
bordered={false}
|
||||
defaultActiveKey={listData.map((group) => group.id)}
|
||||
expandIcon={({ isActive }) => <IconChevronRight className={mergeCls(isActive ? "" : "rotate-90", "transition-transform")} size="1.25em" />}
|
||||
expandIcon={({ isActive }) => <IconChevronRight className={mergeCls(isActive ? "rotate-90" : "", "transition-transform")} size="1.25em" />}
|
||||
items={listData.map((group) => {
|
||||
return {
|
||||
key: group.id,
|
||||
|
||||
@@ -64,8 +64,8 @@ const WorkflowRuns = ({ className, style, workflowId }: WorkflowRunsProps) => {
|
||||
title: t("workflow_run.props.trigger"),
|
||||
ellipsis: true,
|
||||
render: (_, record) => {
|
||||
if (record.trigger === WORKFLOW_TRIGGERS.AUTO) {
|
||||
return t("workflow_run.props.trigger.auto");
|
||||
if (record.trigger === WORKFLOW_TRIGGERS.SCHEDULED) {
|
||||
return t("workflow_run.props.trigger.scheduled");
|
||||
} else if (record.trigger === WORKFLOW_TRIGGERS.MANUAL) {
|
||||
return t("workflow_run.props.trigger.manual");
|
||||
}
|
||||
@@ -203,6 +203,10 @@ const WorkflowRuns = ({ className, style, workflowId }: WorkflowRunsProps) => {
|
||||
return [...prev];
|
||||
});
|
||||
|
||||
if (cb.record.id === detailDrawerProps.data?.id) {
|
||||
setDetailRecord({ ...detailDrawerProps.data, ...cb.record });
|
||||
}
|
||||
|
||||
if (cb.record.status !== WORKFLOW_RUN_STATUSES.PENDING && cb.record.status !== WORKFLOW_RUN_STATUSES.RUNNING) {
|
||||
unsubscribeWorkflowRun(item.id);
|
||||
}
|
||||
|
||||
@@ -40,14 +40,14 @@ const StartNode = ({ node, disabled }: StartNodeProps) => {
|
||||
return (
|
||||
<div className="flex items-center justify-between space-x-2">
|
||||
<Typography.Text className="truncate">
|
||||
{config.trigger === WORKFLOW_TRIGGERS.AUTO
|
||||
? t("workflow.props.trigger.auto")
|
||||
{config.trigger === WORKFLOW_TRIGGERS.SCHEDULED
|
||||
? t("workflow.props.trigger.scheduled")
|
||||
: config.trigger === WORKFLOW_TRIGGERS.MANUAL
|
||||
? t("workflow.props.trigger.manual")
|
||||
: "\u00A0"}
|
||||
</Typography.Text>
|
||||
<Typography.Text className="truncate" type="secondary">
|
||||
{config.trigger === WORKFLOW_TRIGGERS.AUTO ? config.triggerCron : ""}
|
||||
{config.trigger === WORKFLOW_TRIGGERS.SCHEDULED ? config.triggerCron : ""}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -40,7 +40,7 @@ const StartNodeConfigForm = forwardRef<StartNodeConfigFormInstance, StartNodeCon
|
||||
.string()
|
||||
.nullish()
|
||||
.refine((v) => {
|
||||
if (fieldTrigger !== WORKFLOW_TRIGGERS.AUTO) return true;
|
||||
if (fieldTrigger !== WORKFLOW_TRIGGERS.SCHEDULED) return true;
|
||||
return validCronExpression(v!);
|
||||
}, t("workflow_node.start.form.trigger_cron.errmsg.invalid")),
|
||||
});
|
||||
@@ -58,7 +58,7 @@ const StartNodeConfigForm = forwardRef<StartNodeConfigFormInstance, StartNodeCon
|
||||
}, [fieldTriggerCron]);
|
||||
|
||||
const handleTriggerChange = (value: string) => {
|
||||
if (value === WORKFLOW_TRIGGERS.AUTO) {
|
||||
if (value === WORKFLOW_TRIGGERS.SCHEDULED) {
|
||||
formInst.setFieldValue("triggerCron", formProps.initialValues?.triggerCron || initFormModel().triggerCron);
|
||||
} else {
|
||||
formInst.setFieldValue("triggerCron", undefined);
|
||||
@@ -89,7 +89,7 @@ const StartNodeConfigForm = forwardRef<StartNodeConfigFormInstance, StartNodeCon
|
||||
<Form className={className} style={style} {...formProps} disabled={disabled} layout="vertical" scrollToFirstError onValuesChange={handleFormChange}>
|
||||
<Form.Item name="trigger" label={t("workflow_node.start.form.trigger.label")} rules={[formRule]}>
|
||||
<Radio.Group onChange={(e) => handleTriggerChange(e.target.value)}>
|
||||
<Radio value={WORKFLOW_TRIGGERS.AUTO}>{t("workflow_node.start.form.trigger.option.auto.label")}</Radio>
|
||||
<Radio value={WORKFLOW_TRIGGERS.SCHEDULED}>{t("workflow_node.start.form.trigger.option.scheduled.label")}</Radio>
|
||||
<Radio value={WORKFLOW_TRIGGERS.MANUAL}>{t("workflow_node.start.form.trigger.option.manual.label")}</Radio>
|
||||
</Radio.Group>
|
||||
</Form.Item>
|
||||
@@ -97,7 +97,7 @@ const StartNodeConfigForm = forwardRef<StartNodeConfigFormInstance, StartNodeCon
|
||||
<Form.Item
|
||||
name="triggerCron"
|
||||
label={t("workflow_node.start.form.trigger_cron.label")}
|
||||
hidden={fieldTrigger !== WORKFLOW_TRIGGERS.AUTO}
|
||||
hidden={fieldTrigger !== WORKFLOW_TRIGGERS.SCHEDULED}
|
||||
rules={[formRule]}
|
||||
tooltip={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.start.form.trigger_cron.tooltip") }}></span>}
|
||||
extra={
|
||||
@@ -118,7 +118,7 @@ const StartNodeConfigForm = forwardRef<StartNodeConfigFormInstance, StartNodeCon
|
||||
<Input placeholder={t("workflow_node.start.form.trigger_cron.placeholder")} />
|
||||
</Form.Item>
|
||||
|
||||
<Show when={fieldTrigger === WORKFLOW_TRIGGERS.AUTO}>
|
||||
<Show when={fieldTrigger === WORKFLOW_TRIGGERS.SCHEDULED}>
|
||||
<Form.Item>
|
||||
<Alert type="info" message={<span dangerouslySetInnerHTML={{ __html: t("workflow_node.start.form.trigger_cron.guide") }}></span>} />
|
||||
</Form.Item>
|
||||
|
||||
@@ -8,16 +8,16 @@ export interface CertificateModel extends BaseModel {
|
||||
privateKey: string;
|
||||
issuerOrg: string;
|
||||
keyAlgorithm: string;
|
||||
effectAt: ISO8601String;
|
||||
expireAt: ISO8601String;
|
||||
workflowId: string;
|
||||
validityNotBefore: ISO8601String;
|
||||
validityNotAfter: ISO8601String;
|
||||
workflowRef: string;
|
||||
expand?: {
|
||||
workflowId?: WorkflowModel; // TODO: ugly, maybe to use an alias?
|
||||
workflowRef?: WorkflowModel;
|
||||
};
|
||||
}
|
||||
|
||||
export const CERTIFICATE_SOURCES = Object.freeze({
|
||||
WORKFLOW: "workflow",
|
||||
REQUEST: "request",
|
||||
UPLOAD: "upload",
|
||||
} as const);
|
||||
|
||||
|
||||
@@ -13,13 +13,13 @@ export interface WorkflowModel extends BaseModel {
|
||||
content?: WorkflowNode;
|
||||
draft?: WorkflowNode;
|
||||
hasDraft?: boolean;
|
||||
lastRunId?: string;
|
||||
lastRunRef?: string;
|
||||
lastRunStatus?: string;
|
||||
lastRunTime?: string;
|
||||
}
|
||||
|
||||
export const WORKFLOW_TRIGGERS = Object.freeze({
|
||||
AUTO: "auto",
|
||||
SCHEDULED: "scheduled",
|
||||
MANUAL: "manual",
|
||||
} as const);
|
||||
|
||||
@@ -135,7 +135,7 @@ export type WorkflowNodeConfigForStart = {
|
||||
|
||||
export const defaultNodeConfigForStart = (): Partial<WorkflowNodeConfigForStart> => {
|
||||
return {
|
||||
trigger: WORKFLOW_TRIGGERS.AUTO,
|
||||
trigger: WORKFLOW_TRIGGERS.SCHEDULED,
|
||||
triggerCron: "0 0 * * *",
|
||||
};
|
||||
};
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
import { type WorkflowModel } from "./workflow";
|
||||
|
||||
export interface WorkflowRunModel extends BaseModel {
|
||||
workflowId: string;
|
||||
workflowRef: string;
|
||||
status: string;
|
||||
trigger: string;
|
||||
startedAt: ISO8601String;
|
||||
endedAt: ISO8601String;
|
||||
error?: string;
|
||||
expand?: {
|
||||
workflowId?: WorkflowModel; // TODO: ugly, maybe to use an alias?
|
||||
workflowRef?: WorkflowModel;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
"certificate.props.validity.filter.expired": "Expired",
|
||||
"certificate.props.brand": "Brand",
|
||||
"certificate.props.source": "Source",
|
||||
"certificate.props.source.workflow": "Workflow",
|
||||
"certificate.props.source.request": "Request",
|
||||
"certificate.props.source.upload": "Upload",
|
||||
"certificate.props.certificate": "Certificate chain",
|
||||
"certificate.props.private_key": "Private key",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"workflow.props.name": "Name",
|
||||
"workflow.props.description": "Description",
|
||||
"workflow.props.trigger": "Trigger",
|
||||
"workflow.props.trigger.auto": "Scheduled",
|
||||
"workflow.props.trigger.scheduled": "Scheduled",
|
||||
"workflow.props.trigger.manual": "Manual",
|
||||
"workflow.props.last_run_at": "Last run at",
|
||||
"workflow.props.state": "Active",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"workflow_node.start.default_name": "Start",
|
||||
"workflow_node.start.form.trigger.label": "Trigger",
|
||||
"workflow_node.start.form.trigger.placeholder": "Please select trigger",
|
||||
"workflow_node.start.form.trigger.option.auto.label": "Scheduled",
|
||||
"workflow_node.start.form.trigger.option.scheduled.label": "Scheduled",
|
||||
"workflow_node.start.form.trigger.option.manual.label": "Manual",
|
||||
"workflow_node.start.form.trigger_cron.label": "Cron expression",
|
||||
"workflow_node.start.form.trigger_cron.placeholder": "Please enter cron expression",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"workflow_run.props.status.failed": "Failed",
|
||||
"workflow_run.props.status.canceled": "Canceled",
|
||||
"workflow_run.props.trigger": "Trigger",
|
||||
"workflow_run.props.trigger.auto": "Timing",
|
||||
"workflow_run.props.trigger.scheduled": "Scheduled",
|
||||
"workflow_run.props.trigger.manual": "Manual",
|
||||
"workflow_run.props.started_at": "Started at",
|
||||
"workflow_run.props.ended_at": "Ended at",
|
||||
|
||||
@@ -26,8 +26,8 @@
|
||||
"certificate.props.validity.filter.expired": "已过期",
|
||||
"certificate.props.brand": "证书品牌",
|
||||
"certificate.props.source": "来源",
|
||||
"certificate.props.source.workflow": "工作流",
|
||||
"certificate.props.source.upload": "用户上传",
|
||||
"certificate.props.source.request": "申请",
|
||||
"certificate.props.source.upload": "上传",
|
||||
"certificate.props.certificate": "证书内容",
|
||||
"certificate.props.private_key": "私钥内容",
|
||||
"certificate.props.serial_number": "证书序列号",
|
||||
|
||||
@@ -36,7 +36,7 @@
|
||||
"workflow.props.name": "名称",
|
||||
"workflow.props.description": "描述",
|
||||
"workflow.props.trigger": "触发方式",
|
||||
"workflow.props.trigger.auto": "定时",
|
||||
"workflow.props.trigger.scheduled": "定时",
|
||||
"workflow.props.trigger.manual": "手动",
|
||||
"workflow.props.last_run_at": "最近执行时间",
|
||||
"workflow.props.state": "启用",
|
||||
|
||||
@@ -15,7 +15,7 @@
|
||||
"workflow_node.start.default_name": "开始",
|
||||
"workflow_node.start.form.trigger.label": "触发方式",
|
||||
"workflow_node.start.form.trigger.placeholder": "请选择触发方式",
|
||||
"workflow_node.start.form.trigger.option.auto.label": "定时触发",
|
||||
"workflow_node.start.form.trigger.option.scheduled.label": "定时触发",
|
||||
"workflow_node.start.form.trigger.option.manual.label": "手动触发",
|
||||
"workflow_node.start.form.trigger_cron.label": "Cron 表达式",
|
||||
"workflow_node.start.form.trigger_cron.placeholder": "请输入 Cron 表达式",
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
"workflow_run.props.status.failed": "已失败",
|
||||
"workflow_run.props.status.canceled": "已取消",
|
||||
"workflow_run.props.trigger": "执行方式",
|
||||
"workflow_run.props.trigger.auto": "定时执行",
|
||||
"workflow_run.props.trigger.scheduled": "定时执行",
|
||||
"workflow_run.props.trigger.manual": "手动执行",
|
||||
"workflow_run.props.started_at": "开始时间",
|
||||
"workflow_run.props.ended_at": "完成时间",
|
||||
|
||||
@@ -49,14 +49,14 @@ const CertificateList = () => {
|
||||
render: (_, record) => <Typography.Text>{record.subjectAltNames}</Typography.Text>,
|
||||
},
|
||||
{
|
||||
key: "expiry",
|
||||
key: "validity",
|
||||
title: t("certificate.props.validity"),
|
||||
sorter: true,
|
||||
sortOrder: sorter.columnKey === "expiry" ? sorter.order : undefined,
|
||||
sortOrder: sorter.columnKey === "validity" ? sorter.order : undefined,
|
||||
render: (_, record) => {
|
||||
const total = dayjs(record.expireAt).diff(dayjs(record.created), "d") + 1;
|
||||
const isExpired = dayjs().isAfter(dayjs(record.expireAt));
|
||||
const leftHours = dayjs(record.expireAt).diff(dayjs(), "h");
|
||||
const total = dayjs(record.validityNotAfter).diff(dayjs(record.created), "d") + 1;
|
||||
const isExpired = dayjs().isAfter(dayjs(record.validityNotAfter));
|
||||
const leftHours = dayjs(record.validityNotAfter).diff(dayjs(), "h");
|
||||
const leftDays = Math.round(leftHours / 24);
|
||||
|
||||
return (
|
||||
@@ -83,7 +83,7 @@ const CertificateList = () => {
|
||||
)}
|
||||
|
||||
<Typography.Text ellipsis type="secondary">
|
||||
{t("certificate.props.validity.expiration", { date: dayjs(record.expireAt).format("YYYY-MM-DD") })}
|
||||
{t("certificate.props.validity.expiration", { date: dayjs(record.validityNotAfter).format("YYYY-MM-DD") })}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
);
|
||||
@@ -103,7 +103,7 @@ const CertificateList = () => {
|
||||
key: "source",
|
||||
title: t("certificate.props.source"),
|
||||
render: (_, record) => {
|
||||
const workflowId = record.workflowId;
|
||||
const workflowId = record.workflowRef;
|
||||
return (
|
||||
<div className="flex max-w-full flex-col gap-1 truncate">
|
||||
<Typography.Text ellipsis>{t(`certificate.props.source.${record.source}`)}</Typography.Text>
|
||||
@@ -117,7 +117,7 @@ const CertificateList = () => {
|
||||
}
|
||||
}}
|
||||
>
|
||||
{record.expand?.workflowId?.name ?? <span className="font-mono">{t(`#${workflowId}`)}</span>}
|
||||
{record.expand?.workflowRef?.name ?? <span className="font-mono">{t(`#${workflowId}`)}</span>}
|
||||
</Typography.Link>
|
||||
</div>
|
||||
);
|
||||
@@ -218,7 +218,7 @@ const CertificateList = () => {
|
||||
() => {
|
||||
const { columnKey: sorterKey, order: sorterOrder } = sorter;
|
||||
let sort: string | undefined;
|
||||
sort = sorterKey === "expiry" ? "expireAt" : "";
|
||||
sort = sorterKey === "validity" ? "validityNotAfter" : "";
|
||||
sort = sort && (sorterOrder === "ascend" ? `${sort}` : sorterOrder === "descend" ? `-${sort}` : undefined);
|
||||
|
||||
return listCertificates({
|
||||
|
||||
@@ -245,7 +245,7 @@ const WorkflowRunHistoryTable = ({ className, style }: { className?: string; sty
|
||||
key: "name",
|
||||
title: t("workflow.props.name"),
|
||||
render: (_, record) => {
|
||||
const workflow = record.expand?.workflowId;
|
||||
const workflow = record.expand?.workflowRef;
|
||||
return (
|
||||
<div className="max-w-full truncate">
|
||||
<Typography.Link
|
||||
@@ -256,7 +256,7 @@ const WorkflowRunHistoryTable = ({ className, style }: { className?: string; sty
|
||||
}
|
||||
}}
|
||||
>
|
||||
{workflow?.name ?? <span className="font-mono">{t(`#${record.workflowId}`)}</span>}
|
||||
{workflow?.name ?? <span className="font-mono">{t(`#${record.workflowRef}`)}</span>}
|
||||
</Typography.Link>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -64,10 +64,10 @@ const WorkflowList = () => {
|
||||
return "-";
|
||||
} else if (trigger === WORKFLOW_TRIGGERS.MANUAL) {
|
||||
return <Typography.Text>{t("workflow.props.trigger.manual")}</Typography.Text>;
|
||||
} else if (trigger === WORKFLOW_TRIGGERS.AUTO) {
|
||||
} else if (trigger === WORKFLOW_TRIGGERS.SCHEDULED) {
|
||||
return (
|
||||
<div className="flex max-w-full flex-col gap-1">
|
||||
<Typography.Text>{t("workflow.props.trigger.auto")}</Typography.Text>
|
||||
<Typography.Text>{t("workflow.props.trigger.scheduled")}</Typography.Text>
|
||||
<Typography.Text type="secondary">{record.triggerCron || "\u00A0"}</Typography.Text>
|
||||
</div>
|
||||
);
|
||||
|
||||
@@ -19,9 +19,9 @@ export const list = async (request: ListRequest) => {
|
||||
filters.push(pb.filter("(subjectAltNames~{:keyword} || serialNumber={:keyword})", { keyword: request.keyword }));
|
||||
}
|
||||
if (request.state === "expireSoon") {
|
||||
filters.push(pb.filter("expireAt<{:expiredAt} && expireAt>@now", { expiredAt: dayjs().add(20, "d").toDate() }));
|
||||
filters.push(pb.filter("validityNotAfter<{:expiredAt} && validityNotAfter>@now", { expiredAt: dayjs().add(20, "d").toDate() }));
|
||||
} else if (request.state === "expired") {
|
||||
filters.push(pb.filter("expireAt<={:expiredAt}", { expiredAt: new Date() }));
|
||||
filters.push(pb.filter("validityNotAfter<={:expiredAt}", { expiredAt: new Date() }));
|
||||
}
|
||||
|
||||
const sort = request.sort || "-created";
|
||||
@@ -30,7 +30,7 @@ export const list = async (request: ListRequest) => {
|
||||
const perPage = request.perPage || 10;
|
||||
|
||||
return pb.collection(COLLECTION_NAME_CERTIFICATE).getList<CertificateModel>(page, perPage, {
|
||||
expand: "workflowId",
|
||||
expand: "workflowRef",
|
||||
filter: filters.join(" && "),
|
||||
sort: sort,
|
||||
requestKey: null,
|
||||
@@ -42,7 +42,7 @@ export const listByWorkflowRunId = async (workflowRunId: string) => {
|
||||
|
||||
const list = await pb.collection(COLLECTION_NAME_CERTIFICATE).getFullList<CertificateModel>({
|
||||
batch: 65535,
|
||||
filter: pb.filter("workflowRunId={:workflowRunId}", { workflowRunId: workflowRunId }),
|
||||
filter: pb.filter("workflowRunRef={:workflowRunId}", { workflowRunId }),
|
||||
sort: "created",
|
||||
requestKey: null,
|
||||
});
|
||||
|
||||
@@ -7,7 +7,7 @@ export const listByWorkflowRunId = async (workflowRunId: string) => {
|
||||
|
||||
const list = await pb.collection(COLLECTION_NAME_WORKFLOW_LOG).getFullList<WorkflowLogModel>({
|
||||
batch: 65535,
|
||||
filter: pb.filter("runId={:runId}", { runId: workflowRunId }),
|
||||
filter: pb.filter("runRef={:workflowRunId}", { workflowRunId }),
|
||||
sort: "timestamp",
|
||||
requestKey: null,
|
||||
});
|
||||
|
||||
@@ -16,7 +16,7 @@ export const list = async (request: ListRequest) => {
|
||||
|
||||
const filters: string[] = [];
|
||||
if (request.workflowId) {
|
||||
filters.push(pb.filter("workflowId={:workflowId}", { workflowId: request.workflowId }));
|
||||
filters.push(pb.filter("workflowRef={:workflowId}", { workflowId: request.workflowId }));
|
||||
}
|
||||
|
||||
const page = request.page || 1;
|
||||
@@ -25,7 +25,7 @@ export const list = async (request: ListRequest) => {
|
||||
filter: filters.join(" && "),
|
||||
sort: "-created",
|
||||
requestKey: null,
|
||||
expand: request.expand ? "workflowId" : undefined,
|
||||
expand: request.expand ? "workflowRef" : undefined,
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user