package repository import ( "context" "time" "github.com/geo-platform/tenant-api/internal/tenant/repository/generated" ) type ImageAsset struct { ID int64 TenantID int64 FolderID *int64 ObjectKey string Name string SizeBytes int64 Status string CreatedBy int64 CreatedAt time.Time UpdatedAt time.Time } type ImageAssetListParams struct { TenantID int64 FolderID *int64 SearchQuery *string PageSize int PageOffset int } type InsertImageAssetInput struct { TenantID int64 FolderID *int64 ObjectKey string Name string SizeBytes int64 Status string CreatedBy int64 } type FolderImageSummary struct { ID int64 ObjectKey string SizeBytes int64 } type ImageRepository interface { List(ctx context.Context, params ImageAssetListParams) ([]ImageAsset, int, error) Get(ctx context.Context, tenantID, id int64) (*ImageAsset, error) Insert(ctx context.Context, input InsertImageAssetInput) (int64, error) UpdateStatus(ctx context.Context, tenantID, id int64, status string) error MarkDeleted(ctx context.Context, tenantID, id int64) error UpdateName(ctx context.Context, tenantID, id int64, name string) error UpdateFolder(ctx context.Context, tenantID, id int64, folderID *int64) error ListActiveByFolder(ctx context.Context, tenantID, folderID int64) ([]FolderImageSummary, error) MarkImagesInFolderPendingDelete(ctx context.Context, tenantID, folderID int64) error CountUncategorized(ctx context.Context, tenantID int64) (int, error) } type imageRepository struct { q generated.Querier } func NewImageRepository(db generated.DBTX) ImageRepository { return &imageRepository{q: newQuerier(db)} } func (r *imageRepository) List(ctx context.Context, params ImageAssetListParams) ([]ImageAsset, int, error) { listParams := generated.ListImageAssetsParams{ TenantID: params.TenantID, FolderID: pgInt8(params.FolderID), PageOffset: int32(params.PageOffset), PageSize: int32(params.PageSize), SearchQuery: pgText(params.SearchQuery), } rows, err := r.q.ListImageAssets(ctx, listParams) if err != nil { return nil, 0, err } total, err := r.q.CountImageAssets(ctx, generated.CountImageAssetsParams{ TenantID: params.TenantID, FolderID: listParams.FolderID, SearchQuery: listParams.SearchQuery, }) if err != nil { return nil, 0, err } assets := make([]ImageAsset, len(rows)) for i, row := range rows { assets[i] = ImageAsset{ ID: row.ID, TenantID: row.TenantID, FolderID: nullableInt64(row.FolderID), ObjectKey: row.ObjectKey, Name: row.Name, SizeBytes: row.SizeBytes, Status: row.Status, CreatedBy: row.CreatedBy, CreatedAt: timeFromTimestamp(row.CreatedAt), UpdatedAt: timeFromTimestamp(row.UpdatedAt), } } return assets, int(total), nil } func (r *imageRepository) Get(ctx context.Context, tenantID, id int64) (*ImageAsset, error) { row, err := r.q.GetImageAsset(ctx, generated.GetImageAssetParams{ ID: id, TenantID: tenantID, }) if err != nil { return nil, err } return &ImageAsset{ ID: row.ID, TenantID: row.TenantID, FolderID: nullableInt64(row.FolderID), ObjectKey: row.ObjectKey, Name: row.Name, SizeBytes: row.SizeBytes, Status: row.Status, CreatedBy: row.CreatedBy, CreatedAt: timeFromTimestamp(row.CreatedAt), UpdatedAt: timeFromTimestamp(row.UpdatedAt), }, nil } func (r *imageRepository) Insert(ctx context.Context, input InsertImageAssetInput) (int64, error) { return r.q.InsertImageAsset(ctx, generated.InsertImageAssetParams{ TenantID: input.TenantID, FolderID: pgInt8(input.FolderID), ObjectKey: input.ObjectKey, Name: input.Name, SizeBytes: input.SizeBytes, Status: input.Status, CreatedBy: input.CreatedBy, }) } func (r *imageRepository) UpdateStatus(ctx context.Context, tenantID, id int64, status string) error { return r.q.UpdateImageAssetStatus(ctx, generated.UpdateImageAssetStatusParams{ Status: status, ID: id, TenantID: tenantID, }) } func (r *imageRepository) MarkDeleted(ctx context.Context, tenantID, id int64) error { return r.q.UpdateImageAssetDeleted(ctx, generated.UpdateImageAssetDeletedParams{ ID: id, TenantID: tenantID, }) } func (r *imageRepository) UpdateName(ctx context.Context, tenantID, id int64, name string) error { return r.q.UpdateImageAssetName(ctx, generated.UpdateImageAssetNameParams{ Name: name, ID: id, TenantID: tenantID, }) } func (r *imageRepository) UpdateFolder(ctx context.Context, tenantID, id int64, folderID *int64) error { return r.q.UpdateImageAssetFolder(ctx, generated.UpdateImageAssetFolderParams{ FolderID: pgInt8(folderID), ID: id, TenantID: tenantID, }) } func (r *imageRepository) ListActiveByFolder(ctx context.Context, tenantID, folderID int64) ([]FolderImageSummary, error) { rows, err := r.q.ListActiveImagesByFolder(ctx, generated.ListActiveImagesByFolderParams{ TenantID: tenantID, FolderID: pgInt8(&folderID), }) if err != nil { return nil, err } result := make([]FolderImageSummary, len(rows)) for i, row := range rows { result[i] = FolderImageSummary{ ID: row.ID, ObjectKey: row.ObjectKey, SizeBytes: row.SizeBytes, } } return result, nil } func (r *imageRepository) MarkImagesInFolderPendingDelete(ctx context.Context, tenantID, folderID int64) error { return r.q.MarkImagesInFolderPendingDelete(ctx, generated.MarkImagesInFolderPendingDeleteParams{ TenantID: tenantID, FolderID: pgInt8(&folderID), }) } func (r *imageRepository) CountUncategorized(ctx context.Context, tenantID int64) (int, error) { count, err := r.q.CountUncategorizedImages(ctx, tenantID) if err != nil { return 0, err } return int(count), nil }