Git Product home page Git Product logo

backend's Introduction

TiTi Backend


Links

name url
Tech spec https://www.notion.so/timertiti/Tech-Spec-d5333f20b7f440fcaab9ae986fa610ce
API docs https://www.notion.so/timertiti/API-Docs-dba28903a8fc4d0d9c49ff686b5ec5f6
Usecase https://www.notion.so/timertiti/Usecase-fb15f24e49374bc3934fe3310775a4d4
Ground rules https://www.notion.so/timertiti/Ground-Rules-a68119a7e06b42a4afc0b6c5d2390f7d
Secret https://www.notion.so/timertiti/Secret-8864c36c5a12468fa0c274b409100721
Infrastrcture https://www.notion.so/timertiti/Infrastructure-9dbb8941e9364c1fbfbb8712b964471f

Getting Started

Development Environment

Setting local environment

$ docker-compose up && docker-compose rm -fsv

Project Configuration

Hexagonal Architecture

hexagonal_architecture.png

├── 📂adapter     ▶️ Adapter module that implements specific operations that go outside the system
│     ├── 📂 in
│     └── 📂 out
├── 📂application ▶️ A module that is responsible for domain access and business logic and provides in and out ports
│     ├── 📂 service
│     ├── 📂 in
│     └── 📂 out
└── 📂domain      ▶️ Domain Module

TiTi Architecture

└──🔹titi-backend
      ├──📂.github ▶️ Github Template
      ├──📂sql ▶️ TITI DB Schema Management
      ├──📂src/main/java/com/titi
      │     ├── 📂exception ▶️ Exception Package
      │     │     ├── 📂adapter
      │     │     ├── 📂application
      │     │     └── 📂domain
      │     └── 📂infrastructure ▶️ Infrastructure Configuration Package
      │     │     ├── 📂cache
      │     │     └── 📂persistence
      │     └── 📂security ▶️ Security Package
      │     │     ├── 📂authentication
      │     │     ├── 📂config
      │     │     ├── 📂constant
      │     │     └── 📂matcher
      │     └── 📂springdoc ▶️ Springdoc Package
      │     ├── 📂titi_auth ▶️ Authentication/Authorization Module
      │     │     ├── 📂adapter
      │     │     ├── 📂application
      │     │     ├── 📂common
      │     │     ├── 📂data
      │     │     └── 📂domain
      │     ├── 📂titi_common_lib ▶️ Common Library
      │     │     ├── 📂constant
      │     │     ├── 📂dto
      │     │     └── 📂util
      │     ├── 📂titi_crypto_lib ▶️ Crypto Library
      │     │     ├── 📂constant
      │     │     ├── 📂exception
      │     │     └── 📂util
      │     ├── 📂titi_pusher ▶️ Pusher Module
      │     │     ├── 📂adapter
      │     │     ├── 📂application
      │     │     ├── 📂common
      │     │     ├── 📂data
      │     │     └── 📂domain
      │     ├── 📂titi_user ▶️ User Module
      │     │     ├── 📂adapter
      │     │     ├── 📂application
      │     │     ├── 📂common
      │     │     ├── 📂data
      │     │     └── 📂domain
      ├──📄.gitattributes
      ├──📄.gitignore
      ├──🐘build.gradle
      ├──🐳docker-compose.yml ▶️ Script for configuring MySQL local environment
      ├──📄README.md
      ├──🐘settings.gradle
      └──📜titi_formatter.xml ▶️ TiTi Java Code Formatter

Contributors


seonpilKim

💻
前 SKTelecom
前 Karrotpay
現 SamsungSDS

backend's People

Contributors

seonpilkim avatar

Stargazers

eunyoung lee avatar Jiyeon Yoon avatar wheesunglee avatar

backend's Issues

난수 생성 유틸 클래스 구현 (2h)

Prerequisite

Related

Background

숫자, 영소/대문자, 자리수, 중복 허용 옵션에 따라 난수를 생성하는 유틸 클래스를 구현한다.

AC

Given When Then
숫자, 영소문자, 영소/대문자, 자리수, 중복 허용 옵션이 주어지면 난수를 생성한다

In scope

  • 난수 생성 기능

Out of Scope

  • 자리수 제한

SyncDailys 의 Daily 동기화 업로드 기능 개발 (72h)

Prerequisite

Related

