Skip to content

release: deploy push admin backend - #308

Merged
818jsy merged 69 commits into
mainfrom
develop
Aug 7, 2026
Merged

release: deploy push admin backend#308
818jsy merged 69 commits into
mainfrom
develop

Conversation

@818jsy

@818jsy 818jsy commented Aug 7, 2026

Copy link
Copy Markdown
Contributor

Summary

  • deploy the admin social login endpoint required by admin.kodaero.co.kr
  • deploy push notification admin APIs and app-variant routing already validated on develop
  • include the latest Kakao admin login compatibility fixes

Verification

  • develop Build check: success
  • develop deployment: success
  • dev admin login route returns token-validation response instead of 404

Incident

Production currently returns statusCode 1015 for POST /api/users/login/admin, causing both Google and Kakao admin login callbacks to fail.

dlwls423 and others added 30 commits July 1, 2026 20:21
Feat: 팝업 전용 건의 종류 추가
JokeBear777 and others added 26 commits August 5, 2026 18:49
Feat: 포인트 상점(캐릭터 스토어) 기능 구현
feat: 도메인 이벤트 기반 자동 푸시 알림 및 운영 플래그 추가
Copilot AI lite review requested due to automatic review settings August 7, 2026 03:44
@818jsy
818jsy merged commit 784af1a into main Aug 7, 2026
4 checks passed

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Pull request overview

This PR prepares a production release by adding the admin social-login endpoint and deploying the push-notification admin/worker infrastructure (plus related user/character/points backfills and APIs) needed by admin.kodaero.co.kr and validated on develop.

Changes:

  • Add /api/users/login/admin flow with Kakao admin-audience support and stable email resolution.
  • Introduce push notification infrastructure (installations, dispatches/messages, workers/schedulers, admin APIs, event listeners).
  • Add points/character store + usage-survey APIs, and user level/point persistence/backfill adjustments.

Reviewed changes

