Haccp Pptx
1. 웹입력을 지정 파일 형식으로 생성
1.1. 입력서식
- 입력 받으려는 데이터를 종류와 역할에 따라 구분합니다
- 이름,주소, 주민번호,이미지 등
- 각 입력받는 데이터는 그와 적절한 웹입력 요소를 사용합니다.
1.2. 출력서식
ai가 생성하기 좋은 파일 출력 양식 a. 인터넷 문서 양식
- html : 가장 기본이며 ai 가 출력할 때 가장 기본 형식입니다
- xml : html에 기능, 구조적으로 더 완성 된 형태 입니다.하지만 직접 사람이 편집하거나 취급하기에 복잡합니다.
b. MS Office
- docx: word의 파일 형식입니다. xml 기반으로 호환성이 좋습니다
- xlsx: excel의 파일 형식입니다. xml 기반으로 모양, 서식이 단순하고 주로 데이터 위주인 경우 거의 완벽하게 표현 됩니다.
- pptx: powerpoint 파일 형식입니다. xml 기반으로 모양과서식 , 효과 위주이기 때문에 100% 원본과 같이 표현할 수 없습니다. 하지만 정적인 문서, 복잡한 효과가 없는 이상 대부분 출력가능 합니다
c. 기타 텍스트 형식
- Markdown
- 마크다운은 텍스트 기반의 경량 마크업 언어로, 일반 텍스트 문서를 구조화된 HTML로 변환하는 데 사용됩니다.
- 간단하고 직관적인 문법으로 메모 작성, 문서화, 웹 콘텐츠 제작 등 다양한 용도로 활용됩니다.
- RTF:
- RTF는 문서에 글꼴, 색상, 정렬 등 서식을 적용할 수 있는 텍스트 파일 형식입니다.
- 다양한 워드프로세서에서 호환되어 서식이 유지되는 장점이 있습니다.
- hwpx
- 아래아 한글 hwp파일의 xml 버전 입니다.
- rHWP 공개소스를 통해 편집, 뷰어 가능합니다
1.3. 입력에서 출력까지 흐름
aistudio 기준
파일에 입력받을 항목이름을 붙입니다.
- 항목을 “필드” 라 합니다.
- 문서에 각 항목에 {{필드이름}} 식으로 이름을 입력해 둡니다
ex) 생년 월일 입력받는 곳 –> {{birth}}
- {{ }}: 이 기호는 임의의 기호입니다. 보통 전산에서 필드,항목 이름을 나타내는 기호로 사용됩니다
ai가 읽기 쉬운 형식으로 변환
- 사용하고 있는 문서의 종류와 모양, 구조를 ai에게 전달 합니다.
- ai가 보기 쉬운 형식으로 변환합니다
- html로 변환 가능 하면 가장 정확하게 전달 할 수 있습니다
- 대부분의 오피스파일, pdf 는 바로 인식가능합니다
- 이미지는 OCR을거쳐 인식 합니다
- 입력효율이 좋은 순서 html > xml 파일(오피스 파일, hwpx) > pdf »> image
llm 에게 출력 양식 알려줌
- 필드로 정의된 항목을 필수 입,출력 요소로 지정
- 출력 파일 형식 알려줌
- 세부 서식에 대한 정보 제공 (인터넷 공개 사용 폰트, 로컬에 설치된 폰트 구분)
서식, 모양 유지하기
서식, 모양은 상대적으로 결정되는 요소가 많습니다. 그래서 모양 유지하기가 까다롭습니다 (줄간격 160% –> 현재 폰트 크기 기준)
형식유지 prompt 생성
- llm 에게 자신의 상황을 설명한 뒤 이런 변환에서 html 미리보기가 최종 출력물형식(pptx)로 변환될 때
미리보기를 유지 할 수있는 prompt 생성 요청.
외부 변환 툴 사용.
- 일반 사용자들이 만들어둔 외부 변환 프로그램 소스 이용 (github 검색) ex) rhwp 패키지
끝까지 마무리
- 한번에 완전한 변환은 안됩니다.
- prompt로 수정사항을 웹요소와 스크린샷으로 정확하게 전달 하면서 반복 수정 합니다.
그래도 역시 편한 건 돈
- llm의 coding 기능 사용하세요
- 유료 claude: claude code 문서 작성 능력 가장 좋습니다.
- 무료 chatgpt: chatgpt codex
- 무료지만 10~20장 정도 문서 작성 가능합니다
2. 수동 제작
2.1. promopt
- 간단한 웹앱은 배경, 목적을 간단히 전달해도 간단히 만들 수 있습니다.
- 하지만 조금만 규모가 커지면 나중에 하나 하나 고칠게 너무 많습니다
- LLM 과 충분히 대화하고 PRD, FS 기반으로 제작을 추천합니다.
1. 보고서를 작성하는 웹앱을 만든다.
2. 보고서는 텍스트와 이미지 보고서 두 가지 종류가 하나의 보고서 이다.
3. 텍스트 보고서는 서식과 문단 레벨 서식 적용이다.
4. 이미지 보고서는 간단한 제목과 날짜 입력, 이미지 마다 캡션을 선택 추가 가능하다.
5. template_pdf.pdf 모양의 pptx를 결과물로 만든다.3. Firebase 준비
3.1. Project 만들기



3.2. App 만들기
- App 추가

- 웹 앱 선택

