Skip to content

Conversation

@Jeongminyooa
Copy link
Collaborator

@Jeongminyooa Jeongminyooa commented May 31, 2025

Issue

피드백 카드 저장 시
2025-06-01 06:10:15.640 [http-nio-8080-exec-1] ERROR org.hibernate.engine.jdbc.spi.SqlExceptionHelper - Incorrect string value: '\xF0\x9F\x98\x86' for column 'content' at row 1
-> DB 내 인코딩 이슈 어떻게 설정 변경했는지 @k906506

📝작업 내용

1. 피드백/선물 받기

  • 소비 기록(POST /api/v1/expenses) 완료 시
    • feedback 생성(is_opened : false)
    • reward 생성(is_opened : false)
  • 어제 소비 기록의 날짜가 지난달이라면(e.g. 어제 날짜가 지난달의 말일) 선물 받기 불가능

2. 피드백 조회 (GET api/v1/feedback/content/{useKey})

{
  "statusCode": 201,
  "responseMessage": "성공",
  "responseData": {
    "title": "한숨 돌릴 타이밍",
    "content": "덕분에 오늘 텐션 좀\n올라갔을 듯?",
    "name": "RedWolf22",
    "category": "ENERGY",
    "flagType": true
  }
}

선물 모두 연 케이스에서 해당 API 조회 시

{
  "statusCode": 500,
  "responseMessage": "모든 피드백을 열었습니다.",
  "responseData": null
}

3. 열지 않은 선물 개수 (GET /api/v1/reward/not-open/{userKey})

{
  "statusCode": 200,
  "responseMessage": "성공",
  "responseData": 1
}

4. 연도/월별 별통이 꾸미기 적용 상태 가져오기

  • (case 02)가 쓰일 것으로 예상됨.
    (* default 상태는 기본 꾸미기 아이템이 적용되어 있음)

case 01) GET /api/v1/reward/{userKey}?year=&month

{
  "statusCode": 200,
  "responseMessage": "성공",
  "responseData": [
    {
      "id": 1,
      "name": "기본 배경",
      "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/background_default.png",
      "jsonUrl": null,
      "mp3Url": null,
      "category": "BACKGROUND",
      "owned": true,
      "newAcquiredFlag": false
    },
    {
      "id": 2,
      "name": "기본 효과",
      "imageUrl": null,
      "jsonUrl": null,
      "mp3Url": null,
      "category": "EFFECT",
      "owned": true,
      "newAcquiredFlag": false
    },
    {
      "id": 3,
      "name": "기본 장식",
      "imageUrl": null,
      "jsonUrl": null,
      "mp3Url": null,
      "category": "DECORATION",
      "owned": true,
      "newAcquiredFlag": false
    },
    {
      "id": 4,
      "name": "기본 별통이",
      "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/byeoltong_case_default.png",
      "jsonUrl": null,
      "mp3Url": null,
      "category": "CASE",
      "owned": true,
      "newAcquiredFlag": false
    },
    {
      "id": 5,
      "name": "기본 배경음악",
      "imageUrl": null,
      "jsonUrl": null,
      "mp3Url": null,
      "category": "BGM",
      "owned": true,
      "newAcquiredFlag": false
    }
  ]
}

case 02) 별통이 소비기록 조회에서 같이 가져오기 GET /api/v1/expenses/list/{userKey}

{
  "statusCode": 200,
  "responseMessage": "성공",
  "responseData": {
    "userKey": "1234",
    "records": [
      {
        "date": "2025-06-01",
        "contents": [
          {
            "flag": "GOOD",
            "category": "ENERGY",
            "memo": "ee"
          },
          {
            "flag": "BAD",
            "category": "GREED",
            "memo": "gg"
          }
        ]
      }
    ],
    "saveItems": [
      {
        "id": 1,
        "name": "기본 배경",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/background_default.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BACKGROUND",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 2,
        "name": "기본 효과",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": null,
        "category": "EFFECT",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 3,
        "name": "기본 장식",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": null,
        "category": "DECORATION",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 4,
        "name": "기본 별통이",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/byeoltong_case_default.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "CASE",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 5,
        "name": "기본 배경음악",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BGM",
        "owned": false,
        "newAcquiredFlag": false
      }
    ]
  }
}

5. 꾸미기 탭 진입 시 전체 아이템 조회( 요청 시각 연도/월 소유 여부도 함께 반환 )

