당직·시험 감독·청소 구역 배정이 눈금으로 정해진다 — 균등 배분 추첨 배포기 완전 정복
🏫 학기 초·학기말의 반복 업무 — 전 교직원 당직 근무, 지필평가 고사실 감독관 배치, 교내 환경정리 구역 배정. 기피 요일과 선호를 체크로 취합하면 균등 배분(fair allocation) 알고리즘이 배치표(roster)를 몇 초 만에 만들고, 파일 하나를 공유 폴더에 올려 전 교직원에게 배포합니다.
핵심은 투명성입니다 — 배분 규칙(누적 횟수 최소 우선, 기피 요일 제외)이 화면에 보이므로 수기 배정의 불공정 시비가 원천 차단됩니다. 서버·Apps Script 배포 없이 단일 HTML 더블클릭 완결이며, 배포본은 번호·닉네임만 다룹니다.
📖 한 줄 정의
심기 모드(데이터 임베딩): API 데이터를 미리 받아 HTML 파일 안 상수로 박아두는 방식(앱 실행 중 외부 통신 0).
학내망 원칙: 학교 배포 웹앱은 개인정보 수집·저장·전송 없음(외부 CDN·API 호출 0, 단일 파일) — 학생은 학내망에서 교사 PC 서버에 접속.
1. 3대 핵심 분석 비교표
| 무엇이 바뀌었나요? / 영역 | 초보자를 위한 쉬운 설명 | 이렇게 한번 써보세요! |
|---|---|---|
| 해결 문제 | 수기 배정의 불공정 시비 → 규칙이 코드로 보이는 균등 배분으로 전환. 당직·감독·청소 3가지 모드를 한 파일에서 전환합니다. | 모드 3종 중 하나로 시작. |
| 취합 | 기피 요일·선호 요일을 체크 입력으로 취합(2분) → 배분 계산은 몇 초. 사유까지 묻지 않습니다(정보의 최소 수집). | 취합 표에서 요일만 체크. |
| 균등 배분 알고리즘 | 누적 횟수 최소 우선 + 기피 요일 제외 + 직전 배정 제외 — 배분 규칙이 화면에 표시되어 투명합니다. | allocate 함수로 배분 원리 이해. |
| 배치표·배포 | 배치표(roster)를 화면에 크게 띄우고 CSV 내보내기로 로컬 저장 — 파일을 공유 폴더에 올려 전교직원 배포(자동 외부 전송 없음). | downloadCSV → 공유 폴더 업로드. |
| 개인정보 설계 | 배포본 화면은 번호·닉네임만 — 실명 배치표 CSV는 교무부가 로컬에서 관리합니다. 학내망 안에서 완결됩니다. | EMBED 명단 상수 심기(외부 통신 0). |
2. 핵심 아키텍처 해설
① 데이터: 명단과 요일 조건
const STAFF = [
{ no: 1, nick: "미리내", avoid: ["월"], pref: ["금"] },
{ no: 2, nick: "샛별", avoid: [], pref: ["화"] }
];
avoid는 기피 요일, pref는 선호 요일입니다. 사유는 저장하지 않습니다 — '월요일이 힘들다'는 사정까지 코드가 알 필요는 없습니다(정보의 최소 수집).
② 균등 배분: allocate
function allocate(pool, slots, history) {
const sorted = shuffle(pool).sort(function (a, b) {
return count(history, a.no) - count(history, b.no);
});
const roster = [];
for (const s of slots) {
const pick = sorted.find(function (p) {
return !used(p) && s.avoid.indexOf(p.avoid) === -1;
});
if (pick) roster.push({ slot: s, who: pick });
}
return roster;
}
누적 횟수가 가장 적은 사람부터 슬롯을 채웁니다. 기피 요일이 겹치면 다음 후보로 넘어가고, 선호 요일이면 후보 순서에서 앞당겨집니다 — 배분 규칙이 화면에 그대로 표시됩니다.
③ 배치표(roster) 렌더
roster.forEach(function (r) {
addRow(r.slot.day + " " + r.slot.task + " → " + r.who.no + " " + r.who.nick);
});
배치표는 회의 화면에 큰 글씨로 표기 — 모두가 같은 표를 보는 순간, 배정은 결론이 아니라 확인 절차가 됩니다.
④ CSV 기록과 배포
function rosterCSV(roster) {
return roster.map(function (r) {
return r.slot.day + "," + r.slot.task + "," + r.who.no + "," + r.who.nick;
}).join("\n");
}
// CSV 내보내기로 로컬 파일 저장 — 자동 외부 전송 없음
배치표 CSV를 로컬 파일로 내보내면, 교무부는 그 파일을 학내망 공유 폴더에 올려 전 교직원에게 배포합니다(외부 클라우드·Apps Script 배포 없음). 실명이 필요한 공문용 배치표는 교무부가 로컬에서 관리합니다.
⑤ 운영 체크리스트
- 배분 규칙(누적 최소 우선·기피 제외·직전 배정 제외)을 화면 하단에 상시 표시 — 투명성이 최고의 안전장치입니다.
- '다시 배분'은 회의 안건으로 — 배분의 재현은 규칙 논의의 시작점입니다.
- 신규 교원·신설 업무가 생기면 파일 상단 상수를 갱신(심기 루틴)합니다.
3. 따라하기 3단계
- 제미나이 전용 에러 제로 프롬프트를 복사해 Gemini에 붙여넣습니다.
- AI가 던지는 역질문 3가지(배분 대상, 요일 구조, CSV 서식)에 답하면 단일 HTML 코드가 완성됩니다.
- 코드를
배분배포기.html로 저장 후 더블클릭 — 취합 2분 → 배분 몇 초 → CSV 저장 → 공유 폴더 배포로 마무리됩니다.
제미나이 전용 에러 제로 프롬프트
[🚨 에러 방지 기본 안전장치]
1. 결과물은 외부 라이브러리·폰트·이미지 없이 단일 HTML 파일로 완성한다 — 더블클릭 즉시 실행(서버·설치·회원가입·구글 시트 API·Apps Script 금지).
2. 배포본 화면은 번호·닉네임만 다룬다(실명 저장 금지) — 기피 정보는 '기피 요일'만 취합(사유·건강 정보 저장 금지 — 정보의 최소 수집).
3. 균등 배분: 누적 횟수 최소 우선, 기피 요일 제외, 직전 배정 제외 — 배분 규칙을 화면에 표시해 투명하게.
4. 당직·시험 감독·청소 구역 3가지 모드를 한 파일에서 전환한다.
5. 배치표(roster)는 CSV 내보내기로 로컬 파일 저장 — 자동 외부 전송 없음(시트·공유는 교무부 수동).
6. 회의 화면 대응: 배치표 큰 글씨, 버튼 88px 이상. 배정 확정 사운드는 Web Audio 합성('똑').
7. 명단·요일 조건은 파일 상단 상수로 심기(학내망 배포용 외부 통신 0).
8. // TODO, /* 생략 */ 금지 — 끝까지 완성한다.
[❓ 역질문 유도]
코드를 바로 만들지 말고, 아래 3가지를 먼저 질문한 뒤 내 답변으로 설계를 확정한다.
Q1. 배분 대상은? (당직 / 시험 감독 / 청소 구역 / 3종 모드)
Q2. 요일 구조는? (월~금 / 주말 포함)
Q3. 배치표 CSV 서식은? (요일,업무,번호,닉네임 기본)🎯 에디터 한줄평
수기 배정의 '누가 자꾸 나가?'라는 시비가 누적 횟수라는 한 칸의 눈금으로 끝납니다 — 공정은 감(感)이 아니라 눈금입니다. 그리고 이 도구의 진짜 우아함은 기피 사유까지 묻지 않는 설계에 있습니다. 요일만 묻는 배려는 동료를 존중하는 정보의 최소 수집이자, 배분 알고리즘보다 먼저 지켜야 할 원칙입니다.
📚 기술·교육 참고 링크
- MDN — Array.sort() : 균등 배분의 정렬 원리
- 교육·행정 연계: 교무 기획 업무(당직·시험 감독·환경정리), 연수·회의 운영으로 확장