Line data Source code
1 : // Package skill は ユーザースキルに関するユースケース(アプリケーションロジック)を提供します
2 : package skill
3 :
4 : import (
5 : "context"
6 :
7 : "resume/internal/shared/apperr"
8 : "resume/internal/shared/util"
9 : "resume/internal/shared/valerr"
10 : )
11 :
12 : // UpdateUserSkill は Skillの更新を実行します
13 : func (uc *Interactor) UpdateUserSkill(
14 : ctx context.Context,
15 : in UpdateUserSkillInput,
16 0 : ) (UpdateUserSKillOutput, error) {
17 0 : norm := util.ToCanonical(in.SkillName)
18 0 :
19 0 : err := uc.tx.Do(ctx, func(txCtx context.Context) error {
20 0 : // 既存のスキルを取得
21 0 : existing, err := uc.usRepo.FindByID(txCtx, in.ID)
22 0 : if err != nil {
23 0 : return err
24 0 : }
25 0 : if existing == nil {
26 0 : ve := valerr.New()
27 0 : ve.Add(
28 0 : "domain.user_skill.id",
29 0 : "validation.rules.invalid",
30 0 : map[string]any{
31 0 : "field": "domain.user_skill.id",
32 0 : },
33 0 : )
34 0 : return apperr.New(
35 0 : apperr.CodeUnprocessable,
36 0 : "The request contains semantically invalid data.",
37 0 : ve.ToDetails(),
38 0 : )
39 0 : }
40 :
41 : // 所有者チェック
42 0 : if existing.UserID != in.UserID {
43 0 : ve := valerr.New()
44 0 : ve.Add(
45 0 : "domain.user_skill.id",
46 0 : "validation.rules.invalid",
47 0 : map[string]any{
48 0 : "field": "domain.user_skill.id",
49 0 : },
50 0 : )
51 0 : return apperr.New(
52 0 : apperr.CodeUnprocessable,
53 0 : "The request contains semantically invalid data.",
54 0 : ve.ToDetails(),
55 0 : )
56 0 : }
57 :
58 : // 更新
59 0 : existing.SkillLevelID = in.SkillLevelID
60 0 : existing.SkillCategoryID = in.SkillCategoryID
61 0 : existing.SkillName = in.SkillName
62 0 : existing.ExperienceID = in.ExperienceID
63 0 : existing.SkillNameNorm = norm
64 0 : existing.Evidence = in.Evidence
65 0 :
66 0 : _, err = uc.usRepo.Update(txCtx, existing)
67 0 : return err
68 : })
69 :
70 0 : if err != nil {
71 0 : return UpdateUserSKillOutput{}, err
72 0 : }
73 :
74 0 : return UpdateUserSKillOutput{ID: in.ID}, nil
75 : }
|