Function bodies 261 total
AttendanceService method · java · L25-L29 (5 LOC)src/main/java/com/yumi/yumiclass/service/AttendanceService.java
public AttendanceService(AttendanceRepository attendanceRepository,
StudentRepository studentRepository) {
this.attendanceRepository = attendanceRepository;
this.studentRepository = studentRepository;
}getClassAttendance method · java · L35-L37 (3 LOC)src/main/java/com/yumi/yumiclass/service/AttendanceService.java
public Map<Student, Attendance> getClassAttendance(Integer grade, Integer classNum, LocalDate date) {
return getClassAttendance(grade, classNum, null, date);
}getClassAttendance method · java · L44-L75 (32 LOC)src/main/java/com/yumi/yumiclass/service/AttendanceService.java
public Map<Student, Attendance> getClassAttendance(Integer grade, Integer classNum,
Long studentId, LocalDate date) {
List<Student> students;
// 특정 학생 1명만 조회 (학년/반 필터는 무시하고 해당 학생만)
if (studentId != null) {
Student s = studentRepository.findById(studentId).orElse(null);
students = (s != null) ? List.of(s) : Collections.emptyList();
} else if (grade != null && classNum != null) {
students = studentRepository.findByGradeAndClassNumOrderByNumberAsc(grade, classNum);
} else if (grade != null) {
students = studentRepository.findByGradeOrderByClassNumAscNumberAsc(grade);
} else {
students = studentRepository.findAll(
org.springframework.data.domain.Sort.by("grade", "classNum", "number"));
}
if (students.isEmpty()) {
return Collections.emptyMap();
}
// 2. 해당 날짜 기존 출결 조회saveBatch method · java · L82-L110 (29 LOC)src/main/java/com/yumi/yumiclass/service/AttendanceService.java
public int saveBatch(LocalDate date, Map<Long, AttendanceStatus> studentStatusMap,
Map<Long, String> studentMemoMap) {
int savedCount = 0;
for (Map.Entry<Long, AttendanceStatus> entry : studentStatusMap.entrySet()) {
Long studentId = entry.getKey();
AttendanceStatus status = entry.getValue();
if (status == null) continue; // 선택 안 한 학생은 스킵
Student student = studentRepository.findById(studentId).orElse(null);
if (student == null) continue;
String memo = studentMemoMap != null ? studentMemoMap.get(studentId) : null;
// 기존 기록 조회
Attendance attendance = attendanceRepository
.findByStudentAndAttendanceDate(student, date)
.orElseGet(() -> {
Attendance a = new Attendance();
a.setStudent(student);
a.setAttendanceDate(date);
return a;
ChatbotService class · java · L22-L279 (258 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public class ChatbotService {
private final GeminiApiService geminiApiService;
private final StudentRepository studentRepository;
private final TeacherRepository teacherRepository;
private final ScoreRepository scoreRepository;
private final AttendanceRepository attendanceRepository;
private final AssignmentRepository assignmentRepository;
private final PapsRepository papsRepository;
private final ChatLogRepository chatLogRepository;
private final StatsService statsService;
public ChatbotService(GeminiApiService geminiApiService,
StudentRepository studentRepository, TeacherRepository teacherRepository,
ScoreRepository scoreRepository, AttendanceRepository attendanceRepository,
AssignmentRepository assignmentRepository, PapsRepository papsRepository,
ChatLogRepository chatLogRepository, StatsService statsService) {
this.geminiApiServicChatbotService method · java · L34-L48 (15 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public ChatbotService(GeminiApiService geminiApiService,
StudentRepository studentRepository, TeacherRepository teacherRepository,
ScoreRepository scoreRepository, AttendanceRepository attendanceRepository,
AssignmentRepository assignmentRepository, PapsRepository papsRepository,
ChatLogRepository chatLogRepository, StatsService statsService) {
this.geminiApiService = geminiApiService;
this.studentRepository = studentRepository;
this.teacherRepository = teacherRepository;
this.scoreRepository = scoreRepository;
this.attendanceRepository = attendanceRepository;
this.assignmentRepository = assignmentRepository;
this.papsRepository = papsRepository;
this.chatLogRepository = chatLogRepository;
this.statsService = statsService;
}ask method · java · L55-L90 (36 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public Long ask(String username, UserRole role, String question, Long sessionId) {
String prompt;
Long userId;
if (role == UserRole.STUDENT) {
Student student = studentRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("학생 없음"));
userId = student.getId();
prompt = buildStudentPrompt(student, question);
} else {
Teacher teacher = teacherRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
userId = teacher.getId();
prompt = buildTeacherPrompt(question);
}
// 세션 ID 결정: 전달받은 값이 없거나 0이면 새로 생성
if (sessionId == null || sessionId == 0L) {
sessionId = System.currentTimeMillis();
}
// Gemini 호출
String answer = geminiApiService.ask(prompt);
// 대화 로그 저장 (세션 ID 포함)
ChatLog log = new ChatLog();
log.seRepobility · open methodology · https://repobility.com/research/
buildStudentPrompt method · java · L95-L157 (63 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
private String buildStudentPrompt(Student student, String question) {
StringBuilder sb = new StringBuilder();
sb.append("당신은 Yumi Class 체육수업 AI 도우미입니다. 학생에게 친근하고 격려하는 말투로 답변하세요.\n");
sb.append("중요: 아래 제공된 데이터에 있는 내용만 답변하고, 다른 학생에 대한 정보는 절대 답하지 마세요.\n");
// 조회 질문은 반드시 답변하되, 수정 요청만 거부
sb.append("기본 원칙: 점수/출결/과제/PAPS 등에 대한 '조회/질문'은 아래 데이터를 활용해 정상적으로 답변하세요.\n");
sb.append("단, 사용자가 '데이터를 바꿔줘/수정해줘/삭제해줘/추가해줘/기록해줘' 같이 DB 변경을 요청할 때만 거부하세요.\n");
sb.append("거부 시: '죄송합니다. 저는 조회만 가능하며 데이터를 수정할 수 없습니다. 수정은 해당 페이지에서 직접 해주세요.'\n");
sb.append("파일 생성 요청('엑셀/PDF로 뽑아줘') 시: '파일 다운로드는 해당 페이지의 다운로드 버튼을 이용해주세요.'\n\n");
sb.append("[학생 본인 정보]\n");
sb.append("- 학년/반/번호: ").append(student.getGrade()).append("학년 ")
.append(student.getClassNum()).append("반 ").append(student.getNumber()).append("번\n");
sb.append("- 이름: ").append(student.getName()).append("\n\n");
// 점수
List<Score> scores = scoreRepbuildTeacherPrompt method · java · L162-L220 (59 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
private String buildTeacherPrompt(String question) {
StringBuilder sb = new StringBuilder();
sb.append("당신은 Yumi Class 체육수업 AI 도우미입니다. 선생님의 질문에 정확하고 간결하게 답변하세요.\n");
// 조회 질문은 반드시 답변하되, 수정 요청만 거부
sb.append("기본 원칙: 학생 점수/출결/과제/PAPS/대회 등에 대한 '조회/분석/통계/질문'은 아래 데이터를 활용해 정상적으로 답변하세요.\n");
sb.append("단, 사용자가 '데이터를 바꿔줘/수정해줘/삭제해줘/추가해줘/기록해줘/저장해줘' 같이 DB 변경을 요청할 때만 거부하세요.\n");
sb.append("거부 시: '죄송합니다. 저는 조회만 가능하며 데이터를 수정할 수 없습니다. 수정은 해당 관리 페이지에서 직접 해주세요.'\n");
sb.append("파일 생성 요청('엑셀/PDF로 뽑아줘/다운로드') 시: '파일 다운로드는 해당 페이지의 엑셀 다운로드 버튼을 이용해주세요.'\n\n");
sb.append("[전체 통계]\n");
sb.append("- 등록 학생 수: ").append(statsService.getTotalStudents()).append("명\n");
sb.append("- 오늘 출결 기록: ").append(statsService.getTodayAttendanceCount()).append("건\n");
sb.append("- 진행 대회: ").append(statsService.getTotalLeagues()).append("건\n");
sb.append("- 등록 과제: ").append(statsService.getTotalAssignments()).append("건\n\n");
getSessionMessages method · java · L226-L230 (5 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public List<ChatLog> getSessionMessages(UserRole role, Long userId, Long sessionId) {
if (sessionId == null || sessionId == 0L) return Collections.emptyList();
return chatLogRepository.findByUserTypeAndUserIdAndSessionIdOrderByCreatedAtAsc(
role, userId, sessionId);
}getSessions method · java · L235-L255 (21 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public List<SessionSummary> getSessions(UserRole role, Long userId) {
List<Long> sessionIds = chatLogRepository.findDistinctSessionIdsByUser(role, userId);
List<SessionSummary> result = new ArrayList<>();
for (Long sid : sessionIds) {
List<ChatLog> first = chatLogRepository.findFirstInSession(role, userId, sid);
if (first.isEmpty()) continue;
ChatLog firstLog = first.get(0);
SessionSummary s = new SessionSummary();
s.sessionId = sid;
// 첫 질문을 제목으로 (30자 이내)
String title = firstLog.getQuestion();
if (title != null && title.length() > 30) {
title = title.substring(0, 30) + "…";
}
s.title = title != null ? title : "(제목 없음)";
s.createdAt = firstLog.getCreatedAt();
s.messageCount = first.size(); // 사실 이건 첫 메시지 목록 개수가 아니라 전체 첫번째만. 세션 총 개수 따로.
result.add(s);
}
return result;
}deleteSession method · java · L261-L263 (3 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public int deleteSession(UserRole role, Long userId, Long sessionId) {
return chatLogRepository.deleteSession(role, userId, sessionId);
}SessionSummary class · java · L268-L278 (11 LOC)src/main/java/com/yumi/yumiclass/service/ChatbotService.java
public static class SessionSummary {
public Long sessionId;
public String title;
public java.time.LocalDateTime createdAt;
public int messageCount;
public Long getSessionId() { return sessionId; }
public String getTitle() { return title; }
public java.time.LocalDateTime getCreatedAt() { return createdAt; }
public int getMessageCount() { return messageCount; }
}CustomUserDetailsService class · java · L21-L57 (37 LOC)src/main/java/com/yumi/yumiclass/service/CustomUserDetailsService.java
public class CustomUserDetailsService implements UserDetailsService {
private final TeacherRepository teacherRepository;
private final StudentRepository studentRepository;
public CustomUserDetailsService(TeacherRepository teacherRepository,
StudentRepository studentRepository) {
this.teacherRepository = teacherRepository;
this.studentRepository = studentRepository;
}
@Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 1. 선생님 계정 먼저 조회
Optional<Teacher> teacher = teacherRepository.findByUsername(username);
if (teacher.isPresent() && Boolean.TRUE.equals(teacher.get().getEnabled())) {
return User.builder()
.username(teacher.get().getUsername())
.password(teacher.get().getPassword())
.roles("TEACHER")
.build();
}
// 2. 학생 계정 조회
CustomUserDetailsService method · java · L26-L30 (5 LOC)src/main/java/com/yumi/yumiclass/service/CustomUserDetailsService.java
public CustomUserDetailsService(TeacherRepository teacherRepository,
StudentRepository studentRepository) {
this.teacherRepository = teacherRepository;
this.studentRepository = studentRepository;
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
loadUserByUsername method · java · L33-L56 (24 LOC)src/main/java/com/yumi/yumiclass/service/CustomUserDetailsService.java
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
// 1. 선생님 계정 먼저 조회
Optional<Teacher> teacher = teacherRepository.findByUsername(username);
if (teacher.isPresent() && Boolean.TRUE.equals(teacher.get().getEnabled())) {
return User.builder()
.username(teacher.get().getUsername())
.password(teacher.get().getPassword())
.roles("TEACHER")
.build();
}
// 2. 학생 계정 조회
Optional<Student> student = studentRepository.findByUsername(username);
if (student.isPresent() && Boolean.TRUE.equals(student.get().getEnabled())) {
return User.builder()
.username(student.get().getUsername())
.password(student.get().getPassword())
.roles("STUDENT")
.build();
}
// 3. 없으면 실패
throw new UsernameNotFoundExceptiExcelService class · java · L21-L107 (87 LOC)src/main/java/com/yumi/yumiclass/service/ExcelService.java
public class ExcelService {
private final StudentRepository studentRepository;
private final ScoreService scoreService;
public ExcelService(StudentRepository studentRepository, ScoreService scoreService) {
this.studentRepository = studentRepository;
this.scoreService = scoreService;
}
/** 특정 반 학생 명단 엑셀 생성 */
public byte[] generateStudentListExcel(Integer grade, Integer classNum) throws IOException {
List<Student> students = studentRepository.findByGradeAndClassNumOrderByNumberAsc(grade, classNum);
try (Workbook workbook = new XSSFWorkbook();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Sheet sheet = workbook.createSheet(grade + "학년 " + classNum + "반");
// 헤더
String[] headers = {"학번", "이름", "학년", "반", "번호", "성별"};
Row headerRow = sheet.createRow(0);
CellStyle headerStyle = createHeaderStyle(workbook);
for (int i = 0; i < headers.leExcelService method · java · L26-L29 (4 LOC)src/main/java/com/yumi/yumiclass/service/ExcelService.java
public ExcelService(StudentRepository studentRepository, ScoreService scoreService) {
this.studentRepository = studentRepository;
this.scoreService = scoreService;
}generateStudentListExcel method · java · L32-L61 (30 LOC)src/main/java/com/yumi/yumiclass/service/ExcelService.java
public byte[] generateStudentListExcel(Integer grade, Integer classNum) throws IOException {
List<Student> students = studentRepository.findByGradeAndClassNumOrderByNumberAsc(grade, classNum);
try (Workbook workbook = new XSSFWorkbook();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Sheet sheet = workbook.createSheet(grade + "학년 " + classNum + "반");
// 헤더
String[] headers = {"학번", "이름", "학년", "반", "번호", "성별"};
Row headerRow = sheet.createRow(0);
CellStyle headerStyle = createHeaderStyle(workbook);
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
}
// 데이터
int rowIdx = 1;
for (Student s : students) {
Row row = sheet.createRow(rowIdx++);
row.createCell(0)generateScoreExcel method · java · L64-L95 (32 LOC)src/main/java/com/yumi/yumiclass/service/ExcelService.java
public byte[] generateScoreExcel(Integer grade, Integer classNum) throws IOException {
List<Score> scores = scoreService.findByClass(grade, classNum);
try (Workbook workbook = new XSSFWorkbook();
ByteArrayOutputStream out = new ByteArrayOutputStream()) {
Sheet sheet = workbook.createSheet(grade + "학년 " + classNum + "반 점수");
// 헤더
String[] headers = {"학번", "이름", "번호", "종목", "연도", "학기", "점수", "등급"};
Row headerRow = sheet.createRow(0);
CellStyle headerStyle = createHeaderStyle(workbook);
for (int i = 0; i < headers.length; i++) {
Cell cell = headerRow.createCell(i);
cell.setCellValue(headers[i]);
cell.setCellStyle(headerStyle);
}
// 데이터
int rowIdx = 1;
for (Score s : scores) {
Row row = sheet.createRow(rowIdx++);
row.createCell(0).setCellValue(s.getStudent().gcreateHeaderStyle method · java · L98-L106 (9 LOC)src/main/java/com/yumi/yumiclass/service/ExcelService.java
private CellStyle createHeaderStyle(Workbook workbook) {
CellStyle style = workbook.createCellStyle();
Font font = workbook.createFont();
font.setBold(true);
style.setFont(font);
style.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex());
style.setFillPattern(FillPatternType.SOLID_FOREGROUND);
return style;
}ask function · java · L40-L78 (39 LOC)src/main/java/com/yumi/yumiclass/service/GeminiApiService.java
public String ask(String prompt) {
// API 키 미설정 체크
if (apiKey == null || apiKey.isBlank() || apiKey.contains("여기에")) {
return "[Gemini API 키가 설정되지 않았습니다. application-secret.properties에서 gemini.api.key 값을 입력해주세요.]";
}
try {
// 요청 본문: Gemini API 형식에 맞춰 구성
Map<String, Object> requestBody = Map.of(
"contents", List.of(Map.of(
"parts", List.of(Map.of("text", prompt))
))
);
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<Map<String, Object>> request = new HttpEntity<>(requestBody, headers);
// API 키는 쿼리 파라미터로 전달
String url = API_URL + "?key=" + apiKey;
Map<String, Object> response = restTemplate.postForObject(url, request, Map.class);
// 응답에서 텍스트 추출 (candidates[0].content.parts[0].text)
if (response != nuLeagueService class · java · L21-L411 (391 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public class LeagueService {
private final LeagueRepository leagueRepository;
private final LeagueTeamRepository teamRepository;
private final LeagueMatchRepository matchRepository;
private final TeacherRepository teacherRepository;
public LeagueService(LeagueRepository leagueRepository, LeagueTeamRepository teamRepository,
LeagueMatchRepository matchRepository, TeacherRepository teacherRepository) {
this.leagueRepository = leagueRepository;
this.teamRepository = teamRepository;
this.matchRepository = matchRepository;
this.teacherRepository = teacherRepository;
}
public List<League> findByTeacher(String username) {
Teacher teacher = teacherRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
return leagueRepository.findByTeacherOrderByCreatedAtDesc(teacher);
}
public League findById(Long id) {
return leagueReposiRepobility — same analyzer, your code, free for public repos · /scan/
LeagueService method · java · L28-L34 (7 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public LeagueService(LeagueRepository leagueRepository, LeagueTeamRepository teamRepository,
LeagueMatchRepository matchRepository, TeacherRepository teacherRepository) {
this.leagueRepository = leagueRepository;
this.teamRepository = teamRepository;
this.matchRepository = matchRepository;
this.teacherRepository = teacherRepository;
}findByTeacher method · java · L36-L40 (5 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public List<League> findByTeacher(String username) {
Teacher teacher = teacherRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
return leagueRepository.findByTeacherOrderByCreatedAtDesc(teacher);
}findById method · java · L42-L45 (4 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public League findById(Long id) {
return leagueRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("대회 없음"));
}getStandings method · java · L48-L50 (3 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public List<LeagueTeam> getStandings(League league) {
return teamRepository.findByLeagueOrderByPointsDescWinsDesc(league);
}getMatches method · java · L53-L55 (3 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public List<LeagueMatch> getMatches(League league) {
return matchRepository.findByLeagueOrderByMatchDateAsc(league);
}createLeague method · java · L58-L63 (6 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public League createLeague(League league, String teacherUsername) {
Teacher teacher = teacherRepository.findByUsername(teacherUsername)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
league.setTeacher(teacher);
return leagueRepository.save(league);
}deleteLeague method · java · L66-L72 (7 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public void deleteLeague(Long id) {
// 경기 → 팀 → 대회 순으로 삭제 (FK 때문에)
League league = findById(id);
matchRepository.deleteAll(matchRepository.findByLeagueOrderByMatchDateAsc(league));
teamRepository.deleteAll(teamRepository.findByLeagueOrderByPointsDescWinsDesc(league));
leagueRepository.delete(league);
}addTeam method · java · L76-L82 (7 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public LeagueTeam addTeam(Long leagueId, String teamName) {
League league = findById(leagueId);
LeagueTeam team = new LeagueTeam();
team.setLeague(league);
team.setTeamName(teamName);
return teamRepository.save(team);
}If a scraper extracted this row, it came from Repobility (https://repobility.com)
removeTeam method · java · L85-L87 (3 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public void removeTeam(Long teamId) {
teamRepository.deleteById(teamId);
}generateMatches method · java · L95-L98 (4 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public int generateMatches(Long leagueId) {
// 기본 호출 (하위 호환): 랜덤 방식
return generateMatches(leagueId, MatchOrder.RANDOM);
}generateMatches method · java · L106-L141 (36 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public int generateMatches(Long leagueId, MatchOrder matchOrder) {
League league = findById(leagueId);
// 등록 순서(ID 오름차순)로 가져오려면 별도 정렬 필요
List<LeagueTeam> teams = teamRepository.findByLeagueOrderByPointsDescWinsDesc(league);
if (teams.size() < 2) {
throw new IllegalArgumentException("팀이 2개 이상 필요합니다");
}
// 기존 경기 삭제 후 재생성
matchRepository.deleteAll(matchRepository.findByLeagueOrderByMatchDateAsc(league));
// 매칭 순서에 따라 팀 배열 준비
List<LeagueTeam> arranged = new java.util.ArrayList<>(teams);
if (matchOrder == MatchOrder.BY_NAME) {
// 등록 순서 = ID 오름차순
arranged.sort(java.util.Comparator.comparing(LeagueTeam::getId));
} else {
java.util.Collections.shuffle(arranged);
}
int count = 0;
if (league.getLeagueType() == LeagueType.LEAGUE) {
// 라운드 로빈 + 연속경기 방지 스케줄링
count = generateLeagueSchedule(league, arranged);
generateLeagueSchedule method · java · L149-L219 (71 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
private int generateLeagueSchedule(League league, List<LeagueTeam> teams) {
List<LeagueTeam> arr = new java.util.ArrayList<>(teams);
// 홀수면 bye(null) 추가
if (arr.size() % 2 != 0) arr.add(null);
int n = arr.size();
int rounds = n - 1;
int matchesPerRound = n / 2;
// 라운드별 경기 쌍 목록
List<List<LeagueTeam[]>> byRound = new java.util.ArrayList<>();
for (int r = 0; r < rounds; r++) {
List<LeagueTeam[]> round = new java.util.ArrayList<>();
for (int i = 0; i < matchesPerRound; i++) {
LeagueTeam home = arr.get(i);
LeagueTeam away = arr.get(n - 1 - i);
// bye(null)는 건너뜀 → 해당 팀은 이 라운드에 경기 없음
if (home != null && away != null) {
round.add(new LeagueTeam[]{home, away});
}
}
byRound.add(round);
// 순환: 0번은 고정, 1..n-1 시계방향 회전
LeagueTeam last = arr.get(n - 1);
sharesTeam method · java · L222-L225 (4 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
private boolean sharesTeam(LeagueTeam[] a, LeagueTeam[] b) {
return a[0].getId().equals(b[0].getId()) || a[0].getId().equals(b[1].getId())
|| a[1].getId().equals(b[0].getId()) || a[1].getId().equals(b[1].getId());
}generateTournamentBracket method · java · L234-L315 (82 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
private int generateTournamentBracket(League league, List<LeagueTeam> arrangedTeams, MatchOrder matchOrder) {
// 내부 Slot 클래스: 현재 라운드의 한 자리
class Slot {
LeagueTeam team; // 팀이 확정된 경우 (R1만 초기에 확정)
LeagueMatch sourceMatch; // 이 자리의 팀 = 이 매치의 승자
int leafStart, leafEnd; // 브라켓 상 리프 범위
boolean fromBye; // 직전 라운드에서 부전으로 올라온 자리인지
}
// R1 초기 슬롯 = 팀 목록 (arrangedTeams 는 matchOrder 에 따라 이미 정렬/셔플됨)
List<Slot> slots = new java.util.ArrayList<>();
for (int i = 0; i < arrangedTeams.size(); i++) {
Slot s = new Slot();
s.team = arrangedTeams.get(i);
s.leafStart = i;
s.leafEnd = i + 1;
slots.add(s);
}
int count = 0;
int round = 1;
while (slots.size() > 1) {
// 매 라운드 시작 시 leafStart 오름차순 정렬 (연속성 유지)
slots.sort((a, b) -> Integer.compare(a.leafStart, b.leafStart));
Slot class · java · L236-L241 (6 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
class Slot {
LeagueTeam team; // 팀이 확정된 경우 (R1만 초기에 확정)
LeagueMatch sourceMatch; // 이 자리의 팀 = 이 매치의 승자
int leafStart, leafEnd; // 브라켓 상 리프 범위
boolean fromBye; // 직전 라운드에서 부전으로 올라온 자리인지
}recordMatchResult method · java · L321-L346 (26 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
public void recordMatchResult(Long matchId, Integer homeScore, Integer awayScore) {
LeagueMatch match = matchRepository.findById(matchId)
.orElseThrow(() -> new IllegalArgumentException("경기 없음"));
// 이전 결과가 있다면 롤백 (순위 재계산)
if (match.getResult() != null) {
rollbackStanding(match);
}
match.setHomeScore(homeScore);
match.setAwayScore(awayScore);
MatchResult result;
if (homeScore > awayScore) result = MatchResult.HOME_WIN;
else if (homeScore < awayScore) result = MatchResult.AWAY_WIN;
else result = MatchResult.DRAW;
match.setResult(result);
// 리그전이면 순위표 업데이트
if (match.getLeague().getLeagueType() == LeagueType.LEAGUE) {
updateStanding(match);
}
// 토너먼트면 승자를 다음 라운드 경기에 자동 채워넣기
else if (match.getLeague().getLeagueType() == LeagueType.TOURNAMENT) {
advanceWinnerToNextRound(match);
}
}Repobility · open methodology · https://repobility.com/research/
advanceWinnerToNextRound method · java · L353-L367 (15 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
private void advanceWinnerToNextRound(LeagueMatch match) {
if (match.getResult() == null) return;
LeagueTeam winner = (match.getResult() == MatchResult.HOME_WIN)
? match.getHomeTeam() : match.getAwayTeam();
if (winner == null) return;
if (match.getNextMatchId() == null) return;
LeagueMatch next = matchRepository.findById(match.getNextMatchId()).orElse(null);
if (next == null) return;
if ("HOME".equals(match.getNextMatchSlot())) {
next.setHomeTeam(winner);
} else {
next.setAwayTeam(winner);
}
matchRepository.save(next);
}updateStanding method · java · L370-L388 (19 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
private void updateStanding(LeagueMatch match) {
LeagueTeam home = match.getHomeTeam();
LeagueTeam away = match.getAwayTeam();
switch (match.getResult()) {
case HOME_WIN -> {
home.setWins(home.getWins() + 1); home.setPoints(home.getPoints() + 3);
away.setLosses(away.getLosses() + 1);
}
case AWAY_WIN -> {
away.setWins(away.getWins() + 1); away.setPoints(away.getPoints() + 3);
home.setLosses(home.getLosses() + 1);
}
case DRAW -> {
home.setDraws(home.getDraws() + 1); home.setPoints(home.getPoints() + 1);
away.setDraws(away.getDraws() + 1); away.setPoints(away.getPoints() + 1);
}
}
teamRepository.save(home); teamRepository.save(away);
}rollbackStanding method · java · L391-L410 (20 LOC)src/main/java/com/yumi/yumiclass/service/LeagueService.java
private void rollbackStanding(LeagueMatch match) {
if (match.getLeague().getLeagueType() != LeagueType.LEAGUE) return;
LeagueTeam home = match.getHomeTeam();
LeagueTeam away = match.getAwayTeam();
switch (match.getResult()) {
case HOME_WIN -> {
home.setWins(home.getWins() - 1); home.setPoints(home.getPoints() - 3);
away.setLosses(away.getLosses() - 1);
}
case AWAY_WIN -> {
away.setWins(away.getWins() - 1); away.setPoints(away.getPoints() - 3);
home.setLosses(home.getLosses() - 1);
}
case DRAW -> {
home.setDraws(home.getDraws() - 1); home.setPoints(home.getPoints() - 1);
away.setDraws(away.getDraws() - 1); away.setPoints(away.getPoints() - 1);
}
}
teamRepository.save(home); teamRepository.save(away);
}LessonProgressService class · java · L17-L64 (48 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public class LessonProgressService {
private final LessonProgressRepository lessonRepository;
private final TeacherRepository teacherRepository;
public LessonProgressService(LessonProgressRepository lessonRepository,
TeacherRepository teacherRepository) {
this.lessonRepository = lessonRepository;
this.teacherRepository = teacherRepository;
}
/** 선생님의 모든 수업 진도 (최근순) */
public List<LessonProgress> findByTeacher(String username) {
Teacher teacher = teacherRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
return lessonRepository.findByTeacherOrderByLessonDateDesc(teacher);
}
public LessonProgress findById(Long id) {
return lessonRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("수업 진도 기록 없음: " + id));
}
@Transactional
public LessonProgress create(LessonProgress lesson, String teaLessonProgressService method · java · L22-L26 (5 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public LessonProgressService(LessonProgressRepository lessonRepository,
TeacherRepository teacherRepository) {
this.lessonRepository = lessonRepository;
this.teacherRepository = teacherRepository;
}findByTeacher method · java · L29-L33 (5 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public List<LessonProgress> findByTeacher(String username) {
Teacher teacher = teacherRepository.findByUsername(username)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
return lessonRepository.findByTeacherOrderByLessonDateDesc(teacher);
}findById method · java · L35-L38 (4 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public LessonProgress findById(Long id) {
return lessonRepository.findById(id)
.orElseThrow(() -> new IllegalArgumentException("수업 진도 기록 없음: " + id));
}create method · java · L41-L46 (6 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public LessonProgress create(LessonProgress lesson, String teacherUsername) {
Teacher teacher = teacherRepository.findByUsername(teacherUsername)
.orElseThrow(() -> new IllegalArgumentException("선생님 없음"));
lesson.setTeacher(teacher);
return lessonRepository.save(lesson);
}Citation: Repobility (2026). State of AI-Generated Code. https://repobility.com/research/
update method · java · L49-L58 (10 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public LessonProgress update(Long id, LessonProgress updated) {
LessonProgress existing = findById(id);
existing.setGrade(updated.getGrade());
existing.setClassNum(updated.getClassNum());
existing.setLessonNumber(updated.getLessonNumber());
existing.setTopic(updated.getTopic());
existing.setLessonDate(updated.getLessonDate());
existing.setMemo(updated.getMemo());
return existing;
}delete method · java · L61-L63 (3 LOC)src/main/java/com/yumi/yumiclass/service/LessonProgressService.java
public void delete(Long id) {
lessonRepository.deleteById(id);
}PapsGradeCalculator class · java · L25-L233 (209 LOC)src/main/java/com/yumi/yumiclass/service/PapsGradeCalculator.java
public class PapsGradeCalculator {
/**
* 세부 종목 + 측정값 + 성별 + 학년(고1/고2/고3) 기반으로 PAPS 등급 자동 산출
*
* @param subItem 세부 종목명 (예: "왕복오래달리기", "앉아윗몸앞으로굽히기")
* @param rawValue 측정값 문자열 (숫자 추출해서 사용)
* @param gender 성별
* @param studentGrade 고등학교 학년 (1, 2, 3). null 이거나 범위 밖이면 고1 기준 적용
* @return 계산된 등급 (5등급 하한 미달 → FAIL, 매칭 종목 없음 → null)
*/
public PapsGrade calculate(String subItem, String rawValue, Gender gender, Integer studentGrade) {
if (subItem == null || rawValue == null || gender == null) return null;
Double value = extractNumber(rawValue);
if (value == null) return null;
// 학년 보정: 1/2/3 범위 밖은 고1로 간주
int g = (studentGrade != null && studentGrade >= 1 && studentGrade <= 3) ? studentGrade : 1;
boolean male = (gender == Gender.MALE);
String item = subItem.trim();
// ==== 심폐지구력: 왕복오래달리기(20m 셔틀런, 회) — 오름차순 ====
if (item.contains("왕복오래달리기") || item.contains("셔틀