Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 0 additions & 9 deletions backend/internal/services/project/content_setup.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package project

import (
"github.com/google/uuid"
"gorm.io/datatypes"

"github.com/kurodakayn/mpp-backend/internal/dto"
"github.com/kurodakayn/mpp-backend/internal/models"
Expand Down Expand Up @@ -50,11 +49,3 @@ func (s *Service) validateBrandProfileForProject(userID uuid.UUID, workspaceID u
func contentTemplateDefaultPlatforms(template *models.ContentTemplate) ([]string, error) {
return contentsetup.ContentTemplateDefaultPlatforms(template, NormalizeProjectPlatforms)
}

func contentTemplatePlatformConfig(template *models.ContentTemplate, platform string) map[string]any {
return contentsetup.ContentTemplatePlatformConfig(template, platform)
}

func mergePublicationConfig(base datatypes.JSON, extra map[string]any) (datatypes.JSON, error) {
return contentsetup.MergePublicationConfig(base, extra)
}
40 changes: 2 additions & 38 deletions backend/internal/services/project/detail.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package project

import (
"encoding/json"
"errors"

"github.com/google/uuid"
"gorm.io/gorm"

"github.com/kurodakayn/mpp-backend/internal/dto"
"github.com/kurodakayn/mpp-backend/internal/models"
projectpublication "github.com/kurodakayn/mpp-backend/internal/services/project/publication"
)

func (s *Service) enrichProjectDetail(detail *dto.ProjectDetail, project models.Project, userID *uuid.UUID) error {
Expand All @@ -17,7 +17,7 @@ func (s *Service) enrichProjectDetail(detail *dto.ProjectDetail, project models.
}
detail.PublicationDetails = make([]dto.PublicationDetail, 0, len(project.Publications))
for _, publication := range project.Publications {
detail.PublicationDetails = append(detail.PublicationDetails, publicationDetailFromModel(publication, true))
detail.PublicationDetails = append(detail.PublicationDetails, projectpublication.DetailFromModel(publication, true))
}
if userID == nil {
if detail.PermissionSources == nil {
Expand Down Expand Up @@ -110,39 +110,3 @@ func appendProjectPermissionSource(sources []dto.ProjectPermissionSource, source
}
return append(sources, source)
}

func publicationDetailFromModel(pub models.ProjectPlatformPublication, includeContent bool) dto.PublicationDetail {
var rawConfig map[string]any
_ = json.Unmarshal(pub.Config, &rawConfig)
safeConfig := filterConfig(rawConfig)

var rawContent map[string]any
_ = json.Unmarshal(pub.AdaptedContent, &rawContent)
safeContent := rawContent
if !includeContent {
safeContent = summarizeAdaptedContent(rawContent)
}
if safeContent == nil {
safeContent = map[string]any{}
}

return dto.PublicationDetail{
ID: pub.ID,
Platform: pub.Platform,
Enabled: pub.Enabled,
Status: pub.Status,
DraftStatus: pub.DraftStatus,
ReviewStatus: pub.ReviewStatus,
SyncRequired: pub.SyncRequired,
ErrorMessage: pub.ErrorMessage,
Config: safeConfig,
AdaptedContent: safeContent,
PublishURL: pub.PublishURL,
RemoteID: pub.RemoteID,
RetryCount: pub.RetryCount,
LastAttemptAt: pub.LastAttemptAt,
PublishedAt: pub.PublishedAt,
CreatedAt: pub.CreatedAt,
UpdatedAt: pub.UpdatedAt,
}
}
131 changes: 98 additions & 33 deletions backend/internal/services/project/list.go
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
package project

import (
"strings"
"context"

"github.com/google/uuid"
"gorm.io/gorm"

"github.com/kurodakayn/mpp-backend/internal/dto"
"github.com/kurodakayn/mpp-backend/internal/models"
projectlisting "github.com/kurodakayn/mpp-backend/internal/services/project/listing"
projectpresenter "github.com/kurodakayn/mpp-backend/internal/services/project/presenter"
)

Expand All @@ -30,6 +31,94 @@ func (s *Service) ListCachedWorkspaceProjects(workspaceID uuid.UUID, actorUserID
return s.getCachedWorkspaceProjectList(workspaceID, actorUserID, cursor, page, limit, status, platform)
}

func (s *Service) projectListCache() *projectlisting.Cache {
if s == nil {
return nil
}
return projectlisting.New(projectlisting.Config{
Client: s.cache,
TTL: s.cacheTTL,
Group: s.cacheGroup,
Guard: s.projectListGuard,
})
}

func (s *Service) getCachedDashboardProjectList(cursor string, page, limit int, status, filterUserID, platform string, scopeUserID *uuid.UUID) (*dto.PaginationResponse, error) {
params := projectlisting.Params{
Cursor: cursor,
Page: page,
Limit: limit,
Status: status,
FilterUserID: filterUserID,
Platform: platform,
ScopeUserID: projectlisting.UUIDStringValue(scopeUserID),
}
return s.projectListCache().Get(s.requestContext(), params, func(ctx context.Context) (*dto.PaginationResponse, error) {
return s.WithContext(ctx).computeProjectList(cursor, page, limit, status, filterUserID, platform, scopeUserID)
})
}

func (s *Service) getCachedWorkspaceProjectList(workspaceID uuid.UUID, actorUserID uuid.UUID, cursor string, page, limit int, status, platform string) (*dto.PaginationResponse, error) {
params := projectlisting.Params{
Cursor: cursor,
Page: page,
Limit: limit,
Status: status,
Platform: platform,
WorkspaceID: workspaceID.String(),
ActorUserID: actorUserID.String(),
}
return s.projectListCache().Get(s.requestContext(), params, func(ctx context.Context) (*dto.PaginationResponse, error) {
return s.WithContext(ctx).computeWorkspaceProjectList(workspaceID, actorUserID, cursor, page, limit, status, platform)
})
}

func (s *Service) canUseDashboardProjectListCache() bool {
if s == nil {
return false
}
return s.projectListCache().CanUse(s.requestContext())
}

func (s *Service) InvalidateDashboardProjectListCache(ctx context.Context) {
if s == nil {
return
}
if ctx != nil {
s = s.WithContext(ctx)
}
s.invalidateDashboardProjectListCache()
}

func (s *Service) invalidateDashboardProjectListCache() {
if s == nil {
return
}
s.projectListCache().Invalidate(s.requestContext())
}

func (s *Service) invalidateDashboardCaches(includeStats bool) {
ctx := s.requestContext()
s.InvalidateDashboardProjectListCache(ctx)
if includeStats && s.statsCache != nil {
s.statsCache.InvalidateDashboardStatsCache(ctx)
}
}

func (s *Service) invalidateDashboardScopedStatsCache() {
if s.statsCache == nil {
return
}
s.statsCache.InvalidateDashboardScopedStatsCache(s.requestContext())
}

func (s *Service) refreshProjectReadModel(projectID uuid.UUID) {
if s.readModels == nil || projectID == uuid.Nil {
return
}
s.readModels.RefreshProjectAsync(s.requestContext(), projectID)
}

func (s *Service) computeProjectList(cursor string, page, limit int, status, filterUserID, platform string, scopeUserID *uuid.UUID) (*dto.PaginationResponse, error) {
if scopeUserID == nil && platform == "" && s.canUseReadModels() {
if resp, ok, err := s.adminProjectListFromReadModel(cursor, page, limit, status, filterUserID); err != nil {
Expand Down Expand Up @@ -120,8 +209,8 @@ func (s *Service) projectListReadDB(scopeUserID *uuid.UUID) *gorm.DB {
func (s *Service) ListProjectPage(query *gorm.DB, cursor string, page, limit int, scopeUserID *uuid.UUID) (*dto.PaginationResponse, error) {
var projects []models.Project

page, limit = normalizeProjectListPage(page, limit)
query, err := applyProjectListCursor(query, cursor)
page, limit = projectlisting.NormalizePage(page, limit)
query, err := projectlisting.ApplyCursor(query, cursor)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -166,17 +255,17 @@ func (s *Service) ListProjectPage(query *gorm.DB, cursor string, page, limit int

nextCursor := ""
if hasMore && len(projects) > 0 {
nextCursor = encodeProjectListCursor(projects[len(projects)-1])
nextCursor = projectlisting.EncodeCursor(projects[len(projects)-1])
}

return projectPaginationResponse(items, cursor, page, limit, hasMore, nextCursor), nil
return projectlisting.PaginationResponse(items, cursor, page, limit, hasMore, nextCursor), nil
}

func (s *Service) ListProjectSummaryPage(query *gorm.DB, cursor string, page, limit int) (*dto.PaginationResponse, error) {
var summaries []models.ProjectListSummary

page, limit = normalizeProjectListPage(page, limit)
query, err := applyProjectListCursorColumns(query, cursor, "project_list_summaries.created_at", "project_list_summaries.project_id")
page, limit = projectlisting.NormalizePage(page, limit)
query, err := projectlisting.ApplyCursorColumns(query, cursor, "project_list_summaries.created_at", "project_list_summaries.project_id")
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -206,32 +295,8 @@ func (s *Service) ListProjectSummaryPage(query *gorm.DB, cursor string, page, li
nextCursor := ""
if hasMore && len(summaries) > 0 {
last := summaries[len(summaries)-1]
nextCursor = encodeProjectListCursorValues(last.CreatedAt, last.ProjectID)
}

return projectPaginationResponse(items, cursor, page, limit, hasMore, nextCursor), nil
}

func projectPaginationResponse(items []dto.ProjectListItem, cursor string, page int, limit int, hasMore bool, nextCursor string) *dto.PaginationResponse {
total := int64((page-1)*limit + len(items))
if hasMore {
total++
}
totalPages := page
if len(items) == 0 && page == 1 {
totalPages = 0
} else if hasMore {
totalPages = page + 1
nextCursor = projectlisting.EncodeCursorValues(last.CreatedAt, last.ProjectID)
}

return &dto.PaginationResponse{
Items: items,
Page: page,
Limit: limit,
Total: total,
TotalPages: totalPages,
Cursor: strings.TrimSpace(cursor),
NextCursor: nextCursor,
HasMore: hasMore,
}
return projectlisting.PaginationResponse(items, cursor, page, limit, hasMore, nextCursor), nil
}
98 changes: 0 additions & 98 deletions backend/internal/services/project/list_cache.go

This file was deleted.

Loading
Loading