feat(kol): store KOL prompt content in database with object storage fallback
Add prompt_content columns to kol_prompts and kol_prompt_revisions so prompt bodies live alongside their metadata, eliminating an extra round trip to object storage for the common read path while keeping the old asset key as a fallback for legacy rows. Reads go through a singleflight-deduped, cache-backed loader that prefers the database column, falls back to the asset key, and tolerates missing objects via a new objectstorage.ErrObjectNotFound returned by both the Aliyun OSS and MinIO clients on 404/NoSuchKey responses. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -24,14 +24,15 @@ import (
|
||||
)
|
||||
|
||||
type ScheduleTaskService struct {
|
||||
pool *pgxpool.Pool
|
||||
auditLogs *auditlog.AsyncWriter
|
||||
cache sharedcache.Cache
|
||||
cacheGroup singleflight.Group
|
||||
pool *pgxpool.Pool
|
||||
auditLogs *auditlog.AsyncWriter
|
||||
promptAsset *KolPromptAsset
|
||||
cache sharedcache.Cache
|
||||
cacheGroup singleflight.Group
|
||||
}
|
||||
|
||||
func NewScheduleTaskService(pool *pgxpool.Pool, auditLogs *auditlog.AsyncWriter) *ScheduleTaskService {
|
||||
return &ScheduleTaskService{pool: pool, auditLogs: auditLogs}
|
||||
func NewScheduleTaskService(pool *pgxpool.Pool, auditLogs *auditlog.AsyncWriter, promptAsset *KolPromptAsset) *ScheduleTaskService {
|
||||
return &ScheduleTaskService{pool: pool, auditLogs: auditLogs, promptAsset: promptAsset}
|
||||
}
|
||||
|
||||
func (s *ScheduleTaskService) WithCache(c sharedcache.Cache) *ScheduleTaskService {
|
||||
@@ -1006,7 +1007,14 @@ func (s *ScheduleTaskService) validateKolScheduleGenerationInput(ctx context.Con
|
||||
if err != nil {
|
||||
return input, response.ErrInternal(50110, "kol_prompt_query_failed", err.Error())
|
||||
}
|
||||
if prompt == nil || prompt.PromptAssetKey == nil || *prompt.PromptAssetKey == "" {
|
||||
if prompt == nil {
|
||||
return input, response.ErrInternal(50111, "kol_prompt_content_missing", "published prompt content not found")
|
||||
}
|
||||
content, err := loadKolPromptContent(ctx, s.cache, &s.cacheGroup, repository.NewKolPromptRepository(s.pool), s.promptAsset, prompt)
|
||||
if err != nil {
|
||||
return input, response.ErrInternal(50110, "kol_prompt_query_failed", err.Error())
|
||||
}
|
||||
if strings.TrimSpace(content) == "" {
|
||||
return input, response.ErrInternal(50111, "kol_prompt_content_missing", "published prompt content not found")
|
||||
}
|
||||
schema, err := decodeKolSchema(prompt.SchemaJSON)
|
||||
|
||||
Reference in New Issue
Block a user