| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719 |
- package service
- import (
- "context"
- "encoding/json"
- "net/http"
- "strings"
- "cmr-backend/internal/apperr"
- "cmr-backend/internal/platform/security"
- "cmr-backend/internal/store/postgres"
- )
- type AdminResourceService struct {
- store *postgres.Store
- }
- type AdminMapSummary struct {
- ID string `json:"id"`
- Code string `json:"code"`
- Name string `json:"name"`
- Status string `json:"status"`
- Description *string `json:"description,omitempty"`
- CurrentVersionID *string `json:"currentVersionId,omitempty"`
- CurrentVersion *AdminMapVersionBrief `json:"currentVersion,omitempty"`
- }
- type AdminMapVersionBrief struct {
- ID string `json:"id"`
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- }
- type AdminMapVersion struct {
- ID string `json:"id"`
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- MapmetaURL string `json:"mapmetaUrl"`
- TilesRootURL string `json:"tilesRootUrl"`
- PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
- Bounds map[string]any `json:"bounds,omitempty"`
- Metadata map[string]any `json:"metadata,omitempty"`
- }
- type AdminMapDetail struct {
- Map AdminMapSummary `json:"map"`
- Versions []AdminMapVersion `json:"versions"`
- }
- type CreateAdminMapInput struct {
- Code string `json:"code"`
- Name string `json:"name"`
- Status string `json:"status"`
- Description *string `json:"description,omitempty"`
- }
- type CreateAdminMapVersionInput struct {
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- MapmetaURL string `json:"mapmetaUrl"`
- TilesRootURL string `json:"tilesRootUrl"`
- PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
- Bounds map[string]any `json:"bounds,omitempty"`
- Metadata map[string]any `json:"metadata,omitempty"`
- SetAsCurrent bool `json:"setAsCurrent"`
- }
- type AdminPlayfieldSummary struct {
- ID string `json:"id"`
- Code string `json:"code"`
- Name string `json:"name"`
- Kind string `json:"kind"`
- Status string `json:"status"`
- Description *string `json:"description,omitempty"`
- CurrentVersionID *string `json:"currentVersionId,omitempty"`
- CurrentVersion *AdminPlayfieldVersionBrief `json:"currentVersion,omitempty"`
- }
- type AdminPlayfieldVersionBrief struct {
- ID string `json:"id"`
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- SourceType string `json:"sourceType"`
- }
- type AdminPlayfieldVersion struct {
- ID string `json:"id"`
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- SourceType string `json:"sourceType"`
- SourceURL string `json:"sourceUrl"`
- PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
- ControlCount *int `json:"controlCount,omitempty"`
- Bounds map[string]any `json:"bounds,omitempty"`
- Metadata map[string]any `json:"metadata,omitempty"`
- }
- type AdminPlayfieldDetail struct {
- Playfield AdminPlayfieldSummary `json:"playfield"`
- Versions []AdminPlayfieldVersion `json:"versions"`
- }
- type CreateAdminPlayfieldInput struct {
- Code string `json:"code"`
- Name string `json:"name"`
- Kind string `json:"kind"`
- Status string `json:"status"`
- Description *string `json:"description,omitempty"`
- }
- type CreateAdminPlayfieldVersionInput struct {
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- SourceType string `json:"sourceType"`
- SourceURL string `json:"sourceUrl"`
- PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
- ControlCount *int `json:"controlCount,omitempty"`
- Bounds map[string]any `json:"bounds,omitempty"`
- Metadata map[string]any `json:"metadata,omitempty"`
- SetAsCurrent bool `json:"setAsCurrent"`
- }
- type AdminResourcePackSummary struct {
- ID string `json:"id"`
- Code string `json:"code"`
- Name string `json:"name"`
- Status string `json:"status"`
- Description *string `json:"description,omitempty"`
- CurrentVersionID *string `json:"currentVersionId,omitempty"`
- CurrentVersion *AdminResourcePackVersionBrief `json:"currentVersion,omitempty"`
- }
- type AdminResourcePackVersionBrief struct {
- ID string `json:"id"`
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- }
- type AdminResourcePackVersion struct {
- ID string `json:"id"`
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- ContentEntryURL *string `json:"contentEntryUrl,omitempty"`
- AudioRootURL *string `json:"audioRootUrl,omitempty"`
- ThemeProfileCode *string `json:"themeProfileCode,omitempty"`
- PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
- Metadata map[string]any `json:"metadata,omitempty"`
- }
- type AdminResourcePackDetail struct {
- ResourcePack AdminResourcePackSummary `json:"resourcePack"`
- Versions []AdminResourcePackVersion `json:"versions"`
- }
- type CreateAdminResourcePackInput struct {
- Code string `json:"code"`
- Name string `json:"name"`
- Status string `json:"status"`
- Description *string `json:"description,omitempty"`
- }
- type CreateAdminResourcePackVersionInput struct {
- VersionCode string `json:"versionCode"`
- Status string `json:"status"`
- ContentEntryURL *string `json:"contentEntryUrl,omitempty"`
- AudioRootURL *string `json:"audioRootUrl,omitempty"`
- ThemeProfileCode *string `json:"themeProfileCode,omitempty"`
- PublishedAssetRoot *string `json:"publishedAssetRoot,omitempty"`
- Metadata map[string]any `json:"metadata,omitempty"`
- SetAsCurrent bool `json:"setAsCurrent"`
- }
- func NewAdminResourceService(store *postgres.Store) *AdminResourceService {
- return &AdminResourceService{store: store}
- }
- func (s *AdminResourceService) ListMaps(ctx context.Context, limit int) ([]AdminMapSummary, error) {
- items, err := s.store.ListResourceMaps(ctx, limit)
- if err != nil {
- return nil, err
- }
- results := make([]AdminMapSummary, 0, len(items))
- for _, item := range items {
- results = append(results, AdminMapSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- })
- }
- return results, nil
- }
- func (s *AdminResourceService) CreateMap(ctx context.Context, input CreateAdminMapInput) (*AdminMapSummary, error) {
- input.Code = strings.TrimSpace(input.Code)
- input.Name = strings.TrimSpace(input.Name)
- status := normalizeCatalogStatus(input.Status)
- if input.Code == "" || input.Name == "" {
- return nil, apperr.New(http.StatusBadRequest, "invalid_params", "code and name are required")
- }
- publicID, err := security.GeneratePublicID("map")
- if err != nil {
- return nil, err
- }
- tx, err := s.store.Begin(ctx)
- if err != nil {
- return nil, err
- }
- defer tx.Rollback(ctx)
- item, err := s.store.CreateResourceMap(ctx, tx, postgres.CreateResourceMapParams{
- PublicID: publicID,
- Code: input.Code,
- Name: input.Name,
- Status: status,
- Description: trimStringPtr(input.Description),
- })
- if err != nil {
- return nil, err
- }
- if err := tx.Commit(ctx); err != nil {
- return nil, err
- }
- return &AdminMapSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- }, nil
- }
- func (s *AdminResourceService) GetMapDetail(ctx context.Context, mapPublicID string) (*AdminMapDetail, error) {
- item, err := s.store.GetResourceMapByPublicID(ctx, strings.TrimSpace(mapPublicID))
- if err != nil {
- return nil, err
- }
- if item == nil {
- return nil, apperr.New(http.StatusNotFound, "map_not_found", "map not found")
- }
- versions, err := s.store.ListResourceMapVersions(ctx, item.ID)
- if err != nil {
- return nil, err
- }
- result := &AdminMapDetail{
- Map: AdminMapSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- },
- Versions: make([]AdminMapVersion, 0, len(versions)),
- }
- for _, version := range versions {
- view := AdminMapVersion{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- MapmetaURL: version.MapmetaURL,
- TilesRootURL: version.TilesRootURL,
- PublishedAssetRoot: version.PublishedAssetRoot,
- Bounds: decodeJSONMap(version.BoundsJSON),
- Metadata: decodeJSONMap(version.MetadataJSON),
- }
- result.Versions = append(result.Versions, view)
- if item.CurrentVersionID != nil && *item.CurrentVersionID == version.ID {
- result.Map.CurrentVersion = &AdminMapVersionBrief{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- }
- result.Map.CurrentVersionID = &view.ID
- }
- }
- return result, nil
- }
- func (s *AdminResourceService) CreateMapVersion(ctx context.Context, mapPublicID string, input CreateAdminMapVersionInput) (*AdminMapVersion, error) {
- mapItem, err := s.store.GetResourceMapByPublicID(ctx, strings.TrimSpace(mapPublicID))
- if err != nil {
- return nil, err
- }
- if mapItem == nil {
- return nil, apperr.New(http.StatusNotFound, "map_not_found", "map not found")
- }
- input.VersionCode = strings.TrimSpace(input.VersionCode)
- input.MapmetaURL = strings.TrimSpace(input.MapmetaURL)
- input.TilesRootURL = strings.TrimSpace(input.TilesRootURL)
- if input.VersionCode == "" || input.MapmetaURL == "" || input.TilesRootURL == "" {
- return nil, apperr.New(http.StatusBadRequest, "invalid_params", "versionCode, mapmetaUrl and tilesRootUrl are required")
- }
- publicID, err := security.GeneratePublicID("mapv")
- if err != nil {
- return nil, err
- }
- tx, err := s.store.Begin(ctx)
- if err != nil {
- return nil, err
- }
- defer tx.Rollback(ctx)
- version, err := s.store.CreateResourceMapVersion(ctx, tx, postgres.CreateResourceMapVersionParams{
- PublicID: publicID,
- MapID: mapItem.ID,
- VersionCode: input.VersionCode,
- Status: normalizeVersionStatus(input.Status),
- MapmetaURL: input.MapmetaURL,
- TilesRootURL: input.TilesRootURL,
- PublishedAssetRoot: trimStringPtr(input.PublishedAssetRoot),
- BoundsJSON: input.Bounds,
- MetadataJSON: input.Metadata,
- })
- if err != nil {
- return nil, err
- }
- if input.SetAsCurrent {
- if err := s.store.SetResourceMapCurrentVersion(ctx, tx, mapItem.ID, version.ID); err != nil {
- return nil, err
- }
- }
- if err := tx.Commit(ctx); err != nil {
- return nil, err
- }
- return &AdminMapVersion{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- MapmetaURL: version.MapmetaURL,
- TilesRootURL: version.TilesRootURL,
- PublishedAssetRoot: version.PublishedAssetRoot,
- Bounds: decodeJSONMap(version.BoundsJSON),
- Metadata: decodeJSONMap(version.MetadataJSON),
- }, nil
- }
- func (s *AdminResourceService) ListPlayfields(ctx context.Context, limit int) ([]AdminPlayfieldSummary, error) {
- items, err := s.store.ListResourcePlayfields(ctx, limit)
- if err != nil {
- return nil, err
- }
- results := make([]AdminPlayfieldSummary, 0, len(items))
- for _, item := range items {
- results = append(results, AdminPlayfieldSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Kind: item.Kind,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- })
- }
- return results, nil
- }
- func (s *AdminResourceService) CreatePlayfield(ctx context.Context, input CreateAdminPlayfieldInput) (*AdminPlayfieldSummary, error) {
- input.Code = strings.TrimSpace(input.Code)
- input.Name = strings.TrimSpace(input.Name)
- kind := strings.TrimSpace(input.Kind)
- if kind == "" {
- kind = "course"
- }
- if input.Code == "" || input.Name == "" {
- return nil, apperr.New(http.StatusBadRequest, "invalid_params", "code and name are required")
- }
- publicID, err := security.GeneratePublicID("pf")
- if err != nil {
- return nil, err
- }
- tx, err := s.store.Begin(ctx)
- if err != nil {
- return nil, err
- }
- defer tx.Rollback(ctx)
- item, err := s.store.CreateResourcePlayfield(ctx, tx, postgres.CreateResourcePlayfieldParams{
- PublicID: publicID,
- Code: input.Code,
- Name: input.Name,
- Kind: kind,
- Status: normalizeCatalogStatus(input.Status),
- Description: trimStringPtr(input.Description),
- })
- if err != nil {
- return nil, err
- }
- if err := tx.Commit(ctx); err != nil {
- return nil, err
- }
- return &AdminPlayfieldSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Kind: item.Kind,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- }, nil
- }
- func (s *AdminResourceService) GetPlayfieldDetail(ctx context.Context, publicID string) (*AdminPlayfieldDetail, error) {
- item, err := s.store.GetResourcePlayfieldByPublicID(ctx, strings.TrimSpace(publicID))
- if err != nil {
- return nil, err
- }
- if item == nil {
- return nil, apperr.New(http.StatusNotFound, "playfield_not_found", "playfield not found")
- }
- versions, err := s.store.ListResourcePlayfieldVersions(ctx, item.ID)
- if err != nil {
- return nil, err
- }
- result := &AdminPlayfieldDetail{
- Playfield: AdminPlayfieldSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Kind: item.Kind,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- },
- Versions: make([]AdminPlayfieldVersion, 0, len(versions)),
- }
- for _, version := range versions {
- view := AdminPlayfieldVersion{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- SourceType: version.SourceType,
- SourceURL: version.SourceURL,
- PublishedAssetRoot: version.PublishedAssetRoot,
- ControlCount: version.ControlCount,
- Bounds: decodeJSONMap(version.BoundsJSON),
- Metadata: decodeJSONMap(version.MetadataJSON),
- }
- result.Versions = append(result.Versions, view)
- if item.CurrentVersionID != nil && *item.CurrentVersionID == version.ID {
- result.Playfield.CurrentVersion = &AdminPlayfieldVersionBrief{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- SourceType: version.SourceType,
- }
- result.Playfield.CurrentVersionID = &view.ID
- }
- }
- return result, nil
- }
- func (s *AdminResourceService) CreatePlayfieldVersion(ctx context.Context, publicID string, input CreateAdminPlayfieldVersionInput) (*AdminPlayfieldVersion, error) {
- item, err := s.store.GetResourcePlayfieldByPublicID(ctx, strings.TrimSpace(publicID))
- if err != nil {
- return nil, err
- }
- if item == nil {
- return nil, apperr.New(http.StatusNotFound, "playfield_not_found", "playfield not found")
- }
- input.VersionCode = strings.TrimSpace(input.VersionCode)
- input.SourceType = strings.TrimSpace(input.SourceType)
- input.SourceURL = strings.TrimSpace(input.SourceURL)
- if input.VersionCode == "" || input.SourceType == "" || input.SourceURL == "" {
- return nil, apperr.New(http.StatusBadRequest, "invalid_params", "versionCode, sourceType and sourceUrl are required")
- }
- publicVersionID, err := security.GeneratePublicID("pfv")
- if err != nil {
- return nil, err
- }
- tx, err := s.store.Begin(ctx)
- if err != nil {
- return nil, err
- }
- defer tx.Rollback(ctx)
- version, err := s.store.CreateResourcePlayfieldVersion(ctx, tx, postgres.CreateResourcePlayfieldVersionParams{
- PublicID: publicVersionID,
- PlayfieldID: item.ID,
- VersionCode: input.VersionCode,
- Status: normalizeVersionStatus(input.Status),
- SourceType: input.SourceType,
- SourceURL: input.SourceURL,
- PublishedAssetRoot: trimStringPtr(input.PublishedAssetRoot),
- ControlCount: input.ControlCount,
- BoundsJSON: input.Bounds,
- MetadataJSON: input.Metadata,
- })
- if err != nil {
- return nil, err
- }
- if input.SetAsCurrent {
- if err := s.store.SetResourcePlayfieldCurrentVersion(ctx, tx, item.ID, version.ID); err != nil {
- return nil, err
- }
- }
- if err := tx.Commit(ctx); err != nil {
- return nil, err
- }
- return &AdminPlayfieldVersion{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- SourceType: version.SourceType,
- SourceURL: version.SourceURL,
- PublishedAssetRoot: version.PublishedAssetRoot,
- ControlCount: version.ControlCount,
- Bounds: decodeJSONMap(version.BoundsJSON),
- Metadata: decodeJSONMap(version.MetadataJSON),
- }, nil
- }
- func (s *AdminResourceService) ListResourcePacks(ctx context.Context, limit int) ([]AdminResourcePackSummary, error) {
- items, err := s.store.ListResourcePacks(ctx, limit)
- if err != nil {
- return nil, err
- }
- results := make([]AdminResourcePackSummary, 0, len(items))
- for _, item := range items {
- results = append(results, AdminResourcePackSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- })
- }
- return results, nil
- }
- func (s *AdminResourceService) CreateResourcePack(ctx context.Context, input CreateAdminResourcePackInput) (*AdminResourcePackSummary, error) {
- input.Code = strings.TrimSpace(input.Code)
- input.Name = strings.TrimSpace(input.Name)
- if input.Code == "" || input.Name == "" {
- return nil, apperr.New(http.StatusBadRequest, "invalid_params", "code and name are required")
- }
- publicID, err := security.GeneratePublicID("rp")
- if err != nil {
- return nil, err
- }
- tx, err := s.store.Begin(ctx)
- if err != nil {
- return nil, err
- }
- defer tx.Rollback(ctx)
- item, err := s.store.CreateResourcePack(ctx, tx, postgres.CreateResourcePackParams{
- PublicID: publicID,
- Code: input.Code,
- Name: input.Name,
- Status: normalizeCatalogStatus(input.Status),
- Description: trimStringPtr(input.Description),
- })
- if err != nil {
- return nil, err
- }
- if err := tx.Commit(ctx); err != nil {
- return nil, err
- }
- return &AdminResourcePackSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- }, nil
- }
- func (s *AdminResourceService) GetResourcePackDetail(ctx context.Context, publicID string) (*AdminResourcePackDetail, error) {
- item, err := s.store.GetResourcePackByPublicID(ctx, strings.TrimSpace(publicID))
- if err != nil {
- return nil, err
- }
- if item == nil {
- return nil, apperr.New(http.StatusNotFound, "resource_pack_not_found", "resource pack not found")
- }
- versions, err := s.store.ListResourcePackVersions(ctx, item.ID)
- if err != nil {
- return nil, err
- }
- result := &AdminResourcePackDetail{
- ResourcePack: AdminResourcePackSummary{
- ID: item.PublicID,
- Code: item.Code,
- Name: item.Name,
- Status: item.Status,
- Description: item.Description,
- CurrentVersionID: item.CurrentVersionID,
- },
- Versions: make([]AdminResourcePackVersion, 0, len(versions)),
- }
- for _, version := range versions {
- view := AdminResourcePackVersion{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- ContentEntryURL: version.ContentEntryURL,
- AudioRootURL: version.AudioRootURL,
- ThemeProfileCode: version.ThemeProfileCode,
- PublishedAssetRoot: version.PublishedAssetRoot,
- Metadata: decodeJSONMap(version.MetadataJSON),
- }
- result.Versions = append(result.Versions, view)
- if item.CurrentVersionID != nil && *item.CurrentVersionID == version.ID {
- result.ResourcePack.CurrentVersion = &AdminResourcePackVersionBrief{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- }
- result.ResourcePack.CurrentVersionID = &view.ID
- }
- }
- return result, nil
- }
- func (s *AdminResourceService) CreateResourcePackVersion(ctx context.Context, publicID string, input CreateAdminResourcePackVersionInput) (*AdminResourcePackVersion, error) {
- item, err := s.store.GetResourcePackByPublicID(ctx, strings.TrimSpace(publicID))
- if err != nil {
- return nil, err
- }
- if item == nil {
- return nil, apperr.New(http.StatusNotFound, "resource_pack_not_found", "resource pack not found")
- }
- input.VersionCode = strings.TrimSpace(input.VersionCode)
- if input.VersionCode == "" {
- return nil, apperr.New(http.StatusBadRequest, "invalid_params", "versionCode is required")
- }
- publicVersionID, err := security.GeneratePublicID("rpv")
- if err != nil {
- return nil, err
- }
- tx, err := s.store.Begin(ctx)
- if err != nil {
- return nil, err
- }
- defer tx.Rollback(ctx)
- version, err := s.store.CreateResourcePackVersion(ctx, tx, postgres.CreateResourcePackVersionParams{
- PublicID: publicVersionID,
- ResourcePackID: item.ID,
- VersionCode: input.VersionCode,
- Status: normalizeVersionStatus(input.Status),
- ContentEntryURL: trimStringPtr(input.ContentEntryURL),
- AudioRootURL: trimStringPtr(input.AudioRootURL),
- ThemeProfileCode: trimStringPtr(input.ThemeProfileCode),
- PublishedAssetRoot: trimStringPtr(input.PublishedAssetRoot),
- MetadataJSON: input.Metadata,
- })
- if err != nil {
- return nil, err
- }
- if input.SetAsCurrent {
- if err := s.store.SetResourcePackCurrentVersion(ctx, tx, item.ID, version.ID); err != nil {
- return nil, err
- }
- }
- if err := tx.Commit(ctx); err != nil {
- return nil, err
- }
- return &AdminResourcePackVersion{
- ID: version.PublicID,
- VersionCode: version.VersionCode,
- Status: version.Status,
- ContentEntryURL: version.ContentEntryURL,
- AudioRootURL: version.AudioRootURL,
- ThemeProfileCode: version.ThemeProfileCode,
- PublishedAssetRoot: version.PublishedAssetRoot,
- Metadata: decodeJSONMap(version.MetadataJSON),
- }, nil
- }
- func normalizeCatalogStatus(value string) string {
- switch strings.TrimSpace(value) {
- case "active":
- return "active"
- case "disabled":
- return "disabled"
- case "archived":
- return "archived"
- default:
- return "draft"
- }
- }
- func normalizeVersionStatus(value string) string {
- switch strings.TrimSpace(value) {
- case "active":
- return "active"
- case "archived":
- return "archived"
- default:
- return "draft"
- }
- }
- func trimStringPtr(value *string) *string {
- if value == nil {
- return nil
- }
- trimmed := strings.TrimSpace(*value)
- if trimmed == "" {
- return nil
- }
- return &trimmed
- }
- func decodeJSONMap(raw json.RawMessage) map[string]any {
- if len(raw) == 0 {
- return nil
- }
- result := map[string]any{}
- if err := json.Unmarshal(raw, &result); err != nil || len(result) == 0 {
- return nil
- }
- return result
- }
|