Skip to content

About

[14기] 대학생과 공실 소유자를 연결하는 AI 기반 공실 추천/예약 서비스 Space On

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

Space On

대학생과 공실 소유자를 연결하는 AI 기반 공실 추천 · 예약 서비스

LIKELION HGU 14th · Space On Backend

Java 17 Spring Boot 3.5 MySQL AWS Gemini

서비스 바로가기  ·  Frontend Repository


소개

Space On은 비어 있는 공간(공실)과 그 공간이 필요한 대학생을 이어 주는 서비스입니다.

  • 사용자는 원하는 분위기와 용도를 자연어로 입력합니다. 예: "조용하고 깔끔한 스터디 공간" LLM(Gemini)이 이 문장을 미리 정의된 칩(chip) 으로 바꾸고, 칩이 일치하는 공실을 추천합니다.
  • 공실 소유자(호스트) 는 공간 정보와 사진, 대여 가능한 날짜·시간대를 등록하고 예약 현황을 확인합니다.
  • 여러 명이 함께 쓸 공간이라면, 각자의 위치를 입력해 중간 지점 근처의 공실을 찾을 수 있습니다.

핵심 기능

AI 공실 추천
자연어 → 칩 정규화 → 칩 매칭

Gemini가 입력 문장을 26개의 칩 중 해당하는 것으로 바꿉니다. 동의어·오탈자는 보정하고, 부정 표현("빼고", "제외")은 걸러냅니다. 칩이 하나 이상 겹치는 공실만 추천합니다.

위치 기반 탐색
중간 지점 · 반경 3km · 가격 범위

여러 출발지의 위·경도 평균으로 중간 지점을 구합니다. MySQL에서 Haversine 공식으로 반경 3km 안에 있고 예산 범위에 맞는 공실만 조회한 뒤, 거리순으로 정렬합니다.

슬롯 단위 예약
월별 가능 날짜 · 일별 남은 슬롯

호스트가 연 시간 슬롯에서 이미 예약된 슬롯을 빼고 보여 줍니다. 여러 날짜와 슬롯을 한 번에 예약할 수 있습니다.

호스트 등록 · 내역 조회
multipart 업로드 · 전화번호 조회

공실 정보, 옵션, 칩, 사진(S3), 날짜별 대여 시간을 한 번에 등록합니다. 회원가입 없이 전화번호로 예약·등록 내역을 조회합니다.


추천 파이프라인

flowchart LR
    A["요청<br/>출발지 목록 · 프롬프트 · 가격 범위"] --> B["중간 지점 계산<br/>위·경도 평균"]
    B --> C["MySQL 조회<br/>반경 3km · 가격 범위"]
    A -. 프롬프트 .-> D["Gemini<br/>자연어 → 칩 JSON"]
    C --> E["칩 매칭<br/>1개 이상 일치"]
    D --> E
    E --> F["거리순 정렬"]
    F --> G["추천 공실 목록"]
Loading
  • Gemini 응답 스키마는 {"chips":[{"chip":"모던한"}]}입니다. 일치하는 칩이 없으면 {"chips":[]}를 돌려줍니다.
  • Gemini 호출이나 파싱에 실패하면 반경·가격 조건으로 찾은 공실을 그대로 돌려줍니다. AI가 실패해도 결과가 비지 않게 하기 위한 처리입니다.
칩 목록 — 26개 (canonical 표기)
분류 칩
분위기 활기찬 따뜻한 포근한 여유로운 레트로 영감을_주는 모던한 로맨틱 세련된 컬러풀한 깔끔한 심플 감성적인 조용한 럭셔리 유니크 창의적인 빈티지
용도 회의 스터디 촬영 상담 연습 시험 이벤트
공간 넓은

enum 표기는 영감을_주는처럼 언더스코어를 포함한 형태로 통일합니다.


아키텍처

flowchart LR
    U["사용자 / 호스트"] --> FE["Frontend<br/>React · Vite (Vercel)"]
    FE -->|HTTPS| NG["Nginx<br/>Reverse Proxy · Certbot"]
    subgraph EC2["AWS EC2"]
        NG --> BE["Spring Boot 3.5<br/>Java 17"]
    end
    BE --> DB[("MySQL 8")]
    BE --> S3[("AWS S3<br/>공실 사진")]
    BE --> AI["Google Gemini API<br/>gemini-1.5-flash"]