GET /api/v1/reward/edit/{userKEy}

{
  "statusCode": 200,
  "responseMessage": "성공",
  "responseData": {
    "DECORATION": [
      {
        "id": 3,
        "name": "기본 장식",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": null,
        "category": "DECORATION",
        "owned": true,
        "newAcquiredFlag": true
      },
      {
        "id": 19,
        "name": "달베개",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_달베개.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/descoration_달베개.json",
        "mp3Url": null,
        "category": "DECORATION",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 20,
        "name": "둥둥배",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_둥둥배.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/descoration_둥둥배.json",
        "mp3Url": null,
        "category": "DECORATION",
        "owned": true,
        "newAcquiredFlag": true
      },
      {
        "id": 21,
        "name": "몽글몽글 열기구",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_몽글몽글열기구.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/descoration_몽글열기구.json",
        "mp3Url": null,
        "category": "DECORATION",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 22,
        "name": "토비호",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_토비호.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/descoration_토비호.json",
        "mp3Url": null,
        "category": "DECORATION",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 23,
        "name": "토비의 우주바캉스",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_토비의우주바캉스.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_토비의우주바캉스.json",
        "mp3Url": null,
        "category": "DECORATION",
        "owned": false,
        "newAcquiredFlag": false
      }
    ],
    "EFFECT": [
      {
        "id": 2,
        "name": "기본 효과",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": null,
        "category": "EFFECT",
        "owned": true,
        "newAcquiredFlag": true
      },
      {
        "id": 12,
        "name": "둥실둥실 방울",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/effect_둥실둥실방울.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/effect_둥실둥실방울.json",
        "mp3Url": null,
        "category": "EFFECT",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 13,
        "name": "소원의 유성",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/effect_소원의유성.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/effect_소원의유성.json",
        "mp3Url": null,
        "category": "EFFECT",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 14,
        "name": "하트잔잔",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/effect_하트잔잔.png",
        "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/effect_하트잔잔.json",
        "mp3Url": null,
        "category": "EFFECT",
        "owned": false,
        "newAcquiredFlag": false
      }
    ],
    "CASE": [
      {
        "id": 4,
        "name": "기본 별통이",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/byeoltong_case_default.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "CASE",
        "owned": true,
        "newAcquiredFlag": true
      },
      {
        "id": 24,
        "name": "구슬 별통이",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/byeoltong_case_동글별통이.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "CASE",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 25,
        "name": "몽글 별통이",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/byeoltong_case_몽글별통이.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "CASE",
        "owned": false,
        "newAcquiredFlag": false
      }
    ],
    "BGM": [
      {
        "id": 5,
        "name": "기본 배경음악",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BGM",
        "owned": true,
        "newAcquiredFlag": true
      },
      {
        "id": 28,
        "name": "별사탕의 하루",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/bgm_별사탕의하루.mp3",
        "category": "BGM",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 29,
        "name": "속삭이는 별빛",
        "imageUrl": null,
        "jsonUrl": null,
        "mp3Url": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/bgm_속삭이는별빛.mp3",
        "category": "BGM",
        "owned": false,
        "newAcquiredFlag": false
      }
    ],
    "BACKGROUND": [
      {
        "id": 1,
        "name": "기본 배경",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/background_default.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BACKGROUND",
        "owned": true,
        "newAcquiredFlag": true
      },
      {
        "id": 9,
        "name": "별이 흐르는 바다 배경",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/background_별이흐르는바다.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BACKGROUND",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 10,
        "name": "보랏빛 오로라 배경",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/background_보랏빛오로라.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BACKGROUND",
        "owned": false,
        "newAcquiredFlag": false
      },
      {
        "id": 11,
        "name": "하늘위 산책로 배경",
        "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/background_하늘위산책로.png",
        "jsonUrl": null,
        "mp3Url": null,
        "category": "BACKGROUND",
        "owned": false,
        "newAcquiredFlag": false
      }
    ]
  }
}

