Skip to content

nampongo/Waved_BE

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌊 Riding the Wave of Challenges Toward Employment with WAVED

image image image

πŸ’‘ Project Overview

WAVED is a challenge-based platform designed to motivate and support developers preparing for employment.
Users can join various sessions, set personal goals, and build consistency through daily certification and community interaction.

πŸ”Ή Key Features

  • Personalized Challenges: Tailored challenge sessions designed for developers preparing for jobs.
  • Motivational System: Users deposit participation fees as a commitment incentive and earn rewards upon completion.
  • Flexible Verification Methods: Each challenge supports customized verification types (image, text, GitHub, link).
  • Community Interaction: Participants can share progress and feedback with peers in the same challenge session.

πŸ”— Service Link

https://waved-likelion.site/ (service discontinued)

πŸ—“οΈ Development Period

  • Development: Feb 26, 2024 – Mar 22, 2024
  • Testing & Refactoring: Apr 1, 2024 – Apr 26, 2024

πŸ‘₯ Team

Backend Γ—2 | Frontend Γ—3 | Designer Γ—2

image

πŸ› οΈ Tech Stack & Tools





πŸ“˜ API Documentation

πŸ“Ž Postman API Spec

πŸ—‚οΈ Database Schema

image

πŸ“ Package Structure

src
└── main
    β”œβ”€β”€ java/com/senity/waved
    β”‚     β”œβ”€β”€ base
    β”‚     β”‚     └── config, exception, jwt, redis, security
    β”‚     β”œβ”€β”€ common
    β”‚     └── domain
    β”‚           β”œβ”€β”€ admin, challenge, challengeGroup, event, liked, member,
    β”‚           β”‚ myChallenge, notification, paymentRecord, quiz, review, verification
    β”‚           └── Each includes controller, service, repository, dto, entity
    └── resources
          β”œβ”€β”€ application.yml
          └── application-secret.yml

βš™οΈ Features

🧩 A. Authentication β€” Google OAuth 2.0 + JWT Token

  • Integrated Spring Security with Google OAuth 2.0 for authentication.
  • Used Redis for managing refresh tokens.
  • Implemented blacklist handling to block logged-out tokens until expiry.

πŸ“Έ B. Multiple Challenge Verification Types

Users can verify progress via image, text, link, or GitHub commit.

  • Image verification: Uploaded via multipart and stored in Azure Blob Storage.
  • GitHub verification: Integrated with GitHub API to check daily commit activity.
image image

❀️ C. Like & Review System

Implemented transaction-level isolation to ensure data consistency during concurrent like events.
Even with multiple simultaneous likes, transaction isolation prevents dirty reads and maintains atomicity.

⏰ D. Automated Challenge Generation

Originally, each challenge session had to be created manually.
Added scheduling and auto-generation logic to create new challenge sessions dynamically,
improving operational efficiency and data accuracy.

πŸ’³ E. Payment Integration (PortOne API)

Integrated with PortOne API for the entire payment process:
payment verification, post-payment validation, cancellation, and refund handling.

πŸ”” F. Real-Time Notification (SSE)

Implemented real-time notifications using Spring SSE (Server-Sent Events).
Admins can immediately notify users about canceled verifications or status updates.

🧯 G. Exception Handling

Defined a global exception handler for consistent error response structure across the API.
Each exception type returns an appropriate HTTP status code and message,
reducing redundancy and improving collaboration.

@RestControllerAdvice
public class GlobalExceptionHandler {
    @ExceptionHandler(MemberNotFoundException.class)
    @ResponseStatus(HttpStatus.NOT_FOUND)
    public ResponseEntity<ResponseDto> handleMemberNotFoundException(MemberNotFoundException e) {
        return ResponseDto.of(HttpStatus.NOT_FOUND, e.getMessage());
    }

    @ExceptionHandler(WrongGithubInfoException.class)
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public ResponseEntity<ResponseDto> handleWrongGithubInfoException(WrongGithubInfoException e) {
        return ResponseDto.of(HttpStatus.BAD_REQUEST, e.getMessage());
    }
}

πŸš€ Performance Optimization & Issues

1️⃣ Query Optimization β€” Partial Select


Observed unnecessary data loading and tested multiple partial query methods for performance improvement.

a. Performance Tests

Test1 - Elapsed time: 112 ms  # Default entity query
Test2 - Elapsed time: 673 ms  # QueryDSL partial select
Test3 - Elapsed time: 601 ms  # Projection partial select
Test4 - Elapsed time: 471 ms  # DTO partial select

b. Query Analysis Compared full entity vs DTO projections β€”
DTO-based partial select improved readability and maintenance but had higher overhead, so the default entity query was retained for efficiency.

 
    Hibernate: 
        select
            m1_0.id,
            m1_0.auth_level,
            m1_0.birth_year,
            m1_0.create_date,
            m1_0.email,
            m1_0.gender,
            m1_0.github_id,
            m1_0.github_token,
            m1_0.has_info,
            m1_0.has_new_event,
            m1_0.job_title,
            m1_0.modified_date,
            m1_0.nickname 
        from
            member m1_0 
        where
            m1_0.id=?

    Hibernate: 
        /* SELECT
            new com.senity.waved.domain.challenge.service.NicknameDto(m.nickname) 
        FROM
            Member m 
        WHERE
            m.id =:id */ select
                m1_0.nickname 
            from
                member m1_0 
            where
                m1_0.id=?

c. Memory Usage

Test1 - Elapsed time: 103 ms  | Memory: 4,527,440 bytes  
Test2 - Elapsed time: 564 ms  | Memory: 23,068,640 bytes  

Result: ~5Γ— higher memory usage in DTO-based queries β†’ reverted to full entity select.

2️⃣ Object-Relation Optimization

Due to session-based challenge structure, complex relationships caused redundant data loading.


a. Redefined JPA Mappings
Removed unnecessary relationships and optimized entity mappings.
Maintained referential integrity using explicit foreign key constraints.

b. Entity–DTO Conversion
Introduced DTO conversion to achieve separation of concerns,
improving flexibility and maintainability of service layers.

Result:
Prevented infinite loops during entity fetching.
Reduced query calls, improving load time from 3s β†’ 1s on β€œMy Challenge” page.

About

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Contributors 3

  •  
  •  
  •  

Languages