Skip to content

ClassRoomManager-Woowa-Tech-Course/back

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

85 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

κ°•μ˜μ‹€ 관리 μ‹œμŠ€ν…œ - Backend

μš°μ•„ν•œν…Œν¬μ½”μŠ€ - μ˜€ν”ˆκ³Όμ œ λ°±μ—”λ“œ API μ„œλ²„

κ°•μ˜μ‹€ μ˜ˆμ•½ 및 관리λ₯Ό μœ„ν•œ RESTful API μ„œλ²„μž…λ‹ˆλ‹€.

πŸ“‹ λͺ©μ°¨

🎯 ν”„λ‘œμ νŠΈ μ†Œκ°œ

Spring Boot 기반의 κ°•μ˜μ‹€ 관리 μ‹œμŠ€ν…œ λ°±μ—”λ“œ API μ„œλ²„μž…λ‹ˆλ‹€. 학생과 κ΅μ§μ›μ˜ κ°•μ˜μ‹€ μ˜ˆμ•½, κ΄€λ¦¬μžμ˜ κ°€μ΄λ“œλΌμΈ 관리 κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€. μΆ”κ°€λ‘œ κ³ μž₯ μ‹ κ³ λ₯Ό κ΄€λ¦¬ν•©λ‹ˆλ‹€.

✨ μ£Όμš” κΈ°λŠ₯

1. μ˜ˆμ•½ 관리

  • κ°•μ˜μ‹€ μ˜ˆμ•½ 등둝
  • μ˜ˆμ•½ 쑰회 (λͺ©λ‘/상세)
  • μ˜ˆμ•½ μˆ˜μ • 및 μ·¨μ†Œ
  • λΉ„λ°€λ²ˆν˜Έ 기반 μ˜ˆμ•½ 보호

2. κ°€μ΄λ“œλΌμΈ 관리

  • κ°•μ˜μ‹€λ³„ μ‚¬μš© κ°€μ΄λ“œλΌμΈ 등둝
  • κ°€μ΄λ“œλΌμΈ 쑰회
  • 파일 첨뢀 (AWS S3 연동)

3. κ°•μ˜μ‹€ 관리

  • κ°•μ˜μ‹€ λͺ©λ‘ 쑰회
  • 초기 κ°•μ˜μ‹€ 데이터 μžλ™ μ„€μ •

4. 인증/인가

  • JWT 기반 κ΄€λ¦¬μž 인증
  • 초기 κ΄€λ¦¬μž 계정 μžλ™ 생성

5. κ³ μž₯ μ‹ κ³ 

  • κ°•μ˜μ‹€ κ³ μž₯ μ‹ κ³ 
  • κ°•μ˜μ‹€ κ³ μž₯ μ‹ κ³  λͺ©λ‘ 쑰회
  • κ³ μž₯ 수리 μ™„λ£Œ 처리

πŸ›  기술 μŠ€νƒ

Backend Framework

  • Spring Boot 3.x - μ• ν”Œλ¦¬μΌ€μ΄μ…˜ ν”„λ ˆμž„μ›Œν¬
  • Spring Data JPA - ORM
  • Spring Security - 인증/인가
  • Spring Web - RESTful API

Database

  • MySQL 8.0 - κ΄€κ³„ν˜• λ°μ΄ν„°λ² μ΄μŠ€
  • Docker Compose - μ»¨ν…Œμ΄λ„ˆ μ˜€μΌ€μŠ€νŠΈλ ˆμ΄μ…˜

Cloud & Storage

  • AWS S3 - 파일 μŠ€ν† λ¦¬μ§€ (이미지/λ¬Έμ„œ)
  • Spring Cloud AWS - AWS SDK 톡합

Security

  • JWT (JSON Web Token) - 토큰 기반 인증
  • BCrypt - λΉ„λ°€λ²ˆν˜Έ μ•”ν˜Έν™”

Build Tool

  • Gradle (μΆ”μ •)

πŸš€ μ‹œμž‘ν•˜κΈ°

