1. 공통 응답 형식

이 API는 엔드포인트 성격에 따라 아래 응답 형식을 사용합니다.

1.1. 목록 조회 응답 (페이지네이션)

목록 조회 API는 items, page, pageSize, `total`을 포함한 페이지네이션 구조를 사용합니다.

{
  "items": [
    {
      "...": "리소스 필드"
    }
  ],
  "page": 1,
  "pageSize": 20,
  "total": 120
}

1.2. 단건 조회 응답

단건 조회 API는 해당 리소스 객체를 그대로 반환합니다.

{
  "id": "uuid",
  "...": "리소스 필드"
}

1.3. 파일 다운로드 응답

파일 조회 API(/media/{id})는 JSON이 아닌 바이너리 본문을 반환하며, `Content-Type`은 파일 형식에 따라 달라집니다.

2. 인증(Auth)

2.1. 카카오 로그인

2.1.1. 요청 예시

POST /auth/kakao/login HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 32
Host: localhost:8080

{
  "code" : "kakao-auth-code"
}

2.1.2. 요청 필드

Path Type Description

code

String

카카오 인가 코드

redirectUri

String

인가 요청에 사용한 redirect URI

2.1.3. 응답 필드

경로 타입 설명

accessToken

String

서비스 Access Token

refreshToken

String

서비스 Refresh Token

tokenType

String

토큰 타입(Bearer)

accessTokenExpiresIn

Number

Access Token 만료(초)

refreshTokenExpiresIn

Number

Refresh Token 만료(초)

registrationRequired

Boolean

회원가입 정보 입력 필요 여부

2.1.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 201

{
  "accessToken" : "access-token",
  "refreshToken" : "refresh-token",
  "tokenType" : "Bearer",
  "accessTokenExpiresIn" : 3600,
  "refreshTokenExpiresIn" : 1209600,
  "registrationRequired" : true
}

2.1.5. 응답 본문(JSON)

{
  "accessToken" : "access-token",
  "refreshToken" : "refresh-token",
  "tokenType" : "Bearer",
  "accessTokenExpiresIn" : 3600,
  "refreshTokenExpiresIn" : 1209600,
  "registrationRequired" : true
}

2.2. 토큰 재발급

2.2.1. 요청 예시

POST /auth/refresh HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 38
Host: localhost:8080

{
  "refreshToken" : "refresh-token"
}

2.2.2. 요청 필드

Path Type Description

refreshToken

String

기존 Refresh Token

2.2.3. 응답 필드

경로 타입 설명

accessToken

String

재발급된 Access Token

refreshToken

String

재발급된 Refresh Token

tokenType

String

토큰 타입(Bearer)

accessTokenExpiresIn

Number

Access Token 만료(초)

refreshTokenExpiresIn

Number

Refresh Token 만료(초)

registrationRequired

Boolean

회원가입 정보 입력 필요 여부

2.2.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 210

{
  "accessToken" : "new-access-token",
  "refreshToken" : "new-refresh-token",
  "tokenType" : "Bearer",
  "accessTokenExpiresIn" : 3600,
  "refreshTokenExpiresIn" : 1209600,
  "registrationRequired" : false
}

2.2.5. 응답 본문(JSON)

{
  "accessToken" : "new-access-token",
  "refreshToken" : "new-refresh-token",
  "tokenType" : "Bearer",
  "accessTokenExpiresIn" : 3600,
  "refreshTokenExpiresIn" : 1209600,
  "registrationRequired" : false
}

2.3. 회원가입 정보 등록

2.3.1. 요청 예시

POST /auth/register HTTP/1.1
Content-Type: application/json;charset=UTF-8
Content-Length: 195
Host: localhost:8080

{
  "userType" : "STUDENT",
  "name" : "홍길동",
  "email" : "hong@example.com",
  "department" : "소프트웨어학과",
  "phoneNumber" : "010-1234-5678",
  "studentNumber" : "2020123456"
}

2.3.2. 요청 필드

Path Type Description

userType

String

회원 유형(VISITOR, STUDENT, STAFF, PROFESSOR)

name

String

이름

email

String

이메일

department

String

소속

phoneNumber

String

연락처

studentNumber

String

학번

2.3.3. 응답 예시

HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

3. 전시(Exhibition)

3.1. 전시 목록 조회

3.1.1. 요청 예시

GET /exhibitions?q=cse&slug=sw-gp HTTP/1.1
Host: localhost:8080

3.1.2. 쿼리 파라미터

이름 설명

q

전시회명 검색어

slug

전시회 slug (정확히 일치)

3.1.3. 응답 필드

경로 타입 설명

items

Array

전시회 목록

items[].id

String

전시회 ID

items[].slug

String

전시회 slug

items[].defaultDomain

String

기본 전시 도메인

items[].customDomain

String

커스텀 전시 도메인

items[].name

String

전시회명

items[].description

String

전시회 설명

items[].logoMediaId

Null

로고 미디어 ID

items[].bannerEnabled

Boolean

배너 사용 여부

items[].bannerMediaId

Null

배너 미디어 ID

items[].popupEnabled

Boolean

팝업 사용 여부

items[].popupImageMediaId

Null

팝업 이미지 미디어 ID

items[].popupUrl

Null

팝업 링크 URL

items[].introTitle

Null

인트로 제목

items[].introDescription

Null

인트로 설명

items[].introVideoMediaId

Null

인트로 비디오 미디어 ID

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 건수

3.1.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 595

{
  "items" : [ {
    "id" : "92896530-b91d-4d6f-8d24-755520d092ed",
    "slug" : "sw-gp",
    "defaultDomain" : "exhibition.scg.skku.ac.kr",
    "customDomain" : "custom.exhibition.scg.sh",
    "name" : "소프트웨어융합대학 졸업작품 전시회",
    "description" : "설명",
    "logoMediaId" : null,
    "bannerEnabled" : false,
    "bannerMediaId" : null,
    "popupEnabled" : false,
    "popupImageMediaId" : null,
    "popupUrl" : null,
    "introTitle" : null,
    "introDescription" : null,
    "introVideoMediaId" : null
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

3.1.5. 응답 본문(JSON)

{
  "items" : [ {
    "id" : "92896530-b91d-4d6f-8d24-755520d092ed",
    "slug" : "sw-gp",
    "defaultDomain" : "exhibition.scg.skku.ac.kr",
    "customDomain" : "custom.exhibition.scg.sh",
    "name" : "소프트웨어융합대학 졸업작품 전시회",
    "description" : "설명",
    "logoMediaId" : null,
    "bannerEnabled" : false,
    "bannerMediaId" : null,
    "popupEnabled" : false,
    "popupImageMediaId" : null,
    "popupUrl" : null,
    "introTitle" : null,
    "introDescription" : null,
    "introVideoMediaId" : null
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

3.2. 단일 전시 조회

3.2.1. 경로 파라미터

이름 설명

id

전시회 ID 형식의 더미 값 (실제 조회는 현재 요청 도메인 기준)

3.2.2. 요청 예시

GET /exhibitions/11ba3f4e-d2ed-45db-91ef-232feb4cb8c9 HTTP/1.1
Host: localhost:8080

3.2.3. 응답 필드

경로 타입 설명

id

String

전시회 ID

slug

String

전시회 slug

defaultDomain

String

기본 전시 도메인

customDomain

String

커스텀 전시 도메인

name

String

전시회명

description

String

전시회 설명

logoMediaId

Null

로고 미디어 ID

bannerEnabled

Boolean

배너 사용 여부

bannerMediaId

Null

배너 미디어 ID

popupEnabled

Boolean

팝업 사용 여부

popupImageMediaId

Null

팝업 이미지 미디어 ID

popupUrl

Null

팝업 링크 URL

introTitle

Null

인트로 제목

introDescription

Null

인트로 설명

introVideoMediaId

Null

인트로 비디오 미디어 ID

3.2.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 496

{
  "id" : "11ba3f4e-d2ed-45db-91ef-232feb4cb8c9",
  "slug" : "sw-gp",
  "defaultDomain" : "exhibition.scg.skku.ac.kr",
  "customDomain" : "custom.exhibition.scg.sh",
  "name" : "소프트웨어융합대학 졸업작품 전시회",
  "description" : "설명",
  "logoMediaId" : null,
  "bannerEnabled" : false,
  "bannerMediaId" : null,
  "popupEnabled" : false,
  "popupImageMediaId" : null,
  "popupUrl" : null,
  "introTitle" : null,
  "introDescription" : null,
  "introVideoMediaId" : null
}

3.2.5. 응답 본문(JSON)

{
  "id" : "11ba3f4e-d2ed-45db-91ef-232feb4cb8c9",
  "slug" : "sw-gp",
  "defaultDomain" : "exhibition.scg.skku.ac.kr",
  "customDomain" : "custom.exhibition.scg.sh",
  "name" : "소프트웨어융합대학 졸업작품 전시회",
  "description" : "설명",
  "logoMediaId" : null,
  "bannerEnabled" : false,
  "bannerMediaId" : null,
  "popupEnabled" : false,
  "popupImageMediaId" : null,
  "popupUrl" : null,
  "introTitle" : null,
  "introDescription" : null,
  "introVideoMediaId" : null
}

3.3. 도메인으로 slug 조회

3.3.1. 요청 예시

GET /exhibitions/slug HTTP/1.1
Host: localhost:8080

3.3.2. 응답 필드

경로 타입 설명

slug

String

현재 도메인에 매핑된 전시회 slug

3.3.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 22

{
  "slug" : "sw-gp"
}

3.3.4. 응답 본문(JSON)

{
  "slug" : "sw-gp"
}

4. 관리자(Admin)

전시별 관리자 API는 Authorization 헤더와 함께 X-Exhibition-Id 헤더로 관리 대상 전시 UUID를 전달해야 합니다. 전역 전시 관리 API(/admin/exhibitions/**)는 X-Exhibition-Id 헤더를 사용하지 않습니다.

4.1. 관리 가능한 전시 목록 조회

4.1.1. 요청 헤더

Name Description

Authorization

Bearer access token

4.1.2. 요청 예시

GET /admin/exhibitions HTTP/1.1
Authorization: Bearer access-token
Host: localhost:8080

4.1.3. 응답 필드

경로 타입 설명

items

Array

관리 가능한 전시 목록

items[].id

String

전시 ID

items[].slug

String

전시 slug

items[].defaultDomain

String

기본 도메인

items[].customDomain

Null

커스텀 도메인

items[].name

String

전시 이름

items[].description

String

전시 설명

items[].logoMediaId

Null

로고 미디어 ID

items[].bannerEnabled

Boolean

배너 활성화 여부

items[].bannerMediaId

Null

배너 미디어 ID

items[].popupEnabled

Boolean

팝업 활성화 여부

items[].popupImageMediaId

Null

팝업 이미지 미디어 ID

items[].popupUrl

Null

팝업 이동 URL

items[].introTitle

Null

인트로 제목

items[].introDescription

Null

인트로 설명

items[].introVideoMediaId

Null

인트로 영상 미디어 ID

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 개수

4.1.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 412

{"items":[{"id":"18f04ec7-767e-4652-91fd-49629aa752ca","slug":"graduation-2026","defaultDomain":"graduation.example.com","customDomain":null,"name":"졸업 전시","description":"설명","logoMediaId":null,"bannerEnabled":false,"bannerMediaId":null,"popupEnabled":false,"popupImageMediaId":null,"popupUrl":null,"introTitle":null,"introDescription":null,"introVideoMediaId":null}],"page":1,"pageSize":1,"total":1}

4.2. 전시 생성

4.2.1. 요청 헤더

Name Description

Authorization

Bearer access token

4.2.2. Multipart 파트

Part Description

request

전시 생성 정보 JSON

logoFile

로고 이미지 파일 (nullable: PNG/JPEG/GIF/WebP)

bannerFile

배너 이미지 파일 (nullable: PNG/JPEG/GIF/WebP)

popupImageFile

팝업 이미지 파일 (nullable: PNG/JPEG/GIF/WebP)

introVideoFile

인트로 영상 파일 (nullable: MP4/WebM/MOV)

4.2.3. request JSON 필드

Path Type Description

slug

String

전시 slug (영문 소문자, 숫자, 하이픈)

defaultDomain

String

기본 도메인 호스트

customDomain

Null

커스텀 도메인 호스트 (nullable)

name

String

전시 이름

description

Null

전시 설명 (nullable)

bannerEnabled

Boolean

배너 활성화 여부

popupEnabled

Boolean

팝업 활성화 여부

popupUrl

Null

팝업 이동 URL (nullable)

introTitle

Null

인트로 제목 (nullable, 최대 200자)

introDescription

Null

인트로 설명 (nullable)

4.2.4. 요청 예시

POST /admin/exhibitions HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Authorization: Bearer access-token
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=request
Content-Type: application/json

{
  "slug": "graduation-2026",
  "defaultDomain": "graduation.example.com",
  "customDomain": null,
  "name": "졸업 전시",
  "description": null,
  "bannerEnabled": true,
  "popupEnabled": true,
  "popupUrl": null,
  "introTitle": null,
  "introDescription": null
}

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=logoFile; filename=logo.png
Content-Type: image/png

�PNG


--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--

4.2.5. 응답 필드

경로 타입 설명

id

String

전시 ID

slug

String

전시 slug

defaultDomain

String

기본 도메인 (nullable)

customDomain

Null

커스텀 도메인 (nullable)

name

String

전시 이름

description

String

전시 설명 (nullable)

logoMediaId

Null

로고 미디어 ID (nullable)

bannerEnabled

Boolean

배너 활성화 여부

bannerMediaId

Null

배너 미디어 ID (nullable)

popupEnabled

Boolean

팝업 활성화 여부

popupImageMediaId

Null

팝업 이미지 미디어 ID (nullable)

popupUrl

Null

팝업 이동 URL (nullable)

introTitle

Null

인트로 제목 (nullable)

introDescription

Null

인트로 설명 (nullable)

introVideoMediaId

Null

인트로 영상 미디어 ID (nullable)

4.2.6. 응답 예시

HTTP/1.1 201 Created
Location: /admin/exhibitions/fe11f81b-b72e-4484-b3a8-81e97d222557
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 368

{"id":"fe11f81b-b72e-4484-b3a8-81e97d222557","slug":"graduation-2026","defaultDomain":"graduation.example.com","customDomain":null,"name":"졸업 전시","description":"설명","logoMediaId":null,"bannerEnabled":false,"bannerMediaId":null,"popupEnabled":false,"popupImageMediaId":null,"popupUrl":null,"introTitle":null,"introDescription":null,"introVideoMediaId":null}

4.3. 전시 수정

4.3.1. 요청 헤더

Name Description

Authorization

Bearer access token

4.3.2. 경로 파라미터

이름 설명

exhibitionId

수정할 전시 ID

4.3.3. 요청 필드

Path Type Description

defaultDomain

String

기본 도메인 호스트

customDomain

String

커스텀 도메인 호스트 (nullable)

name

String

전시 이름

description

String

전시 설명 (nullable)

logoMediaId

Null

로고 미디어 ID (nullable)

bannerEnabled

Boolean

배너 활성화 여부

bannerMediaId

Null

배너 미디어 ID (nullable)

popupEnabled

Boolean

팝업 활성화 여부

popupImageMediaId

Null

팝업 이미지 미디어 ID (nullable)

popupUrl

String

팝업 이동 URL (nullable)

introTitle

String

인트로 제목 (nullable, 최대 200자)

introDescription

String

인트로 설명 (nullable)

introVideoMediaId

Null

인트로 영상 미디어 ID (nullable)

4.3.4. 요청 예시

PUT /admin/exhibitions/34ab6a9d-1909-4ee1-8c60-97b6d7df6d03 HTTP/1.1
Content-Type: application/json;charset=UTF-8
Authorization: Bearer access-token
Content-Length: 409
Host: localhost:8080

{
  "defaultDomain": "graduation.example.com",
  "customDomain": "custom.example.com",
  "name": "졸업 전시",
  "description": "설명",
  "logoMediaId": null,
  "bannerEnabled": true,
  "bannerMediaId": null,
  "popupEnabled": true,
  "popupImageMediaId": null,
  "popupUrl": "https://example.com/notice",
  "introTitle": "인트로",
  "introDescription": "전시 소개",
  "introVideoMediaId": null
}

4.3.5. 응답 필드

경로 타입 설명

id

String

전시 ID

slug

String

전시 slug

defaultDomain

String

기본 도메인 (nullable)

customDomain

Null

커스텀 도메인 (nullable)

name

String

전시 이름

description

String

전시 설명 (nullable)

logoMediaId

Null

로고 미디어 ID (nullable)

bannerEnabled

Boolean

배너 활성화 여부

bannerMediaId

Null

배너 미디어 ID (nullable)

popupEnabled

Boolean

팝업 활성화 여부

popupImageMediaId

Null

팝업 이미지 미디어 ID (nullable)

popupUrl

Null

팝업 이동 URL (nullable)

introTitle

Null

인트로 제목 (nullable)

introDescription

Null

인트로 설명 (nullable)

introVideoMediaId

Null

인트로 영상 미디어 ID (nullable)

4.3.6. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 368

{"id":"34ab6a9d-1909-4ee1-8c60-97b6d7df6d03","slug":"graduation-2026","defaultDomain":"graduation.example.com","customDomain":null,"name":"졸업 전시","description":"설명","logoMediaId":null,"bannerEnabled":false,"bannerMediaId":null,"popupEnabled":false,"popupImageMediaId":null,"popupUrl":null,"introTitle":null,"introDescription":null,"introVideoMediaId":null}

4.4. 전시 삭제

4.4.1. 요청 헤더

Name Description

Authorization

Bearer access token

4.4.2. 경로 파라미터

이름 설명

exhibitionId

삭제할 전시 ID

4.4.3. 요청 예시

DELETE /admin/exhibitions/126c48d9-48c2-416c-813b-043571a84767 HTTP/1.1
Authorization: Bearer access-token
Host: localhost:8080

4.4.4. 응답 예시

HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

4.5. 카테고리 수정

4.5.1. 경로 파라미터

이름 설명

id

수정할 카테고리 ID

4.5.2. 요청 필드

Path Type Description

name

String

새 카테고리 이름 (최대 128자)

4.5.3. 요청 예시

PUT /admin/categories/e9feb800-a821-4b55-ae9d-f8b950963552 HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: 50cef27a-e9d6-4b03-b25d-b87951ddf0e4
Content-Length: 21
Host: localhost:8080

{"name":"새 이름"}

4.5.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 137

{"id":"e9feb800-a821-4b55-ae9d-f8b950963552","exhibitionId":"50cef27a-e9d6-4b03-b25d-b87951ddf0e4","slug":"new-name","name":"새 이름"}

4.6. 카테고리 순서 수정

4.6.1. 요청 필드

Path Type Description

categoryIds

Array

노출 순서대로 정렬한 전체 카테고리 ID 목록

4.6.2. 요청 예시

PUT /admin/categories/order HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: 50cef27a-e9d6-4b03-b25d-b87951ddf0e4
Content-Length: 56
Host: localhost:8080

{"categoryIds":["e9feb800-a821-4b55-ae9d-f8b950963552"]}

4.6.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 181

{"items":[{"id":"e9feb800-a821-4b55-ae9d-f8b950963552","exhibitionId":"50cef27a-e9d6-4b03-b25d-b87951ddf0e4","slug":"new-name","name":"새 이름"}],"page":1,"pageSize":1,"total":1}

4.7. 항목 생성

4.7.1. Multipart 파트

Part Description

request

항목 생성 정보 JSON

thumbnailFile

썸네일 이미지 (nullable)

posterFile

포스터 이미지 (nullable)

presentationVideoFile

발표 영상 (nullable)

4.7.2. request JSON 필드

Path Type Description

categoryId

String

카테고리 ID

eventPeriodId

Null

발표회차 ID (미디어 업로드 시 필수)

title

String

항목 제목 (최대 200자)

description

String

항목 설명 (nullable)

participantNames

String

참여자 이름 (nullable)

participantEmails

String

참여자 이메일 (nullable)

advisorNames

String

지도교수 이름 (nullable)

awarded

Boolean

수상 여부

4.7.3. 요청 예시

POST /admin/items HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
X-Exhibition-Id: 1da76647-9683-4971-84ed-4ad98c136f65
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=request
Content-Type: application/json

{"categoryId":"e8a05d8d-e2eb-44e2-80c2-752ab39ba0b8","eventPeriodId":null,"title":"작품","description":"설명","participantNames":"홍길동","participantEmails":"user@example.com","advisorNames":"교수님","awarded":false}
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=thumbnailFile; filename=thumb.jpg
Content-Type: image/jpeg

���
--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--

4.7.4. 응답 예시

HTTP/1.1 201 Created
Location: /admin/items/fb5c6f1d-bbfb-45aa-96a0-b160ff20a20d
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 395

{"id":"fb5c6f1d-bbfb-45aa-96a0-b160ff20a20d","exhibitionId":"1da76647-9683-4971-84ed-4ad98c136f65","categoryId":"e8a05d8d-e2eb-44e2-80c2-752ab39ba0b8","eventPeriodId":null,"title":"작품","description":null,"participantNames":null,"participantEmails":null,"advisorNames":null,"thumbnailMediaId":null,"posterMediaId":null,"presentationVideoMediaId":null,"awarded":false,"likes":0,"isLike":false}

4.8. 항목 수정

4.8.1. 경로 파라미터

이름 설명

id

수정할 항목 ID

4.8.2. 요청 필드

Path Type Description

categoryId

String

카테고리 ID

eventPeriodId

Null

발표회차 ID

title

String

항목 제목 (최대 200자)

description

String

항목 설명

participantNames

String

참여자 이름

participantEmails

String

참여자 이메일

advisorNames

String

지도교수 이름

awarded

Boolean

수상 여부

4.8.3. 요청 예시

PUT /admin/items/fb5c6f1d-bbfb-45aa-96a0-b160ff20a20d HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: 1da76647-9683-4971-84ed-4ad98c136f65
Content-Length: 227
Host: localhost:8080

{"categoryId":"e8a05d8d-e2eb-44e2-80c2-752ab39ba0b8","eventPeriodId":null,"title":"작품","description":"설명","participantNames":"홍길동","participantEmails":"user@example.com","advisorNames":"교수님","awarded":false}

4.8.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 395

{"id":"fb5c6f1d-bbfb-45aa-96a0-b160ff20a20d","exhibitionId":"1da76647-9683-4971-84ed-4ad98c136f65","categoryId":"e8a05d8d-e2eb-44e2-80c2-752ab39ba0b8","eventPeriodId":null,"title":"작품","description":null,"participantNames":null,"participantEmails":null,"advisorNames":null,"thumbnailMediaId":null,"posterMediaId":null,"presentationVideoMediaId":null,"awarded":false,"likes":0,"isLike":false}

4.9. 항목 삭제

4.9.1. 경로 파라미터

이름 설명

id

삭제할 항목 ID

4.9.2. 요청 예시

DELETE /admin/items/fb5c6f1d-bbfb-45aa-96a0-b160ff20a20d HTTP/1.1
X-Exhibition-Id: 1da76647-9683-4971-84ed-4ad98c136f65
Host: localhost:8080

4.9.3. 응답 예시

HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

4.10. 항목 일괄 등록 양식 다운로드

4.10.1. 쿼리 파라미터

이름 설명

eventPeriodId

양식에 포함할 발표회차 ID

4.10.2. 요청 예시

GET /admin/items/bulk/template?eventPeriodId=c195b60e-35c0-4368-983c-8fc58470e920 HTTP/1.1
X-Exhibition-Id: 7e6213e5-171e-4050-ad2c-5ac4d90b346c
Host: localhost:8080

4.10.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
Content-Length: 3
Content-Disposition: attachment; filename="item-bulk-template.xlsx"
Accept-Ranges: bytes
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY



4.11. 항목 일괄 등록

4.11.1. Multipart 파트

Part Description

file

항목 정보가 담긴 Excel 파일

mediaFiles

Excel에서 참조하는 미디어 파일 목록

4.11.2. 요청 예시

POST /admin/items/bulk/upload HTTP/1.1
Content-Type: multipart/form-data;charset=UTF-8; boundary=6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
X-Exhibition-Id: 3ed48131-2185-4d66-a456-2b3c5ee05ce9
Host: localhost:8080

--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=file; filename=items.xlsx
Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet


--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm
Content-Disposition: form-data; name=mediaFiles; filename=thumb.jpg
Content-Type: image/jpeg


--6o2knFse3p53ty9dmcQvWAIx1zInP11uCfbm--

4.11.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 75

{"createdItems":2,"createdMediaAssets":3,"createdClassificationMappings":4}

4.12. 발표회차 생성

4.12.1. 요청 필드

Path Type Description

name

String

발표회차 이름 (최대 50자)

startTime

String

시작 시각 (ISO-8601)

endTime

String

종료 시각 (ISO-8601)

4.12.2. 요청 예시

POST /admin/event-periods HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: 66a57cd0-e639-4b92-ae50-d1e341610e7e
Content-Length: 83
Host: localhost:8080

{"name":"2026","startTime":"2026-01-01T00:00:00Z","endTime":"2026-12-31T00:00:00Z"}

4.12.3. 응답 예시

HTTP/1.1 201 Created
Location: /admin/event-periods/2d52ff17-d65f-4827-b735-2068d44183d3
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 181

{"id":"2d52ff17-d65f-4827-b735-2068d44183d3","exhibitionId":"66a57cd0-e639-4b92-ae50-d1e341610e7e","name":"2026","startTime":"2026-01-01T00:00:00Z","endTime":"2026-12-31T00:00:00Z"}

4.13. 발표회차 수정

4.13.1. 경로 파라미터

이름 설명

id

수정할 발표회차 ID

4.13.2. 요청 필드

Path Type Description

name

String

발표회차 이름 (최대 50자)

startTime

String

시작 시각 (ISO-8601)

endTime

String

종료 시각 (ISO-8601)

4.13.3. 요청 예시

PUT /admin/event-periods/2d52ff17-d65f-4827-b735-2068d44183d3 HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: 66a57cd0-e639-4b92-ae50-d1e341610e7e
Content-Length: 83
Host: localhost:8080

{"name":"2026","startTime":"2026-01-01T00:00:00Z","endTime":"2026-12-31T00:00:00Z"}

4.13.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 181

{"id":"2d52ff17-d65f-4827-b735-2068d44183d3","exhibitionId":"66a57cd0-e639-4b92-ae50-d1e341610e7e","name":"2026","startTime":"2026-01-01T00:00:00Z","endTime":"2026-12-31T00:00:00Z"}

4.14. 발표회차 삭제

4.14.1. 경로 파라미터

이름 설명

id

삭제할 발표회차 ID

4.14.2. 요청 예시

DELETE /admin/event-periods/2d52ff17-d65f-4827-b735-2068d44183d3 HTTP/1.1
X-Exhibition-Id: 66a57cd0-e639-4b92-ae50-d1e341610e7e
Host: localhost:8080

4.14.3. 응답 예시

HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

4.15. 게시글 생성

4.15.1. 요청 필드

Path Type Description

title

String

게시글 제목 (최대 200자)

content

String

게시글 내용 (최대 16000자)

4.15.2. 요청 예시

POST /admin/boards HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: b39bc5f9-e610-49a0-8203-75c761a14d3f
Content-Length: 37
Host: localhost:8080

{"title":"공지","content":"내용"}

4.15.3. 응답 예시

HTTP/1.1 201 Created
Location: /admin/boards/34261d40-138a-449f-becf-899c28441595
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 325

{"id":"34261d40-138a-449f-becf-899c28441595","exhibitionId":"b39bc5f9-e610-49a0-8203-75c761a14d3f","title":"공지","content":"내용","attachmentMediaIds":[],"attachmentMedias":[],"authorUserId":"bec27e3c-f8f9-44d7-a070-eda6ad0efe30","createdAt":"2026-08-24T07:59:37.410568163Z","updatedAt":"2026-08-24T07:59:37.410569405Z"}

4.16. 게시글 수정

4.16.1. 경로 파라미터

이름 설명

id

수정할 게시글 ID

4.16.2. 요청 필드

Path Type Description

title

String

게시글 제목 (최대 200자)

content

String

게시글 내용 (최대 16000자)

4.16.3. 요청 예시

PUT /admin/boards/34261d40-138a-449f-becf-899c28441595 HTTP/1.1
Content-Type: application/json;charset=UTF-8
X-Exhibition-Id: b39bc5f9-e610-49a0-8203-75c761a14d3f
Content-Length: 37
Host: localhost:8080

{"title":"공지","content":"내용"}

4.16.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 325

{"id":"34261d40-138a-449f-becf-899c28441595","exhibitionId":"b39bc5f9-e610-49a0-8203-75c761a14d3f","title":"공지","content":"내용","attachmentMediaIds":[],"attachmentMedias":[],"authorUserId":"bec27e3c-f8f9-44d7-a070-eda6ad0efe30","createdAt":"2026-08-24T07:59:37.410568163Z","updatedAt":"2026-08-24T07:59:37.410569405Z"}

4.17. 게시글 삭제

4.17.1. 경로 파라미터

이름 설명

id

삭제할 게시글 ID

4.17.2. 요청 예시

DELETE /admin/boards/34261d40-138a-449f-becf-899c28441595 HTTP/1.1
X-Exhibition-Id: b39bc5f9-e610-49a0-8203-75c761a14d3f
Host: localhost:8080

4.17.3. 응답 예시

HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

5. 카테고리(Category)

5.1. 카테고리 목록 조회

5.1.1. 요청 예시

GET /categories HTTP/1.1
Host: localhost:8080

5.1.2. 응답 필드

경로 타입 설명

items

Array

카테고리 목록

items[].id

String

카테고리 ID

items[].exhibitionId

String

전시 ID

items[].slug

String

카테고리 슬러그

items[].name

String

카테고리명

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 건수

5.1.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 221

{
  "items" : [ {
    "id" : "2fe2bd7b-ddc3-4017-bdaa-d787cfaa8952",
    "exhibitionId" : "f983c588-3125-459b-9276-d878a6e56405",
    "slug" : "ai",
    "name" : "AI"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

5.1.4. 응답 본문(JSON)

{
  "items" : [ {
    "id" : "2fe2bd7b-ddc3-4017-bdaa-d787cfaa8952",
    "exhibitionId" : "f983c588-3125-459b-9276-d878a6e56405",
    "slug" : "ai",
    "name" : "AI"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

5.2. 단일 카테고리 조회

5.2.1. 요청 예시

GET /categories/cecd2669-0b90-4126-be24-1a6129fc53d4 HTTP/1.1
Host: localhost:8080

5.2.2. 응답 필드

경로 타입 설명

id

String

카테고리 ID

exhibitionId

String

전시 ID

slug

String

카테고리 슬러그

name

String

카테고리명

5.2.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 146

{
  "id" : "cecd2669-0b90-4126-be24-1a6129fc53d4",
  "exhibitionId" : "10d095d1-c67a-4bb9-a1f0-3246f862e86d",
  "slug" : "web",
  "name" : "Web"
}

5.2.4. 응답 본문(JSON)

{
  "id" : "cecd2669-0b90-4126-be24-1a6129fc53d4",
  "exhibitionId" : "10d095d1-c67a-4bb9-a1f0-3246f862e86d",
  "slug" : "web",
  "name" : "Web"
}

6. 항목(Item)

6.1. 항목 목록 조회

6.1.1. 쿼리 파라미터

이름 설명

categoryId

카테고리 ID

categorySlug

카테고리 슬러그

eventPeriodId

이벤트 기간 ID

classificationId

분야(분류) ID

awarded

수상 여부 필터 (true: 수상작만, false: 미수상작만)

q

검색어 (제목, 지도교수, 학생명)

page

페이지 번호(0부터 시작)

size

페이지 크기

sort

정렬 (예: title,asc 또는 createdAt,desc)

6.1.2. 요청 예시

GET /items HTTP/1.1
Host: localhost:8080

6.1.3. 응답 필드

경로 타입 설명

items

Array

아이템 목록

items[].id

String

아이템 ID

items[].exhibitionId

String

전시 ID

items[].categoryId

String

카테고리 ID

items[].eventPeriodId

Null

이벤트 기간 ID

items[].title

String

제목

items[].description

String

설명

items[].participantNames

String

참여자명단: 쉼표로 구분됨

items[].participantEmails

String

발표자 이메일 명단: 쉼표로 구분됨

items[].advisorNames

String

지도교수명단: 쉼표로 구분됨

items[].thumbnailMediaId

Null

썸네일 미디어 ID

items[].posterMediaId

Null

포스터 미디어 ID

items[].presentationVideoMediaId

Null

발표 영상 미디어 ID

items[].awarded

Boolean

수상 여부

items[].likes

Number

좋아요 수

items[].isLike

Boolean

현재 로그인 사용자의 좋아요 여부 (비로그인 시 false)

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 건수

6.1.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 607

{
  "items" : [ {
    "id" : "d4807c1e-492c-480e-9bd4-9b253735e5b3",
    "exhibitionId" : "709bf9c2-520d-4ca6-8f54-1cb71613df09",
    "categoryId" : "cbf2a606-a47f-4368-8f7b-a530db9bfdd6",
    "eventPeriodId" : null,
    "title" : "Smart Campus",
    "description" : "desc",
    "participantNames" : "홍길동",
    "participantEmails" : "hong@example.com",
    "advisorNames" : "김교수",
    "thumbnailMediaId" : null,
    "posterMediaId" : null,
    "presentationVideoMediaId" : null,
    "awarded" : false,
    "likes" : 0,
    "isLike" : false
  } ],
  "page" : 1,
  "pageSize" : 20,
  "total" : 1
}

6.1.5. 응답 본문(JSON)

{
  "items" : [ {
    "id" : "d4807c1e-492c-480e-9bd4-9b253735e5b3",
    "exhibitionId" : "709bf9c2-520d-4ca6-8f54-1cb71613df09",
    "categoryId" : "cbf2a606-a47f-4368-8f7b-a530db9bfdd6",
    "eventPeriodId" : null,
    "title" : "Smart Campus",
    "description" : "desc",
    "participantNames" : "홍길동",
    "participantEmails" : "hong@example.com",
    "advisorNames" : "김교수",
    "thumbnailMediaId" : null,
    "posterMediaId" : null,
    "presentationVideoMediaId" : null,
    "awarded" : false,
    "likes" : 0,
    "isLike" : false
  } ],
  "page" : 1,
  "pageSize" : 20,
  "total" : 1
}

6.2. 단일 항목 조회

6.2.1. 경로 파라미터

이름 설명

id

아이템 ID

6.2.2. 요청 예시

GET /items/7073c540-a615-4721-9f85-cfe7ad87f5f9 HTTP/1.1
Host: localhost:8080

6.2.3. 응답 필드

경로 타입 설명

id

String

아이템 ID

exhibitionId

String

전시 ID

categoryId

String

카테고리 ID

eventPeriodId

String

이벤트 기간 ID

title

String

제목

description

String

설명

participantNames

String

참여자 명단: 쉼표로 구분됨

participantEmails

String

발표자 이메일 명단: 쉼표로 구분됨

advisorNames

String

지도교수 명단: 쉼표로 구분됨

thumbnailMediaId

Null

썸네일 미디어 ID

posterMediaId

Null

포스터 미디어 ID

presentationVideoMediaId

Null

발표 영상 미디어 ID

awarded

Boolean

수상 여부

likes

Number

좋아요 수

isLike

Boolean

현재 로그인 사용자의 좋아요 여부 (비로그인 시 false)

6.2.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 568

{
  "id" : "7073c540-a615-4721-9f85-cfe7ad87f5f9",
  "exhibitionId" : "297e90ad-7476-4069-ad90-b36fcfdd009c",
  "categoryId" : "032eb259-2ddf-41a0-8e0e-40af0c84f029",
  "eventPeriodId" : "e1befc98-7272-4506-a42b-c18ed17c63a2",
  "title" : "Smart Campus",
  "description" : "desc",
  "participantNames" : "홍길동,양현준",
  "participantEmails" : "hong@example.com,yang@example.com",
  "advisorNames" : "김교수",
  "thumbnailMediaId" : null,
  "posterMediaId" : null,
  "presentationVideoMediaId" : null,
  "awarded" : false,
  "likes" : 0,
  "isLike" : false
}

6.2.5. 응답 본문(JSON)

{
  "id" : "7073c540-a615-4721-9f85-cfe7ad87f5f9",
  "exhibitionId" : "297e90ad-7476-4069-ad90-b36fcfdd009c",
  "categoryId" : "032eb259-2ddf-41a0-8e0e-40af0c84f029",
  "eventPeriodId" : "e1befc98-7272-4506-a42b-c18ed17c63a2",
  "title" : "Smart Campus",
  "description" : "desc",
  "participantNames" : "홍길동,양현준",
  "participantEmails" : "hong@example.com,yang@example.com",
  "advisorNames" : "김교수",
  "thumbnailMediaId" : null,
  "posterMediaId" : null,
  "presentationVideoMediaId" : null,
  "awarded" : false,
  "likes" : 0,
  "isLike" : false
}

6.3. 항목 좋아요 추가

6.3.1. 경로 파라미터

이름 설명

id

아이템 ID

6.3.2. 요청 헤더

Name Description

Authorization

Bearer Access Token

6.3.3. 요청 예시

POST /items/d5e95d58-7a1e-4661-bd3c-9e2311fc8b4e/like HTTP/1.1
Authorization: Bearer {accessToken}
Host: localhost:8080
Content-Type: application/x-www-form-urlencoded

6.3.4. 응답 예시

HTTP/1.1 201 Created
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

6.4. 항목 좋아요 취소

6.4.1. 경로 파라미터

이름 설명

id

아이템 ID

6.4.2. 요청 헤더

Name Description

Authorization

Bearer Access Token

6.4.3. 요청 예시

DELETE /items/d489fff3-5ad5-486c-8254-cb84d54645bb/like HTTP/1.1
Authorization: Bearer {accessToken}
Host: localhost:8080

6.4.4. 응답 예시

HTTP/1.1 204 No Content
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY

7. 분류(Classification)

7.1. 분류 목록 조회

7.1.1. 요청 예시

GET /classifications HTTP/1.1
Host: localhost:8080

7.1.2. 응답 필드

경로 타입 설명

items

Array

분류 목록

items[].id

String

분류 ID

items[].exhibitionId

String

전시 ID

items[].name

String

분류명

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 건수

7.1.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 206

{
  "items" : [ {
    "id" : "0e29f425-9966-488b-a4a8-aa02f045c394",
    "exhibitionId" : "670a3dd3-8974-423a-9678-7ff46d15c753",
    "name" : "작품"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

7.1.4. 응답 본문(JSON)

{
  "items" : [ {
    "id" : "0e29f425-9966-488b-a4a8-aa02f045c394",
    "exhibitionId" : "670a3dd3-8974-423a-9678-7ff46d15c753",
    "name" : "작품"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

7.2. 단일 분류 조회

7.2.1. 요청 예시

GET /classifications/ca3920f5-15dc-4cf4-915b-f2254a11c97f HTTP/1.1
Host: localhost:8080

7.2.2. 응답 필드

경로 타입 설명

id

String

분류 ID

exhibitionId

String

전시 ID

name

String

분류명: ex. 논문, 작품 등

7.2.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 131

{
  "id" : "ca3920f5-15dc-4cf4-915b-f2254a11c97f",
  "exhibitionId" : "9352c56f-3923-4c5b-9c01-4f030620349d",
  "name" : "논문"
}

7.2.4. 응답 본문(JSON)

{
  "id" : "ca3920f5-15dc-4cf4-915b-f2254a11c97f",
  "exhibitionId" : "9352c56f-3923-4c5b-9c01-4f030620349d",
  "name" : "논문"
}

8. 이벤트 기간(Event Period)

8.1. 이벤트 기간 목록 조회

8.1.1. 요청 예시

GET /event-periods HTTP/1.1
Host: localhost:8080

8.1.2. 응답 필드

경로 타입 설명

items

Array

이벤트 기간 목록

items[].id

String

이벤트 기간 ID

items[].exhibitionId

String

전시 ID

items[].name

String

이벤트 기간명

items[].startTime

String

시작 시각

items[].endTime

String

종료 시각

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 건수

8.1.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 294

{
  "items" : [ {
    "id" : "7d48808a-d25d-4c9a-92f9-f360830919b3",
    "exhibitionId" : "b11bae2a-6de4-4871-b34f-7753dfa8a9bf",
    "name" : "2025-1학기",
    "startTime" : "2025-03-01T00:00:00Z",
    "endTime" : "2025-06-30T00:00:00Z"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

8.1.4. 응답 본문(JSON)

{
  "items" : [ {
    "id" : "7d48808a-d25d-4c9a-92f9-f360830919b3",
    "exhibitionId" : "b11bae2a-6de4-4871-b34f-7753dfa8a9bf",
    "name" : "2025-1학기",
    "startTime" : "2025-03-01T00:00:00Z",
    "endTime" : "2025-06-30T00:00:00Z"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

8.2. 단일 이벤트 기간 조회

8.2.1. 요청 예시

GET /event-periods/72ea2d5c-12a3-4286-a16c-cfba54f3259e HTTP/1.1
Host: localhost:8080

8.2.2. 응답 필드

경로 타입 설명

id

String

이벤트 기간 ID

exhibitionId

String

전시 ID

name

String

이벤트 기간명

startTime

String

시작 시각

endTime

String

종료 시각

8.2.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 215

{
  "id" : "72ea2d5c-12a3-4286-a16c-cfba54f3259e",
  "exhibitionId" : "184b0ca5-f147-4a20-9283-237bd864d143",
  "name" : "2025-2학기",
  "startTime" : "2025-09-01T00:00:00Z",
  "endTime" : "2025-12-31T00:00:00Z"
}

8.2.4. 응답 본문(JSON)

{
  "id" : "72ea2d5c-12a3-4286-a16c-cfba54f3259e",
  "exhibitionId" : "184b0ca5-f147-4a20-9283-237bd864d143",
  "name" : "2025-2학기",
  "startTime" : "2025-09-01T00:00:00Z",
  "endTime" : "2025-12-31T00:00:00Z"
}

9. 게시판(Board)

9.1. 게시판 목록 조회

9.1.1. 요청 예시

GET /boards HTTP/1.1
Host: localhost:8080

9.1.2. 응답 필드

경로 타입 설명

items

Array

게시판 목록

items[].id

String

게시판 글 ID

items[].exhibitionId

String

전시 ID

items[].title

String

제목

items[].content

String

내용

items[].attachmentMediaIds

Array

첨부 미디어 ID 목록

items[].attachmentMedias

Array

첨부 미디어 목록

items[].attachmentMedias[].id

String

첨부 미디어 ID

items[].attachmentMedias[].fileName

String

첨부 미디어 파일명

items[].authorUserId

String

작성자 사용자 ID

items[].createdAt

String

생성 일시

items[].updatedAt

String

수정 일시

page

Number

페이지 번호

pageSize

Number

페이지 크기

total

Number

전체 건수

9.1.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 604

{
  "items" : [ {
    "id" : "aefdb493-06c4-4fc7-b000-f2dc002399f7",
    "exhibitionId" : "d31b2fc0-991f-4b22-b3b4-7eac5b84f961",
    "title" : "공지",
    "content" : "안내 내용",
    "attachmentMediaIds" : [ "80d28209-df1d-4247-9712-6928cc2c66df" ],
    "attachmentMedias" : [ {
      "id" : "80d28209-df1d-4247-9712-6928cc2c66df",
      "fileName" : "notice-list.pdf"
    } ],
    "authorUserId" : "b8b2380c-7d3f-4a02-ac99-78dea37cb26d",
    "createdAt" : "2026-08-24T07:59:37.978487647Z",
    "updatedAt" : "2026-08-24T07:59:37.978489079Z"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

9.1.4. 응답 본문(JSON)

{
  "items" : [ {
    "id" : "aefdb493-06c4-4fc7-b000-f2dc002399f7",
    "exhibitionId" : "d31b2fc0-991f-4b22-b3b4-7eac5b84f961",
    "title" : "공지",
    "content" : "안내 내용",
    "attachmentMediaIds" : [ "80d28209-df1d-4247-9712-6928cc2c66df" ],
    "attachmentMedias" : [ {
      "id" : "80d28209-df1d-4247-9712-6928cc2c66df",
      "fileName" : "notice-list.pdf"
    } ],
    "authorUserId" : "b8b2380c-7d3f-4a02-ac99-78dea37cb26d",
    "createdAt" : "2026-08-24T07:59:37.978487647Z",
    "updatedAt" : "2026-08-24T07:59:37.978489079Z"
  } ],
  "page" : 1,
  "pageSize" : 1,
  "total" : 1
}

9.2. 단일 게시판 조회

9.2.1. 요청 예시

GET /boards/4c93f203-c38d-4c00-996f-9c261871c966 HTTP/1.1
Host: localhost:8080

9.2.2. 응답 필드

경로 타입 설명

id

String

게시판 글 ID

exhibitionId

String

전시 ID

title

String

제목

content

String

내용

attachmentMediaIds

Array

첨부 미디어 ID 목록

attachmentMedias

Array

첨부 미디어 목록

attachmentMedias[].id

String

첨부 미디어 ID

attachmentMedias[].fileName

String

첨부 미디어 파일명

authorUserId

String

작성자 사용자 ID

createdAt

String

생성 일시

updatedAt

String

수정 일시

9.2.3. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 506

{
  "id" : "4c93f203-c38d-4c00-996f-9c261871c966",
  "exhibitionId" : "acf1337b-1ef7-4bf5-bbb5-2a7710aa92a4",
  "title" : "공지",
  "content" : "안내 내용",
  "attachmentMediaIds" : [ "d591a871-c2d0-4253-a587-5d17e4af8cd0" ],
  "attachmentMedias" : [ {
    "id" : "b90a2e5f-d3cf-470b-be2a-e0e08f380759",
    "fileName" : "notice.pdf"
  } ],
  "authorUserId" : "d755823d-9d45-43c1-ae5b-a7abff339357",
  "createdAt" : "2026-08-24T07:59:37.922636588Z",
  "updatedAt" : "2026-08-24T07:59:37.922637900Z"
}

9.2.4. 응답 본문(JSON)

{
  "id" : "4c93f203-c38d-4c00-996f-9c261871c966",
  "exhibitionId" : "acf1337b-1ef7-4bf5-bbb5-2a7710aa92a4",
  "title" : "공지",
  "content" : "안내 내용",
  "attachmentMediaIds" : [ "d591a871-c2d0-4253-a587-5d17e4af8cd0" ],
  "attachmentMedias" : [ {
    "id" : "b90a2e5f-d3cf-470b-be2a-e0e08f380759",
    "fileName" : "notice.pdf"
  } ],
  "authorUserId" : "d755823d-9d45-43c1-ae5b-a7abff339357",
  "createdAt" : "2026-08-24T07:59:37.922636588Z",
  "updatedAt" : "2026-08-24T07:59:37.922637900Z"
}

10. 미디어(Media)

10.1. 미디어 파일 다운로드

10.1.1. 요청 예시

GET /media/15b8a96c-a025-4325-a718-b2ff38a07ef4 HTTP/1.1
Host: localhost:8080

10.1.2. 응답 항목(헤더)

Name Description

Content-Type

미디어 MIME 타입

Content-Length

파일 바이트 크기

10.1.3. 응답 예시

HTTP/1.1 200 OK
Cache-Control: public, max-age=31536000, immutable
Content-Type: image/jpeg
Content-Length: 3
Accept-Ranges: bytes
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
X-Frame-Options: DENY



10.1.4. 응답 본문(바이너리)



11. 사용자(User)

11.1. 내 정보 조회

11.1.1. 요청 헤더

Name Description

Authorization

Bearer Access Token

11.1.2. 요청 예시

GET /users/me HTTP/1.1
Authorization: Bearer {accessToken}
Host: localhost:8080

11.1.3. 응답 필드

경로 타입 설명

name

String

이름

role

String

사용자 권한

email

String

이메일

department

String

소속

phoneNumber

String

연락처

studentNumber

String

학번

registrationCompleted

Boolean

회원가입 정보 입력 완료 여부

11.1.4. 응답 예시

HTTP/1.1 200 OK
Content-Type: application/json
X-Content-Type-Options: nosniff
X-XSS-Protection: 0
Cache-Control: no-cache, no-store, max-age=0, must-revalidate
Pragma: no-cache
Expires: 0
X-Frame-Options: DENY
Content-Length: 225

{
  "name" : "홍길동",
  "role" : "STUDENT",
  "email" : "hong@example.com",
  "department" : "소프트웨어학과",
  "phoneNumber" : "010-1234-5678",
  "studentNumber" : "2020123456",
  "registrationCompleted" : true
}

11.1.5. 응답 본문(JSON)

{
  "name" : "홍길동",
  "role" : "STUDENT",
  "email" : "hong@example.com",
  "department" : "소프트웨어학과",
  "phoneNumber" : "010-1234-5678",
  "studentNumber" : "2020123456",
  "registrationCompleted" : true
}