Background

  • TiTi 연구소 - Sync Dailys 의 동기화 기능중 Daily 에 대한 업로드 기능을 개발한다.

AC

Given When Then
Daily.json 를 전달받았을 때 status 가 "uploaded" 이라면 업로드 대상에서 제외한다.
최초 동기화시도 Daily 인 경우 중복되는 날짜가 없다면 신규 Daily 를 생성한다.
최초 동기화시도 Daily 인 경우 중복되는 날짜가 이미 존재한다면 최신/과거 Daily 형태에 따라서 신규 Daily 로 덮어씌울지를 결정한다.
중복 날짜 검증시 최신 형태의 Daily 이라면 TaskHistory 의 EndDate 끝 시간대값을 비교한다.
중복 날짜 검증시 과거 형태의 Daily 이라면 Day 값을 비교한다.
기존 동기화 이력이 있는 Daily 를 업로드 하는경우 기존 Daily 를 신규 Daily 로 덮어씌운다.

In scope

Out of Scope

RecordTimes 내려받기 기능 개발 (2h)

Prerequisite

Related

Background

  • 기록 측정이력 (RecordTime) 에 대한 내역을 조회하기 기능을 개발한다.

AC

Given When Then
조회시 RecordTImes 이력이 존재하는 경우 기록 내역을 반환한다.
조회시 RecordTImes 이력이 존재하지 않는 경우 에러를 반환한다.

In scope

Out of Scope

이메일 전송 기능 개발 (8h)

Background

사용자와의 소통을 위한 이메일 전송 기능을 개발한다.

AC

Given When Then
제목, 내용(text), 대상 이메일이 주어지면 대상 이메일에게 이메일을 전송한다.
메일 전송에 실패하면(MailException 발생) 에러 로그를 남긴다.

In scope

  • Gmail SMTP Server를 이용한 이메일 전송 기능 개발
  • 이메일 전송은 비동기로 처리한다.
  • 비동기 설정 클래스 추가

Out of Scope

  • html 전송 기능 구현
  • 이메일 전송 템플릿 생성
  • 이메일 전송 실패 로그 webhook 알림 추가

Github PR Template 내용 및 CODEOWNERS 추가 (1h)

Prerequisite

Related

Background

PR에 자동으로 issue를 연결한다.
PR에 자동으로 reviewers를 지정한다.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

  • Github PR Template 내용 추가
  • CODEOWNERS 추가

Out of Scope

SyncDailys 의 Task, TaskHistory, DailyTask 동기화 업로드 기능 개발 (8h)

Prerequisite

Related

Background

  • TiTi 연구소 - Sync Dailys 의 동기화 기능중 Task, TaskHistorys, DailyTask 에 대한 업로드 기능을 개발한다.

AC

Given When Then
업로드할 Task 리스트가 주어질때 새롭게 생성할 Task 리스트로 재구성한다.
새롭게 재구성된 Task 리스트가 주어졌을때 모두 저장한다.
Task 리스트가 모두 저장된 경우 요청으로 주어진 Daily 와 Task 를 매핑시켜줄 DailyTask 를 생성한다.
Task 리스트가 모두 저장된 경우 TaskHistory 를 저장한다.

In scope

Out of Scope

인증 코드 발급 API 개발 (8h)

Prerequisite

Related

Background

사용자 인증을 위한 코드를 생성 및 전송하는 API를 개발한다.

AC

Given When Then
사용자가 이메일 인증 코드 전송 API를 호출하면 이메일이 이메일 형식이고 30자 이내라면 6자리 난수(영소/대문자, 숫자가 포함된)를 생성하여 Redis에 (이메일, IP)와 함께 5분간 저장하고, 사용자에게 전달한다. \
이메일로 인증 코드를 전송했을 때 예외가 발생하면 Redis에 저장한 인증 코드와, 인증 코드 생성 기록을 즉시 삭제한다.
이메일이 이메일 형식이 아니거나, 30자 초과라면 Validation Exception을 발생시킨다.

In scope

  • 인증 코드 Redis 저장/삭제 기능 구현
  • 이메일 인증 코드 전송 기능 구현
  • Redis key-value model 설계

Out of Scope

  • 난수 생성 기능 구현
  • 블랙리스트 기능 구현
  • 인증 코드 생성 이력 DB 저장 기능 구현

README.md 업데이트

Prerequisite

Related

Background

  • 패키지 구조 및 개발 환경을 업데이트해요.
  • Swagger(dev) url을 추가해요.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

  • README.md 업데이트