- App 이름 지정 –> Console 이동
3.3. Authentification 추가
- 로그인 방법 추가
3.4. firestore 추가
3.4.1. 규칙설정
rules_version = '2';
service cloud.firestore {
match /databases/{database}/documents {
match /{document=**} {
allow read, write: if request.auth != null;
}
}
}3.5. 설정 정보 확인
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyA2cGAPnPmoA9MKuhczvAqGPlvJffl0-X4",
authDomain: "ksd-pptx.firebaseapp.com",
projectId: "ksd-pptx",
storageBucket: "ksd-pptx.firebasestorage.app",
messagingSenderId: "675031558591",
appId: "1:675031558591:web:e86c3664f7d72a86f3590a",
measurementId: "G-TSRK59MZT9"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);4. PRD-FS 제작법
4.1. prd요청
- Prd 대화 prompt
## Instruction
1. 너는 웹앱 기획 전문가이다.
2. 나는 초보자이다. 전문용어는 쉽게 설명하라 (용어 해설 추가).
3. 나는 `{개발앱목적}`을 만들고 싶다.
4. Google AI Studio를 사용한다.
5. PRD 문서, FS 문서를 작성하려 한다.
6. PRD 문서 작성을 위한 토론을 하자.
7. 필요한 정보는 나에게 질문하라.
8. 서술어·수식어 없이 핵심만 간단한 대화식으로 진행하라.
9. 대답은 선택 질문 시 객관식 선택사항 또는 단답형으로, 한 번에 하나의 질문씩 진행하라.
10. 웹앱의 기능 정보는 `{Rule}`을 참고하라.
### 입력: 개발앱목적
- 작업자가 자신의 작업을 텍스트 보고서, 이미지 보고서를 입력하면 template 형식의 pptx 로 출력하고싶다.
## Strong Rule
1. 내가 "됐어"라고 할 때까지 PRD 관련 검토와 질문을 이어가라.
2. 답변을 받으면 예상되는 문제와 개선책을 고민해서 대화를 이어가라.
3. 더 나은 새로운 기능과 아이디어가 있으면 적극 추천하라.
4. 대화가 종료되면 "PRD 문서", "FS 문서"를 Markdown으로 출력하라.
### 입력: Rule
## 일반회원 (행위자1)
1. 나는 로그인해서 보고서를 작성한다.
2. 보고서는 두 종류이다.
- CKEditor5 편집기를 사용하는 **텍스트 보고서**: 이미지 보고서 내용을 요약 정리한다
- 이미지를 첨부하는 **이미지 보고서**
3. 입력이 끝나면 `template_pdf.pdf` 모양으로 작성해서 PPTX로 출력한다.
## 관리자 (행위자2)
1. 회원들의 가입정보를 관리할 수 있다.
2. 전체 목록을 관리한다.
3. 회원들의 보고서를 개별 또는 하나의 파일(PPTX)로 출력한다.
## Rule
- 템플릿 파일의 첫번째 페이지는 이미지 보고서의 상세 내용을 요약하는 페이지
- 템플릿 파일의 두번째 페이지는 작업 내용 이미지와 간단설명이다.
- **Template**: 첨부한 `template_pdf.pdf`를 사용한다.
- 회원은 가입하면 자동 승인된다.
- 데이터는 Firebase의 **Firestore**에 저장한다.
- 이미지는 1MB 이하로 자동 리사이즈되어 Firestore에 저장한다.
- 입력 내용과 서식은 `template_pdf`의 `{{필드이름}}`를 따라간다.
- 결과다운로드

