"그 공문 어디까지 갔어?" — 공문서 진행 현황 트래커 (GAS + 구글 시트 백엔드)
📋 교내 수신 공문서·기안 결재 진행 현황 투명 트래킹 — 행정실에서 문서를 등록하면 구글 시트에 문서 번호·제목·담당자·진행 단계(기안→검토→결재→완료)가 자동 기록되고, 전 교직원이 폰에서 현재 진행 상태를 원클릭으로 확인합니다. "그 문서 어디까지 갔나요?"를 묻는 전화가 사라집니다.
📖 한 줄 정의
Google Apps Script(GAS): 구글 스프레드시트 안에서 실행되는 서버리스 백엔드 스크립트 — 별도 서버 없이 무료로 웹앱을 배포할 수 있습니다.
구글 스프레드시트 = 무료 DB: 공문서 진행 이력이 시트에 시간순 누적되어 행정실이 엑셀처럼 확인·감사할 수 있습니다.
⚠️ 개인정보·보안 안내 (필독)
이 웹앱은 GAS + 구글 스프레드시트를 활용하여 데이터를 구글 클라우드에 저장합니다.
• 구현 전 반드시 소속 교육청 정보보호 담당과에 사전 문의하세요.
• 이 도구는 교사 전용입니다 — 학생 개인정보를 일절 다루지 않습니다.
1. 3대 핵심 분석 비교표
| 무엇이 바뀌었나요? | 쉬운 설명 | 써보세요! |
|---|---|---|
| 진행 단계 투명화 | 기안 → 검토 → 결재 → 완료 4단계의 현재 위치가 실시간으로 누구에게나 보입니다. | #2026-312 학생채용공문: 🔵 검토 (교무부장 단계) |
| 담당자 자동 알림 | 문서가 다음 단계로 넘어가면 담당자에게 구글 메일로 자동 알림을 보낼 수 있습니다. | MailApp.sendEmail("다음 결재자@school.kr", "결재 요청") |
| 월말 통계 자동화 | 월말에 시트를 필터링하면 완료 건수, 평균 소요 일수, 미결 문서가 자동 집계됩니다. | 이번 달 완료 42건 / 평균 3.2일 / 미결 5건 |
2. GAS 실전 구축 가이드
파일 1: Code.gs (백엔드)
function doGet(e) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("문서현황");
var data = sheet.getDataRange().getValues();
var rows = [];
for (var i = 1; i < data.length; i++) {
rows.push({ id: data[i][0], title: data[i][1], owner: data[i][2], stage: data[i][3], date: data[i][4] });
}
return ContentService.createTextOutput(JSON.stringify({ documents: rows })).setMimeType(ContentService.MimeType.JSON);
}
function doPost(e) {
var p = JSON.parse(e.postData.contents);
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("문서현황");
var id = "2026-" + String(sheet.getLastRow()).padStart(3, "0");
sheet.appendRow([id, p.title, p.owner, "🟡 기안", new Date().toLocaleString("ko-KR")]);
return ContentService.createTextOutput(JSON.stringify({ ok: true, id: id })).setMimeType(ContentService.MimeType.JSON);
}
function updateStage(id, stage) {
var sheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("문서현황");
var data = sheet.getDataRange().getValues();
for (var i = 1; i < data.length; i++) {
if (data[i][0] === id) {
sheet.getRange(i + 1, 4).setValue(stage);
break;
}
}
return ContentService.createTextOutput(JSON.stringify({ ok: true })).setMimeType(ContentService.MimeType.JSON);
}
파일 2: index.html (프런트엔드)
<!DOCTYPE html>
<html lang="ko"><head>
<meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>공문서 진행 현황</title>
</head><body>
<h2>📋 공문서 진행 현황</h2>
<div id="list">로딩 중...</div>
<script>
var G = "여기에_배포_URL";
fetch(G).then(function(r){return r.json();}).then(function(d){
var h = "<table border='1'><tr><th>문서번호</th><th>제목</th><th>담당자</th><th>단계</th><th>일자</th></tr>";
d.documents.forEach(function(x){
h += "<tr><td>" + x.id + "</td><td>" + x.title + "</td><td>" + x.owner + "</td><td>" + x.stage + "</td><td>" + x.date + "</td></tr>";
});
document.getElementById("list").innerHTML = h + "</table>";
});
</script>
</body></html>
제미나이 전용 에러 제로 프롬프트
[🚨 에러 방지 기본 안전장치]
1. 2개 파일 완결성: Code.gs와 index.html을 각각 완성한다.
2. doGet: 시트에서 전체 문서 현황을 읽어 JSON으로 반환한다.
3. doPost: 문서 ID 자동 생성(2026-001 형식) 후 시트에 appendRow한다.
4. updateStage: 진행 단계를 변경하는 별도 함수를 구현한다.
5. 학생 개인정보 0: 문서 제목과 담당 교사 이름만 다룬다.
6. // TODO, /* 생략 */ 금지 — 끝까지 완성한다.
[❓ 역질문]
1. 진행 단계는 몇 단계인가요? (기본: 기안/검토/결재/완료 4단계)
2. 문서 분류(수신/기안) 구분이 필요한가요? (기본: 구분 칸 추가)
🎯 에디터 한줄평
"교무실의 습격 이야기입니다. '저 문서 어디 갔어요?'는 사실상 '담당자에게 재촉하라'는 뜻이었고, 그 재촉이 학교 전체의 긴장감을 만들었습니다. 진행 상태가 투명하게 공유되면 재촉이 필요 없어집니다 — 데이터가 신뢰를 대체합니다."
📚 참고 링크
- Google Apps Script 공식 문서: https://developers.google.com/apps-script
- 교육과정 연계: 교무 행정(공문서 관리), 교사 업무 자동화