Out of Scope

일반 회원 가입 API Request Body attribute name 및 Swagger example 수정

🍑 배경

  • wrapped -> ecnrypted 로 네이밍을 변경해요. wrapping은 암복호화 key를 안전하게 전달하기 위해 암호화하는 것을 의미해요. data를 암호화할 때는 encrypt 용어를 사용하도록 통일해요.
  • Swagger에서 encodedEncryptedPassword example 데이터가 local 환경에서 사용하던 key로 암호화되어, 개발 환경에서 테스트할 때 복호화 에러가 발생했어요. 개발환경에서 정상적으로 복호화가 가능하도록 example 데이터를 변경해요.

암/복호화(AES) 기능 개발 (2h)

Prerequisite

Related

Background

개인정보를 암/복호화하기 위한 기능을 개발한다.
암호화 기술은 AES 대칭키 암호화 기술을 사용한다.

대표적인 암호화 기술 비교

AES는 대칭키 암호화 기술 중 가장 보안성이 뛰어난 알고리즘 중 하나입니다. 키의 길이에 따라 128비트, 192비트, 256비트 중 하나를 선택하여 사용할 수 있으며, 블록 암호화 기술을 사용합니다. 블록 크기는 128비트이며, 암호화 블록과 복호화 블록을 같은 방식으로 처리합니다. AES는 대칭키를 사용하기 때문에 암호화와 복호화에 동일한 비밀키를 사용합니다.

DES는 대칭키 암호화 기술 중 가장 오래된 알고리즘 중 하나입니다. 키의 길이는 56비트이며, 블록 암호화 기술을 사용합니다. 블록 크기는 64비트이며, 암호화 블록과 복호화 블록을 같은 방식으로 처리합니다. 하지만, DES는 현재 보안성이 낮아졌기 때문에 사용하지 않는 것이 좋습니다.

RSA는 비대칭키 암호화 기술 중 가장 대표적인 기술 중 하나입니다. 공개키와 비밀키를 사용하며, 공개키는 모두에게 공개되어 있습니다. 키의 길이는 일반적으로 2048비트 이상으로 사용됩니다. RSA는 대칭키 암호화 기술과 달리 복잡한 암호화 기술을 사용하기 때문에, 암호화 및 복호화가 느리다는 단점이 있습니다.

AC

Given When Then
암호화 함수를 호출할 때 평문과 key가 주어지면 암호문을 반환한다.
복호화 함수를 호출할 때 암호문과 key가 주어지면 평문을 반환한다.

In scope

  • 암/복호화(AES) 기능 개발

Out of Scope

Code Style Configuration 변경 (1h)

Prerequisite

Related

Background

원활한 개발을 위해 불필요한 코드 스타일을 제거하고, 잘못 적용된 부분들을 해결한다.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

  • .editorconfig에 indent_size 설정을 추가한다.
  • checkstyle 관련 xml 파일 및 gradle script를 제거한다.
  • formatter import order를 변경한다.
  • .gitattributes 파일명 오타를 정정한다.

Out of Scope

SyncDailys 의 TimeLine 동기화 업로드 기능 개발 (2h)

Prerequisite

Related

Background

  • TiTi 연구소 - Sync Dailys 의 동기화 기능중 TimeLine 에 대한 업로드 기능을 개발한다.

AC

Given When Then
최초 업로드가 시도된 Daily 에 대한 TimeLine 인 경우 새롭게 생성한다.
최초 업로드가 시도된 Daily 에 대한 TimeLine 인 경우 기존 값을 덮어씌운다.

In scope

Out of Scope

SyncDailys 의 Dailys.json 동기화 내려받기 기능 개발 (2h)

Prerequisite

Related

Background

  • TiTi 연구소 - Sync Dailys 의 동기화 기능중 Daily 에 대한 내려받기(다운로드) 기능을 개발한다.

AC

Given When Then
동기화 업로드가 완료되고 내려받기가 시도되면 Daily.json 형식에 알맞게 응답을 생성한다.
내려받기가 시도되면 각 Daily 에 대한 DTO 를 리스트로 생성한다.

In scope

Out of Scope

해시코드 생성 MySQL 함수 생성 (2h)

Prerequisite

Related

Background

중복 닉네임을 구분하기 위한 해시코드를 생성하는 MySQL 함수를 생성한다.

  • Application 단에서 구현하지 않는 이유
    • 생성된 해시코드가 DB에서 중복 일 때마다 여러 번 네트워크를 통하는 latency 최소화 목적

AC

Given When Then
해시코드를 생성하는 함수를 실행하면 존재하지 않는 해시코드인 경우 해시코드를 반환한다.
해시코드를 생성하는 함수를 실행하면 존재하는 해시코드인 경우 해시코드를 다시 생성한다.

In scope

  • 해시코드 생성 MySQL 함수 구현

Out of Scope

공통 응답 모델 추가 (1h)

Background

클라이언트에게 일관성 있는 응답 모델을 제공하기 위함

AC

Given When Then
API 응답 데이터를 전달할 때 공통 응답으로 (HTTP 상태 코드, Business 코드, 메시지)를 반환한다.

In scope

  • 공통 응답 모델(Response) 추가

Out of Scope

  • 예외 처리 핸들러
  • 응답 모델 컨버터

패키지 구조 개선(0.5h)

Prerequisite

Related

Background

  • 하나의 독립적인 서비스 모듈들을 모듈 단위가 아닌, 패키지 단위로 구성하고 있어, 다른 패키지와 구분이 어려워 개선이 필요해요.
└──🔹titi-backend
      ├──📂src/main/java/com/titi
      │     ├── 📂exception
      │     ├── 📂infrastrcture
      │     ├── 📂security
      │     ├── 📂titi_auth
      │     ├── 📂titi_common_lib
      │     ├── 📂titi_crypto_lib
      │     ├── 📂titi_pusher
      │     ├── 📂titi_user
  • titi_ prefix가 붙은 패키지는 MSA 전환 시, 단일 모듈 혹은 라이브러리가 될 예정이에요.
    • 그 외의 패키지는 각 모듈에서 필요 시 가져가서 적절히 변형하여 사용해요.
    • Spring Security를 이용한 인증 처리는 titi-api-gateway 모듈에서 수행할 예정이에요.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

  • 패키지 prefix 적용

Out of Scope

TiTiException Class 및 Exception Handler 구현 (2h)

Background

비즈니스 로직에서 발생하는 예외를 의미하는 클래스(TiTiException)를 생성한다.
비즈니스 예외를 포함한 여러 가지 예외를 한 곳에서 처리하는 글로벌 핸들러를 구현한다.

AC

Given When Then
비즈니스 로직에서 발생하는 예외를 의미하는 최상위 클래스를 생성한다.
비즈니스 로직이 수행될 때 예외가 발생하면 Global Exception Handler가 예외를 처리한다.

In scope

  • TiTiException Class 생성
  • Exception Handler 구현 (아래 예외들에 대한 핸들러를 구현한다.)
    • TiTiException
    • ConstraintViolationException
    • MethodArgumentNotValidException
    • BindException
    • MissingServletRequestParameterException
    • MissingServletRequestPartException
    • MethodArgumentTypeMismatchException
    • HttpMessageNotReadableException
    • HttpRequestMethodNotSupportedException
    • Exception

Out of Scope

  • 위에 기재된 Exception을 제외한 나머지 Exception에 대한 핸들러 구현

JWT 토큰 생성 기능 구현

Prerequisite

Related

Background

JWT 토큰을 생성하는 기능을 구현해요.
RFC-6749 스펙에 맞게 구현해요.

In scope

  • JWT 생성 기능

Out of Scope

일반 로그인 API에 deviceId 발급 로직 및 devices 테이블 추가

🍑 배경

  • 각 사용자마다 기기별 고유 Id(deviceId)를 발급하는 로직을 추가해요.
  • 사용자를 인증할 수 있는 로그인 API에 deviceId를 발급하는 로직을 추가해요.
  • 로그인 API request body의 deviceId를 nullable로 변경하고, null인 경우 deviceId를 발급하도록 구현해요.
    • deviceId가 not null이지만, DB에 등록되어 있지 않은 경우, 새롭게 DB에 등록하는 로직도 구현해요.
  • 로그인 API response body에 deviceId(nullable)을 추가하고, 새로 발급한 경우 deviceId를 response body에 포함시켜요.
  • API 명세서에 포함된 deviceId 설명을 수정해요.
  • 로그인 API에 device별 최근 접속 일시 update 로직을 추가해요.
    • Access Token 재발급 API에도 device별 최근 접속 일시 update 로직을 추가해요. 해당 API의 domain을 user domain으로 변경하여 재설계해요. #76
    • 최근 1년간 로그인하지 않은 deviceId가 존재한다면 제거하는 기능은 다른 issue로 등록하여 개발해요.
  • Usecase 시나리오에 수정된 부분을 반영해요.
  • devices 테이블을 추가하여 사용자별로 device 정보를 관리해요.