4.2. prd, fs 문서
4.2.1. prd 문서
# PRD — 작업 보고서 PPTX 생성 웹앱
> **PRD(Product Requirements Document)**: 무엇을, 왜, 누구를 위해 만드는지 정의하는 기획 문서.
---
## 1. 개요
| 항목 | 내용 |
|---|---|
| 제품명 | 작업 보고서 PPTX 생성 웹앱 (가칭) |
| 목적 | 작업자가 텍스트·이미지 보고서를 입력하면, 국순당 템플릿 형식의 PPTX로 출력 |
| 핵심 가치 | 보고서 작성 → 통일된 서식의 발표자료 자동 생성 (수작업 제거) |
| 개발 도구 | Google AI Studio (Gemini 기반 코드 생성·프로토타입) |
| 데이터 저장 | Firebase Firestore |
| 문서 버전 | v1.0 |
---
## 2. 문제 정의
- 작업자마다 보고서 서식이 제각각 → 통일 필요
- 텍스트 요약 + 현장 사진을 매번 수동으로 PPT에 배치 → 시간 소모
- 관리자가 여러 보고서를 한 파일로 취합하기 번거로움
**해결**: 정해진 템플릿(`template_pdf.pdf`)에 입력만 하면 자동으로 PPTX 완성.
---
## 3. 사용자 정의 (행위자)
### 3.1 일반회원 (작업자)
- 로그인 후 본인 보고서 작성·수정·삭제
- 텍스트 보고서 + 이미지 보고서 입력
- 미리보기 확인 후 PPTX 다운로드
### 3.2 관리자 (admin)
- 지정된 관리자 이메일로 로그인 시 관리자 화면
- 회원 목록 조회, 회원 삭제, 보고서 삭제
- 회원 보고서를 개별 또는 하나의 PPTX로 취합 출력
---
## 4. 핵심 기능 요구사항
### 4.1 인증 / 회원
| ID | 요구사항 |
|---|---|
| A-1 | 이메일+비밀번호 로그인 (Firebase Authentication) |
| A-2 | 가입 시 자동 승인 (이메일 인증 없음) |
| A-3 | 가입 정보: 이메일, 비밀번호, 이름, 부서/소속 |
| A-4 | 관리자 이메일은 코드에 고정 지정, 해당 계정만 관리자 화면 진입 |
### 4.2 보고서 작성 (작업자)
| ID | 요구사항 |
|---|---|
| R-1 | 텍스트 보고서: CKEditor5 편집기로 작성 (작업자가 직접 요약 입력) |
| R-2 | 텍스트 서식(표·색상 포함) 최대한 유지하여 PPTX 반영 |
| R-3 | 이미지 보고서: 1~6장 첨부, 각 이미지에 간단설명(글자 수 제한 없음) |
| R-4 | 본인 보고서만 접근 가능 (수정·삭제 포함) |
| R-5 | 임시저장: 작성 중 이탈해도 이어쓰기 가능 |
| R-6 | 이미지 드래그로 순서 변경 → 순서가 PPTX 배치 칸을 결정 |
### 4.3 PPTX 출력
| ID | 요구사항 |
|---|---|
| P-1 | 템플릿 구조 준수: [텍스트 페이지 1~N] + [이미지 페이지] |
| P-2 | 1페이지(텍스트): 내용이 넘치면 페이지 자동 추가 |
| P-3 | 텍스트 이어지는 페이지: 머리말(제목·로고·띠) 없이 내용만 |
| P-4 | 2페이지(이미지): 장수(1~6)별 고정 레이아웃 적용 |
| P-5 | 이미지 설명이 칸보다 길면 글자 자동 축소(최소 크기 이하는 잘림) |
| P-6 | 브랜드 색상·로고·파란 띠를 코드로 재현 |
| P-7 | 미리보기 화면 확인 후 다운로드 |
| P-8 | PPTX 생성은 브라우저에서 처리 (서버 없음) |
### 4.4 관리자 기능
| ID | 요구사항 |
|---|---|
| M-1 | 회원 목록 조회 |
| M-2 | 회원 삭제 (보고서·이미지는 남김, 작성자 미상 처리) |
| M-3 | 회원 보고서 삭제 |
| M-4 | 보고서 개별 PPTX 출력 |
| M-5 | 여러 보고서를 하나의 PPTX로 취합 (관리자가 순서 지정) |
| M-6 | 취합 시 보고서별 간지 1장 삽입 (제목·작성자·날짜) |
| M-7 | 대량 취합 시 1회 처리 개수 제한 (브라우저 과부하 방지) |
### 4.5 편의 기능
| ID | 요구사항 |
|---|---|
| E-1 | 작성일 기준 보고서 검색·필터 |
| E-2 | 이미지 드래그 순서 변경 (R-6과 동일) |
---
## 5. 템플릿 사양 (template_pdf.pdf 기준)
### 5.1 텍스트 페이지 (1페이지)
- 필드: `{{텍스트 제목}}`, `{{텍스트 부제목}}`, `{{기간}}`, `{{작성날짜}}`, `{{텍스트_보고서_영역}}`
- 상단: 주황 사각형 + 제목 + 국순당 로고
- `{{텍스트_보고서_영역}}`: CKEditor5 HTML 내용 삽입
### 5.2 이미지 페이지 (2페이지)
- 필드: `{{그림보고서_제목}}` (+ `_HACCP`), `{{그림_기간}}` (파란 띠 안 "…활동"), `{{그림영역}}`
- 상단: 제목 + 로고 / 그 아래 파란 띠(기간) / 본문: 이미지 + 설명
### 5.3 브랜드 색상
| 용도 | HEX |
|---|---|
| 파란 띠 (네이비) | `#002060` |
| 주황 사각형/포인트 | `#DD6909` |
| 로고 주황 원 | `#FA9F17` |
| 검정 글자 | `#221E21` |
---
## 6. 이미지 장수별 레이아웃 (P-4)
| 장수 | 배치 |
|---|---|
| 1장 | 중앙 크게 1개 |
| 2장 | 좌우 2분할 |
| 3장 | 상단 2 + 하단 1 (또는 가로 3분할) |
| 4장 | 2×2 |
| 5장 | 상단 3 + 하단 2 |
| 6장 | 2×3 (3열 2행) |
> 정확한 픽셀 배치는 FS 문서 참조.
---
## 7. 데이터 규칙
- 저장소: Firestore
- 이미지: 브라우저에서 업로드 시 자동 리사이즈 (800KB 이하 권장) 후 저장
- Firestore 문서 1MB 제한 → 이미지는 이미지별 문서(별도 컬렉션)로 분산 저장
- 이미지는 Base64 문자열로 Firestore에 보관
---
## 8. 사용자 흐름 (User Flow)
### 작업자
```
로그인 → 보고서 작성(텍스트 + 이미지 1~6장 + 설명)
→ 이미지 순서 조정 → 저장(임시저장 가능)
→ 미리보기 확인 → PPTX 다운로드
```
### 관리자
```
관리자 로그인 → 회원/보고서 목록 조회 (날짜 검색·필터)
→ 보고서 선택 + 순서 지정 → 취합 PPTX 생성(간지 포함)
→ 다운로드
(필요 시 회원/보고서 삭제)
```
---
## 9. 범위 밖 (Out of Scope) — v1 미포함
- AI 자동 요약 (향후 옵션)
- 구글 계정 로그인
- 회원 정보 수정 (관리자)
- 이메일 인증
- Firebase Storage 사용 (Rule에 따라 Firestore만)
---
## 10. 성공 기준
- 작업자가 5분 내 보고서 작성 → PPTX 다운로드 완료
- 생성된 PPTX가 템플릿 서식과 색상을 정확히 재현
- 관리자가 다수 보고서를 1개 PPTX로 취합 성공4.2.2. FS 문서
# FS — 기능 명세서 (Functional Specification)
> **FS(Functional Specification)**: PRD에서 정한 것을 "어떻게" 만들지 정의하는 설계 문서. 화면, 데이터, 기능 로직을 구체화.
---
## 1. 기술 스택
| 구분 | 선택 | 설명 |
|---|---|---|
| 개발 도구 | Google AI Studio | Gemini로 코드 생성·프로토타입 |
| 프론트엔드 | React (또는 순수 JS) | 화면 구성 |
| 인증 | Firebase Authentication | 이메일+비밀번호 |
| DB | Firebase Firestore | 회원·보고서·이미지 저장 |
| 텍스트 편집기 | CKEditor5 | 서식 있는 텍스트 → HTML 출력 |
| 이미지 리사이즈 | browser-image-compression | 브라우저에서 축소 |
| PPTX 생성 | PptxGenJS | 브라우저에서 PPTX 생성 |
| 드래그 정렬 | SortableJS (또는 dnd-kit) | 이미지 순서 변경 |
> **용어**
> - **React**: 화면을 부품(컴포넌트)으로 조립하는 웹 도구
> - **HTML**: 웹 서식을 표현하는 코드
> - **Base64**: 이미지 파일을 글자 문자열로 바꾼 형태 (Firestore에 텍스트로 저장하기 위함)
---
## 2. 데이터 구조 (Firestore)
> **컬렉션**: 문서를 담는 폴더. **문서**: 실제 데이터 한 건.
### 2.1 `users` 컬렉션
```
users/{uid}
├─ email: string
├─ name: string
├─ department: string // 부서/소속
├─ role: "member" | "admin" // admin은 지정 이메일에만
└─ createdAt: timestamp
```
### 2.2 `reports` 컬렉션
```
reports/{reportId}
├─ ownerUid: string // 작성자 uid (삭제되면 null → "작성자 미상")
├─ ownerName: string // 작성 시점 이름 (스냅샷)
├─ ownerDept: string
├─ textTitle: string // {{텍스트 제목}}
├─ textSubtitle: string // {{텍스트 부제목}}
├─ period: string // {{기간}} / {{그림_기간}}
├─ writeDate: timestamp // {{작성날짜}}
├─ imgReportTitle: string // {{그림보고서_제목}}
├─ textHtml: string // CKEditor5 HTML (텍스트 보고서 영역)
├─ imageOrder: string[] // 이미지 문서 id 순서 배열
├─ status: "draft" | "saved" // 임시저장 / 저장
├─ createdAt: timestamp
└─ updatedAt: timestamp
```
### 2.3 `reports/{reportId}/images` 하위 컬렉션
> 이미지를 별도 문서로 분산 저장 (Firestore 1MB 문서 제한 회피)
```
reports/{reportId}/images/{imageId}
├─ data: string // Base64 이미지 (800KB 이하)
├─ caption: string // 간단설명 (글자 수 제한 없음)
└─ order: number // 정렬 순서
```
---
## 3. 화면 명세
### 3.1 로그인 / 회원가입 화면
| 요소 | 동작 |
|---|---|
| 이메일 입력 | 형식 검증 |
| 비밀번호 입력 | 6자 이상 |
| 로그인 버튼 | Firebase Auth 인증 → 역할 판별 후 분기 |
| 회원가입 링크 | 이름·부서 추가 입력 → 자동 승인 → 즉시 로그인 |
| 관리자 판별 | 로그인 이메일 == 지정 관리자 이메일 → 관리자 화면 |
### 3.2 작업자 — 보고서 목록 화면
| 요소 | 동작 |
|---|---|
| 내 보고서 목록 | 본인 것만 표시 |
| 날짜 검색·필터 | 작성일 범위로 필터 (E-1) |
| 새 보고서 버튼 | 작성 화면 이동 |
| 각 항목 | 수정 / 삭제 / 미리보기·다운로드 |
### 3.3 작업자 — 보고서 작성 화면
| 영역 | 요소 | 동작 |
|---|---|---|
| 기본정보 | 제목, 부제목, 기간, 그림보고서 제목 | 텍스트 입력 |
| 텍스트 보고서 | CKEditor5 | 서식 편집 → HTML 저장 |
| 이미지 보고서 | 파일 첨부(1~6장) | 업로드 시 자동 리사이즈 |
| 이미지 설명 | 각 이미지별 캡션 | 텍스트 입력 |
| 순서 변경 | 드래그 | order 갱신 (R-6) |
| 저장 | 임시저장 / 저장 | status 반영 |
| 미리보기 | 버튼 | 결과 모양 화면 렌더 |
| 다운로드 | 버튼 | PPTX 생성·저장 |
### 3.4 관리자 화면
| 탭 | 기능 |
|---|---|
| 회원 관리 | 목록 조회 / 삭제 (M-1, M-2) |
| 보고서 관리 | 전체 목록 / 날짜 필터 / 삭제 (M-3) |
| 개별 출력 | 보고서 1건 → PPTX (M-4) |
| 취합 출력 | 다중 선택 + 드래그 순서 → 1개 PPTX (간지 포함, M-5·M-6) |
---
## 4. PPTX 생성 로직 (PptxGenJS)
### 4.1 슬라이드 크기
- 16:9 기준 (템플릿 비율)
### 4.2 텍스트 페이지 렌더
```
1) 첫 페이지:
- 좌상단 주황 사각형(#DD6909) + 제목(검정 #221E21)
- 우상단 국순당 로고 이미지(PNG)
- 부제목 · 기간 · 작성날짜
- 본문: textHtml → PPTX 텍스트 변환 (표·색상 반영)
2) 본문 높이가 슬라이드를 초과하면:
- 다음 슬라이드 자동 추가
- 이어지는 슬라이드는 머리말(제목·로고·띠) 없이 본문만 (P-3)
```
> **HTML → PPTX 변환 주의**: CKEditor5 HTML을 파싱하여 문단·굵게·기울임·목록·표·글자색을 PptxGenJS 요소로 매핑. 복잡한 중첩 서식은 근사 처리(깨질 수 있음, PRD 리스크 참조).
### 4.3 이미지 페이지 렌더
```
1) 제목 + 로고
2) 파란 띠(#002060) 안에 "{{그림_기간}} 활동"
3) 이미지 개수(imageOrder.length)에 따라 레이아웃 선택
```
### 4.4 장수별 레이아웃 좌표 (슬라이드 폭 10 × 높이 5.63 inch 기준, 본문 영역 예시)
| 장수 | 배치 (열 × 행) | 이미지 크기(대략) |
|---|---|---|
| 1 | 1×1 중앙 | 6.0 × 3.4 |
| 2 | 2×1 | 4.4 × 3.0 |
| 3 | 상2 하1 | 4.0 × 1.9 |
| 4 | 2×2 | 4.4 × 1.7 |
| 5 | 상3 하2 | 2.9 × 1.7 |
| 6 | 3×2 | 2.9 × 1.7 |
- 각 이미지 아래 caption 배치
- caption 길이 > 칸 폭 → 글자 크기 자동 축소 (최소 8pt, 그 이하는 말줄임 처리, P-5)
### 4.5 취합 출력 로직 (관리자)
```
선택 보고서 배열(관리자 지정 순서) 순회:
for 각 보고서:
- 간지 슬라이드 1장 삽입 (제목·작성자·날짜, M-6)
- 텍스트 페이지(들) 렌더
- 이미지 페이지 렌더
1회 처리 개수 상한 설정 (예: 20건) → 초과 시 안내 (M-7)
```
---
## 5. 이미지 리사이즈 로직
```
파일 선택 시:
browser-image-compression 옵션
maxSizeMB: 0.8 // 800KB
maxWidthOrHeight: 1600
→ 압축 결과를 Base64 변환
→ reports/{id}/images 문서로 저장
```
> 800KB로 잡는 이유: Firestore 문서 1MB 한도에서 caption·필드 여유 확보.
---
## 6. 권한 규칙 (Firestore Security Rules 개념)
| 대상 | 작업자 | 관리자 |
|---|---|---|
| 본인 user 문서 | 읽기 | 전체 읽기/삭제 |
| 본인 reports | 읽기·쓰기·삭제 | 전체 읽기·삭제 |
| 타인 reports | 불가 | 가능 |
| 관리자 판별 | 지정 이메일 상수와 일치 여부 |
---
## 7. 상태 처리 / 예외
| 상황 | 처리 |
|---|---|
| 이미지 0장 | 이미지 페이지 생략 또는 경고 |
| 이미지 6장 초과 시도 | 첨부 차단 (최대 6) |
| 텍스트 비어있음 | 저장 경고 |
| 작성자 삭제된 보고서 | ownerName "작성자 미상" 표시, 조회·출력 유지 |
| 취합 대량 초과 | 상한 안내 후 분할 요청 |
| 압축 후에도 큰 이미지 | 재압축 또는 첨부 거부 안내 |
---
## 8. 개발 순서 (권장)
1. Firebase 프로젝트 + Auth + Firestore 세팅
2. 로그인/회원가입 + 역할 분기
3. 보고서 작성 화면 (CKEditor5 + 이미지 업로드·리사이즈)
4. Firestore 저장/조회 (임시저장 포함)
5. PPTX 생성 (텍스트 페이지 → 이미지 페이지 → 미리보기)
6. 장수별 레이아웃 6종 구현
7. 관리자 화면 (목록·삭제·개별 출력)
8. 취합 출력(간지·순서·상한)
9. 검색·필터, 드래그 정렬 마감
10. 예외 처리·테스트
---
## 9. 준비물 체크리스트
- [ ] 국순당 로고 PNG (준비 완료: `국순당로고.png`)
- [ ] 관리자 지정 이메일 확정
- [ ] 브랜드 색상 (확정: #002060 / #DD6909 / #FA9F17 / #221E21)
- [ ] Firebase 프로젝트 생성 및 API 키
- [ ] 템플릿 필드 최종 확인 (`template_pdf.pdf`)4.3. 제작 요청
- prompt 와 template_pdf.pdf 를 같이 제공합니다 template_pdf_withoutlevel.pdf
1. 나는 웹에서 입력 받아 pptx 로 출력하는 웹 앱을 작성한다
2. 첨부한 PRD, FS 문서를 참고하여 step by step 으로 작성하라
3. 언어: 한국어
4. 디자인: 세력, 모던, 오피스 느낌
## firebase config info (minux4shop)
// Import the functions you need from the SDKs you need
import { initializeApp } from "firebase/app";
import { getAnalytics } from "firebase/analytics";
// TODO: Add SDKs for Firebase products that you want to use
// https://firebase.google.com/docs/web/setup#available-libraries
// Your web app's Firebase configuration
// For Firebase JS SDK v7.20.0 and later, measurementId is optional
const firebaseConfig = {
apiKey: "AIzaSyA2cGAPnPmoA9MKuhczvAqGPlvJffl0-X4",
authDomain: "ksd-pptx.firebaseapp.com",
projectId: "ksd-pptx",
storageBucket: "ksd-pptx.firebasestorage.app",
messagingSenderId: "675031558591",
appId: "1:675031558591:web:e86c3664f7d72a86f3590a",
measurementId: "G-TSRK59MZT9"
};
// Initialize Firebase
const app = initializeApp(firebaseConfig);
const analytics = getAnalytics(app);
- 대화내용 요약.
4.4. 초기 결과
- 로그인 화면

- 작성화면

4.5. 테스트 보고서작성 기능
4.5.1. 작업기간 수정
- 작업기간이 단일 날짜 입력으로 되어 있습니다
- 시작 끝 날짜 입력으로 변경

결과가 나오면 기능을 하나 씩 테스트 합니다
4.5.2. 글작성기기능 수정
문단레벨 기능
H1,H2,H3 에 대한 서식적용 요청
- CKeditor5 서식 도구에서 H1, H2, H3 서식 기능을 적용하라 각 레벨마다 들여쓰기 서식내용 1. H1: 맑은고딕 18 pt(진하게) 2. H2: 맑은 고딕 16 pt 3. H3: 맑은 고딕 14 pt 4. 본문(기본): 맑은고딕 12Pt

레벨 버튼 모양 수정
- 레벨기호를 [ H1, H2,H3,Body ] 로 만 표시. 드롭다운 메뉴 사용
글머리 헤더 버튼
- 수정툴 사용. 글머리 기능 구현
- 글머리 기능 구현 1. 블릿 글머리 구현(레벨에 맞는 들여쓰기적용) 2. 숫자 글머리 구현(레벨에 맞는 들여쓰기적용)
표 편집 기능
표 편집 기능 구현
- 표 편집기능을 구현하다 - 메뉴아이콘으로 각기능을 메뉴에 표시하라(메뉴를 기호,아이콘으로만표시,드롭다운으로 심플하게) 1. 표(행, 열) 추가, 삭제 2. 표 (행,열,셀) 크기 변경 3. 표 합치기, 나누기

4.6. 이미지 보고서 수정
4.6.1. 이미지 비율 수정
- 여러장 입력시 가로세로 비율이 찌그러 집니다(pptx 출력물)

- pptx 이미지 출력과 미리보기 할 때 원본 사진의 가로,세로 비유을 유지하라
- 이미지 배치시 아래 레이아웃 반영해.
## layout
1장: 중앙 대형 프레임 (가로 6.0인치)
2장: 가로 2열 균등 배치 (가로 4.2인치 x 높이 3.0인치)
3장: 가로 3열 정렬 중앙 배치 (가로 2.8인치 x 높이 3.0인치)
4장: 2x2 대칭 그리드
5장: 상단 3개, 하단 2개 중앙 정렬
6장: 3x2 표준 그리드4.6.2. 미리 보기 수정
4.7. 보고서 페이지 추가
- 텍스트,이미지 보고서가 각 1장 씩만 작성가능합니다
- 각 페이지를 추가 합니다
- 텍스트보고서와 이미지보고서가 기본1장이다.
- 텍스트 보고서와 이미지 보고서를 선택해서 추가하도록하라
- 각 페이지의 위/아래 이동,삭제 가능4.8. 미리보기 기능 수정
4.8.1. 미리보기 추가 페이지 보기
- 현재 첫페이지만 미리보기 가능하고 추가 페이지는 나타나지 않습니다
- pptx 미리보기 기능에 첫페이지만 보이고 나머지 추가 페이지는 나타나지않는다
- 전체 페이지 내용을 모두 미리보기에 표시하라
4.8.2. 미리보기창 이동
화면에 보고서작성,미리보기가 한번에 보여 불편합니다. 이를 분리합니다
- pptx 미리보기 페이지를 따로 추가하라 - 사이드에 slide in, out 페이지로 변경하라 - 보고서 편집 화면을 화면전체에 표시

4.9. pptx 출력조정
4.9.1. 텍스트 보고서 글머리 기호 수정
pptx 출력시 글머리기호 오류 수정
pptx 내보내기 결과에서 줄 마다 글머리 기호가 추가됨

4.9.2. 레벨 들여쓰기 반영
문단레벨에 따른 들여쓰기 반영

pptx 출력에 문단의 레벨에 따른 들여쓰기 반영이 안되었다.출력시 로고
pptx 출력시 우측상단의 로고 교체
- pptx 출력시 우측 상단의 로고를 첨부한 파일을 사용하라 - 가로, 세로 비율 유지
4.10. 전체보고서 관리 페이지
더미페이지 추가
“관리자패널” 에 테스트를 위한 더미데이터 추가 기능을 추가합니다
- 관리자 계정에서 "관리자 패널" 에 더미데이터 생성 기능을 추가하라. - 더미데이터 개수를 입력 받는다. - 각 보고서는 텍스트보고서(500글자,표), 이미지 보고서(1~6장 랜덤) 으로 구성된다

4.11. 기타 기능테스트
- 여러리포트 합성출력 테스트
- 개별 리포트의 삭제, 다운로드 버튼 기능을 테스트 합니다
버튼이 안될 때 –> F12 디버깅 창의 정보를 복사해서 채팅창에 수정 요청
버튼 클릭시 에러에 아래내용 발생한다.수정하라 Ignored call to 'confirm()'. The document is sandboxed, and the 'allow-modals' keyword is not set. 6[Violation] 'setInterval' handler took <N>ms
- 데이터 목록 “리스트보기” 추가, 검색 필터링기능 추가
5. 데이터 재활용
5.1. excel 로 내보내기
- 다른 서비스로 재활용하기위해 보고서내용과 이미지 파일들을 묶어서 zip 으로 저장합니다
- 다른 서비스에서 활용하기 쉽게 보고서 하나 마다 하나의 레코드로 생성합니다
관리자 기능의 "관리자패널" 에 "Excel저장" 기능을 추가하라
- 하나의 보고서는 하나의 레코드로 만든다
- 필드 이름은 template에서 사용한 필드이름과 일치시킨다.
- 보고서내 이미지파일을 같이 저장해서 엑셀 파일과 함께 zip 으로 다운로드 한다
5.2. excel 데이터 활용
- excel 데이터로 추출하면 다른 여러 서비스에 활용 할 수 있습니다
- chatgpt 의 Codex 기능으로 pptx를 생성 해 봅니다
- 데이터파일 zip 파일과 템플릿 파일을 chatgpt에게 주고 pptx 생성을 합니다
5.3. Chatgpt Codex 활용
템플릿 파일에 zip파일 내용을 이용하여 pptx를 작성하라.
- 작업에 필요한 skill 을 검색 추가하라.
- 템플릿 파일의 필드이름과 엑실의 필드가 일치 된다.
- 템플릿 파일을 기준으로 만들고 더 나은 디자인이나 글꼴, 개체 배치를 고려해서 작성하라.
- 엑셀 레코드 하나 마다 하나의 pptx를 작성하라
템플릿: templatge_for_html.pptx
자료: 국순당_전체보고서.zip
6. PPTX 출력시 효과적 Prompt
web 에서 만들어지는 문서는 기본 html 문서 입니다
이 html을 다양한 출력 포맷시 정교한 조정이 힘듭니다
이 때 여러 노하우가 있는 출력 prompt를 llm 에게 물어서 적용해봅니다
1. ai studio 에서 html 으로 문서를 작성했다 2. 이 결과를 powerpoint pptx로 변환시 개체위치, 글꼴, 레이아웃 모양에 차이 난다 3 pptx 파일이 차이없이 생성 될 수 있는 prompt를 markdown 문서로 출력하라
6.1. pptx export 용 규칙
다음 조건을 반드시 준수하여 Microsoft PowerPoint용 PPTX 파일을 생성하라.
가장 중요한 목표는 AI 웹 화면의 미리보기와 Microsoft PowerPoint에서 PPTX 파일을 열었을 때의 레이아웃이 최대한 동일하게 보이도록 하는 것이다.
[최종 렌더링 기준]
1. 웹 미리보기가 아니라 Microsoft PowerPoint 데스크톱 버전을 최종 기준 렌더러로 간주한다.
2. 모든 슬라이드는 Microsoft PowerPoint에서 열었을 때 개체 위치, 크기, 정렬, 줄바꿈이 변경되지 않도록 작성한다.
3. 브라우저 전용 HTML, CSS, JavaScript 렌더링 결과를 PPTX 개체로 단순 변환하지 않는다.
4. PowerPoint에서 안정적으로 지원되는 기본 도형, 텍스트 상자, 표, 이미지 개체만 사용한다.
[슬라이드 규격]
1. 슬라이드 크기는 4:3 와이드로 고정한다.
3. 모든 개체 위치와 크기는 슬라이드 기준 절대좌표로 지정한다.
4. 픽셀 좌표를 직접 사용하지 말고 inch, point 또는 EMU 단위를 사용한다.
5. 개체 위치를 백분율이나 브라우저 반응형 레이아웃으로 계산하지 않는다.
6. 모든 좌표와 크기는 정수 EMU 값으로 최종 저장한다.
7. 반복 배치되는 개체는 이전 개체 위치에 값을 누적하지 말고 기준점에서 직접 계산한다.
[폰트 규칙]
1. 모든 텍스트의 폰트 이름과 크기를 명시적으로 지정한다.
2. 테마 폰트, 기본 폰트, 자동 폰트 상속에 의존하지 않는다.
3. 한국어와 영어가 섞여 있어도 동일하게 렌더링되는 폰트를 사용한다.
4. 기본 폰트는 다음 중 실제 제작 환경에 설치된 하나만 사용한다.
* 맑은 고딕
* Arial
* Calibri
* Aptos
5. 특수 폰트, 웹폰트, Google Fonts, 가변 폰트는 사용하지 않는다.
6. 한글 텍스트에는 동아시아 글꼴 속성도 동일한 폰트로 지정한다.
7. 텍스트의 각 run에 폰트 이름, 크기, 굵기, 색상을 직접 지정한다.
8. 폰트 대체가 발생할 가능성이 있는 글꼴은 사용하지 않는다.
[텍스트 상자 규칙]
1. 텍스트 상자의 자동 크기 조절을 사용하지 않는다.
2. 텍스트에 맞춰 도형 크기를 자동 변경하지 않는다.
3. 텍스트가 넘칠 때 자동으로 글자 크기를 축소하지 않는다.
4. 모든 텍스트 상자는 고정된 위치와 크기를 사용한다.
5. word wrap 사용 여부를 명시적으로 설정한다.
6. 텍스트 상자의 왼쪽, 오른쪽, 위쪽, 아래쪽 내부 여백을 직접 지정한다.
7. 모든 문단의 다음 속성을 직접 지정한다.
* 수평 정렬
* 수직 정렬
* 줄 간격
* 문단 앞 간격
* 문단 뒤 간격
* 들여쓰기
8. 한 텍스트 상자 안에 지나치게 많은 텍스트를 넣지 않는다.
9. 텍스트가 영역을 넘을 가능성이 있으면 글자 크기를 자동 축소하지 말고 문장을 줄이거나 텍스트 상자를 미리 크게 설계한다.
10. 제목과 본문 텍스트 상자는 최소 5% 이상의 여유 공간을 확보한다.
[개체 배치 규칙]
1. 모든 개체의 left, top, width, height 값을 명시적으로 지정한다.
2. PowerPoint의 자동 정렬, 자동 맞춤, 자동 배치 기능에 의존하지 않는다.
3. 정렬되는 개체는 동일한 기준 좌표를 공유하도록 계산한다.
4. 여러 개체를 균등 배치할 때 반올림 오차를 고려하여 마지막 개체의 좌표와 크기를 보정한다.
5. 슬라이드 경계와 개체 사이에 최소 0.3 inch의 안전 여백을 둔다.
6. 개체끼리 겹치지 않도록 bounding box를 검사한다.
7. 그룹 도형 사용을 최소화한다.
8. 그룹 내부 좌표계를 사용하는 복잡한 구조는 만들지 않는다.
9. 회전된 도형과 회전된 텍스트를 가급적 사용하지 않는다.
10. 회전이 필요한 시각 요소는 가능하면 미리 렌더링된 PNG 이미지로 사용한다.
[표 규칙]
1. 표의 전체 위치와 크기를 명시적으로 지정한다.
2. 각 열의 너비를 직접 지정한다.
3. 각 행의 높이를 직접 지정한다.
4. 열 너비의 합은 표 전체 너비와 정확히 같아야 한다.
5. 행 높이의 합은 표 전체 높이와 정확히 같아야 한다.
6. 표 셀의 내부 여백을 직접 지정한다.
7. 표 셀의 텍스트 자동 맞춤을 사용하지 않는다.
8. 셀 안의 폰트, 크기, 문단 간격, 정렬을 각각 지정한다.
9. 셀 안의 텍스트가 넘치지 않도록 작성 단계에서 텍스트 길이를 제한한다.
[이미지 규칙]
1. 이미지의 원래 종횡비를 유지한다.
2. width와 height를 임의로 동시에 변경하여 이미지가 찌그러지지 않도록 한다.
3. 이미지는 지정된 영역 안에서 contain 또는 crop 방식으로 배치한다.
4. 이미지 크롭 위치를 명시적으로 지정한다.
5. SVG는 PowerPoint 버전에 따라 다르게 보일 수 있으므로 가능하면 고해상도 PNG를 사용한다.
6. 복잡한 아이콘, 그래프, 수식, 다이어그램은 필요하면 2배 이상의 해상도를 가진 투명 PNG로 렌더링하여 삽입한다.
7. 이미지에 CSS 필터, 브라우저 그림자, 마스크 효과를 적용하지 않는다.
[도형과 효과 규칙]
1. PowerPoint 기본 도형만 사용한다.
2. 복잡한 그라데이션, 블렌딩 모드, CSS 그림자, backdrop filter를 사용하지 않는다.
3. 투명도는 꼭 필요한 경우에만 사용한다.
4. 그림자, 광택, 3차원 회전, 입체 효과를 사용하지 않는다.
5. 둥근 모서리는 PowerPoint 기본 round rectangle 도형만 사용한다.
6. 선 두께는 point 단위로 명시한다.
7. 선 끝 모양, 점선 유형, 채우기 색상과 투명도를 명시한다.
[차트와 다이어그램 규칙]
1. 차트가 PowerPoint에서 편집 가능해야 한다면 PowerPoint 기본 차트 개체로 작성한다.
2. 웹 기반 차트 라이브러리의 결과를 직접 PowerPoint 차트로 변환하지 않는다.
3. 웹 차트와 PowerPoint 차트의 모양이 달라질 가능성이 크다면 고해상도 PNG로 렌더링하여 삽입한다.
4. SmartArt는 사용하지 않는다.
5. 복잡한 연결선 다이어그램은 연결선 위치가 변경될 수 있으므로 하나의 고해상도 이미지로 고정하는 방법을 우선 검토한다.
[레이아웃 안정성 규칙]
1. placeholder의 기본 위치와 테마 스타일에 의존하지 않는다.
2. 빈 슬라이드 레이아웃 위에 일반 텍스트 상자와 일반 도형을 배치한다.
3. 제목 placeholder, 내용 placeholder의 자동 서식을 사용하지 않는다.
4. 마스터 슬라이드의 자동 재배치 기능에 의존하지 않는다.
5. 모든 슬라이드 요소의 z-order를 명시적으로 관리한다.
6. 배경, 장식, 이미지, 도형, 텍스트 순서로 레이어를 구성한다.
7. 서로 다른 개체가 동일한 경계선에 정확히 붙도록 배치하지 말고 최소 0.01 inch의 안전 간격을 둔다.
[편집 가능성과 시각적 동일성 구분]
다음 기준으로 개체를 선택한다.
1. 사용자가 수정해야 하는 제목, 본문, 숫자, 표 데이터는 PowerPoint 편집 가능한 텍스트 또는 표로 만든다.
2. 복잡한 인포그래픽, 수식, 장식, 아이콘 조합, 정밀한 그래프는 하나의 PNG 이미지로 고정한다.
3. 시각적 동일성이 편집 가능성보다 중요한 요소는 이미지로 삽입한다.
4. 편집 가능성이 필요한 요소는 단순한 PowerPoint 기본 개체로 작성한다.
5. 한 개체 안에 너무 많은 효과를 조합하지 않는다.
[검증 절차]
파일을 저장하기 전에 다음 항목을 검사한다.
1. 텍스트가 텍스트 상자 밖으로 넘치지 않는지 검사한다.
2. 모든 개체가 슬라이드 경계 안에 있는지 검사한다.
3. 개체끼리 의도하지 않게 겹치는지 검사한다.
4. 표의 열 너비 합과 표 전체 너비가 일치하는지 검사한다.
5. 이미지 종횡비가 유지되는지 검사한다.
6. 사용된 모든 폰트가 허용된 폰트 목록에 포함되는지 검사한다.
7. 텍스트 자동 맞춤이 활성화된 개체가 없는지 검사한다.
8. 모든 텍스트 상자의 여백과 문단 간격이 명시되어 있는지 검사한다.
9. 저장한 PPTX 파일을 다시 열어 모든 개체의 좌표와 크기가 저장 전과 동일한지 검사한다.
10. 가능하면 Microsoft PowerPoint에서 파일을 자동으로 열고 다시 저장하여 PowerPoint 렌더링 엔진으로 최종 정규화한다.
11. PowerPoint에서 각 슬라이드를 PNG로 렌더링한 뒤 웹 미리보기 이미지와 비교한다.
12. 차이가 발생한 슬라이드는 웹 미리보기에 맞추지 말고 PowerPoint 출력 결과를 기준으로 수정한다.
[최종 산출물]
1. 최종 PPTX 파일을 제공한다.
2. 동일한 슬라이드의 PNG 미리보기 파일도 제공한다.
3. 웹 미리보기는 자체 HTML 렌더링 결과가 아니라 가능하면 최종 PPTX를 PowerPoint 또는 PowerPoint 호환 렌더러로 렌더링한 이미지로 표시한다.
4. 사용한 슬라이드 크기, 폰트, 색상, 좌표 단위와 자동 맞춤 설정을 함께 보고한다.
5. PowerPoint에서 렌더링 차이가 발생할 수 있는 요소가 있다면 해당 슬라이드와 개체를 명시한다.
이상의 조건은 디자인의 화려함보다 우선한다. 웹 미리보기와 PowerPoint 결과의 동일성을 위해 복잡한 효과는 제거하고, 고정 좌표, 고정 크기, 고정 폰트, 고정 여백을 사용하라.7. 체크포인트
8. 배포 하기
8.1. 배포를 위한 서비스 가입
8.2. github 가입하기
8.2.1. github sign up

8.2.2. google 계정 선택
- AI Studio의 Google 계정과 동일한 계정을 이용합니다.
- 다른 계정도 가능하지만 사용하다 보면 꼬이거나 혼란스러운 경우가 생깁니다.

8.3. vercel 가입하기
8.3.1. vercel sing up
- https://www.vercel.com 접속
- 우측 상단의 “sign up” 클릭

8.3.2. google 계정 선택
- ai stuido 의 google 과 같은 것 선택

8.4. github 배포하기
8.4.1. github 연결하기
- 우측 상단 설정
- github 선택

8.4.2. github commit
- 현재 작업물을 github에 올리는 것을 COMMIT (커밋) 이라 합니다.
- 하단의 “Stage and commit all changes” 클릭하기

8.4.3. github 결과 확인해보기
- github에 다시 접속해서 commit 한 결과가 반영 되었는지 확인합니다

- 주소확인
- 생성한 git 의 주소를 확인합니다
- 주소형식
https://github.com/mintubehan/buchae.git
–>
https://github.com/사용자이름/저장소이름.git형태

8.5. vercel 에 배포하기
8.5.1. import project
- vercel 초기 화면에서
import project선택import project 를 하거나

또는
Add New–>Project

- vercel에 github 도구 설치
- Vercel에 GitHub을 사용할 수 있는 도구를 설치합니다.

Install클릭 하면 자동으로 github에 있던 모든 저장소가 보입니다

- project(만든 앱) 을 가져옵니다
- 자동으로 인식된 저장소 목록에서 해당
앱을Import합니다
- 자동으로 인식된 저장소 목록에서 해당

배포하기
- Vercel에 이 앱 배포의 새로운 이름을 입력하고
Deploy클릭

배포확인하기
성공하면 배포된 미리보기 화면과 주소가 표시됩니다.
buchae.vercel.app처럼 앱이름.vercel.app 형태입니다.- 이제
https://buchae.vercel.app을 주소로 배포할 수 있습니다.
