feat: P1 profile/portrait API and freeze local-dev environment
Add host-first environment contracts (Local vs CI vs Prod), deps-only compose, and the Profile → Portrait → deep-access mock payment slice with device identity and auto-migrate on API startup. Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,49 @@
|
||||
package profile
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
|
||||
"github.com/yuxingu/digital-psychology/apps/api/internal/model"
|
||||
"github.com/yuxingu/digital-psychology/apps/api/internal/repository"
|
||||
)
|
||||
|
||||
// Service manages personal archives.
|
||||
type Service struct {
|
||||
Repo *repository.ProfileRepo
|
||||
}
|
||||
|
||||
// CreateInput is validated create payload.
|
||||
type CreateInput struct {
|
||||
Relation string
|
||||
DisplayName string
|
||||
BirthDate time.Time
|
||||
RelationType *string
|
||||
}
|
||||
|
||||
// Create stores a profile for the user.
|
||||
func (s *Service) Create(ctx context.Context, userID uuid.UUID, in CreateInput) (*model.Profile, error) {
|
||||
if in.Relation != "self" && in.Relation != "other" {
|
||||
return nil, errors.New("relation must be self or other")
|
||||
}
|
||||
if in.BirthDate.IsZero() {
|
||||
return nil, errors.New("birth_date required")
|
||||
}
|
||||
name := in.DisplayName
|
||||
if name == "" {
|
||||
if in.Relation == "self" {
|
||||
name = "我"
|
||||
} else {
|
||||
name = "TA"
|
||||
}
|
||||
}
|
||||
return s.Repo.Create(ctx, userID, in.Relation, name, in.BirthDate, in.RelationType)
|
||||
}
|
||||
|
||||
// List returns user's profiles.
|
||||
func (s *Service) List(ctx context.Context, userID uuid.UUID) ([]model.Profile, error) {
|
||||
return s.Repo.ListByUser(ctx, userID)
|
||||
}
|
||||
Reference in New Issue
Block a user