6. 선물 열기 (PUT /api/v1/reward/open/{userKey}

  • 열지 않은 선물 n개 동시 오픈, 피드백 isOpened 상태 변환
{
  "statusCode": 200,
  "responseMessage": "성공",
  "responseData": [
    {
      "id": 20,
      "name": "둥둥배",
      "imageUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/decoration_둥둥배.png",
      "jsonUrl": "https://kr.object.ncloudstorage.com/donmani.bucket/reward_content/descoration_둥둥배.json",
      "mp3Url": null,
      "category": "DECORATION",
      "owned": true,
      "newAcquiredFlag": false
    }
  ]
}

7. 별통이 꾸미기 (PUT /api/v1/reward )

  • Client 단으로부터 요청 연도/월을 함께 받아 실제 저장 시각과 비교
    • edge case : 5월 31일 23:59에 꾸미기 탭 들어가 6월 1일 00:00시 저장 시, 5월 아이템으로 6월에 꾸미기가 저장되는 상황 방지
{
  "userKey": "1234",
  "year": 2025,
  "month": 6,
  "backgroundId": 1,
  "effectId": 2,
  "decorationId": 20,
  "byeoltongCaseId": 4,
  "bgmId": 5
}

8. 설정 탭 꾸미기 최초 방문 여부 (User Controller > /api/v1/reward/status/{userKey})

  • 공지사항과 동일 기능 제공

9. Hidden Item

  • 해당 월의 14개 선물 열기 충족 시 Hidden 아이템 획득
  • 꾸미기 탭 에서 (GET api/v1/reward/edit/{userKey} ) hidden : true, newAcquiredFlag : true 라면, 히든 아이템에 대한 소개가 노출되어야 하는 상태.
image - 히든아이템 획득 후 관련 노티 확인 (PUT `/api/v1/reward/hidden-read`) image

@Jeongminyooa Jeongminyooa self-assigned this May 31, 2025
@github-actions
Copy link

github-actions bot commented May 31, 2025

Unit Test Results

1 tests   1 ✔️  0s ⏱️
1 suites  0 💤
1 files    0

Results for commit 44c820c.

♻️ This comment has been updated with latest results.

@k906506
Copy link
Collaborator

k906506 commented Jun 1, 2025

@Jeongminyooa

DB 설정 변경했어!

ALTER TABLE feedback CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
SHOW FULL COLUMNS FROM feedback;

-- 컬럼명 | 타입 | 문자셋/Collation
-- content | varchar(255) | utf8mb4_unicode_ci

스크린샷 2025-06-01 오전 10 46 08

@Jeongminyooa Jeongminyooa added bug Something isn't working enhancement New feature or request labels Jun 1, 2025
Copy link
Collaborator

@k906506 k906506 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

진짜 너무 고생 많았어...ㅠ
케이스들 다 신경 쓰느라🥲 굿굿!

User user = userService.getUser(userKey);
Feedback notOpenedFeedback = feedbackRepository.findFirstByUserAndIsOpenedFalseOrderByCreatedDateDesc(user).orElseThrow();

Boolean isToday = notOpenedFeedback.getExpense().getCreatedAt().format(formatter).equals(localDateTime.format(formatter));
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

클라쪽에서 어떤 화면이랑 연결되는 변수인지 궁금해!

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

미사용 변수인데 FeedbackOpenResponseDTO 그대로 재활용 하려다보니까 일단 오빠가 구현한거 로직 그대로 들고와서 값 넣어줬다! ! 추후 DTO 바꾸면서 삭제 필요합니닷

@Column
private String mp3Url;

private boolean hidden; // 히든 아이템 여부
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

다른 변수랑 통일성을 주기 위해 isHidden은 어때?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

오키 반영 완료!

}

@GetMapping("api/v1/reward/status/{userKey}")
public ResponseEntity<RewardCheckDTO> getRewardCheckedStatus(@PathVariable String userKey) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

선물 도착! 에 대한 확인 여부라면 별도의 API로 두지 말고,
/api/v1/expenses/list/{userKey} Response에 추가하는건 어때?

새로 작업 해야하는 부분이니까 나중에 ㅋㅋ

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거 선물 도착여부는 아니고(이미 그건 피드백쪽에서 flag성으로 주는 것 같아서!)
설정 탭에서 공지사항 레드닷처럼 꾸미기탭 레드닷이 있길래 넣어놨으

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fileService는 어디서 사용하는거야?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이거는 추후에 관련 콘텐츠를 더 확장하거나 할 때 API로 뗄 수 있게끔 파일업로드 미리 구현해놨오

@Jeongminyooa Jeongminyooa merged commit 516a33d into dev Jun 1, 2025
2 checks passed
@Jeongminyooa Jeongminyooa deleted the feature/48 branch June 16, 2025 23:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants