Files
breakpilot-compliance/ai-compliance-sdk/internal/training/store_media.go
Sharang Parnerkar 9f96061631 refactor(go): split training/store, ucca/rules, ucca_handlers, document_export under 500 LOC
Each of the four oversized files (training/store.go 1569 LOC, ucca/rules.go 1231 LOC,
ucca_handlers.go 1135 LOC, document_export.go 1101 LOC) is split by logical group
into same-package files, all under the 500-line hard cap. Zero behavior changes,
no renamed exported symbols. Also fixed pre-existing hazard_library split (missing
functions and duplicate UUID keys from a prior session).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-19 09:29:54 +02:00

193 lines
6.3 KiB
Go

package training
import (
"context"
"encoding/json"
"time"
"github.com/google/uuid"
"github.com/jackc/pgx/v5"
)
// CreateMedia creates a new media record
func (s *Store) CreateMedia(ctx context.Context, media *TrainingMedia) error {
media.ID = uuid.New()
media.CreatedAt = time.Now().UTC()
media.UpdatedAt = media.CreatedAt
if media.Metadata == nil {
media.Metadata = json.RawMessage("{}")
}
_, err := s.pool.Exec(ctx, `
INSERT INTO training_media (
id, module_id, content_id, media_type, status,
bucket, object_key, file_size_bytes, duration_seconds,
mime_type, voice_model, language, metadata,
error_message, generated_by, is_published, created_at, updated_at
) VALUES (
$1, $2, $3, $4, $5,
$6, $7, $8, $9,
$10, $11, $12, $13,
$14, $15, $16, $17, $18
)
`,
media.ID, media.ModuleID, media.ContentID, string(media.MediaType), string(media.Status),
media.Bucket, media.ObjectKey, media.FileSizeBytes, media.DurationSeconds,
media.MimeType, media.VoiceModel, media.Language, media.Metadata,
media.ErrorMessage, media.GeneratedBy, media.IsPublished, media.CreatedAt, media.UpdatedAt,
)
return err
}
// GetMedia retrieves a media record by ID
func (s *Store) GetMedia(ctx context.Context, id uuid.UUID) (*TrainingMedia, error) {
var media TrainingMedia
var mediaType, status string
err := s.pool.QueryRow(ctx, `
SELECT id, module_id, content_id, media_type, status,
bucket, object_key, file_size_bytes, duration_seconds,
mime_type, voice_model, language, metadata,
error_message, generated_by, is_published, created_at, updated_at
FROM training_media WHERE id = $1
`, id).Scan(
&media.ID, &media.ModuleID, &media.ContentID, &mediaType, &status,
&media.Bucket, &media.ObjectKey, &media.FileSizeBytes, &media.DurationSeconds,
&media.MimeType, &media.VoiceModel, &media.Language, &media.Metadata,
&media.ErrorMessage, &media.GeneratedBy, &media.IsPublished, &media.CreatedAt, &media.UpdatedAt,
)
if err == pgx.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
media.MediaType = MediaType(mediaType)
media.Status = MediaStatus(status)
return &media, nil
}
// GetMediaForModule retrieves all media for a module
func (s *Store) GetMediaForModule(ctx context.Context, moduleID uuid.UUID) ([]TrainingMedia, error) {
rows, err := s.pool.Query(ctx, `
SELECT id, module_id, content_id, media_type, status,
bucket, object_key, file_size_bytes, duration_seconds,
mime_type, voice_model, language, metadata,
error_message, generated_by, is_published, created_at, updated_at
FROM training_media WHERE module_id = $1
ORDER BY media_type, created_at DESC
`, moduleID)
if err != nil {
return nil, err
}
defer rows.Close()
var mediaList []TrainingMedia
for rows.Next() {
var media TrainingMedia
var mediaType, status string
if err := rows.Scan(
&media.ID, &media.ModuleID, &media.ContentID, &mediaType, &status,
&media.Bucket, &media.ObjectKey, &media.FileSizeBytes, &media.DurationSeconds,
&media.MimeType, &media.VoiceModel, &media.Language, &media.Metadata,
&media.ErrorMessage, &media.GeneratedBy, &media.IsPublished, &media.CreatedAt, &media.UpdatedAt,
); err != nil {
return nil, err
}
media.MediaType = MediaType(mediaType)
media.Status = MediaStatus(status)
mediaList = append(mediaList, media)
}
if mediaList == nil {
mediaList = []TrainingMedia{}
}
return mediaList, nil
}
// UpdateMediaStatus updates the status and related fields of a media record
func (s *Store) UpdateMediaStatus(ctx context.Context, id uuid.UUID, status MediaStatus, sizeBytes int64, duration float64, errMsg string) error {
_, err := s.pool.Exec(ctx, `
UPDATE training_media
SET status = $2, file_size_bytes = $3, duration_seconds = $4,
error_message = $5, updated_at = NOW()
WHERE id = $1
`, id, string(status), sizeBytes, duration, errMsg)
return err
}
// PublishMedia publishes or unpublishes a media record
func (s *Store) PublishMedia(ctx context.Context, id uuid.UUID, publish bool) error {
_, err := s.pool.Exec(ctx, `
UPDATE training_media SET is_published = $2, updated_at = NOW() WHERE id = $1
`, id, publish)
return err
}
// GetPublishedAudio gets the published audio for a module
func (s *Store) GetPublishedAudio(ctx context.Context, moduleID uuid.UUID) (*TrainingMedia, error) {
var media TrainingMedia
var mediaType, status string
err := s.pool.QueryRow(ctx, `
SELECT id, module_id, content_id, media_type, status,
bucket, object_key, file_size_bytes, duration_seconds,
mime_type, voice_model, language, metadata,
error_message, generated_by, is_published, created_at, updated_at
FROM training_media
WHERE module_id = $1 AND media_type = 'audio' AND is_published = true
ORDER BY created_at DESC LIMIT 1
`, moduleID).Scan(
&media.ID, &media.ModuleID, &media.ContentID, &mediaType, &status,
&media.Bucket, &media.ObjectKey, &media.FileSizeBytes, &media.DurationSeconds,
&media.MimeType, &media.VoiceModel, &media.Language, &media.Metadata,
&media.ErrorMessage, &media.GeneratedBy, &media.IsPublished, &media.CreatedAt, &media.UpdatedAt,
)
if err == pgx.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
media.MediaType = MediaType(mediaType)
media.Status = MediaStatus(status)
return &media, nil
}
// GetPublishedVideo gets the published video for a module
func (s *Store) GetPublishedVideo(ctx context.Context, moduleID uuid.UUID) (*TrainingMedia, error) {
var media TrainingMedia
var mediaType, status string
err := s.pool.QueryRow(ctx, `
SELECT id, module_id, content_id, media_type, status,
bucket, object_key, file_size_bytes, duration_seconds,
mime_type, voice_model, language, metadata,
error_message, generated_by, is_published, created_at, updated_at
FROM training_media
WHERE module_id = $1 AND media_type = 'video' AND is_published = true
ORDER BY created_at DESC LIMIT 1
`, moduleID).Scan(
&media.ID, &media.ModuleID, &media.ContentID, &mediaType, &status,
&media.Bucket, &media.ObjectKey, &media.FileSizeBytes, &media.DurationSeconds,
&media.MimeType, &media.VoiceModel, &media.Language, &media.Metadata,
&media.ErrorMessage, &media.GeneratedBy, &media.IsPublished, &media.CreatedAt, &media.UpdatedAt,
)
if err == pgx.ErrNoRows {
return nil, nil
}
if err != nil {
return nil, err
}
media.MediaType = MediaType(mediaType)
media.Status = MediaStatus(status)
return &media, nil
}