Loading

API

Method Endpoint 설명
POST /main 현재 위치 기준 반경 3km 안의 공실 카드 (가까운 순 최대 3개)
POST /search/middle 여러 출발지의 중간 지점 계산
POST /recommend 출발지 · 자연어 프롬프트 · 가격 범위로 AI 추천
GET /recommend/detail/{roomId} 공실 상세 정보
POST /reservation/{roomId} 예약 페이지용 공실 정보
POST /reservation/available/days/{roomId} 해당 월의 예약 가능 날짜
POST /reservation/available/timeslots/{roomId} 해당 날짜의 남은 시간 슬롯
POST /reservation/done/{roomId} 예약 확정 (여러 날짜 · 슬롯 일괄)
POST /enrollment/done 공실 등록 (multipart/form-data, 사진 → S3)
POST /enrollment/confirmation 호스트 전화번호로 등록 공실의 예약 현황 조회
POST /reservation/confirmation 예약자 전화번호로 예약 내역 조회 (날짜별 병합)
POST /gemini/query 칩 추출 테스트용

도메인 모델

erDiagram
    ROOM ||--|| ADDRESS : "위치"
    ROOM ||--o{ SCHEDULE : "대여 가능 시간"
    ROOM ||--o{ RESERVATION : "예약"

    ROOM {
        Long id
        String enName "호스트 이름"
        String enPhoneNumber "호스트 연락처"
        String account
        int maxPeople
        int price
        String memo
        List optionList
        List chipList
        List photoList "S3 URL"
    }
    ADDRESS {
        Long id
        String roadName
        double latitude
        double longitude
    }
    SCHEDULE {
        Long id
        LocalDate date
        Set slotIndex "대여 가능 슬롯"
    }
    RESERVATION {
        Long id
        String name
        String phoneNumber
        LocalDate date
        Set slotIndex "예약한 슬롯"
    }
Loading

프로젝트 구조

src/main/java/com/likelionhgu/nvidia
├── ai/            # Gemini 클라이언트, 프롬프트, 칩 JSON 매핑
├── config/        # CORS(WebConfig), S3 설정 · 업로드 서비스
├── controller/    # REST 컨트롤러, request/response 객체
├── converter/     # Set<Integer> ↔ DB 컬럼 변환
├── domain/        # Room · Address · Schedule · Reservation · Chip
├── dto/           # 서비스 계층 DTO
├── repository/    # Spring Data JPA (Haversine 반경 쿼리 포함)
└── service/       # 추천 · 예약 · 등록 비즈니스 로직
src/main/resources
└── import.sql     # 개발용 더미 데이터

로컬 실행

요구 사항: JDK 17, MySQL 8, AWS S3 버킷, Gemini API 키

  1. src/main/resources/application.yaml을 만듭니다. 이 파일은 .gitignore에 포함되어 있습니다. 키 값은 환경 변수로 주입하는 것을 권장합니다.

    spring:
      datasource:
        url: jdbc:mysql://localhost:3306/space_on?serverTimezone=Asia/Seoul
        username: ${DB_USERNAME}
        password: ${DB_PASSWORD}
        driver-class-name: com.mysql.cj.jdbc.Driver
      jpa:
        hibernate:
          ddl-auto: create            # import.sql 더미 데이터를 함께 적재
        defer-datasource-initialization: true
      sql:
        init:
          mode: always
    
    cloud:
      aws:
        region:
          static: ap-northeast-2
        credentials:
          accessKey: ${AWS_ACCESS_KEY}
          secretKey: ${AWS_SECRET_KEY}
        s3:
          bucket: ${S3_BUCKET}
    
    gemini:
      api:
        key: ${GEMINI_API_KEY}
  2. 서버를 실행합니다.

    ./gradlew bootRun

팀

JuanHubb
JuanHubb

Backend
sion1212
sion1212

Backend
Gyuho-Han
Gyuho-Han

Frontend
dkrehd0519
dkrehd0519

Frontend

About

[14기] 대학생과 공실 소유자를 연결하는 AI 기반 공실 추천/예약 서비스 Space On

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages