落地埋点 ingest/数据看板、首页宫格 CMS 与测评上下架;含账号引导、问答流式与免责声明去重,以及 review P1 审计同事务修复。 Co-authored-by: Cursor <cursoragent@cursor.com>
66 lines
1.9 KiB
Go
66 lines
1.9 KiB
Go
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
|
|
}
|