ν•„μˆ˜ μš”κ΅¬μ‚¬ν•­

  • Java 17+
  • Docker & Docker Compose
  • AWS 계정 (S3 μ‚¬μš©)

1. μ €μž₯μ†Œ 클둠

git clone [repository-url]
cd classroom-manager-backend

2. Docker둜 MySQL μ‹€ν–‰

docker-compose up -d

3. 둜컬 μ„€μ • 파일 생성

src/main/resources/application-local.yml 파일 생성:

# AWS S3 μ„€μ •
spring:
  cloud:
    aws:
      s3:
        bucket: {bucket 이름}
      credentials:
        access-key: {access key}
        secret-key: {secret-key}

# κ΄€λ¦¬μž 계정
admin:
  super:
    id: super_admin
    password: super_admin

# JWT
jwt:
  secret-key: {secret key}

# Frontend URL
front:
  url: http://localhost:5173

⚠️ λ³΄μ•ˆ μ£Όμ˜μ‚¬ν•­:

  • application-local.yml νŒŒμΌμ€ μ ˆλŒ€ Git에 μ»€λ°‹ν•˜μ§€ λ§ˆμ„Έμš”
  • .gitignore에 μΆ”κ°€λ˜μ–΄ μžˆλŠ”μ§€ ν™•μΈν•˜μ„Έμš”
  • 운영 ν™˜κ²½μ—μ„œλŠ” ν™˜κ²½ λ³€μˆ˜ λ˜λŠ” AWS Secrets Manager μ‚¬μš© ꢌμž₯

4. .gitignore 확인

# λ―Όκ°ν•œ μ„€μ • 파일 (λ°˜λ“œμ‹œ 포함!)
application-local.yml
application-dev.yml
application-prod.yml

# 기타
.env
*.log
target/
build/

5. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰

# Gradle μ‚¬μš© μ‹œ
./gradlew bootRun --args='--spring.profiles.active=local'

# Maven μ‚¬μš© μ‹œ
./mvnw spring-boot:run -Dspring-boot.run.profiles=local

IntelliJ IDEAμ—μ„œ μ‹€ν–‰:

  1. Run β†’ Edit Configurations
  2. Active profiles에 local μž…λ ₯
  3. Apply β†’ OK
  4. μ‹€ν–‰ λ²„νŠΌ 클릭

μ„œλ²„κ°€ http://localhost:8080μ—μ„œ μ‹€ν–‰λ©λ‹ˆλ‹€.

βš™οΈ ν™˜κ²½ μ„€μ •

ν”„λ‘œνŒŒμΌ ꡬ쑰

src/main/resources/
β”œβ”€β”€ application.yml              # 곡톡 μ„€μ • (Git에 컀밋)
β”œβ”€β”€ application-local.yml        # 둜컬 개발 (Git μ œμ™Έ)
β”œβ”€β”€ application-dev.yml          # 개발 μ„œλ²„ (Git μ œμ™Έ)
└── application-prod.yml         # 운영 μ„œλ²„ (Git μ œμ™Έ)

application.yml (곡톡 μ„€μ •)

spring:
  application:
    name: manager
  datasource:
    url: jdbc:mysql://localhost:3306/classroom_db?useSSL=false&allowPublicKeyRetrieval=true
    username: classroom_user
    password: classroom_user
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    open-in-view: false
    hibernate:
      ddl-auto: create  # 운영: validate
    properties:
      hibernate:
        format_sql: true
    show-sql: true
  cloud:
    aws:
      s3:
        bucket: ${AWS_S3_BUCKET:default-bucket}
      region:
        static: "ap-northeast-2"
      credentials:
        access-key: ${AWS_ACCESS_KEY}
        secret-key: ${AWS_SECRET_KEY}

admin:
  super:
    id: ${ADMIN_ID:super_admin}
    password: ${ADMIN_PASSWORD:super_admin}
    name: "전체 κ΄€λ¦¬μž"
    contact: "010-0000-0000"

