完善活动运营域与联调标准化

This commit is contained in:
2026-04-03 13:11:41 +08:00
parent 0e28f70bad
commit 129ea935db
56 changed files with 11004 additions and 196 deletions

View File

@@ -15,15 +15,18 @@ type AdminPipelineService struct {
}
type AdminReleaseView struct {
ID string `json:"id"`
ReleaseNo int `json:"releaseNo"`
ConfigLabel string `json:"configLabel"`
ManifestURL string `json:"manifestUrl"`
ManifestChecksumSha256 *string `json:"manifestChecksumSha256,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
BuildID *string `json:"buildId,omitempty"`
Status string `json:"status"`
PublishedAt string `json:"publishedAt"`
ID string `json:"id"`
ReleaseNo int `json:"releaseNo"`
ConfigLabel string `json:"configLabel"`
ManifestURL string `json:"manifestUrl"`
ManifestChecksumSha256 *string `json:"manifestChecksumSha256,omitempty"`
RouteCode *string `json:"routeCode,omitempty"`
BuildID *string `json:"buildId,omitempty"`
Status string `json:"status"`
PublishedAt string `json:"publishedAt"`
Runtime *RuntimeSummaryView `json:"runtime,omitempty"`
Presentation *PresentationSummaryView `json:"presentation,omitempty"`
ContentBundle *ContentBundleSummaryView `json:"contentBundle,omitempty"`
}
type AdminEventPipelineView struct {
@@ -38,6 +41,16 @@ type AdminRollbackReleaseInput struct {
ReleaseID string `json:"releaseId"`
}
type AdminBindReleaseRuntimeInput struct {
RuntimeBindingID string `json:"runtimeBindingId"`
}
type AdminPublishBuildInput struct {
RuntimeBindingID string `json:"runtimeBindingId,omitempty"`
PresentationID string `json:"presentationId,omitempty"`
ContentBundleID string `json:"contentBundleId,omitempty"`
}
func NewAdminPipelineService(store *postgres.Store, configService *ConfigService) *AdminPipelineService {
return &AdminPipelineService{
store: store,
@@ -77,7 +90,18 @@ func (s *AdminPipelineService) GetEventPipeline(ctx context.Context, eventPublic
}
releases := make([]AdminReleaseView, 0, len(releaseRecords))
for _, item := range releaseRecords {
releases = append(releases, buildAdminReleaseView(item))
view := buildAdminReleaseView(item)
if enrichedPresentation, err := loadPresentationSummaryByPublicID(ctx, s.store, item.PresentationID); err != nil {
return nil, err
} else if enrichedPresentation != nil {
view.Presentation = enrichedPresentation
}
if enrichedBundle, err := loadContentBundleSummaryByPublicID(ctx, s.store, item.ContentBundleID); err != nil {
return nil, err
} else if enrichedBundle != nil {
view.ContentBundle = enrichedBundle
}
releases = append(releases, view)
}
result := &AdminEventPipelineView{
@@ -94,6 +118,19 @@ func (s *AdminPipelineService) GetEventPipeline(ctx context.Context, eventPublic
ManifestChecksumSha256: event.ManifestChecksum,
RouteCode: event.RouteCode,
Status: "published",
Runtime: buildRuntimeSummaryFromEvent(event),
Presentation: buildPresentationSummaryFromEvent(event),
ContentBundle: buildContentBundleSummaryFromEvent(event),
}
if enrichedPresentation, err := loadPresentationSummaryByPublicID(ctx, s.store, event.PresentationID); err != nil {
return nil, err
} else if enrichedPresentation != nil {
result.CurrentRelease.Presentation = enrichedPresentation
}
if enrichedBundle, err := loadContentBundleSummaryByPublicID(ctx, s.store, event.ContentBundleID); err != nil {
return nil, err
} else if enrichedBundle != nil {
result.CurrentRelease.ContentBundle = enrichedBundle
}
}
return result, nil
@@ -107,8 +144,84 @@ func (s *AdminPipelineService) GetBuild(ctx context.Context, buildID string) (*E
return s.configService.GetEventConfigBuild(ctx, buildID)
}
func (s *AdminPipelineService) PublishBuild(ctx context.Context, buildID string) (*PublishedReleaseView, error) {
return s.configService.PublishBuild(ctx, PublishBuildInput{BuildID: buildID})
func (s *AdminPipelineService) PublishBuild(ctx context.Context, buildID string, input AdminPublishBuildInput) (*PublishedReleaseView, error) {
return s.configService.PublishBuild(ctx, PublishBuildInput{
BuildID: buildID,
RuntimeBindingID: input.RuntimeBindingID,
PresentationID: input.PresentationID,
ContentBundleID: input.ContentBundleID,
})
}
func (s *AdminPipelineService) GetRelease(ctx context.Context, releasePublicID string) (*AdminReleaseView, error) {
release, err := s.store.GetEventReleaseByPublicID(ctx, strings.TrimSpace(releasePublicID))
if err != nil {
return nil, err
}
if release == nil {
return nil, apperr.New(http.StatusNotFound, "release_not_found", "release not found")
}
view := buildAdminReleaseView(*release)
if enrichedPresentation, err := loadPresentationSummaryByPublicID(ctx, s.store, release.PresentationID); err != nil {
return nil, err
} else if enrichedPresentation != nil {
view.Presentation = enrichedPresentation
}
if enrichedBundle, err := loadContentBundleSummaryByPublicID(ctx, s.store, release.ContentBundleID); err != nil {
return nil, err
} else if enrichedBundle != nil {
view.ContentBundle = enrichedBundle
}
return &view, nil
}
func (s *AdminPipelineService) BindReleaseRuntime(ctx context.Context, releasePublicID string, input AdminBindReleaseRuntimeInput) (*AdminReleaseView, error) {
release, err := s.store.GetEventReleaseByPublicID(ctx, strings.TrimSpace(releasePublicID))
if err != nil {
return nil, err
}
if release == nil {
return nil, apperr.New(http.StatusNotFound, "release_not_found", "release not found")
}
input.RuntimeBindingID = strings.TrimSpace(input.RuntimeBindingID)
if input.RuntimeBindingID == "" {
return nil, apperr.New(http.StatusBadRequest, "invalid_params", "runtimeBindingId is required")
}
runtimeBinding, err := s.store.GetMapRuntimeBindingByPublicID(ctx, input.RuntimeBindingID)
if err != nil {
return nil, err
}
if runtimeBinding == nil {
return nil, apperr.New(http.StatusNotFound, "runtime_binding_not_found", "runtime binding not found")
}
if runtimeBinding.EventID != release.EventID {
return nil, apperr.New(http.StatusConflict, "runtime_binding_not_belong_to_event", "runtime binding does not belong to release event")
}
tx, err := s.store.Begin(ctx)
if err != nil {
return nil, err
}
defer tx.Rollback(ctx)
if err := s.store.SetEventReleaseRuntimeBinding(ctx, tx, release.ID, &runtimeBinding.ID); err != nil {
return nil, err
}
if err := tx.Commit(ctx); err != nil {
return nil, err
}
updated, err := s.store.GetEventReleaseByPublicID(ctx, release.PublicID)
if err != nil {
return nil, err
}
if updated == nil {
return nil, apperr.New(http.StatusNotFound, "release_not_found", "release not found")
}
view := buildAdminReleaseView(*updated)
return &view, nil
}
func (s *AdminPipelineService) RollbackRelease(ctx context.Context, eventPublicID string, input AdminRollbackReleaseInput) (*AdminReleaseView, error) {
@@ -167,6 +280,9 @@ func buildAdminReleaseView(item postgres.EventRelease) AdminReleaseView {
BuildID: item.BuildID,
Status: item.Status,
PublishedAt: item.PublishedAt.Format(timeRFC3339),
Runtime: buildRuntimeSummaryFromRelease(&item),
Presentation: buildPresentationSummaryFromRelease(&item),
ContentBundle: buildContentBundleSummaryFromRelease(&item),
}
}