CREATE TABLE IF NOT EXISTS devices
(
    uuid                 BINARY(16) NOT NULL,
    member_id            BIGINT NOT NULL COMMENT '회원 PK',
    device_type          VARCHAR(255) COMMENT '기기 유형',
    last_accessed_at     DATETIME(6) NOT NULL COMMENT '최근 접속 일시',
    created_at           DATETIME(6) NOT NULL COMMENT '생성 일시',
    updated_at           DATETIME(6) NOT NULL COMMENT '수정 일시',
    PRIMARY KEY (uuid),
    CONSTRAINT fk_devices_member_id FOREIGN KEY (member_id) REFERENCES members(id)
) COMMENT '기기';

Redis Config Bean 추가 (2h)

Background

Redis와 통신하기 위한 설정 파일을 구현한다.

AC

Given When Then
Redis Server에 연결하고, 통신할 수 있는 RedisTemplate을 반환하는 Bean을 생성한다.

In scope

  • RedisConfig 구현
  • EmbeddedRedisConfig 구현 (for test & local)

Out of Scope

  • Redis key-value model 구성

Gradle Dependency Configuration 변경 (1h)

Prerequisite

Related

Background

각 모듈에서 의존하는 모듈을 implementation으로 명시하여, 각 모듈간 의존관계를 명확하게 파악할 수 있도록 한다.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

Out of Scope

일반 로그인 API & 토큰 재발급 API -> 인증 토큰 발급 API 통합

🍑 배경

  • 일반 로그인 API & 토큰 재발급 API를 OAuth2.0 스펙 분석을 기반으로 인증 토큰 발급 API로 통합해요.
  • 비즈니스 로직에 최근접속일 업데이트 로직을 추가해요.
  • accounts, members 테이블 분리에 대한 내용도 이번 작업에서 함께 진행해요.

RecordTimes 업로드 기능 개발 (2h)

Prerequisite

Related

Background

  • 타이머(스톱워치) 기록 측정시 RecordTimes 업로드 기능을 개발한다.

AC

Given When Then
RecordTimes 기록 측정 정보가 주어지면 과거 스냅샷이 존재하는 경우 최신 버전으로 업데이트한다.
최초 기록 측정인 경우 RecordTimes 를 새롭게 생성한다.

In scope

Out of Scope

Access Token 재발급 API 개발

Background

  • API 명세서를 참고하여 Access Token 재발급 API를 개발해요.
  • 로그인 API에서 Refresh Token을 Redis에 저장하는 로직을 추가해요.
    • 사용자별 + 기기별로 관리해야 해요. 모바일 기기 식별 방안 논의 이후에 해당 내용을 반영하여 개발해요.
    • key는 memberId + deviceId를 hash한 값으로 사용해요.
    • Access Token 및 Refresh Token 생성은 auth 모듈에서 담당해요. user 모듈에서는 auth 모듈의 gateway를 통해 호출해요.
  • members 테이블에 추가된 컬럼(email_certificated)을 반영해요.

properties 파일(yml) 환경별 분리 (1h)

Prerequisite

Related

Background

  • 환경별로 프로퍼티 파일(yml)을 분리해서 관리해요.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

  • properties 파일(yml) 환경별 분리

Out of Scope

Spring Security v6.0.2 적용 (8h)

Prerequisite

Related

Background

사용자 인증 및 인가 처리를 위해 Spring Security v6.0.2을 적용해요.
6.0.x 버전부터 달라지는 점이 많아, 공식문서를 분석하는 시간이 충분히 필요해요.
기능이 잘 동작하는지 검증하기 위해 테스트 코드를 반드시 작성해요.

AC

Given When Then
(조건,상황) (행동) (결과)

In scope

  • JWT 토큰 인증 방식으로 인증 및 인가 기능을 구현해요.

Out of Scope

  • 인증 및 인가 로직에 필요한 기능만 구현해요. 토큰을 생성하고 revoke하는 등의 기능은 다른 이슈에서 구현해요.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.