class:
  code:
    - "5413"
    - "5414"
    - "5527"
    - "5507"
    - "5508"
    - "627-A"
    - "627-B"

jwt:
  access-token-expiration-day: 10
  secret-key: ${JWT_SECRET_KEY}

front:
  url: ${FRONT_URL:http://localhost:5173}

ν”„λ‘œνŒŒμΌλ³„ μ‹€ν–‰

# 둜컬 개발
./gradlew bootRun --args='--spring.profiles.active=local'

# 개발 μ„œλ²„
./gradlew bootRun --args='--spring.profiles.active=dev'

# 운영 μ„œλ²„
java -jar build/libs/app.jar --spring.profiles.active=prod

5. μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹€ν–‰

# Gradle μ‚¬μš© μ‹œ
./gradlew bootRun

# λ˜λŠ” IDEμ—μ„œ 직접 μ‹€ν–‰

μ„œλ²„κ°€ http://localhost:8080μ—μ„œ μ‹€ν–‰λ©λ‹ˆλ‹€.

πŸ“‘ API λ¬Έμ„œ

Base URL

http://localhost:8080/api

μ£Όμš” μ—”λ“œν¬μΈνŠΈ

μ˜ˆμ•½ κ΄€λ ¨ API

# μ˜ˆμ•½ λͺ©λ‘ 쑰회
GET /api/reservations/{roomCode}?yearMonth={yearMonth}

# μ˜ˆμ•½ 상세 쑰회
GET /api/reservations/detail/{reservationId}

# μ˜ˆμ•½ 등둝
POST /api/reservations
Content-Type: application/json

{
  "memberId": "2021001",
  "contact": "010-1234-5678",
  "role": "STUDENT",
  "roomCode": "5413",
  "title": "μŠ€ν„°λ””",
  "purpose": "μ•Œκ³ λ¦¬μ¦˜ μŠ€ν„°λ””",
  "startDate": "2024-01-15T09:00",
  "endDate": "2024-01-15T11:00",
  "password": "1234"
}

# μ˜ˆμ•½ μˆ˜μ •
PUT /api/reservations/{reservationId}
Content-Type: application/json

{
  "memberId": "2021001",
  "contact": "010-1234-5678",
  "role": "STUDENT",
  "roomCode": "5413",
  "title": "μŠ€ν„°λ””",
  "purpose": "μ•Œκ³ λ¦¬μ¦˜ μŠ€ν„°λ””",
  "startDate": "2024-01-15T09:00",
  "endDate": "2024-01-15T11:00",
  "password": "1234"
}

# μ˜ˆμ•½ μ·¨μ†Œ
DELETE /api/reservations/{reservationId}
Content-Type: application/json

{
    "password":"1234"
}

κ°€μ΄λ“œλΌμΈ κ΄€λ ¨ API

# κ°€μ΄λ“œλΌμΈ λͺ©λ‘ 쑰회
GET /api/guidelines

# κ°€μ΄λ“œλΌμΈ 상세 쑰회
GET /api/guidelines/{guideLineId}

# κ°€μ΄λ“œλΌμΈ 등둝 (κ΄€λ¦¬μž)
POST /api/guidelines
Authorization: Bearer {jwt-token}
Content-Type: multipart/form-data

{
  "guideLine": {
    "roomCode": "5413",
    "content": "κ°•μ˜μ‹€ μ‚¬μš© κ°€μ΄λ“œλΌμΈ"
  },
  "files": [파일1, 파일2, ...]
}

κ°•μ˜μ‹€ κ΄€λ ¨ API

# κ°•μ˜μ‹€ λͺ©λ‘ 쑰회
GET /api/classrooms

인증 κ΄€λ ¨ API

# κ΄€λ¦¬μž 둜그인
POST /api/admins/login
Content-Type: application/json

{
  "adminId": "super_admin",
  "password": "super_admin"
}

# 응닡
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
}

βš™οΈ ν™˜κ²½ μ„€μ •

Docker Compose μ„€μ •

