TESOL 학생정보
CLASS-STUDENT-INFORMATION · /my-class/student-information
기능
7
API 호출
0
가드레일
16
id 가 테스트 이름
구현 단계
32 / 32
개발 스펙
이 화면에서 할 수 있어야 하는 것 (2)
- 내 정보 · 수강기간 · 결제 · 합격 · 자격증 발급 여부를 본다.
- 조건이 되면 입학확인증과 스캔본을 받는다.
비즈니스 규칙 (3)
- 입학확인증 행: 결제 + 준비완료라야 보인다.근거: studentInformation.php:87
- 스캔본 행: 위 조건 + 사이버승인 + 합격이라야 보인다.근거: studentInformation.php:98
- 합격일은 pass_date(YYYYMMDDHHmmss) 앞 8자리를 YYYY-MM-DD 로.근거: view_date($d, false)
API (6)
| 메서드 | 경로 | 권한 | 모듈 · 설명 |
|---|---|---|---|
GET | /api/learning/students/me/entrance | 수강생 | 입학확인증 내려받기. 파일 바이트를 그대로 준다. domains:learning:learning-web403 DOCUMENT_NOT_ALLOWED 404 DOCUMENT_NOT_FOUND 404 DOCUMENT_FILE_MISSING |
GET | /api/learning/students/me/scan | 수강생 | 스캔본 내려받기. 합격해야 받을 수 있다. domains:learning:learning-web403 DOCUMENT_NOT_ALLOWED 404 DOCUMENT_NOT_FOUND |
GET | /api/learning/students/me | 수강생 | 학생 정보와 자료 노출 조건. domains:learning:learning-web |
GET | /api/learning/students/me/entrance | 수강생 | 입학확인증 다운로드. domains:learning:learning-web403 NOT_ELIGIBLE |
GET | /api/learning/students/me/certificate-address | 수강생 | 자격증 배송 주소 조회. 합격 + 자격증발급이라야 열린다. domains:learning:learning-web응답: { zip, address1, address2 } 403 CERTIFICATE_NOT_ISSUED |
POST | /api/learning/students/me/certificate-address | 수강생 | 배송 주소 저장. 대상은 언제나 토큰 주인이다. domains:learning:learning-web요청: { zip, address1, address2 } 403 CERTIFICATE_NOT_ISSUED 400 INVALID_ADDRESS |
가드레일 (16) — id 가 곧 테스트 이름이다
| id | 반드시 만족해야 하는 것 | 등급 |
|---|---|---|
profile-change-requires-login | 로그인하지 않으면 이름 · 영문 이름을 바꿀 수 없다. | critical |
profile-english-name-saved | 영문 이름을 바꾸면 저장되고 학생정보에 그대로 보인다. | high |
profile-form-shown | 이름과 영문 이름을 화면에서 고칠 수 있다. 원본은 값 옆에 [저장] 버튼을 두고 ajax 로 바꿨다(studentInformation.php:435~). 옮기는 동안 목업으로 두었던 것을 실제로 붙였다. | high |
profile-form-saves | 고친 값은 다시 열어도 남아 있다. | high |
profile-form-shows-server-message | 거절된 값은 서버가 준 문구를 그대로 보여 준다. | normal |
document-path-stays-in-kind-dir | DB 의 파일 경로가 자료 종류 디렉터리를 벗어나면 읽지 않아야 한다. 루트만 검사하면 "/../scan/..." 으로 합격자 전용 스캔본을 입학확인증인 척 받아 갈 수 있다. 원본 _download_entrance.php 는 DB 값을 그대로 이어 붙였다. | critical |
document-requires-login | 토큰 없이 자료를 받을 수 없어야 한다. | critical |
student-scan-requires-pass | 합격 전에는 스캔본 다운로드가 노출되지도, API 로 받아지지도 않아야 한다. | critical |
student-own-data-only | 항상 로그인한 본인 정보만 나와야 한다. | critical |
certificate-address-requires-issued | 합격 + 자격증발급이 아니면 배송 주소를 조회도 저장도 할 수 없어야 한다. 원본 조건 그대로다(studentInformation.php:199). 화면에서 폼을 감추는 것만으로는 부족하다 — 직접 POST 하면 뚫린다. | critical |
certificate-address-own-only | 요청에 회원을 담아 보내도 남의 주소를 바꿀 수 없어야 한다. 원본은 폼의 아이디를 세션과 대조하고 어긋나면 실패 로그를 남겼다. 우리는 아예 받지 않는다 — 대상이 언제나 토큰의 memberId 라 지목할 방법이 없다. | critical |
certificate-address-per-course | TESOL 과 TEC 주소가 섞이면 안 된다. 원본도 post_update_new.php · post_update_tec_new.php 로 나눴고 테이블에 course_code 가 있다. | high |
certificate-address-validated | 우편번호와 주소가 비었거나 형식이 틀리면 저장하지 않아야 한다. 컬럼이 varchar 라 길이를 넘기면 DB 에서 잘린다. 잘린 주소로는 배송이 안 된다. | high |
certificate-address-hidden-without-issue | 자격이 없으면 화면에 폼이 아예 나오지 않아야 한다. | normal |
certificate-address-form-shape | 주소 입력칸이 폼 안에 있어야 한다. 원본은 <table> 안에 <form> 을 넣었는데 그건 HTML 상 유효하지 않다. 브라우저가 폼을 표 밖으로 끌어내면 input 이 떨어져 나가 서버 액션이 아무것도 못 받는다. | normal |
certificate-address-roundtrip | 저장한 주소가 다시 읽혀야 하고, 두 번째 저장은 새 행이 아니라 갱신이어야 한다. | normal |
구현 계획 (32/32)
- ●ProfileChange — 값 검사. 영문 이름은 영문자만, 30자까지
identity-domain - ●MemberProfileUseCase — 대상은 언제나 토큰의 회원
identity-app - ●PATCH /members/me/name · /members/me/english-name
identity-web - ●StudentInfo 에 englishName 추가
learning-domain - ●StudentDocument · DocumentStorage 포트 정의
learning-domain - ●LearningUseCase.document — 노출 조건 재검사 후 파일 반환
learning-app - ●LocalDocumentStorage — 업로드 루트에서 읽고 경로 조작 차단
learning-infrastructure - ●GET /students/me/entrance · /scan 구현
learning-web - ●앱 라우트 /api/learning/entrance · /scan 연결
wvctesol - ●CurriculumUnit · ScoreReport · StudentInfo · 포트 2개
learning-domain - ●LearningUseCase · CourseCatalog
learning-app - ●Curriculum · Learner 어댑터
learning-infrastructure - ●/api/learning/students/me 구현
learning-web - ●/api/learning/students/me/entrance 구현
learning-web - ●Next.js 를 BFF 로 전환 — Prisma 직접 접근 제거
wvctesol - ●CertificateAddress · CertificateStatus 값 객체와 자격 판정
learning-domain - ●certificateStatus · certificateAddress · saveCertificateAddress 포트
learning-domain - ●유스케이스 — 자격을 다시 보고 저장. 수강권은 보지 않는다
learning-app - ●certificate_post upsert 어댑터 (login_id + course_code 로 한 행)
learning-infrastructure - ●GET/POST /students/me/certificate-address
learning-web - ●학생정보 화면의 주소 폼 — 다음 우편번호 조회 포함
wvctesol - ●StudentDocument · DocumentStorage 포트 정의
learning-domain - ●LearningUseCase.document — 노출 조건 재검사 후 파일 반환
learning-app - ●LocalDocumentStorage — 업로드 루트에서 읽고 경로 조작 차단
learning-infrastructure - ●GET /students/me/entrance · /scan 구현
learning-web - ●앱 라우트 /api/learning/entrance · /scan 연결
wvctesol - ●CurriculumUnit · ScoreReport · StudentInfo · 포트 2개
learning-domain - ●LearningUseCase · CourseCatalog
learning-app - ●Curriculum · Learner 어댑터
learning-infrastructure - ●/api/learning/students/me 구현
learning-web - ●/api/learning/students/me/entrance 구현
learning-web - ●Next.js 를 BFF 로 전환 — Prisma 직접 접근 제거
wvctesol
서버 사이드 구현 계획 — 자바 객체별 요구사항 (8/8)
| 객체 | 모듈 | 책임 · 지켜야 할 것 |
|---|---|---|
● StudentDocumentrecord | learning-domain | 수강생에게 내려 줄 파일 한 건.
|
● DocumentStorageinterface | learning-domain | 파일 저장소 포트.
|
● LocalDocumentStorageclass | learning-infrastructure | 업로드 디렉터리에서 파일을 읽는다.
|
● ScoreReportrecord | learning-domain | 성적표 계산. 원본 resultOfCourse.php:99~143.
|
● CourseCatalogclass | learning-app | 과정별 상수(유닛 수 · 차수 순서 · 시험 유무).
|
● LearningUseCaseservice | learning-app | 커리큘럼 · 성적표 · 학생정보 조회.
|
● CurriculumRepositoryAdapterclass | learning-infrastructure | unit · lesson 조회.
|
● LearnerRepositoryAdapterclass | learning-infrastructure | 수강 자격 · 성적 · 학생정보 조회.
|
테스트 방법 (17)
| 가드레일 | 종류 | 확인 방법 |
|---|---|---|
profile-change-requires-login | e2e | 토큰 없이 PATCH → 401 |
profile-english-name-saved | e2e | 바꾼 뒤 학생정보 조회로 확인 |
profile-form-shown | e2e | 두 입력칸이 보인다 |
profile-form-saves | e2e | 저장 후 새로고침해도 값이 남는다 |
profile-form-shows-server-message | e2e | 한글을 넣으면 "영문자" 문구가 뜬다 |
certificate-address-requires-issued | e2e | 합격하지 않은 계정으로 조회·저장 → 둘 다 403 CERTIFICATE_NOT_ISSUED |
certificate-address-own-only | e2e | 요청 본문에 loginId·memberId 를 실어 보내도 남의 주소가 바뀌지 않는다 |
certificate-address-per-course | e2e | TESOL 을 저장한 뒤 TEC 을 읽어 같은 주소가 아닌지 |
certificate-address-validated | e2e | 빈 값 · 문자 우편번호 · 짧은 우편번호 → 400 |
certificate-address-hidden-without-issue | e2e | 자격 없는 계정의 학생정보 화면에 폼이 0개 |
certificate-address-form-shape | e2e | zip · address1 · address2 가 form 의 자손인지 |
certificate-address-roundtrip | e2e | 저장 → 재조회 일치, 두 번째 저장도 갱신되는지 |
document-path-stays-in-kind-dir | integration | entrance 컬럼을 "/../scan/..." 으로 두고 요청 → 404, 로그에 차단 기록 |
document-requires-login | e2e | 토큰 없이 /students/me/entrance · /scan 호출 → 401 |
student-scan-requires-pass | e2e | pass_yn=N 계정으로 /students/me/scan 호출 → 403 DOCUMENT_NOT_ALLOWED |
student-scan-requires-pass | e2e | pass_yn=N 계정에서 스캔본 행이 없고, 다운로드 API 직접 호출 시 403 |
student-own-data-only | e2e | 토큰의 회원과 다른 회원 정보가 응답에 섞이지 않음 |
스냅샷
로그인 세션으로 촬영한 실제 화면입니다.

기능 목록 (7)
입력
- ·폼
3개 - ·제출 버튼
2개 - ·입력 필드
4개
상태
- ·화면 상태
value, zip, address1
인증
- ·세션 확인
- ·로그인 필요
proxy 가 /login 으로 보냄
하드코딩
- ·하드코딩 데이터
tabs
화면 이동
← 이 화면으로 오는 곳
없음
이 화면에서 가는 곳 →
CLASS/my-classCLASS-TEC-ONLINE/my-class/tec-onlineCLASS-UNIVERSITY-REGISTER/my-class/university-registerAUTH-LOGIN/login
연결
API
직접 호출하는 API 가 없습니다
소스
src/app/my-class/student-information/page.tsx