release_view.go 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. package service
  2. import (
  3. "context"
  4. "strings"
  5. "cmr-backend/internal/store/postgres"
  6. )
  7. const (
  8. LaunchSourceEventCurrentRelease = "event_current_release"
  9. LaunchModeManifestRelease = "manifest_release"
  10. )
  11. type ResolvedReleaseView struct {
  12. LaunchMode string `json:"launchMode"`
  13. Source string `json:"source"`
  14. EventID string `json:"eventId"`
  15. ReleaseID string `json:"releaseId"`
  16. ConfigLabel string `json:"configLabel"`
  17. ManifestURL string `json:"manifestUrl"`
  18. ManifestChecksumSha256 *string `json:"manifestChecksumSha256,omitempty"`
  19. RouteCode *string `json:"routeCode,omitempty"`
  20. }
  21. type RuntimeSummaryView struct {
  22. RuntimeBindingID string `json:"runtimeBindingId"`
  23. PlaceID string `json:"placeId"`
  24. PlaceName *string `json:"placeName,omitempty"`
  25. MapID string `json:"mapId"`
  26. MapName *string `json:"mapName,omitempty"`
  27. TileReleaseID string `json:"tileReleaseId"`
  28. CourseSetID string `json:"courseSetId"`
  29. CourseVariantID string `json:"courseVariantId"`
  30. CourseVariantName *string `json:"courseVariantName,omitempty"`
  31. RouteCode *string `json:"routeCode,omitempty"`
  32. }
  33. type PresentationSummaryView struct {
  34. PresentationID string `json:"presentationId"`
  35. Name *string `json:"name,omitempty"`
  36. PresentationType *string `json:"presentationType,omitempty"`
  37. TemplateKey *string `json:"templateKey,omitempty"`
  38. Version *string `json:"version,omitempty"`
  39. }
  40. type ContentBundleSummaryView struct {
  41. ContentBundleID string `json:"contentBundleId"`
  42. Name *string `json:"name,omitempty"`
  43. BundleType *string `json:"bundleType,omitempty"`
  44. Version *string `json:"version,omitempty"`
  45. EntryURL *string `json:"entryUrl,omitempty"`
  46. AssetRootURL *string `json:"assetRootUrl,omitempty"`
  47. }
  48. func buildResolvedReleaseFromEvent(event *postgres.Event, source string) *ResolvedReleaseView {
  49. if event == nil || event.CurrentReleasePubID == nil || event.ConfigLabel == nil || event.ManifestURL == nil {
  50. return nil
  51. }
  52. return &ResolvedReleaseView{
  53. LaunchMode: LaunchModeManifestRelease,
  54. Source: source,
  55. EventID: event.PublicID,
  56. ReleaseID: *event.CurrentReleasePubID,
  57. ConfigLabel: *event.ConfigLabel,
  58. ManifestURL: *event.ManifestURL,
  59. ManifestChecksumSha256: event.ManifestChecksum,
  60. RouteCode: event.RouteCode,
  61. }
  62. }
  63. func buildRuntimeSummaryFromEvent(event *postgres.Event) *RuntimeSummaryView {
  64. if event == nil ||
  65. event.RuntimeBindingID == nil ||
  66. event.PlacePublicID == nil ||
  67. event.MapAssetPublicID == nil ||
  68. event.TileReleasePublicID == nil ||
  69. event.CourseSetPublicID == nil ||
  70. event.CourseVariantID == nil {
  71. return nil
  72. }
  73. return &RuntimeSummaryView{
  74. RuntimeBindingID: *event.RuntimeBindingID,
  75. PlaceID: *event.PlacePublicID,
  76. PlaceName: event.PlaceName,
  77. MapID: *event.MapAssetPublicID,
  78. MapName: event.MapAssetName,
  79. TileReleaseID: *event.TileReleasePublicID,
  80. CourseSetID: *event.CourseSetPublicID,
  81. CourseVariantID: *event.CourseVariantID,
  82. CourseVariantName: event.CourseVariantName,
  83. RouteCode: firstNonNilString(event.RuntimeRouteCode, event.RouteCode),
  84. }
  85. }
  86. func buildRuntimeSummaryFromRelease(release *postgres.EventRelease) *RuntimeSummaryView {
  87. if release == nil ||
  88. release.RuntimeBindingID == nil ||
  89. release.PlacePublicID == nil ||
  90. release.MapAssetPublicID == nil ||
  91. release.TileReleaseID == nil ||
  92. release.CourseSetID == nil ||
  93. release.CourseVariantID == nil {
  94. return nil
  95. }
  96. return &RuntimeSummaryView{
  97. RuntimeBindingID: *release.RuntimeBindingID,
  98. PlaceID: *release.PlacePublicID,
  99. PlaceName: release.PlaceName,
  100. MapID: *release.MapAssetPublicID,
  101. MapName: release.MapAssetName,
  102. TileReleaseID: *release.TileReleaseID,
  103. CourseSetID: *release.CourseSetID,
  104. CourseVariantID: *release.CourseVariantID,
  105. CourseVariantName: release.CourseVariantName,
  106. RouteCode: firstNonNilString(release.RuntimeRouteCode, release.RouteCode),
  107. }
  108. }
  109. func buildPresentationSummaryFromEvent(event *postgres.Event) *PresentationSummaryView {
  110. if event == nil || event.PresentationID == nil {
  111. return nil
  112. }
  113. return &PresentationSummaryView{
  114. PresentationID: *event.PresentationID,
  115. Name: event.PresentationName,
  116. PresentationType: event.PresentationType,
  117. }
  118. }
  119. func buildPresentationSummaryFromRelease(release *postgres.EventRelease) *PresentationSummaryView {
  120. if release == nil || release.PresentationID == nil {
  121. return nil
  122. }
  123. return &PresentationSummaryView{
  124. PresentationID: *release.PresentationID,
  125. Name: release.PresentationName,
  126. PresentationType: release.PresentationType,
  127. }
  128. }
  129. func buildContentBundleSummaryFromEvent(event *postgres.Event) *ContentBundleSummaryView {
  130. if event == nil || event.ContentBundleID == nil {
  131. return nil
  132. }
  133. return &ContentBundleSummaryView{
  134. ContentBundleID: *event.ContentBundleID,
  135. Name: event.ContentBundleName,
  136. EntryURL: event.ContentEntryURL,
  137. AssetRootURL: event.ContentAssetRootURL,
  138. }
  139. }
  140. func buildContentBundleSummaryFromRelease(release *postgres.EventRelease) *ContentBundleSummaryView {
  141. if release == nil || release.ContentBundleID == nil {
  142. return nil
  143. }
  144. return &ContentBundleSummaryView{
  145. ContentBundleID: *release.ContentBundleID,
  146. Name: release.ContentBundleName,
  147. EntryURL: release.ContentEntryURL,
  148. AssetRootURL: release.ContentAssetURL,
  149. }
  150. }
  151. func buildResolvedReleaseFromSession(session *postgres.Session, source string) *ResolvedReleaseView {
  152. if session == nil || session.ReleasePublicID == nil || session.ConfigLabel == nil || session.ManifestURL == nil {
  153. return nil
  154. }
  155. view := &ResolvedReleaseView{
  156. LaunchMode: LaunchModeManifestRelease,
  157. Source: source,
  158. ReleaseID: *session.ReleasePublicID,
  159. ConfigLabel: *session.ConfigLabel,
  160. ManifestURL: *session.ManifestURL,
  161. ManifestChecksumSha256: session.ManifestChecksum,
  162. RouteCode: session.RouteCode,
  163. }
  164. if session.EventPublicID != nil {
  165. view.EventID = *session.EventPublicID
  166. }
  167. return view
  168. }
  169. func loadPresentationSummaryByPublicID(ctx context.Context, store *postgres.Store, publicID *string) (*PresentationSummaryView, error) {
  170. if store == nil || publicID == nil || strings.TrimSpace(*publicID) == "" {
  171. return nil, nil
  172. }
  173. record, err := store.GetEventPresentationByPublicID(ctx, strings.TrimSpace(*publicID))
  174. if err != nil {
  175. return nil, err
  176. }
  177. if record == nil {
  178. return nil, nil
  179. }
  180. return buildPresentationSummaryFromRecord(record)
  181. }
  182. func loadContentBundleSummaryByPublicID(ctx context.Context, store *postgres.Store, publicID *string) (*ContentBundleSummaryView, error) {
  183. if store == nil || publicID == nil || strings.TrimSpace(*publicID) == "" {
  184. return nil, nil
  185. }
  186. record, err := store.GetContentBundleByPublicID(ctx, strings.TrimSpace(*publicID))
  187. if err != nil {
  188. return nil, err
  189. }
  190. if record == nil {
  191. return nil, nil
  192. }
  193. return buildContentBundleSummaryFromRecord(record)
  194. }
  195. func buildPresentationSummaryFromRecord(record *postgres.EventPresentation) (*PresentationSummaryView, error) {
  196. if record == nil {
  197. return nil, nil
  198. }
  199. summary := &PresentationSummaryView{
  200. PresentationID: record.PublicID,
  201. Name: &record.Name,
  202. PresentationType: &record.PresentationType,
  203. }
  204. schema, err := decodeJSONObject(record.SchemaJSON)
  205. if err != nil {
  206. return nil, err
  207. }
  208. summary.TemplateKey = readStringField(schema, "templateKey")
  209. summary.Version = readStringField(schema, "version")
  210. return summary, nil
  211. }
  212. func buildContentBundleSummaryFromRecord(record *postgres.ContentBundle) (*ContentBundleSummaryView, error) {
  213. if record == nil {
  214. return nil, nil
  215. }
  216. summary := &ContentBundleSummaryView{
  217. ContentBundleID: record.PublicID,
  218. Name: &record.Name,
  219. EntryURL: record.EntryURL,
  220. AssetRootURL: record.AssetRootURL,
  221. }
  222. metadata, err := decodeJSONObject(record.MetadataJSON)
  223. if err != nil {
  224. return nil, err
  225. }
  226. summary.BundleType = readStringField(metadata, "bundleType")
  227. summary.Version = readStringField(metadata, "version")
  228. return summary, nil
  229. }
  230. func readStringField(object map[string]any, key string) *string {
  231. if object == nil {
  232. return nil
  233. }
  234. value, ok := object[key]
  235. if !ok {
  236. return nil
  237. }
  238. text, ok := value.(string)
  239. if !ok {
  240. return nil
  241. }
  242. text = strings.TrimSpace(text)
  243. if text == "" {
  244. return nil
  245. }
  246. return &text
  247. }
  248. func firstNonNilString(values ...*string) *string {
  249. for _, value := range values {
  250. if value != nil {
  251. return value
  252. }
  253. }
  254. return nil
  255. }