docker-compose.yml:

version: '3.8'

services:
  mysql-db:
    image: mysql:8.0
    container_name: classroom-manager-db-container
    restart: always
    environment:
      MYSQL_ROOT_PASSWORD: admin
      MYSQL_DATABASE: "classroom_db"
      MYSQL_USER: "classroom_user"
      MYSQL_PASSWORD: "classroom_user"
    ports:
      - "3306:3306"
    volumes:
      - mysql-data:/var/lib/mysql
    command:
      - --character-set-server=utf8mb4
      - --collation-server=utf8mb4_unicode_ci
      - --default-time-zone=Asia/Seoul

volumes:
  mysql-data:

MySQL 접속 정보

Host: localhost
Port: 3306
Database: classroom_db
Username: classroom_user
Password: classroom_user

초기 데이터

μ• ν”Œλ¦¬μΌ€μ΄μ…˜ μ‹œμž‘ μ‹œ μžλ™μœΌλ‘œ μƒμ„±λ˜λŠ” 데이터:

1. κ΄€λ¦¬μž 계정

ID: super_admin
Password: super_admin
Role: SUPER_ADMIN

2. κ°•μ˜μ‹€ λͺ©λ‘

- 5413
- 5414
- 5527
- 5507
- 5508
- 627-A
- 627-B

πŸ—„οΈ λ°μ΄ν„°λ² μ΄μŠ€ μŠ€ν‚€λ§ˆ

κ°œλ…μ  λͺ¨λΈλ§

