package relation import ( "context" "encoding/json" "errors" "github.com/google/uuid" "github.com/yuxingu/digital-psychology/apps/api/internal/model" releng "github.com/yuxingu/digital-psychology/apps/api/internal/relation" "github.com/yuxingu/digital-psychology/apps/api/internal/repository" ) // Service creates relation understanding reports. type Service struct { Profiles *repository.ProfileRepo Reports *repository.ReportRepo Relations *repository.RelationRepo } // CreateInsightResult is API payload. type CreateInsightResult struct { Insight *model.RelationInsight `json:"insight"` Report *model.GrowthReport `json:"report"` } // Create builds 关系理解 for two owned profiles. func (s *Service) Create(ctx context.Context, userID, aID, bID uuid.UUID) (*CreateInsightResult, error) { if aID == bID { return nil, errors.New("need two different profiles") } pa, err := s.Profiles.GetForUser(ctx, userID, aID) if err != nil { return nil, errors.New("profile_a not found") } pb, err := s.Profiles.GetForUser(ctx, userID, bID) if err != nil { return nil, errors.New("profile_b not found") } relType := "" if pb.RelationType != nil { relType = *pb.RelationType } out := releng.BuildFull(pa.BirthDate, pb.BirthDate, pa.BirthTime, pb.BirthTime, pa.BirthPlace, pb.BirthPlace, pa.DisplayName, pb.DisplayName, relType) sum, _ := json.Marshal(out.Summary) det, _ := json.Marshal(out.Detail) peer := bID rep, err := s.Reports.UpsertWithPeer(ctx, userID, aID, &peer, "relation", sum, det) if err != nil { return nil, err } ins, err := s.Relations.Create(ctx, userID, aID, bID, sum, rep.ID) if err != nil { return nil, err } // entitlement trim on report deep, _ := s.Reports.HasDeepAccess(ctx, userID, rep.ID) vip, _ := s.Reports.HasActiveMembership(ctx, userID) rep.HasDeep = deep || vip if !rep.HasDeep { rep.Detail = nil } return &CreateInsightResult{Insight: ins, Report: rep}, nil }