feat: Implement video workflow repository and related services

- Added videoWorkflowRepository with methods to manage video and user interactions.
- Introduced catalog_mapper for converting database models to protobuf representations.
- Created domain_helpers for normalizing domain and ad format values.
- Defined service interfaces for payment, account, notification, domain, ad template, player config, video, and user management.
- Implemented OAuth helpers for generating state and caching keys.
- Developed payment_proto_helpers for mapping payment-related models to protobuf.
- Added service policy helpers to enforce plan requirements and user permissions.
- Created user_mapper for converting user payloads to protobuf format.
- Implemented value_helpers for handling various value conversions and nil checks.
- Developed video_helpers for normalizing video statuses and managing storage types.
- Created video_mapper for mapping video models to protobuf format.
- Implemented render workflow for managing video creation and job processing.
This commit is contained in:
2026-03-26 18:38:47 +07:00
parent fbbecd7674
commit a0ae2b681a
55 changed files with 3464 additions and 13091 deletions

View File

@@ -0,0 +1,103 @@
package service
import appv1 "stream.api/internal/api/proto/app/v1"
import "stream.api/internal/database/model"
func toProtoDomain(item *model.Domain) *appv1.Domain {
if item == nil {
return nil
}
return &appv1.Domain{
Id: item.ID,
Name: item.Name,
CreatedAt: timeToProto(item.CreatedAt),
UpdatedAt: timeToProto(item.UpdatedAt),
}
}
func toProtoAdTemplate(item *model.AdTemplate) *appv1.AdTemplate {
if item == nil {
return nil
}
return &appv1.AdTemplate{
Id: item.ID,
Name: item.Name,
Description: item.Description,
VastTagUrl: item.VastTagURL,
AdFormat: model.StringValue(item.AdFormat),
Duration: int64PtrToInt32Ptr(item.Duration),
IsActive: boolValue(item.IsActive),
IsDefault: item.IsDefault,
CreatedAt: timeToProto(item.CreatedAt),
UpdatedAt: timeToProto(item.UpdatedAt),
}
}
func toProtoPlayerConfig(item *model.PlayerConfig) *appv1.PlayerConfig {
if item == nil {
return nil
}
return &appv1.PlayerConfig{
Id: item.ID,
Name: item.Name,
Description: item.Description,
Autoplay: item.Autoplay,
Loop: item.Loop,
Muted: item.Muted,
ShowControls: boolValue(item.ShowControls),
Pip: boolValue(item.Pip),
Airplay: boolValue(item.Airplay),
Chromecast: boolValue(item.Chromecast),
IsActive: boolValue(item.IsActive),
IsDefault: item.IsDefault,
CreatedAt: timeToProto(item.CreatedAt),
UpdatedAt: timeToProto(&item.UpdatedAt),
EncrytionM3U8: boolValue(item.EncrytionM3u8),
LogoUrl: nullableTrimmedString(item.LogoURL),
}
}
func toProtoAdminPlayerConfig(item *model.PlayerConfig, ownerEmail *string) *appv1.AdminPlayerConfig {
if item == nil {
return nil
}
return &appv1.AdminPlayerConfig{
Id: item.ID,
UserId: item.UserID,
Name: item.Name,
Description: item.Description,
Autoplay: item.Autoplay,
Loop: item.Loop,
Muted: item.Muted,
ShowControls: boolValue(item.ShowControls),
Pip: boolValue(item.Pip),
Airplay: boolValue(item.Airplay),
Chromecast: boolValue(item.Chromecast),
IsActive: boolValue(item.IsActive),
IsDefault: item.IsDefault,
OwnerEmail: ownerEmail,
CreatedAt: timeToProto(item.CreatedAt),
UpdatedAt: timeToProto(&item.UpdatedAt),
EncrytionM3U8: boolValue(item.EncrytionM3u8),
LogoUrl: nullableTrimmedString(item.LogoURL),
}
}
func toProtoPlan(item *model.Plan) *appv1.Plan {
if item == nil {
return nil
}
return &appv1.Plan{
Id: item.ID,
Name: item.Name,
Description: item.Description,
Price: item.Price,
Cycle: item.Cycle,
StorageLimit: item.StorageLimit,
UploadLimit: item.UploadLimit,
DurationLimit: item.DurationLimit,
QualityLimit: item.QualityLimit,
Features: item.Features,
IsActive: boolValue(item.IsActive),
}
}