erDiagram
    MEMBER {
        string member_id PK
        string contact
        string role
        string name
    }

    ADMIN {
        string admin_id PK
        string name
        string contact
        string role
        string authorization
        string active
        string password
    }

    CLASSROOM {
        bigint room_id PK
        string roomNumber UK
    }

    REPORT {
        bigint report_id PK
        string member_id FK
        bigint room_id FK
        datetime date
        string item
        string contact
        string content
        string status
    }
    
    RESERVATION {
        bigint reservation_id PK
        string member_id FK
        bigint room_id FK
        string purpose
        datetime start_time
        datetime end_time
    }
    
    GUIDELINE {
        bigint guideline_id PK
        bigint room_id FK
        string content
    }
    
    FILE {
        bigint file_id PK
        string file_type
        string file_url
        string original_filename
        bigint related_id
        string related_type "REPORT, GUIDELINE, RESERVATION"
    }
    
    MEMBER ||--o{ REPORT : "report"
    MEMBER ||--o{ RESERVATION : "reserve"
    CLASSROOM ||--o{ RESERVATION : "has"
    CLASSROOM ||--o{ REPORT : "is_related_to"
    ADMIN ||--o{ GUIDELINE :"creates"
    CLASSROOM ||--o{ GUIDELINE : "is_related_to"
    
    REPORT ||..o{ FILE : "has"
    RESERVATION ||..o{ FILE : "has"
    GUIDELINE ||..o{ FILE : "has"
Loading

논리적 λͺ¨λΈλ§

erDiagram
    MEMBER {
        string member_id PK
        string contact
        Role role "STUDENT, STAFF"
        string name
    }

    ADMIN {
        string admin_id PK
        string name
        string contact
        string password
        Role role "STUDENT, STAFF"
        Authorization authorization "SUPER_ADMIN, ADMIN, EDITOR, VIEWER"
        Active active "ACTIVE, INACTIVE"
    }

    CLASSROOM {
        bigint room_id PK
        string room_code UK
    }

    REPORT {
        bigint report_id PK
        string member_id FK
        bigint room_id FK
        datetime date
        Item item "PROJECTOR, PC, SPEAKER, MICROPHONE"
        string contact
        string content
        Status status "PENDING, COMPLETED"
    }
    
    RESERVATION {
        bigint reservation_id PK
        string member_id FK
        bigint room_id FK
        string purpose
        datetime start_time
        datetime end_time
    }
    
    GUIDELINE {
        bigint guideline_id PK
        bigint room_id FK
        string admin_id FK
        string content
    }
    
    FILE {
        bigint file_id PK
        string file_url
        string file_type
        string original_filename
        bigint related_id
        string related_type "REPORT, GUIDELINE, RESERVATION"
    }
    
    MEMBER ||--o{ REPORT : "report"
    MEMBER ||--o{ RESERVATION : "reserve"
    CLASSROOM ||--o{ RESERVATION : "has"
    CLASSROOM ||--o{ REPORT : "is_related_to"
    ADMIN ||--o{ GUIDELINE :"creates"
    CLASSROOM ||--o{ GUIDELINE : "is_related_to"
Loading

πŸ“¦ μ£Όμš” μ˜μ‘΄μ„±

dependencies {
    // Spring Boot
    implementation 'org.springframework.boot:spring-boot-starter-web'
    implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
    implementation 'org.springframework.boot:spring-boot-starter-security'
    implementation 'org.springframework.boot:spring-boot-starter-validation'
    
    // Database
    runtimeOnly 'com.mysql:mysql-connector-j'
    
    // AWS
    implementation 'org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE'
    
    // JWT
    implementation 'io.jsonwebtoken:jjwt-api:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-impl:0.11.5'
    runtimeOnly 'io.jsonwebtoken:jjwt-jackson:0.11.5'
    
    // Test
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

πŸ”§ 개발 팁

MySQL μ»¨ν…Œμ΄λ„ˆ 관리

# μ»¨ν…Œμ΄λ„ˆ μ‹œμž‘
docker-compose up -d

# μ»¨ν…Œμ΄λ„ˆ 쀑지
docker-compose down

# 둜그 확인
docker-compose logs -f mysql-db

# MySQL 접속
docker exec -it classroom-manager-db-container mysql -u classroom_user -p

λ°μ΄ν„°λ² μ΄μŠ€ μ΄ˆκΈ°ν™”

# μ»¨ν…Œμ΄λ„ˆ 및 λ³Όλ₯¨ μ‚­μ œ (데이터 μ™„μ „ μ‚­μ œ)
docker-compose down -v

# μž¬μ‹œμž‘
docker-compose up -d

JWT 토큰 ν…ŒμŠ€νŠΈ

# 둜그인
curl -X POST http://localhost:8080/api/admins/login \
  -H "Content-Type: application/json" \
  -d '{"memberId":"super_admin","password":"super_admin"}'

# μ‘λ‹΅μ—μ„œ 토큰 볡사 ν›„ μ‚¬μš©
curl -X GET http://localhost:8080/api/admins/something \
  -H "Authorization: Bearer {your-token}"

🚨 μ£Όμ˜μ‚¬ν•­

λ³΄μ•ˆ

  • ⚠️ application.yml에 μžˆλŠ” AWS 킀와 JWT secret은 μ ˆλŒ€ Git에 μ»€λ°‹ν•˜μ§€ λ§ˆμ„Έμš”
  • ν™˜κ²½ λ³€μˆ˜ λ˜λŠ” .env 파일 μ‚¬μš© ꢌμž₯
  • .gitignore에 λ‹€μŒ μΆ”κ°€:
    .env
    application-local.yml
    application-prod.yml
    

DDL μ„€μ •

  • 개발: spring.jpa.hibernate.ddl-auto: create
  • 운영: spring.jpa.hibernate.ddl-auto: validate λ˜λŠ” none

CORS μ„€μ •

  • ν”„λ‘ νŠΈμ—”λ“œ URL을 front.url에 μ •ν™•νžˆ μ„€μ •
  • 운영 ν™˜κ²½μ—μ„œλŠ” 도메인 ν™”μ΄νŠΈλ¦¬μŠ€νŠΈ 관리

Woowa-Tech-Course - μ˜€ν”ˆκ³Όμ œ

About

πŸ§‘πŸ»β€πŸ’»κ°•μ˜μ‹€ 관리 μ‹œμŠ€ν…œ

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages