package repository import ( "context" "errors" "fmt" "time" "github.com/geo-platform/tenant-api/internal/shared/cache" "github.com/jackc/pgx/v5" "golang.org/x/sync/singleflight" ) const ( templateCacheTTL = 5 * time.Minute templateCacheEmptyTTL = 1 * time.Minute ) type cachedTemplateRepository struct { inner TemplateRepository cache cache.Cache group singleflight.Group } func NewCachedTemplateRepository(inner TemplateRepository, c cache.Cache) TemplateRepository { return &cachedTemplateRepository{inner: inner, cache: c} } func (r *cachedTemplateRepository) ListTemplates(ctx context.Context, tenantID int64) ([]TemplateRecord, error) { key := fmt.Sprintf("tmpl_list:%d", tenantID) records, _, err := cache.LoadJSONWithEmpty(ctx, r.cache, &r.group, key, templateCacheTTL, templateCacheEmptyTTL, func(loadCtx context.Context) ([]TemplateRecord, bool, error) { records, err := r.inner.ListTemplates(loadCtx, tenantID) if err != nil { return nil, false, err } return records, true, nil }) if err != nil { return nil, err } for i := range records { applyPlatformTemplatePromptOverrides(&records[i]) } return records, nil } func (r *cachedTemplateRepository) GetTemplateByID(ctx context.Context, id, tenantID int64) (*TemplateRecord, error) { key := fmt.Sprintf("tmpl:%d:%d", tenantID, id) record, found, err := cache.LoadJSONWithEmpty(ctx, r.cache, &r.group, key, templateCacheTTL, templateCacheEmptyTTL, func(loadCtx context.Context) (*TemplateRecord, bool, error) { record, err := r.inner.GetTemplateByID(loadCtx, id, tenantID) if err != nil { if errors.Is(err, pgx.ErrNoRows) { return nil, false, nil } return nil, false, err } return record, true, nil }) if err != nil { return nil, err } if !found || record == nil { return nil, pgx.ErrNoRows } applyPlatformTemplatePromptOverrides(record) return record, nil }