Files
cmr-mini/backend/internal/service/release_view.go

281 lines
8.6 KiB
Go

package service
import (
"context"
"strings"
"cmr-backend/internal/store/postgres"
)
const (
LaunchSourceEventCurrentRelease = "event_current_release"
LaunchModeManifestRelease = "manifest_release"
)
type ResolvedReleaseView struct {
LaunchMode string `json:"launchMode"`
Source string `json:"source"`
EventID string `json:"eventId"`
ReleaseID string `json:"releaseId"`
ConfigLabel string `json:"configLabel"`
ManifestURL string `json:"manifestUrl"`
ManifestChecksumSha256 *string `json:"manifestChecksumSha256,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
}
type RuntimeSummaryView struct {
RuntimeBindingID string `json:"runtimeBindingId"`
PlaceID string `json:"placeId"`
PlaceName *string `json:"placeName,omitempty"`
MapID string `json:"mapId"`
MapName *string `json:"mapName,omitempty"`
TileReleaseID string `json:"tileReleaseId"`
CourseSetID string `json:"courseSetId"`
CourseVariantID string `json:"courseVariantId"`
CourseVariantName *string `json:"courseVariantName,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
}
type PresentationSummaryView struct {
PresentationID string `json:"presentationId"`
Name *string `json:"name,omitempty"`
PresentationType *string `json:"presentationType,omitempty"`
TemplateKey *string `json:"templateKey,omitempty"`
Version *string `json:"version,omitempty"`
}
type ContentBundleSummaryView struct {
ContentBundleID string `json:"contentBundleId"`
Name *string `json:"name,omitempty"`
BundleType *string `json:"bundleType,omitempty"`
Version *string `json:"version,omitempty"`
EntryURL *string `json:"entryUrl,omitempty"`
AssetRootURL *string `json:"assetRootUrl,omitempty"`
}
func buildResolvedReleaseFromEvent(event *postgres.Event, source string) *ResolvedReleaseView {
if event == nil || event.CurrentReleasePubID == nil || event.ConfigLabel == nil || event.ManifestURL == nil {
return nil
}
return &ResolvedReleaseView{
LaunchMode: LaunchModeManifestRelease,
Source: source,
EventID: event.PublicID,
ReleaseID: *event.CurrentReleasePubID,
ConfigLabel: *event.ConfigLabel,
ManifestURL: *event.ManifestURL,
ManifestChecksumSha256: event.ManifestChecksum,
RouteCode: event.RouteCode,
}
}
func buildRuntimeSummaryFromEvent(event *postgres.Event) *RuntimeSummaryView {
if event == nil ||
event.RuntimeBindingID == nil ||
event.PlacePublicID == nil ||
event.MapAssetPublicID == nil ||
event.TileReleasePublicID == nil ||
event.CourseSetPublicID == nil ||
event.CourseVariantID == nil {
return nil
}
return &RuntimeSummaryView{
RuntimeBindingID: *event.RuntimeBindingID,
PlaceID: *event.PlacePublicID,
PlaceName: event.PlaceName,
MapID: *event.MapAssetPublicID,
MapName: event.MapAssetName,
TileReleaseID: *event.TileReleasePublicID,
CourseSetID: *event.CourseSetPublicID,
CourseVariantID: *event.CourseVariantID,
CourseVariantName: event.CourseVariantName,
RouteCode: firstNonNilString(event.RuntimeRouteCode, event.RouteCode),
}
}
func buildRuntimeSummaryFromRelease(release *postgres.EventRelease) *RuntimeSummaryView {
if release == nil ||
release.RuntimeBindingID == nil ||
release.PlacePublicID == nil ||
release.MapAssetPublicID == nil ||
release.TileReleaseID == nil ||
release.CourseSetID == nil ||
release.CourseVariantID == nil {
return nil
}
return &RuntimeSummaryView{
RuntimeBindingID: *release.RuntimeBindingID,
PlaceID: *release.PlacePublicID,
PlaceName: release.PlaceName,
MapID: *release.MapAssetPublicID,
MapName: release.MapAssetName,
TileReleaseID: *release.TileReleaseID,
CourseSetID: *release.CourseSetID,
CourseVariantID: *release.CourseVariantID,
CourseVariantName: release.CourseVariantName,
RouteCode: firstNonNilString(release.RuntimeRouteCode, release.RouteCode),
}
}
func buildPresentationSummaryFromEvent(event *postgres.Event) *PresentationSummaryView {
if event == nil || event.PresentationID == nil {
return nil
}
return &PresentationSummaryView{
PresentationID: *event.PresentationID,
Name: event.PresentationName,
PresentationType: event.PresentationType,
}
}
func buildPresentationSummaryFromRelease(release *postgres.EventRelease) *PresentationSummaryView {
if release == nil || release.PresentationID == nil {
return nil
}
return &PresentationSummaryView{
PresentationID: *release.PresentationID,
Name: release.PresentationName,
PresentationType: release.PresentationType,
}
}
func buildContentBundleSummaryFromEvent(event *postgres.Event) *ContentBundleSummaryView {
if event == nil || event.ContentBundleID == nil {
return nil
}
return &ContentBundleSummaryView{
ContentBundleID: *event.ContentBundleID,
Name: event.ContentBundleName,
EntryURL: event.ContentEntryURL,
AssetRootURL: event.ContentAssetRootURL,
}
}
func buildContentBundleSummaryFromRelease(release *postgres.EventRelease) *ContentBundleSummaryView {
if release == nil || release.ContentBundleID == nil {
return nil
}
return &ContentBundleSummaryView{
ContentBundleID: *release.ContentBundleID,
Name: release.ContentBundleName,
EntryURL: release.ContentEntryURL,
AssetRootURL: release.ContentAssetURL,
}
}
func buildResolvedReleaseFromSession(session *postgres.Session, source string) *ResolvedReleaseView {
if session == nil || session.ReleasePublicID == nil || session.ConfigLabel == nil || session.ManifestURL == nil {
return nil
}
view := &ResolvedReleaseView{
LaunchMode: LaunchModeManifestRelease,
Source: source,
ReleaseID: *session.ReleasePublicID,
ConfigLabel: *session.ConfigLabel,
ManifestURL: *session.ManifestURL,
ManifestChecksumSha256: session.ManifestChecksum,
RouteCode: session.RouteCode,
}
if session.EventPublicID != nil {
view.EventID = *session.EventPublicID
}
return view
}
func loadPresentationSummaryByPublicID(ctx context.Context, store *postgres.Store, publicID *string) (*PresentationSummaryView, error) {
if store == nil || publicID == nil || strings.TrimSpace(*publicID) == "" {
return nil, nil
}
record, err := store.GetEventPresentationByPublicID(ctx, strings.TrimSpace(*publicID))
if err != nil {
return nil, err
}
if record == nil {
return nil, nil
}
return buildPresentationSummaryFromRecord(record)
}
func loadContentBundleSummaryByPublicID(ctx context.Context, store *postgres.Store, publicID *string) (*ContentBundleSummaryView, error) {
if store == nil || publicID == nil || strings.TrimSpace(*publicID) == "" {
return nil, nil
}
record, err := store.GetContentBundleByPublicID(ctx, strings.TrimSpace(*publicID))
if err != nil {
return nil, err
}
if record == nil {
return nil, nil
}
return buildContentBundleSummaryFromRecord(record)
}
func buildPresentationSummaryFromRecord(record *postgres.EventPresentation) (*PresentationSummaryView, error) {
if record == nil {
return nil, nil
}
summary := &PresentationSummaryView{
PresentationID: record.PublicID,
Name: &record.Name,
PresentationType: &record.PresentationType,
}
schema, err := decodeJSONObject(record.SchemaJSON)
if err != nil {
return nil, err
}
summary.TemplateKey = readStringField(schema, "templateKey")
summary.Version = readStringField(schema, "version")
return summary, nil
}
func buildContentBundleSummaryFromRecord(record *postgres.ContentBundle) (*ContentBundleSummaryView, error) {
if record == nil {
return nil, nil
}
summary := &ContentBundleSummaryView{
ContentBundleID: record.PublicID,
Name: &record.Name,
EntryURL: record.EntryURL,
AssetRootURL: record.AssetRootURL,
}
metadata, err := decodeJSONObject(record.MetadataJSON)
if err != nil {
return nil, err
}
summary.BundleType = readStringField(metadata, "bundleType")
summary.Version = readStringField(metadata, "version")
return summary, nil
}
func readStringField(object map[string]any, key string) *string {
if object == nil {
return nil
}
value, ok := object[key]
if !ok {
return nil
}
text, ok := value.(string)
if !ok {
return nil
}
text = strings.TrimSpace(text)
if text == "" {
return nil
}
return &text
}
func firstNonNilString(values ...*string) *string {
for _, value := range values {
if value != nil {
return value
}
}
return nil
}