Copilot reviewed 194 out of 195 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
src/test/resources/logback-test.xml Add console-only test logging
src/test/resources/logback-spring.xml Add CI-friendly console logging
src/test/resources/application-test.yml Add dedicated test profile config
src/test/java/devkor/com/teamcback/global/aop/UpdateScoreLevelTest.java Test score→level/point updates
src/test/java/devkor/com/teamcback/domain/user/validator/KakaoValidatorTest.java Test Kakao email resolution
src/test/java/devkor/com/teamcback/domain/user/service/UserServiceReleaseLoginTest.java Test loginKey from verified token
src/test/java/devkor/com/teamcback/domain/user/service/UserServiceGetUserInfoTest.java Test persisted level + reset
src/test/java/devkor/com/teamcback/domain/user/service/UserServiceDeleteUserTest.java Test delete cleanup ordering
src/test/java/devkor/com/teamcback/domain/user/repository/UserRepositoryBackfillTest.java Test backfill + point deduction
src/test/java/devkor/com/teamcback/domain/user/entity/LevelTest.java Test Level enum + point floor
src/test/java/devkor/com/teamcback/domain/report/service/ReportServiceTest.java Test report-resolved event publish
src/test/java/devkor/com/teamcback/domain/notification/validation/PushActionValidatorTest.java Test push deep-link validation
src/test/java/devkor/com/teamcback/domain/notification/template/DomainPushContentFactoryTest.java Test push content templates
src/test/java/devkor/com/teamcback/domain/notification/service/PushEventFlagServiceTest.java Test feature-flag behavior
src/test/java/devkor/com/teamcback/domain/notification/scheduler/PushMessageRecoverySchedulerTest.java Test scheduler default-off
src/test/java/devkor/com/teamcback/domain/notification/resolver/PushTargetResolverTest.java Test recipient resolution rules
src/test/java/devkor/com/teamcback/domain/notification/repository/PushMessageRepositoryQueryTest.java Assert critical native queries
src/test/java/devkor/com/teamcback/domain/notification/listener/ReportResolvedPushEventListenerTest.java Test report-result push enqueue
src/test/java/devkor/com/teamcback/domain/notification/listener/DomainPushEventListenerAnnotationTest.java Assert AFTER_COMMIT + REQUIRES_NEW
src/test/java/devkor/com/teamcback/domain/notification/factory/PushPayloadFactoryTest.java Test payload variant embedding
src/test/java/devkor/com/teamcback/domain/notification/controller/AdminNotificationControllerTest.java Test admin flag API reflection
src/test/java/devkor/com/teamcback/domain/character/service/CharacterDataSeederTest.java Test character seeding behavior
src/test/java/devkor/com/teamcback/domain/character/repository/UserCharacterRepositoryTest.java Test ownership/uniqueness constraints
src/test/java/devkor/com/teamcback/domain/character/repository/CharacterRepositoryTest.java Test character queries + uniqueness
src/main/resources/application.yml Add push/character/jwt config
src/main/java/devkor/com/teamcback/infra/s3/FilePath.java Add S3 path for characters
src/main/java/devkor/com/teamcback/global/security/SecurityConfig.java Secure new push/store/survey APIs
src/main/java/devkor/com/teamcback/global/response/ResultCode.java Add notification/character/survey codes
src/main/java/devkor/com/teamcback/global/response/CommonResponse.java Add no-data success response
src/main/java/devkor/com/teamcback/global/jwt/JwtAuthorizationFilter.java Remove access-token logging
src/main/java/devkor/com/teamcback/global/config/TimeConfig.java Provide injectable Clock bean
src/main/java/devkor/com/teamcback/global/aop/UpdateScoreAspect.java Sync level + point on score updates
src/main/java/devkor/com/teamcback/domain/user/validator/KakaoValidator.java Support admin audience + resolveEmail
src/main/java/devkor/com/teamcback/domain/user/service/UserService.java Add admin login; persist level/point behaviors
src/main/java/devkor/com/teamcback/domain/user/scheduler/UserLevelBackfillRunner.java Backfill level/point on startup
src/main/java/devkor/com/teamcback/domain/user/repository/UserRepository.java Add backfill + atomic point deduction
src/main/java/devkor/com/teamcback/domain/user/entity/User.java Add point/level/equippedCharacterId fields
src/main/java/devkor/com/teamcback/domain/user/entity/Level.java Add fromScore + lazy profile image
src/main/java/devkor/com/teamcback/domain/user/dto/response/LoginUserRes.java Include loginKey in login response
src/main/java/devkor/com/teamcback/domain/user/dto/response/GetUserInfoRes.java Include point in user info response
src/main/java/devkor/com/teamcback/domain/user/dto/response/AdminLoginRes.java New admin login response DTO
src/main/java/devkor/com/teamcback/domain/user/dto/request/AdminLoginReq.java New admin login request DTO
src/main/java/devkor/com/teamcback/domain/user/controller/UserController.java Expose admin login endpoint
src/main/java/devkor/com/teamcback/domain/usagesurvey/repository/UsageSurveyResponseRepository.java Usage survey response persistence
src/main/java/devkor/com/teamcback/domain/usagesurvey/repository/UsageSurveyDismissalRepository.java Usage survey dismissal persistence
src/main/java/devkor/com/teamcback/domain/usagesurvey/entity/UsageSurveyResponse.java Usage survey response entity
src/main/java/devkor/com/teamcback/domain/usagesurvey/entity/UsageSurveyQuestion.java Survey question keys enum
src/main/java/devkor/com/teamcback/domain/usagesurvey/entity/UsageSurveyDismissReason.java Dismiss reason enum
src/main/java/devkor/com/teamcback/domain/usagesurvey/entity/UsageSurveyDismissal.java Dismissal entity
src/main/java/devkor/com/teamcback/domain/usagesurvey/dto/response/UsageSurveyStatusRes.java Status response record
src/main/java/devkor/com/teamcback/domain/usagesurvey/dto/response/SubmitUsageSurveyResponseRes.java Submit response + score hooks
src/main/java/devkor/com/teamcback/domain/usagesurvey/dto/request/SubmitUsageSurveyResponseReq.java Submit request record
src/main/java/devkor/com/teamcback/domain/usagesurvey/dto/request/RecordUsageSurveyDismissalReq.java Dismiss request record
src/main/java/devkor/com/teamcback/domain/usagesurvey/controller/UsageSurveyController.java Usage survey user endpoints
src/main/java/devkor/com/teamcback/domain/suggestion/entity/SuggestionType.java Add POPUP suggestion type
src/main/java/devkor/com/teamcback/domain/review/service/ReviewService.java Add equipped profile image to review feed
src/main/java/devkor/com/teamcback/domain/review/dto/response/SearchPlaceReviewRes.java Include username + profile image URL
src/main/java/devkor/com/teamcback/domain/report/service/ReportService.java Publish ReportResolvedEvent on finalization
src/main/java/devkor/com/teamcback/domain/report/event/ReportResolvedEvent.java New domain event record
src/main/java/devkor/com/teamcback/domain/place/entity/PlaceType.java Add PHARMACY type
src/main/java/devkor/com/teamcback/domain/notification/validation/PushActionValidator.java Validate/normalize push deep-link params
src/main/java/devkor/com/teamcback/domain/notification/template/PushContent.java Push content record
src/main/java/devkor/com/teamcback/domain/notification/template/DomainPushContentFactory.java Central push message templates
src/main/java/devkor/com/teamcback/domain/notification/service/PushReceiptWorker.java Receipt polling worker
src/main/java/devkor/com/teamcback/domain/notification/service/PushMessageRecoveryWorker.java Recovery worker wrapper
src/main/java/devkor/com/teamcback/domain/notification/service/PushMessageRecoveryService.java Recover stale SENDING messages
src/main/java/devkor/com/teamcback/domain/notification/service/PushMessageDispatchWorker.java Message send worker
src/main/java/devkor/com/teamcback/domain/notification/service/PushInstallationService.java Register/deactivate installations
src/main/java/devkor/com/teamcback/domain/notification/service/PushEventFlagService.java Redis-backed event flags + targeting
src/main/java/devkor/com/teamcback/domain/notification/service/PushDispatchService.java Enqueue push dispatch + messages
src/main/java/devkor/com/teamcback/domain/notification/scheduler/PushReceiptWorkerScheduler.java Schedule receipt polling
src/main/java/devkor/com/teamcback/domain/notification/scheduler/PushMessageWorkerScheduler.java Schedule message dispatch
src/main/java/devkor/com/teamcback/domain/notification/scheduler/PushMessageRecoveryScheduler.java Schedule stale-message recovery
src/main/java/devkor/com/teamcback/domain/notification/resolver/PushTargetResolver.java Resolve target recipients
src/main/java/devkor/com/teamcback/domain/notification/repository/SurveyPushScheduleRepository.java Survey schedule queries + SKIP LOCKED
src/main/java/devkor/com/teamcback/domain/notification/repository/PushMessageRepository.java Message claim/recovery queries
src/main/java/devkor/com/teamcback/domain/notification/repository/PushInstallationRepository.java Installation lookups
src/main/java/devkor/com/teamcback/domain/notification/repository/PushDispatchRepository.java Dispatch admin queries
src/main/java/devkor/com/teamcback/domain/notification/listener/ReportResolvedPushEventListener.java Push on report finalization
src/main/java/devkor/com/teamcback/domain/notification/listener/CrowdVacantPushEventListener.java Push on BLE vacancy event
src/main/java/devkor/com/teamcback/domain/notification/listener/CharacterUnlockedPushEventListener.java Push on character unlock
src/main/java/devkor/com/teamcback/domain/notification/factory/PushPayloadFactory.java Build/size-check Expo payload
src/main/java/devkor/com/teamcback/domain/notification/entity/type/SurveyReminderSuppressedBy.java Survey suppression enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/SurveyPushScheduleStatus.java Survey schedule status enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/SurveyNotificationStage.java Survey stage enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/PushTargetType.java Push target enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/PushMode.java Push mode enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/PushMessageStatus.java Message status enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/PushEventType.java Event flag enum + redis keys
src/main/java/devkor/com/teamcback/domain/notification/entity/type/PushDispatchStatus.java Dispatch status enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/PushActionType.java Deep-link action enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/NotificationType.java Notification type enum
src/main/java/devkor/com/teamcback/domain/notification/entity/type/AppVariant.java App variant enum + JSON mapping
src/main/java/devkor/com/teamcback/domain/notification/entity/SurveyPushSchedule.java Survey schedule entity
src/main/java/devkor/com/teamcback/domain/notification/entity/PushInstallation.java Installation entity
src/main/java/devkor/com/teamcback/domain/notification/dto/worker/PushWorkerDispatchResult.java Worker result record
src/main/java/devkor/com/teamcback/domain/notification/dto/worker/PushSendItem.java Worker send item record
src/main/java/devkor/com/teamcback/domain/notification/dto/worker/PushReceiptWorkerResult.java Receipt worker result record
src/main/java/devkor/com/teamcback/domain/notification/dto/worker/PushReceiptItem.java Receipt claim item record
src/main/java/devkor/com/teamcback/domain/notification/dto/response/SurveyReminderRes.java Survey reminder response record
src/main/java/devkor/com/teamcback/domain/notification/dto/response/PushDispatchEnqueueRes.java Enqueue response DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/response/NotificationTestRes.java Test-push response record
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminSurveyPushScheduleStageRes.java Admin schedule stage response
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminSurveyPushScheduleRes.java Admin schedule response
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminPushInstallationRes.java Admin installation view DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminPushEventFlagRes.java Admin flag response record
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminPushDispatchSummaryRes.java Admin dispatch summary DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminPushDispatchPreviewRes.java Admin dispatch preview DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/response/AdminPushDispatchDetailRes.java Admin dispatch detail DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/request/UpdatePushEventFlagReq.java Update flag request record
src/main/java/devkor/com/teamcback/domain/notification/dto/request/PushInstallationRegisterReq.java Register installation request record
src/main/java/devkor/com/teamcback/domain/notification/dto/request/PushDispatchCommand.java Internal dispatch command record
src/main/java/devkor/com/teamcback/domain/notification/dto/request/NotificationTestReq.java Test-push request record
src/main/java/devkor/com/teamcback/domain/notification/dto/request/AdminSurveyPushScheduleReq.java Admin schedule request record
src/main/java/devkor/com/teamcback/domain/notification/dto/request/AdminPushDispatchReq.java Admin dispatch request record
src/main/java/devkor/com/teamcback/domain/notification/dto/payload/PushPayload.java Push payload record schema
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoReceiptResponse.java Expo receipt response DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoReceiptRequest.java Expo receipt request DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoPushTicket.java Expo ticket DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoPushResponse.java Expo send response DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoPushRequest.java Expo send request DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoPushReceipt.java Expo receipt DTO
src/main/java/devkor/com/teamcback/domain/notification/dto/expo/ExpoPushErrorDetails.java Expo error details DTO
src/main/java/devkor/com/teamcback/domain/notification/controller/SurveyNotificationController.java Survey reminder endpoint
src/main/java/devkor/com/teamcback/domain/notification/controller/PushInstallationController.java Installation register/deactivate APIs
src/main/java/devkor/com/teamcback/domain/notification/controller/NotificationTestController.java DEV/PREVIEW test-push endpoint
src/main/java/devkor/com/teamcback/domain/notification/controller/AdminSurveyPushScheduleController.java Admin survey schedule APIs
src/main/java/devkor/com/teamcback/domain/notification/config/PushWorkerProperties.java Worker configuration properties
src/main/java/devkor/com/teamcback/domain/notification/config/PushRecoveryWorkerProperties.java Recovery worker properties
src/main/java/devkor/com/teamcback/domain/notification/config/PushReceiptWorkerProperties.java Receipt worker properties
src/main/java/devkor/com/teamcback/domain/notification/config/ExpoPushPropertiesConfig.java Enable push properties binding
src/main/java/devkor/com/teamcback/domain/notification/config/ExpoPushProperties.java Expo client properties
src/main/java/devkor/com/teamcback/domain/notification/config/ExpoPushFeignConfig.java Feign client config
src/main/java/devkor/com/teamcback/domain/notification/client/ExpoPushClientException.java Client exception wrapper
src/main/java/devkor/com/teamcback/domain/notification/client/ExpoPushApi.java Feign API interface
src/main/java/devkor/com/teamcback/domain/character/repository/UserCharacterRepository.java User-character queries
src/main/java/devkor/com/teamcback/domain/character/repository/CharacterRepository.java Character queries
src/main/java/devkor/com/teamcback/domain/character/event/CharacterUnlockedEvent.java Character unlock event record
src/main/java/devkor/com/teamcback/domain/character/entity/UserCharacter.java Ownership entity + uniqueness
src/main/java/devkor/com/teamcback/domain/character/entity/PurchaseStatus.java Store purchase state enum
src/main/java/devkor/com/teamcback/domain/character/entity/KoCharacter.java Character catalog entity
src/main/java/devkor/com/teamcback/domain/character/dto/response/UnequipCharacterRes.java Unequip response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/PurchaseCharacterRes.java Purchase response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/ModifyCharacterRes.java Modify response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GrantCharacterRes.java Grant response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GetStoreRes.java Store view response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GetStoreCharacterRes.java Store item response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GetMyCharacterRes.java Owned character response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GetMyCharacterListRes.java Owned list response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GetAdminCharacterRes.java Admin character DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/GetAdminCharacterListRes.java Admin list DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/EquipCharacterRes.java Equip response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/DeleteCharacterRes.java Delete response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/response/CreateCharacterRes.java Create response DTO
src/main/java/devkor/com/teamcback/domain/character/dto/request/ModifyCharacterReq.java Modify request DTO
src/main/java/devkor/com/teamcback/domain/character/dto/request/CreateCharacterReq.java Create request DTO
src/main/java/devkor/com/teamcback/domain/bookmark/repository/CategoryRepository.java Add distinct userId query
src/main/java/devkor/com/teamcback/domain/ble/service/BLEService.java Publish vacancy event on transition
src/main/java/devkor/com/teamcback/domain/ble/repository/BLEDataRepository.java Add deterministic latest lookup
src/main/java/devkor/com/teamcback/domain/ble/event/PlaceBecameVacantEvent.java BLE vacancy event record
.gitignore Ignore local-only configs
.github/workflows/cd.yml Remove public IP step
.github/workflows/cd-dev.yml Add workflow_dispatch; remove IP step
Suppressed comments (1)

src/main/java/devkor/com/teamcback/domain/notification/template/DomainPushContentFactory.java:47

  • characterUnlocked()name + "을 만나러..."도 조사가 고정되어 캐릭터을처럼 사용자 노출 문구가 어색해집니다. 마지막 글자의 받침 유무에 따라 을/를을 선택하거나 문장 구조를 바꾸는 방식으로 문구를 교정하는 것이 좋습니다.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +49 to +50
@Modifying(flushAutomatically = true, clearAutomatically = true)
@Query("update User u set u.point = u.point - :price where u.userId = :userId and u.point >= :price")
Comment on lines +35 to +45
public List<AppVariant> getTargetAppVariants() {
List<AppVariant> configuredVariants = Arrays.stream(targetAppVariants.split(","))
.map(String::trim)
.filter(value -> !value.isEmpty())
.map(value -> AppVariant.valueOf(value.toUpperCase(Locale.ROOT)))
.distinct()
.toList();
return configuredVariants.isEmpty()
? List.of(AppVariant.PRODUCTION)
: configuredVariants;
}
// UPDATE 실패를 catch해도 rollback-only 커밋 예외가 리스너 밖으로 나가 부팅이 실패한다.
@EventListener(ApplicationReadyEvent.class)
public void backfillUserLevels() {
if(env.equals("test")) return; // H2 테스트 환경은 create-drop이라 백필 불필요 + Redis 미기동
Comment on lines +107 to +114
// notification 17000
NOT_FOUND_PUSH_INSTALLATION(HttpStatus.NOT_FOUND, 17000, "Push installation not found."),
FORBIDDEN_PUSH_INSTALLATION(HttpStatus.FORBIDDEN, 17001, "Push installation is not owned by the current user."),
INACTIVE_PUSH_INSTALLATION(HttpStatus.BAD_REQUEST, 17002, "Push installation is inactive."),
UNSUPPORTED_PUSH_INSTALLATION_VARIANT(HttpStatus.BAD_REQUEST, 17003, "Push installation variant is not supported for test push."),
EXPO_PUSH_RETRYABLE_ERROR(HttpStatus.SERVICE_UNAVAILABLE, 17004, "Expo push request failed with retryable error."),
EXPO_PUSH_NON_RETRYABLE_ERROR(HttpStatus.BAD_GATEWAY, 17005, "Expo push request failed with non-retryable error."),
EXPO_PUSH_TICKET_ERROR(HttpStatus.BAD_GATEWAY, 17006, "Expo push ticket returned error status."),
Comment on lines +24 to +29
String location = joinNonBlank(buildingName, placeName);

return new PushContent(
VACANT_TITLE,
location + "이 한산해요. 방문하기 전 현황을 확인해보세요."
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants