학적 API
학적정보, 메인 통합조회, 학적사항 탭별 조회, 학사일정, 공지사항, 즐겨찾기
엔드포인트 목록
| 메서드 | 경로 | 인증 | 설명 |
|---|---|---|---|
GET | /api/academic/info/ | 쿠키 | 학적 기본정보 |
GET | /api/main/info/ | 쿠키 | 메인페이지 통합정보 |
GET | /api/academic/status/ | 쿠키 | 학적사항 탭별 조회 |
GET | /api/academic/status/photo/ | 쿠키 | 학생 증명사진 프록시 |
GET | /api/events/academic/ | 불필요 | 학사일정 (공개) |
GET | /api/notices/ | 불필요 | 공지사항 (공개) |
GET | /api/favorites/ | 쿠키 | 즐겨찾기 조회 |
POST | /api/favorites/ | 쿠키 | 즐겨찾기 저장 |
GET /api/academic/info/
SCH 서버에서 학적 기본정보를 실시간 조회합니다. DB에 저장하지 않습니다.
응답
200 OK
{
"nm_eng": "HONG GIL DONG",
"univ_nm": "공과대학",
"sust_nm": "컴퓨터소프트웨어공학과",
"shyr": "4 학년/7 학기이수",
"mj_gb": "전공심화",
"mj_nm": "컴퓨터소프트웨어공학전공",
"sch_regi_div": "재학",
"entn_yy": "2021"
}| 필드 | 타입 | 설명 |
|---|---|---|
nm_eng | string | 영문 성명 (대문자) |
univ_nm | string | 단과대학명 |
sust_nm | string | 학과명 |
shyr | string | 학년 (원문 그대로, 예: "4 학년/7 학기이수") |
mj_gb | string | 전공 구분 (전공심화 / 부복수전공 등) |
mj_nm | string | 전공명 (없으면 빈 문자열) |
sch_regi_div | string | 학적 상태 (재학 / 휴학 / 졸업 등) |
entn_yy | string | 입학연도 (예: "2021") |
shyr 파싱 유틸: 프론트엔드의 parseYear(shyr) 함수를 사용하면 "4학년" 형태로 변환할 수 있습니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 또는 만료 |
SCH_UNAVAILABLE | 503 | SCH 서버에서 학적 정보를 가져오지 못함 |
GET /api/main/info/
메인 대시보드 전용 API. 학적, 시간표, 성적, 졸업진도를 한 번의 요청으로 통합 반환합니다.
- 시간표는 현재 학기(
get_current_semester()) 기준으로 조회하며, 과목코드별 강의실·교수 정보를 별도로 병합합니다. - 일부 항목 조회 실패 시에도 나머지 항목을 포함하여 응답합니다.
응답
200 OK
{
"nm_eng": "HONG GIL DONG",
"univ_nm": "공과대학",
"sust_nm": "컴퓨터소프트웨어공학과",
"shyr": "4 학년/7 학기이수",
"mj_gb": "전공심화",
"mj_nm": "컴퓨터소프트웨어공학전공",
"sch_regi_div": "재학",
"photo_path": "PHTDown::photodownload.cmd?FILE_PATH=...&FILE_NM=...",
"timetable": [
{
"name": "자료구조",
"code": "CS3001",
"day": 0,
"start": "09:00",
"end": "10:30",
"room": "공학관 301",
"professor": "김교수",
"credits": "3"
}
],
"grades": {
"semesters": [
{
"label": "2024-1",
"gpa": 4.0,
"credits": 18
}
],
"totalCredits": 120
},
"graduation": {
"gdtCdt": 140,
"tgdtCdt": 130,
"cgdtCdt": 128,
"libCdt": 36,
"tlibCdt": 36,
"mjrCdt": 60,
"tmjrCdt": 62,
"entnYy": "2021"
}
}timetable 항목 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
name | string | 과목명 |
code | string | 과목코드 |
day | number | 요일 (0=월 1=화 2=수 3=목 4=금) |
start | string | 시작 시간 "HH:MM" |
end | string | 종료 시간 "HH:MM" |
room | string | 강의실 (병합 조회, 실패 시 빈 문자열) |
professor | string | 담당 교수명 (병합 조회) |
credits | string | 학점 |
graduation 필드:
| 필드 | 타입 | 설명 |
|---|---|---|
gdtCdt | number | 졸업 요구 총학점 |
tgdtCdt | number | 수강신청 포함 이수 총학점 |
cgdtCdt | number | 확정 취득 총학점 |
libCdt | number | 교양 요구학점 |
tlibCdt | number | 교양 수강 포함 이수학점 |
mjrCdt | number | 전공 요구학점 |
tmjrCdt | number | 전공 수강 포함 이수학점 |
entnYy | string | 입학연도 |
graduation이 null이면 졸업진도 조회 실패입니다. timetable이 빈 배열이면 시간표 조회 실패 또는 수강 과목 없음입니다.
photo_path 처리:
photo_path가 빈 문자열이 아니라면 프론트엔드의 buildPhotoUrl() 함수로 /api/academic/status/photo/ URL을 생성하세요.
// types.ts의 buildPhotoUrl() 함수
function buildPhotoUrl(photoPath: string): string | null {
if (!photoPath) return null;
const qs = photoPath.includes("?") ? photoPath.split("?")[1] : "";
const p = new URLSearchParams(qs);
const fp = p.get("FILE_PATH");
const fn = p.get("FILE_NM");
if (!fp || !fn) return null;
return `/api/academic/status/photo/?file_path=${encodeURIComponent(fp)}&file_nm=${encodeURIComponent(fn)}`;
}GET /api/academic/status/
학적사항관리(학생용) 탭별 단건 조회. ?tab= 파라미터로 원하는 탭을 지정합니다.
쿼리 파라미터
| 파라미터 | 필수 | 기본값 | 설명 |
|---|---|---|---|
tab | O | header | 조회할 탭 이름 |
tab 허용값 및 반환 타입
tab | 설명 | 주요 반환 필드 |
|---|---|---|
header | 기본 신상 요약 | std_no, nm, univ_nm, sust_nm, shyr, mj_gb, mj_nm, dubl_mj_nm_1, dubl_mj_nm_2, mnr_nm, mic_deg, sch_regi_div, std_div_nm, crclm_div_nm, sex, final_chg_nm, final_chg_dd, photo_path |
basic | 기본 정보 + 차량 + 장애 | basic, vehicle, disability 객체 |
address | 주소 + 보호자 정보 | std_mobile, std_road_addr_1, protecr_nm, prot_mobile 등 |
scholarship | 장학 수혜 이력 | 배열: name, yy, smt_nm, amt |
registration | 등록금 납부 이력 | 배열: div_nm, yy, smt_nm, total_amt, schlsh_amt, real_paid_amt, rtn_yn |
changes | 학적 변동 이력 | 배열: chg_nm, basi_dt, proc_yn, rtn_expt_dd |
major | 전공 신청 이력 | 배열: mj_kd, sust, aply_dt, aprv_dt, aprv_st |
transfer | 편입 이력 | 배열: bef_sust, bef_mj, aft_sust, aft_mj, proc_dt |
teacher | 담임교원 정보 | 배열: mj_div, lic_yn, sprof_yn, sprof_lic_no |
license | 자격증 이력 | 배열: lic_nm, sco, acqst_dt |
tab=header 응답 예시
{
"std_no": "20201234",
"nm": "홍길동",
"univ_nm": "공과대학",
"sust_nm": "컴퓨터소프트웨어공학과",
"shyr": "4 학년/7 학기이수",
"mj_gb": "전공심화",
"mj_nm": "컴퓨터소프트웨어공학전공",
"dubl_mj_nm_1": "",
"dubl_mj_nm_2": "",
"mnr_nm": "",
"mic_deg": "",
"sch_regi_div": "재학",
"std_div_nm": "일반",
"crclm_div_nm": "2021학년도",
"sex": "남",
"final_chg_nm": "재학",
"final_chg_dd": "2024-03-02",
"photo_path": "PHTDown::photodownload.cmd?FILE_PATH=...&FILE_NM=..."
}tab=basic 응답 예시
{
"basic": {
"nm_eng": "HONG GIL DONG",
"nm_ch": "",
"email": "student@sch.ac.kr",
"pfor_nm": "",
"absn_use_cnt": 0,
"absn_posb_cnt": "4",
"rtn_expt_dd": "",
"bank": "신한",
"bank_rel_nm": "본인",
"actng_no": "1100000000000",
"depotr": "홍길동"
},
"vehicle": {
"car_nm_1": "",
"car_no_1": "",
"car_nm_2": "",
"car_no_2": "",
"pinfo_agrmt_yn": "Y"
},
"disability": {
"handi_yn": "N",
"handi_div": "",
"handi_grade": ""
}
}에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
INVALID_TAB | 400 | 허용되지 않은 tab 값 |
SCH_UNAVAILABLE | 503 | SCH 서버 연결 실패 |
GET /api/academic/status/photo/
학생 증명사진을 SCH 서버에서 바이너리로 가져와 그대로 전달하는 프록시 엔드포인트입니다.
쿼리 파라미터
| 파라미터 | 필수 | 설명 |
|---|---|---|
file_path | O | photo_path 파싱 결과의 FILE_PATH 값 (URL 인코딩) |
file_nm | O | photo_path 파싱 결과의 FILE_NM 값 (URL 인코딩) |
응답
이미지 바이너리 데이터. Content-Type은 SCH 서버 응답을 그대로 따릅니다.
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
UNAUTHORIZED | 401 | 세션 없음 |
MISSING_PARAMS | 400 | file_path 또는 file_nm 누락 |
PHOTO_UNAVAILABLE | 503 | 사진 다운로드 실패 |
GET /api/events/academic/
학사일정을 반환합니다. 인증 불필요 (공개 API). DB의 academic_events 테이블에서 조회합니다.
쿼리 파라미터
| 파라미터 | 필수 | 설명 |
|---|---|---|
year | O | 조회 연도 (예: 2025) |
month | O | 조회 월 (1~12) |
GET /api/events/academic/?year=2025&month=3응답
200 OK
[
{
"id": 1,
"start": "2025-03-03",
"end": "2025-03-03",
"content": "2025학년도 1학기 개강",
"cat": "break"
},
{
"id": 2,
"start": "2025-04-14",
"end": "2025-04-18",
"content": "2025학년도 1학기 중간고사",
"cat": "exam"
}
]| 필드 | 타입 | 설명 |
|---|---|---|
id | number | 학사일정 ID |
start | string | 시작일 YYYY-MM-DD |
end | string | 종료일 YYYY-MM-DD |
content | string | 일정 내용 |
cat | string | 카테고리 (아래 표 참고) |
cat 분류 기준:
| 값 | 분류 기준 키워드 |
|---|---|
exam | 고사, 시험, 중간평가, 기말평가 |
enroll | 수강신청, 수강과목, 수강료, 등록금 |
grade | 성적 |
break | 개강, 방학, 계절학기, 학위수여식, 입학식 |
graduation | 졸업, 재입학 |
holiday | 공휴일, 대체휴일, 연휴, 성탄절 등 |
acad | 위에 해당하지 않는 일반 학사 일정 |
에러 응답
| 에러 코드 | HTTP | 설명 |
|---|---|---|
| (문자열 메시지) | 400 | year, month 누락 또는 유효하지 않은 값 |
GET /api/notices/
공지사항을 페이지네이션으로 반환합니다. 인증 불필요 (공개 API). 로컬 DB의 공지사항 테이블을 UNION 조회합니다.
쿼리 파라미터
| 파라미터 | 필수 | 기본값 | 설명 |
|---|---|---|---|
category | 아니오 | all | 공지 카테고리 (아래 표 참고) |
page | 아니오 | 1 | 페이지 번호 (1-based) |
limit | 아니오 | 20 | 페이지당 항목 수 (최대 50) |
preview | 아니오 | false | true이면 limit=8 강제 (홈화면 미리보기용) |
category 허용값:
| 값 | 설명 |
|---|---|
all | 전체 |
academic | 학사공지 |
career | 취업정보 |
university | 대학공지 |
sw | SW사업단 |
src | SRC센터 |
scholarship | 장학공지 |
nanum | 향설교양대학 |
bid | 입찰공고 |
응답
200 OK
{
"items": [
{
"id": "academic_42",
"category": "academic",
"category_name": "학사공지",
"category_key": "acad",
"seq": "2025-001",
"title": "2025학년도 1학기 수강신청 안내",
"author": "교학처",
"post_date": "2025-01-15",
"views": 1523,
"link": "https://..."
}
],
"total": 120,
"page": 1,
"has_next": true
}| 필드 | 타입 | 설명 |
|---|---|---|
items[].id | string | "{category}_{db_id}" 형식 복합 ID |
items[].category | string | 카테고리 슬러그 |
items[].category_name | string | 카테고리 한국어 이름 |
items[].category_key | string | CSS 칩 클래스 키 |
items[].seq | string | 공지 번호 |
items[].title | string | 제목 |
items[].author | string | 작성자 |
items[].post_date | string | 게시일 YYYY-MM-DD |
items[].views | number | 조회수 |
items[].link | string | 원문 링크 URL |
total | number | 전체 항목 수 |
page | number | 현재 페이지 |
has_next | boolean | 다음 페이지 존재 여부 |
GET /api/favorites/
로그인한 학생의 즐겨찾기 메뉴 항목 목록을 반환합니다. DB의 student_favorites 테이블에서 조회합니다.
응답
200 OK
{
"items": [
"개인별 누적 성적 조회",
"외박 신청서",
"내게 맞는 장학 찾기"
]
}items 배열의 각 문자열은 sitemap.ts의 메뉴 항목 이름과 동일합니다.
POST /api/favorites/
즐겨찾기 목록 전체를 덮어씁니다 (upsert).
요청
{
"items": [
"개인별 누적 성적 조회",
"외박 신청서"
]
}응답
200 OK — 저장된 목록 반환
{
"items": [
"개인별 누적 성적 조회",
"외박 신청서"
]
}