Vk/86ff gsd discuss phas - #25
Conversation
All phases complete: Foundation+CI, CD Pipeline, Hardening (8 plans). 259 files changed across the milestone. Roadmap collapsed, PROJECT.md evolved.
Archived to milestones/v1.2-REQUIREMENTS.md. Fresh requirements will be created for next milestone.
…uages - Trimmed SUPPORTED_LANGUAGES from 13 to 5 entries (javascript, python, java, c, cpp) - Matches CodeExecutionService whitelist to prevent submissions in unsupported languages
…parsing - All 5 batch wrappers (JS, Python, C, C++, Java) read /sys/fs/cgroup/memory.current - parseBatchResults extracts memory bytes and converts to MB - buildCaseResult accepts double memoryMb parameter, formats as "X.XMB" - Execute method computes maxMemory from case results instead of hardcoded "0KB" - emptyResult uses "0.0MB" instead of "0KB"
- 10 test methods covering: pollAndProcess, processJob, determineVerdict, shouldRetry, onFailure, parseMemoryMb, parseRuntimeMs - Tests verify verdict priority ordering (RE > MLE > TLE > WA > PE > Accepted) - Tests verify retry logic skips compile errors and unsupported languages - Tests verify System Error handling for null/empty test cases
…, and WebSocket push - JudgeWorkerProcessor implements JobProcessor<JudgeJob>, polls Redis judge_queue via @scheduled - Verdict priority: RE > MLE > TLE > WA > PE > Accepted - Retry with exponential backoff (2s, 4s, 8s), max 3 retries; compile errors not retried - System Error verdict after exhausting retries - WebSocket push via RealtimeService.emitSubmissionResult after verdict - AtomicInteger activeJobs guard prevents unbounded concurrency - QueueConfig adds judgeEnabled field for conditional activation - 27 unit tests pass covering all behaviors
- SUMMARY.md with 2 tasks, 3 files, 11min duration - STATE.md advanced to plan 2/2 (100%), ready for verification - ROADMAP.md phase 12 marked Complete - REQUIREMENTS.md JUDGE-01 marked complete
Two plans covering contest entity creation, admin CRUD, announcement management, and contest submission recording. - 13-01: Entities + mappers + admin contest lifecycle (Wave 1) - 13-02: Contest submission recording + announcement CRUD (Wave 2) Covers: CONTEST-01, CONTEST-02, CONTEST-05, CONTEST-07
… research questions
…es and mappers - Rename PARTICIPATING->STARTED, COMPLETED->FINISHED in enum to match DB schema - Update all references in ContestServiceImpl (8 occurrences) and ContestParticipantMapper SQL - Create ContestProblem entity (Long problemId matching bigint column) - Create ContestSubmission entity (no updatedAt per V3 DDL) - Create ContestAnnouncement entity (no updatedAt per V3 DDL) - Create ContestProblemMapper with findByContestId, countByContestId, deleteByContestId, findByProblemId - Create ContestSubmissionMapper with findByContestIdAndParticipantId, countByContestId - Create ContestAnnouncementMapper with findByContestIdOrderByCreatedAtDesc (pinned first)
- Add createContest with problem bulk-insert (Q1/Q2/Q3 labels, UPCOMING status)
- Add updateContest with status validation (UPCOMING only) and problem replacement
- Add deleteContest with soft-delete (UPCOMING or FINISHED only)
- Add startContest (UPCOMING->RUNNING, validates at least one problem assigned)
- Add endContest (RUNNING->FINISHED)
- Extend toAdminVO to set problemCount from contestProblemMapper.countByContestId
- Add 5 REST endpoints: POST /, PATCH /{id}, DELETE /{id}, POST /{id}/start, POST /{id}/end
- All endpoints require ADMIN or SUPER_ADMIN role via @PreAuthorize
…ervice - Record ContestSubmission atomically alongside regular Submission for active contest participants - Guard contest recording with try-catch to never break main submission flow - Check for RUNNING contest status and STARTED participant status before recording - Add announcement CRUD methods (create, update, delete, list) to AdminContestService - Emit WebSocket push via RealtimeService.emitAnnouncement() on announcement creation
…ContestController - Create CreateAnnouncementDTO with @notblank on title/content and @SiZe(max=200) on title - Create UpdateAnnouncementDTO with optional fields for PATCH semantics - Add GET/POST/PATCH/DELETE announcement endpoints to AdminContestController - All endpoints require ADMIN/SUPER_ADMIN role and use typed DTOs (no Map usage)
…tle infrastructure - Add RankingService dependency via constructor injection - Add markDirty(String) method to mark contests with pending ranking updates - Add @scheduled(fixedRate=1000) flushPendingRankings() to emit at most one ranking update per second per contest - Map ContestRankingVO fields (score, penalty, problemsSolved) to RankingItem - Add Set and Collectors imports for throttle logic Per D-12 (throttled to max once per second per contest), D-13 (ranking recalculated on every submission), D-14 (payload: userId, username, rank, score, penalty, solved count)
…cking and fix contestId in WebSocket payload
SubmissionServiceImpl:
- Inject RealtimeService via constructor
- Call realtimeService.markDirty(contestId) after ContestSubmission insert
JudgeWorkerProcessor:
- Inject ContestSubmissionMapper via constructor
- Add findContestIdBySubmissionId() helper using MyBatis-Plus query wrapper
- Update pushResult() signature to accept contestId parameter
- Pass contestId (not null) to SubmissionResultPayload.of() at all call sites
- All three pushResult call sites updated: processJob (success),
processJob (System Error fallback), and onFailure (retry exhausted)
Per D-15 (JudgeWorkerProcessor has WebSocket push),
D-16 (pushed to /user/{userId}/submission),
D-17 (payload: submissionId, status, score, timeUsed, memoryUsed, judgedAt)
…lementation - RatingCalculationService interface with calculateAndUpdate(contestId) - CF Elo formula: expected=1/(1+10^((opp-my)/400)), K=32/24/16 by rating - Rating clamped to 0-3500 range - fromRating() maps rating to correct RatingTitle per D-08 thresholds (10 levels) - Assigns final_rank 1-based from sorted participants (score DESC, penalty ASC) - Only rates participants with existing global_ranking records (D-11) - Updates global_rankings and recalculates global ranks after batch update Refs: D-06, D-07, D-08, D-09, D-10, D-11, T-14-05, T-14-06
ContestStatusEvent.ContestStatus enum uses ENDED, not FINISHED. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
CR-01 fix: actual score now uses rank-based binary outcome (actual=1 if me.rank < opp.rank, else 0), not always 1. Also rename oderId -> userId per IN-01. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 14: 2/2 plans complete - 14-01: throttle infrastructure (markDirty + flushPendingRankings + contestId fix) - 14-02: ContestScheduler + RatingCalculationService + ContestScheduler ENDED fix + CF Elo formula fix Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Phase 15: Problem + User Enhancements - PROB-01: GET /problems/random endpoint - PROB-02: acceptance rate calculation from submissions - PROB-03: admin bulk operations API - PROB-04: extend CreateProblemDTO with full fields - USER-01: globalRank in UserStatsDTO - USER-02: acceptanceRate in UserStatsDTO - USER-03: public user profile routing - USER-04: achievement path aliases - USER-05: submissionCount in UserStatsDTO Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Wave 1 (15-01): PROB-01/02 random problem + acceptance rate, USER-01/02/05 stats enrichment Wave 2 (15-02): PROB-03/04 admin bulk ops + extended DTO, USER-03/04 public profile + achievement aliases Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add findRandomPublished() method to ProblemService interface for PROB-01: GET /problems/random endpoint implementation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PROB-01: Implement findRandomPublished() in ProblemServiceImpl using ORDER BY RAND() LIMIT 1 to select a random published problem. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PROB-01: Add GET /problems/random public endpoint to ProblemController. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
PROB-02: Add static factory methods from(Problem) and from(Problem, BigDecimal) to ProblemVO to support acceptance rate calculation from SQL aggregation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
USER-01/USER-02/USER-05: Add three new SQL queries to SubmissionMapper: - findGlobalRankByUserId: get global rank from global_rankings table - calculateAcceptanceRateByUserId: compute acceptance rate percentage - countTotalSubmissionsByUserId: count total submissions per user Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…atsDTO USER-01/USER-02/USER-05: Add globalRank, acceptanceRate, and submissionCount fields to UserStatsDTO and populate them in getUserStatsById() via SubmissionMapper queries. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add BulkProblemRequestDTO and BulkProblemResultDTO for batch operations on problems (publish, unpublish, delete, edit). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Implement bulkAction method to perform batch operations (publish, unpublish, delete, edit) on multiple problems. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add bulk action endpoint for batch operations on problems. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add summary, content, examples, constraints, hints, languages, and tags fields to support full problem creation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add /achievements/my and /achievements/points as aliases for frontend routes /achievements/user/me and /achievements/user/me/points. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Add user profile route to console router. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Create user profile page that displays username, join date, global rank, acceptance rate, submission count, and solved problems breakdown. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
…shed Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: ba0053d1eb
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if (newRating > gr.getMaxRating()) { | ||
| globalRankingMapper.updateMaxRatingTitle(newTitle.name(), userId); |
There was a problem hiding this comment.
Pass mapper arguments in correct order
The updateMaxRatingTitle call swaps userId and maxRatingTitle: the mapper signature is (userId, maxRatingTitle), but this code sends (newTitle.name(), userId). When a user reaches a new max rating, the SQL WHERE user_id = ... clause is evaluated against a title string (e.g., EXPERT), so the row is not updated (and may violate enum expectations for max_rating_title).
Useful? React with 👍 / 👎.
| contest.setStatus(ContestStatus.FINISHED.name()); | ||
| contestMapper.updateById(contest); |
There was a problem hiding this comment.
Invoke contest finalization side effects on manual end
This admin path sets contest status to FINISHED and returns, but it does not trigger rating computation. In this commit, rating updates are only executed from ContestScheduler.transitionToFinished, which runs only when transitioning a RUNNING contest itself; once admin sets FINISHED here, that scheduler path is skipped, leaving final ranks/ratings stale for manually ended contests.
Useful? React with 👍 / 👎.
| .memory(results.stream() | ||
| .map(RunResultDTO.RunCaseResult::getMemory) | ||
| .max(String::compareTo) | ||
| .orElse("0.0MB")) |
There was a problem hiding this comment.
Aggregate memory usage numerically, not lexicographically
The overall memory field is computed via max(String::compareTo) on values like "4.0MB", which performs lexicographic comparison rather than numeric comparison. This can report the wrong peak memory (for example, "9.5MB" can be treated as larger than "12.0MB"), causing inaccurate submission metrics.
Useful? React with 👍 / 👎.
* chore: archive v1.2 CI/CD Pipeline milestone All phases complete: Foundation+CI, CD Pipeline, Hardening (8 plans). 259 files changed across the milestone. Roadmap collapsed, PROJECT.md evolved. * chore: remove REQUIREMENTS.md for v1.2 milestone Archived to milestones/v1.2-REQUIREMENTS.md. Fresh requirements will be created for next milestone. * docs: start milestone v1.3 Core Features * docs: define milestone v1.3 requirements (20 requirements, 4 categories) * docs: create milestone v1.3 roadmap (4 phases, 20 requirements) * docs(12): capture phase context * docs(state): record phase 12 context session * docs(12): research judge worker phase domain * docs(12-judge-worker): create phase plan * docs(12): phase plans created (2 plans, 2 waves) * feat(12-01): restrict SUPPORTED_LANGUAGES to 5 sandbox-supported languages - Trimmed SUPPORTED_LANGUAGES from 13 to 5 entries (javascript, python, java, c, cpp) - Matches CodeExecutionService whitelist to prevent submissions in unsupported languages * feat(12-01): add cgroup v2 memory measurement to wrapper scripts and parsing - All 5 batch wrappers (JS, Python, C, C++, Java) read /sys/fs/cgroup/memory.current - parseBatchResults extracts memory bytes and converts to MB - buildCaseResult accepts double memoryMb parameter, formats as "X.XMB" - Execute method computes maxMemory from case results instead of hardcoded "0KB" - emptyResult uses "0.0MB" instead of "0KB" * docs(12-01): complete language-validation-and-memory plan * test(12-02): add failing tests for JudgeWorkerProcessor - 10 test methods covering: pollAndProcess, processJob, determineVerdict, shouldRetry, onFailure, parseMemoryMb, parseRuntimeMs - Tests verify verdict priority ordering (RE > MLE > TLE > WA > PE > Accepted) - Tests verify retry logic skips compile errors and unsupported languages - Tests verify System Error handling for null/empty test cases * feat(12-02): implement JudgeWorkerProcessor with verdict logic, retry, and WebSocket push - JudgeWorkerProcessor implements JobProcessor<JudgeJob>, polls Redis judge_queue via @scheduled - Verdict priority: RE > MLE > TLE > WA > PE > Accepted - Retry with exponential backoff (2s, 4s, 8s), max 3 retries; compile errors not retried - System Error verdict after exhausting retries - WebSocket push via RealtimeService.emitSubmissionResult after verdict - AtomicInteger activeJobs guard prevents unbounded concurrency - QueueConfig adds judgeEnabled field for conditional activation - 27 unit tests pass covering all behaviors * docs(12-02): complete Judge Worker plan - SUMMARY.md with 2 tasks, 3 files, 11min duration - STATE.md advanced to plan 2/2 (100%), ready for verification - ROADMAP.md phase 12 marked Complete - REQUIREMENTS.md JUDGE-01 marked complete * docs(phase-12): complete phase execution * docs(13): capture phase context * docs(state): record phase 13 context session * docs(13): research contest data layer phase * docs(13): create phase plan for contest data layer Two plans covering contest entity creation, admin CRUD, announcement management, and contest submission recording. - 13-01: Entities + mappers + admin contest lifecycle (Wave 1) - 13-02: Contest submission recording + announcement CRUD (Wave 2) Covers: CONTEST-01, CONTEST-02, CONTEST-05, CONTEST-07 * docs(13): revise plans to fix enum mismatch, typed DTOs, and resolved research questions * docs(state): record phase 13 planning complete * feat(13-01): fix ContestParticipantStatus enum, create contest entities and mappers - Rename PARTICIPATING->STARTED, COMPLETED->FINISHED in enum to match DB schema - Update all references in ContestServiceImpl (8 occurrences) and ContestParticipantMapper SQL - Create ContestProblem entity (Long problemId matching bigint column) - Create ContestSubmission entity (no updatedAt per V3 DDL) - Create ContestAnnouncement entity (no updatedAt per V3 DDL) - Create ContestProblemMapper with findByContestId, countByContestId, deleteByContestId, findByProblemId - Create ContestSubmissionMapper with findByContestIdAndParticipantId, countByContestId - Create ContestAnnouncementMapper with findByContestIdOrderByCreatedAtDesc (pinned first) * feat(13-01): implement admin contest CRUD and lifecycle endpoints - Add createContest with problem bulk-insert (Q1/Q2/Q3 labels, UPCOMING status) - Add updateContest with status validation (UPCOMING only) and problem replacement - Add deleteContest with soft-delete (UPCOMING or FINISHED only) - Add startContest (UPCOMING->RUNNING, validates at least one problem assigned) - Add endContest (RUNNING->FINISHED) - Extend toAdminVO to set problemCount from contestProblemMapper.countByContestId - Add 5 REST endpoints: POST /, PATCH /{id}, DELETE /{id}, POST /{id}/start, POST /{id}/end - All endpoints require ADMIN or SUPER_ADMIN role via @PreAuthorize * docs(13-01): complete contest-entities-and-admin-crud plan * docs(phase-13): update tracking after wave 1 * feat(13-02): add contest submission recording and announcement CRUD service - Record ContestSubmission atomically alongside regular Submission for active contest participants - Guard contest recording with try-catch to never break main submission flow - Check for RUNNING contest status and STARTED participant status before recording - Add announcement CRUD methods (create, update, delete, list) to AdminContestService - Emit WebSocket push via RealtimeService.emitAnnouncement() on announcement creation * feat(13-02): create announcement DTOs and add REST endpoints to AdminContestController - Create CreateAnnouncementDTO with @notblank on title/content and @SiZe(max=200) on title - Create UpdateAnnouncementDTO with optional fields for PATCH semantics - Add GET/POST/PATCH/DELETE announcement endpoints to AdminContestController - All endpoints require ADMIN/SUPER_ADMIN role and use typed DTOs (no Map usage) * docs(13-02): complete announcement CRUD and contest submission recording plan * docs(phase-13): update tracking after wave 2 * docs(phase-13): complete phase execution * docs(14): capture phase context * docs(state): record phase 14 context session * docs(14): research contest engine domain - Spring @scheduled patterns from BackupScheduler - CF Elo rating formula with K-factor thresholds - RealtimeService throttle/flush infrastructure - JUDGE-04 WebSocket verdict push gap (missing contestId) - Null end_time risk for RUNNING→FINISHED transition - Rating title enum vs threshold mismatch risk Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(14): create contest engine plans -- throttle, scheduler, rating feat(14-01): Add RealtimeService markDirty/flushPendingRankings throttle - Wire SubmissionServiceImpl.markDirty() after contest submission - Fix SubmissionResultPayload to include contestId - Fix JUDGE-04 (verdict push) and CONTEST-04 (real-time ranking) feat(14-02): Create ContestScheduler and RatingCalculationService - ContestScheduler polls every 10s for UPCOMING->RUNNING->FINISHED - RatingCalculationService uses CF Elo with K=32/24/16, 10 title levels - Addresses CONTEST-03 (lifecycle) and CONTEST-06 (rating calc) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(14-contest-engine): add markDirty and flushPendingRankings throttle infrastructure - Add RankingService dependency via constructor injection - Add markDirty(String) method to mark contests with pending ranking updates - Add @scheduled(fixedRate=1000) flushPendingRankings() to emit at most one ranking update per second per contest - Map ContestRankingVO fields (score, penalty, problemsSolved) to RankingItem - Add Set and Collectors imports for throttle logic Per D-12 (throttled to max once per second per contest), D-13 (ranking recalculated on every submission), D-14 (payload: userId, username, rank, score, penalty, solved count) * feat(14-contest-engine): wire contest submission verdict to dirty tracking and fix contestId in WebSocket payload SubmissionServiceImpl: - Inject RealtimeService via constructor - Call realtimeService.markDirty(contestId) after ContestSubmission insert JudgeWorkerProcessor: - Inject ContestSubmissionMapper via constructor - Add findContestIdBySubmissionId() helper using MyBatis-Plus query wrapper - Update pushResult() signature to accept contestId parameter - Pass contestId (not null) to SubmissionResultPayload.of() at all call sites - All three pushResult call sites updated: processJob (success), processJob (System Error fallback), and onFailure (retry exhausted) Per D-15 (JudgeWorkerProcessor has WebSocket push), D-16 (pushed to /user/{userId}/submission), D-17 (payload: submissionId, status, score, timeUsed, memoryUsed, judgedAt) * docs(14): complete plan 14-01 summary * feat(14-contest-engine): add RatingCalculationService with CF Elo implementation - RatingCalculationService interface with calculateAndUpdate(contestId) - CF Elo formula: expected=1/(1+10^((opp-my)/400)), K=32/24/16 by rating - Rating clamped to 0-3500 range - fromRating() maps rating to correct RatingTitle per D-08 thresholds (10 levels) - Assigns final_rank 1-based from sorted participants (score DESC, penalty ASC) - Only rates participants with existing global_ranking records (D-11) - Updates global_rankings and recalculates global ranks after batch update Refs: D-06, D-07, D-08, D-09, D-10, D-11, T-14-05, T-14-06 * docs(14): complete plan 14-02 summary * fix(14): use ContestStatus.ENDED instead of FINISHED in ContestScheduler ContestStatusEvent.ContestStatus enum uses ENDED, not FINISHED. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * fix(14): correct CF Elo formula and rename oderId to userId CR-01 fix: actual score now uses rank-based binary outcome (actual=1 if me.rank < opp.rank, else 0), not always 1. Also rename oderId -> userId per IN-01. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(14): mark phase complete, update ROADMAP and STATE tracking Phase 14: 2/2 plans complete - 14-01: throttle infrastructure (markDirty + flushPendingRankings + contestId fix) - 14-02: ContestScheduler + RatingCalculationService + ContestScheduler ENDED fix + CF Elo formula fix Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(15): capture phase 15 context Phase 15: Problem + User Enhancements - PROB-01: GET /problems/random endpoint - PROB-02: acceptance rate calculation from submissions - PROB-03: admin bulk operations API - PROB-04: extend CreateProblemDTO with full fields - USER-01: globalRank in UserStatsDTO - USER-02: acceptanceRate in UserStatsDTO - USER-03: public user profile routing - USER-04: achievement path aliases - USER-05: submissionCount in UserStatsDTO Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(state): record phase 15 context session Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(15): add plan files for Phase 15 Problem + User Enhancements Wave 1 (15-01): PROB-01/02 random problem + acceptance rate, USER-01/02/05 stats enrichment Wave 2 (15-02): PROB-03/04 admin bulk ops + extended DTO, USER-03/04 public profile + achievement aliases Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(state): update Phase 15 status to plans ready Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(problem): add findRandomPublished() to ProblemService Add findRandomPublished() method to ProblemService interface for PROB-01: GET /problems/random endpoint implementation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(problem): implement findRandomPublished() with RAND() query PROB-01: Implement findRandomPublished() in ProblemServiceImpl using ORDER BY RAND() LIMIT 1 to select a random published problem. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(problem): add GET /problems/random endpoint PROB-01: Add GET /problems/random public endpoint to ProblemController. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(problem): add from() factory methods to ProblemVO PROB-02: Add static factory methods from(Problem) and from(Problem, BigDecimal) to ProblemVO to support acceptance rate calculation from SQL aggregation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(user): add globalRank, acceptanceRate, submissionCount queries USER-01/USER-02/USER-05: Add three new SQL queries to SubmissionMapper: - findGlobalRankByUserId: get global rank from global_rankings table - calculateAcceptanceRateByUserId: compute acceptance rate percentage - countTotalSubmissionsByUserId: count total submissions per user Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(user): add globalRank, acceptanceRate, submissionCount to UserStatsDTO USER-01/USER-02/USER-05: Add globalRank, acceptanceRate, and submissionCount fields to UserStatsDTO and populate them in getUserStatsById() via SubmissionMapper queries. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(admin): add bulk problem operation DTOs Add BulkProblemRequestDTO and BulkProblemResultDTO for batch operations on problems (publish, unpublish, delete, edit). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(admin): implement bulkAction in AdminProblemService Implement bulkAction method to perform batch operations (publish, unpublish, delete, edit) on multiple problems. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(admin): add POST /admin/problems/bulk endpoint Add bulk action endpoint for batch operations on problems. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(problem): extend CreateProblemDTO with content fields Add summary, content, examples, constraints, hints, languages, and tags fields to support full problem creation. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(achievement): add /my and /points path aliases Add /achievements/my and /achievements/points as aliases for frontend routes /achievements/user/me and /achievements/user/me/points. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(console): add /users/:id route for public user profiles Add user profile route to console router. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * feat(console): add UserProfileView for public user profiles Create user profile page that displays username, join date, global rank, acceptance rate, submission count, and solved problems breakdown. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> * docs(state): milestone v1.3 complete — Phase 15 done, all phases finished Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
No description provided.