Skip to content

Integrate Google Generative AI and add AI settings UI#401

Open
devgoodway wants to merge 164 commits into
devfrom
claude/add-chat-settings-menu-BZxkP
Open

Integrate Google Generative AI and add AI settings UI#401
devgoodway wants to merge 164 commits into
devfrom
claude/add-chat-settings-menu-BZxkP

Conversation

@devgoodway

Copy link
Copy Markdown
Collaborator

Added @google/generative-ai dependency and backend API endpoints for AI features. Implemented new AI-related controllers and routes in the backend. Updated frontend to include AI settings tabs and AI generation popups for seasons and courses. Modified models and types to support AI configuration.

devgoodway and others added 30 commits January 29, 2026 07:31
Added @google/generative-ai dependency and backend API endpoints for AI features. Implemented new AI-related controllers and routes in the backend. Updated frontend to include AI settings tabs and AI generation popups for seasons and courses. Modified models and types to support AI configuration.
Implemented endpoints for uploading, downloading, and deleting AI reference files for seasons, including S3 integration and text extraction from PDF, DOCX, TXT, and HWP files. Added new utility for text extraction, updated the Season model to store file metadata, and registered new routes. Updated backend dependencies to include 'mammoth' and 'pdf-parse' for document parsing.
Refactored backend to use Server-Sent Events (SSE) for streaming AI syllabus generation progress and results, including step-by-step updates and error handling. Updated frontend popup to handle SSE events, display progress steps, and show streaming AI output in real time, improving user feedback and interactivity during content generation.
The AI prompt now includes the user's teaching (syllabus creation) history, giving it higher priority over enrollment history for more personalized and relevant syllabus generation. This change fetches up to 10 recent syllabi created by the user and incorporates them into the prompt for improved AI output.
Introduces the ability to select and store a custom AI model for each academy. Backend now saves and returns the selected model, provides an endpoint to list available models, and uses the chosen model for AI operations. Frontend UI allows owners to browse, select, or manually enter a model, and persists the selection with the API key.
Introduces backend and frontend support for setting and saving the AI model per academy. Adds a new API endpoint and controller for updating the AI model, updates the model listing logic to use saved API keys if available, and enhances the AI settings UI to allow owners to save their selected model.
Replaces Google Calendar integration with a new self-hosted calendar event system. Adds backend models, controllers, and routes for calendar events, including support for recurring events and syncing enrollments/mentoring schedules. Updates frontend calendar to fetch, create, and delete events via the new API, and introduces a new event form popup for event creation. Removes legacy calendar fields and endpoints from user and school models/controllers.
Fix a typo in the monthly view directory name by renaming frontend/src/components/calendarV2/view/MonthlyViwer to MonthlyViewer (component and stylesheet). Update the import in Calendar.tsx to use the corrected path. No functional logic changes.
๊ฒŒ์‹œํŒ, ๊ฒŒ์‹œ๊ธ€, ๋Œ“๊ธ€ ๊ธฐ๋Šฅ ์ถ”๊ฐ€:
- Board/Post/Comment ๋ชจ๋ธ, ์ปจํŠธ๋กค๋Ÿฌ, ๋ผ์šฐํŠธ, ์„œ๋น„์Šค
- ๊ฒŒ์‹œํŒ ํŽ˜์ด์ง€ (๋ชฉ๋ก, ์ƒ์„ธ, ์ž‘์„ฑ/์ˆ˜์ •)
- ๋งˆํฌ๋‹ค์šด ์—๋””ํ„ฐ/๋ทฐ์–ด ์ปดํฌ๋„ŒํŠธ
- ๊ถŒํ•œ ๊ธฐ๋ฐ˜ ์ฝ๊ธฐ/์“ฐ๊ธฐ ์„ค์ • ์ง€์›

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
์•Œ๋ฆผ ์‹œ์Šคํ…œ ๊ฐœ์„ :
- ์•Œ๋ฆผ ์„ค์ • ๊ธฐ๋Šฅ ์ถ”๊ฐ€ (์‚ฌ์šฉ์ž๋ณ„ ์ˆ˜์‹  ์„ค์ •)
- ์•Œ๋ฆผ ์ผ๊ด„ ํ™•์ธ API (bulk-check)
- ํœ˜๋ฐœ์„ฑ ์•Œ๋ฆผ ์ง€์› (autoDeleteOnCheck)
- ์Šค์ผ€์ค„๋Ÿฌ ์„œ๋น„์Šค ์ถ”๊ฐ€
- Navbar ์•Œ๋ฆผ UI ๊ฐœ์„ 
- ๊ด€๋ฆฌ์ž ์•Œ๋ฆผ ๊ด€๋ฆฌ ํƒญ ์ถ”๊ฐ€

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
UI ์ปดํฌ๋„ŒํŠธ ๊ฐœ์„ :
- Calendar ์ปดํฌ๋„ŒํŠธ ์ˆ˜์ •
- Table ์ปดํฌ๋„ŒํŠธ ์Šคํƒ€์ผ ๊ฐœ์„ 
- ToggleSwitch ์ปดํฌ๋„ŒํŠธ ์ˆ˜์ •
- SVG ์•„์ด์ฝ˜ ์ถ”๊ฐ€

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
์ˆ˜๊ฐ• ๋ฐ ๊ฐ•์˜๊ณ„ํš์„œ ์ปจํŠธ๋กค๋Ÿฌ ์—…๋ฐ์ดํŠธ:
- enrollments ์ปจํŠธ๋กค๋Ÿฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€
- syllabuses ์ปจํŠธ๋กค๋Ÿฌ ๊ธฐ๋Šฅ ์ถ”๊ฐ€

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
๊ณตํ†ต ํŒŒ์ผ ๋ฐ ์˜์กด์„ฑ ์—…๋ฐ์ดํŠธ:
- Board/Post/Comment API ํ›… ์ถ”๊ฐ€ (useAPIv2.ts)
- ์•Œ๋ฆผ ์„ค์ • API ํ›… ์ถ”๊ฐ€
- ๊ฒŒ์‹œํŒ ๋ผ์šฐํŠธ ๋“ฑ๋ก (RouterPage.tsx)
- ๋ชจ๋ธ ๋ฐ ๋ผ์šฐํŠธ ์ธ๋ฑ์Šค ์—…๋ฐ์ดํŠธ
- ์„ค์ • ํŽ˜์ด์ง€ ํƒญ ์ถ”๊ฐ€
- ์˜์กด์„ฑ ํŒจํ‚ค์ง€ ์—…๋ฐ์ดํŠธ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
yarn์„ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ์ ํŠธ์ด๋ฏ€๋กœ npm lock ํŒŒ์ผ ์ œ์™ธ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ์•Œ๋ฆผ ์„ค์ •๊ณผ ๊ฒŒ์‹œํŒ ๊ด€๋ฆฌ๋ฅผ ํƒญ์œผ๋กœ ๋ถ„๋ฆฌ
- ์•Œ๋ฆผ ์œ ํ˜•์„ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„๋กœ ๊ทธ๋ฃนํ™” (์ผ๋ฐ˜, ์ˆ˜์—…, ์ผ์ • ๋ฐ ๊ฒŒ์‹œ๊ธ€, ๋ฉ”์‹œ์ง€)
- ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์นด๋“œ ์Šคํƒ€์ผ ์ปจํ…Œ์ด๋„ˆ ์ ์šฉ
- ์„ค์ • ํ•ญ๋ชฉ์˜ ์ค‘๋ณต ์„ค๋ช… ์ œ๊ฑฐ
- ๋ฒ„ํŠผ ๋ช…์นญ ์ˆ˜์ • (์•Œ๋ฆผ ์ถ”๊ฐ€ โ†’ ๊ฒŒ์‹œํŒ ์ถ”๊ฐ€)
- ํƒญ๊ณผ ์ฝ˜ํ…์ธ  ๊ฐ„ ์—ฌ๋ฐฑ ์ถ”๊ฐ€

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ์•Œ๋ฆผ ์„ค์ •๊ณผ ๊ฒŒ์‹œํŒ ๊ด€๋ฆฌ๋ฅผ ํƒญ์œผ๋กœ ๋ถ„๋ฆฌ
- ์•Œ๋ฆผ ์œ ํ˜•์„ ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„๋กœ ๊ทธ๋ฃนํ™” (์ผ๋ฐ˜, ์ˆ˜์—…, ์ผ์ • ๋ฐ ๊ฒŒ์‹œ๊ธ€, ๋ฉ”์‹œ์ง€)
- ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์นด๋“œ ์Šคํƒ€์ผ ์ปจํ…Œ์ด๋„ˆ ์ ์šฉ
- ์„ค์ • ํ•ญ๋ชฉ์˜ ์ค‘๋ณต ์„ค๋ช… ์ œ๊ฑฐ
- ๋ฒ„ํŠผ ๋ช…์นญ ์ˆ˜์ • (์•Œ๋ฆผ ์ถ”๊ฐ€ โ†’ ๊ฒŒ์‹œํŒ ์ถ”๊ฐ€)
- ํƒญ๊ณผ ์ฝ˜ํ…์ธ  ๊ฐ„ ์—ฌ๋ฐฑ ์ถ”๊ฐ€
- ๊ฒŒ์‹œํŒ ํƒญ ์Šคํฌ๋กค๋ฐ” ์ˆจ๊น€ ์ฒ˜๋ฆฌ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ์•Œ๋ฆผ ํŒ์—…์˜ '์ „์ฒด ์•Œ๋ฆผ ๋ณด๊ธฐ' โ†’ '๊ฒŒ์‹œํŒ ๋ณด๊ธฐ'
- ๊ฒŒ์‹œํŒ ํŽ˜์ด์ง€ ์ œ๋ชฉ '์•Œ๋ฆผ' โ†’ '๊ฒŒ์‹œํŒ'
- ๊ฒŒ์‹œํŒ ์ƒ์„ฑ ํŒ์—…์˜ ๋ชจ๋“  '์•Œ๋ฆผ' ๋ฌธ๊ตฌ๋ฅผ '๊ฒŒ์‹œํŒ'์œผ๋กœ ์ˆ˜์ •

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ์•Œ๋ฆผ์ด ๋งŽ์„ ๋•Œ ์Šคํฌ๋กค์ด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋ฒ—์–ด๋‚˜๋Š” ๋ฌธ์ œ ์ˆ˜์ • (flex ๋ ˆ์ด์•„์›ƒ ์ ์šฉ, max-height ๋ทฐํฌํŠธ ๊ธฐ๋ฐ˜ ์ œํ•œ)
- ๊ฐ ์•Œ๋ฆผ ํ•ญ๋ชฉ์— ์‹œ๊ฐ„ ํ‘œ์‹œ ์ถ”๊ฐ€ (๋ฐฉ๊ธˆ, N๋ถ„ ์ „, N์‹œ๊ฐ„ ์ „, N์ผ ์ „, M/D)
- ์นด๋“œ ํ˜•์‹์„ ๊ตฌ๋ถ„์„  ํ˜•์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜์—ฌ ๊ฐ„๊ฒฐํ•˜๊ฒŒ ํ‘œ์‹œ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ์ˆ˜๊ฐ• ์ทจ์†Œ ์‹œ ๊ด€๋ จ ์บ˜๋ฆฐ๋” ์ด๋ฒคํŠธ๋„ ํ•จ๊ป˜ ์‚ญ์ œ๋˜๋„๋ก ์ฒ˜๋ฆฌ
- ์บ˜๋ฆฐ๋” ๋™๊ธฐํ™” ์‹œ ๋” ์ด์ƒ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ์ˆ˜๊ฐ•/๋ฉ˜ํ† ๋ง์˜ ๊ณ ์•„ ์ด๋ฒคํŠธ ์ •๋ฆฌ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- useEditorStore(Zustand + immer) ์‹ ๊ทœ ์ƒ์„ฑ: ๋ธ”๋ก CRUD, ์…€ ์„ ํƒ, Undo/Redo ๋“ฑ ์ „์ฒด ์ƒํƒœ ๊ด€๋ฆฌ ํ†ตํ•ฉ
- EditorBlock, CellData ๋“ฑ ํƒ€์ž… ์ •์˜ ํŒŒ์ผ(types/index.ts) ๋ถ„๋ฆฌ
- 1300์ค„ ์ด์ƒ์˜ ๋ชจ๋†€๋ฆฌ์‹ Sidebar ์ปดํฌ๋„ŒํŠธ๋ฅผ ๊ฐœ๋ณ„ ํŒจ๋„๋กœ ๋ถ„๋ฆฌ
  (BlockPanel, CellTypePanel, ImagePanel, InputPanel, ParagraphPanel, TableCellPanel)
- InlineToolbar ์ถ”๊ฐ€: ์„ ํƒ๋œ ๋ธ”๋ก ์˜†์— ์ด๋™/๋ณต์ œ/์‚ญ์ œ ๋ฒ„ํŠผ ํ‘œ์‹œ
- ImageBlock ์ถ”๊ฐ€: ์ด๋ฏธ์ง€ ์—…๋กœ๋“œ(Base64) ๋ฐ ์บก์…˜/์ •๋ ฌ ์ง€์›
- ๋ธ”๋ก ๋“œ๋ž˜๊ทธ ์•ค ๋“œ๋กญ ์žฌ์ •๋ ฌ ๊ธฐ๋Šฅ (drag handle UI)
- ํ‚ค๋ณด๋“œ ๋‹จ์ถ•ํ‚ค ์ง€์› (Ctrl+Z ์‹คํ–‰์ทจ์†Œ, Ctrl+Shift+Z ๋‹ค์‹œ์‹คํ–‰, Ctrl+S ์ €์žฅ, Ctrl+\ ์‚ฌ์ด๋“œ๋ฐ”)
- Menu ์ปดํฌ๋„ŒํŠธ์— ์ ‘๊ธฐ/ํŽผ์น˜๊ธฐ ํ† ๊ธ€ ์ถ”๊ฐ€
- useEditorCompat ํ˜ธํ™˜์„ฑ ๋ ˆ์ด์–ด๋กœ ๋ ˆ๊ฑฐ์‹œ editorContext ์‚ฌ์šฉ ์ฝ”๋“œ ์ ์ง„์  ์ „ํ™˜
- ๊ฐ Block/Cell ์ปดํฌ๋„ŒํŠธ๋ฅผ React.memo๋กœ ๊ฐ์‹ธ ๋ถˆํ•„์š”ํ•œ ๋ฆฌ๋ Œ๋”๋ง ๋ฐฉ์ง€

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ์นดํ…Œ๊ณ ๋ฆฌ๋ณ„ ์ผ์ • ํ‘œ์‹œ/์ˆจ๊น€ ํ•„ํ„ฐ๋ง (์ˆ˜๊ฐ•์ˆ˜์—…, ๋‹ด๋‹น์ˆ˜์—…, ๋ฉ”๋ชจ, ํ•™๊ต, ๊ฐœ์ธ)
- CalendarTab ์‹ ๊ทœ: SettingPopup์—์„œ ์‚ฌ์šฉ์ž ์บ˜๋ฆฐ๋” ์ƒ์„ฑ/์ˆ˜์ •/์‚ญ์ œ ๊ด€๋ฆฌ
- ColorPicker ๊ณตํ†ต ์ปดํฌ๋„ŒํŠธ ๊ฐœ๋ฐœ: ํ”„๋ฆฌ์…‹ ์ƒ‰์ƒ + HEX ์ง์ ‘ ์ž…๋ ฅ + ๋„ค์ดํ‹ฐ๋ธŒ ํ”ผ์ปค
- EventFormPopup ๊ฐœ์„ :
  - ์บ˜๋ฆฐ๋” ์„ ํƒ ๋“œ๋กญ๋‹ค์šด (๊ฐœ์ธ/ํ•™๊ต/์‚ฌ์šฉ์ž ์บ˜๋ฆฐ๋”)
  - ์ฃผ๊ฐ„ ๋ฐ˜๋ณต ์‹œ ์š”์ผ ๋‹ค์ค‘ ์„ ํƒ๊ธฐ (์ผ~ํ† )
  - ๋ฐ˜๋ณต ์ข…๋ฃŒ์ผ ํ•™๊ธฐ ์ข…๋ฃŒ์ผ ์ž๋™ ์„ค์ •
  - ์ˆ˜์ • ๋ชจ๋“œ ์ง€์› (create/edit)
- EventPopup: ์ˆ˜์ •/์‚ญ์ œ ๋ฒ„ํŠผ ์ถ”๊ฐ€, ๋ฐ˜๋ณต ์ผ์ • ์›๋ณธ ์ด๋ฒคํŠธ ๊ธฐ๋ฐ˜ ํŽธ์ง‘
- ์ฃผ๊ฐ„ ๋ทฐ ํ—ค๋”์— N์ฃผ์ฐจ ํ‘œ์‹œ, ํ•™๊ธฐ๋ช…/๊ธฐ๊ฐ„ ์ •๋ณด ์„œ๋ธŒํƒ€์ดํ‹€ ํ‘œ์‹œ
- computeSpanningEvents() ์œ ํ‹ธ๋ฆฌํ‹ฐ: ๋‹ค์ผ ์ผ์ • ๋ ˆ์ธ ๊ธฐ๋ฐ˜ ๋ ˆ์ด์•„์›ƒ ๊ณ„์‚ฐ
- mergeConsecutiveRecurrenceInstances(): ์—ฐ์† ๋ฐ˜๋ณต ์ธ์Šคํ„ด์Šค ๋ณ‘ํ•ฉ
- resolveEventColor(): sourceType๋ณ„ ๊ธฐ๋ณธ ์ƒ‰์ƒ ํ•ด์„
- ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์บ˜๋ฆฐ๋” ์กฐํšŒ ์ง€์› (userId prop, ScheduleTab ์—ฐ๋™)
- ์›”๊ฐ„/์ฃผ๊ฐ„/์ผ๊ฐ„ ๋ทฐ์— ๋นˆ ์˜์—ญ ํด๋ฆญ ์‹œ ํ•ด๋‹น ๋‚ ์งœ/์‹œ๊ฐ„์œผ๋กœ ์ผ์ • ์ƒ์„ฑ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## ์‚ฌ์šฉ์ž ์บ˜๋ฆฐ๋” (UserCalendar)
- UserCalendar ๋ชจ๋ธ ์‹ ๊ทœ: ์‚ฌ์šฉ์ž๋ณ„ ์บ˜๋ฆฐ๋” ๊ทธ๋ฃน (๊ฐœ์ธ/ํ•™๊ต scope, ์ƒ‰์ƒ, ๊ธฐ๋ณธ ์บ˜๋ฆฐ๋”)
- CRUD ์ปจํŠธ๋กค๋Ÿฌ ๋ฐ ๋ผ์šฐํ„ฐ ์ถ”๊ฐ€ (์ƒ์„ฑ/์กฐํšŒ/์ˆ˜์ •/์‚ญ์ œ)
- ๊ธฐ๋ณธ ์บ˜๋ฆฐ๋” ์‚ญ์ œ ๋ฐฉ์ง€, ํ•™๊ต ์บ˜๋ฆฐ๋”๋Š” admin/manager๋งŒ ์ƒ์„ฑ ๊ฐ€๋Šฅ

## CalendarEvent ๊ฐœ์„ 
- calendarId ํ•„๋“œ ์ถ”๊ฐ€: ์ด๋ฒคํŠธ๋ฅผ ํŠน์ • ์‚ฌ์šฉ์ž ์บ˜๋ฆฐ๋”์— ์—ฐ๊ฒฐ
- ์ฃผ๊ฐ„ ๋ฐ˜๋ณต์— ์š”์ผ(days) ๋ฐฐ์—ด ์ง€์›: ํŠน์ • ์š”์ผ๋งŒ ๋ฐ˜๋ณต
- ์ด๋ฒคํŠธ ์กฐํšŒ ์‹œ user ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž์˜ ์ผ์ • ์กฐํšŒ ์ง€์›

## ๋™๊ธฐํ™”(syncEnrollments) ๊ฐœ์„ 
- targetUser ํŒŒ๋ผ๋ฏธํ„ฐ: admin/teacher/manager๊ฐ€ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž ์ผ์ • ๋™๊ธฐํ™” ๊ฐ€๋Šฅ
- ๋ฉ”๋ชจ(memo) ๋™๊ธฐํ™” ์ถ”๊ฐ€: registration.memos๋ฅผ ์บ˜๋ฆฐ๋” ์ด๋ฒคํŠธ๋กœ ์ƒ์„ฑ
- upsert ๋กœ์ง ๊ฐœ์„ : ๊ธฐ์กด findOne โ†’ updateOne($set/$setOnInsert)์œผ๋กœ ๋ณ€๊ฒฝ
- ๋ฉ”๋ชจ๋Š” $setOnInsert๋กœ ์‚ฌ์šฉ์ž ์ˆ˜์ • ๋‚ด์—ญ ๋ณด์กด
- ๋™๊ธฐํ™” ์‹œ ์ค‘๋ณต ์ด๋ฒคํŠธ ์ž๋™ ์ •๋ฆฌ (processedSourceIds ๊ธฐ๋ฐ˜)
- ๊ณ ์•„ ์ด๋ฒคํŠธ ์ •๋ฆฌ ๋Œ€์ƒ์— memo sourceType ํฌํ•จ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- canUserSeePost() ํ•จ์ˆ˜ ์ถ”๊ฐ€: targetAudience ํƒ€์ž…๋ณ„ ์ ‘๊ทผ ๊ถŒํ•œ ํŒ๋‹จ
  (all: ์ „์ฒด ๊ณต๊ฐœ, custom: ํŠน์ • ์‚ฌ์šฉ์ž, teacher/student/manager: ์—ญํ• ๋ณ„)
- ๊ฒŒ์‹œ๊ธ€ ๋‹จ๊ฑด ์กฐํšŒ ์‹œ targetAudience ๊ธฐ๋ฐ˜ 403 ์‘๋‹ต ์ฒ˜๋ฆฌ
- ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก ์กฐํšŒ ์‹œ targetAudience ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง ์ ์šฉ
- ๋ ˆ๊ฑฐ์‹œ ์•Œ๋ฆผ(Notification) โ†’ ๊ฒŒ์‹œ๊ธ€ ๋ณ€ํ™˜ ์‹œ ์ž‘์„ฑ์ž์˜ ๊ฒŒ์‹œํŒ ์“ฐ๊ธฐ ๊ถŒํ•œ ๊ฒ€์ฆ
  (๊ถŒํ•œ ์—†๋Š” ์‚ฌ์šฉ์ž๊ฐ€ ์ž‘์„ฑํ•œ ์•Œ๋ฆผ ์ œ์™ธ)
- ๋ ˆ๊ฑฐ์‹œ ์•Œ๋ฆผ์—๋„ targetAudience ํ•„ํ„ฐ๋ง ์ ์šฉ
- admin๊ณผ ์ž‘์„ฑ์ž ๋ณธ์ธ์€ ํ•ญ์ƒ ์ ‘๊ทผ ๊ฐ€๋Šฅ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## ๋ฐฑ์—”๋“œ
- findByRegistration: ํ•™์ƒ viewAndEdit ๊ถŒํ•œ ์‹œ ์•„์นด์ด๋ธŒ ์ ‘๊ทผ ํ—ˆ์šฉ
- ํ•™์ƒ ๋ณธ์ธ ๋ฐ์ดํ„ฐ ์กฐํšŒ ์‹œ ๊ต์‚ฌ ๋“ฑ๋ก ํ™•์ธ ๊ฑด๋„ˆ๋›ฐ๊ธฐ (isOwnData ์ฒดํฌ)
- updateByRegistration: ํ•™์ƒ ์ž๊ธฐํŽธ์ง‘ ๊ถŒํ•œ ๊ฒ€์ฆ ๋กœ์ง ์ถ”๊ฐ€
  (formArchiveItem.authStudent === "viewAndEdit" && ๋ณธ์ธ ๋ฐ์ดํ„ฐ์ธ ๊ฒฝ์šฐ ์ˆ˜์ • ํ—ˆ์šฉ)

## ํ”„๋ก ํŠธ์—”๋“œ
- Pid.tsx: authStudent "viewAndEdit" ๊ถŒํ•œ ์ฒ˜๋ฆฌ ๋ฐ editable prop ์ „๋‹ฌ
- ArrayView: editable ๋ชจ๋“œ์—์„œ ์…€ ์ง์ ‘ ํŽธ์ง‘ ๊ฐ€๋Šฅ (select, input-number, text)
  - ์ œ์ถœ ๋ฒ„ํŠผ ๋ฐ Progress ํŒ์—…์œผ๋กœ ์ €์žฅ ์ƒํƒœ ํ‘œ์‹œ
  - ํ–‰ ์ˆ˜์ •(rowEdit) ๊ธฐ๋Šฅ ์ถ”๊ฐ€
- ObjectView: editable ๋ชจ๋“œ์—์„œ ํ•„๋“œ ์ง์ ‘ ํŽธ์ง‘ ๋ฐ ์ €์žฅ ๊ธฐ๋Šฅ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## ๋ฐฑ์—”๋“œ
- copyRecurringEvents ์˜ต์…˜: ๊ธฐ์กด ํ•™๊ธฐ์˜ ๋ฐ˜๋ณต ์ผ์ •์„ ์ƒˆ ํ•™๊ธฐ๋กœ ๋ณต์‚ฌ
- adjustRecurringEventDates() ํ•จ์ˆ˜: ๋ฐ˜๋ณต ์œ ํ˜•(weekly/daily/monthly)๋ณ„๋กœ
  ์ƒˆ ํ•™๊ธฐ ๊ธฐ๊ฐ„์— ๋งž๊ฒŒ ์‹œ์ž‘์ผ/์ข…๋ฃŒ์ผ/๋ฐ˜๋ณต ์ข…๋ฃŒ์ผ ์ž๋™ ์กฐ์ •
- ํ•™๊ต(school scope) ๋ฐ˜๋ณต ์ผ์ •๊ณผ ๊ฐœ์ธ(personal scope) ๋ฐ˜๋ณต ์ผ์ • ๋ชจ๋‘ ๋ณต์‚ฌ
- ์ˆ˜๋™(manual) ์ƒ์„ฑ ์ด๋ฒคํŠธ๋งŒ ๋ณต์‚ฌ ๋Œ€์ƒ (๋™๊ธฐํ™” ์ด๋ฒคํŠธ ์ œ์™ธ)

## ํ”„๋ก ํŠธ์—”๋“œ
- AddPopup์— '๋ฐ˜๋ณต ์ผ์ •๋„ ๋ณต์‚ฌ' ์ฒดํฌ๋ฐ•์Šค ์ถ”๊ฐ€
- ๋ณต์‚ฌํ•  ํ•™๊ธฐ ์„ ํƒ ์‹œ์—๋งŒ ์ฒดํฌ๋ฐ•์Šค ํ‘œ์‹œ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## useAPIv2 ํ™•์žฅ
- UserCalendar API (CUserCalendar, RUserCalendars, UUserCalendar, DUserCalendar)
- Form ๊ถŒํ•œ API (UFormPermission, CFormPermissionException, DFormPermissionException)
- CalendarEvent API: calendarId, recurrence.days, user ์ฟผ๋ฆฌ ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€
- SyncCalendarEvents: targetUser ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€
- CSeason: copyRecurringEvents ํŒŒ๋ผ๋ฏธํ„ฐ ์ถ”๊ฐ€

## ์‚ฌ์ด๋“œ๋ฐ”
- '๋ฌธ์„œ' ๋ฉ”๋‰ด๋ฅผ ๊ต์‚ฌ ์ „์šฉ์—์„œ ํ•™์ƒ ํฌํ•จ ์ „์ฒด ์—ญํ• ๋กœ ์ด๋™

## ๊ธฐํƒ€
- SVG ์•„์ด์ฝ˜ ์ถ”๊ฐ€ (chevronUp, chevronDown ๋“ฑ)
- button.module.scss ์Šคํƒ€์ผ ๋ฏธ์„ธ ์กฐ์ •
- School ๋ชจ๋ธ ํƒ€์ž… ์ˆ˜์ •
- files ์ปจํŠธ๋กค๋Ÿฌ ๋ถˆํ•„์š” ์ฝ”๋“œ ์ œ๊ฑฐ

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
## ๋ฐฑ์—”๋“œ
- Form ๋ชจ๋ธ์— permissionView ํ•„๋“œ ์ถ”๊ฐ€
  (teacher/student ์—ญํ• ๋ณ„ ํ—ˆ์šฉ + ์‚ฌ์šฉ์ž๋ณ„ ์˜ˆ์™ธ ๋ชฉ๋ก)
- hasFormViewPermission(): ์—ญํ• /์˜ˆ์™ธ ๊ธฐ๋ฐ˜ ์–‘์‹ ์—ด๋žŒ ๊ถŒํ•œ ํŒ๋‹จ ํ•จ์ˆ˜
- RForm ๋‹จ๊ฑด ์กฐํšŒ ์‹œ ๊ถŒํ•œ ๊ฒ€์ฆ ์ถ”๊ฐ€ (admin/manager ์ œ์™ธ)
- RForms ๋ชฉ๋ก ์กฐํšŒ ์‹œ ๊ถŒํ•œ ๊ธฐ๋ฐ˜ ํ•„ํ„ฐ๋ง ์ ์šฉ
- updatePermission API: ๊ต์‚ฌ/ํ•™์ƒ ๊ธฐ๋ณธ ๊ถŒํ•œ ์ˆ˜์ • (PUT /forms/:_id/permission)
- addPermissionException API: ํŠน์ • ์‚ฌ์šฉ์ž ์˜ˆ์™ธ ์ถ”๊ฐ€ (POST /forms/:_id/permission/exceptions)
- removePermissionException API: ํŠน์ • ์‚ฌ์šฉ์ž ์˜ˆ์™ธ ์‚ญ์ œ (DELETE /forms/:_id/permission/exceptions)

## ํ”„๋ก ํŠธ์—”๋“œ
- FormPermissionPopup ์‹ ๊ทœ: ์–‘์‹๋ณ„ ์—ด๋žŒ ๊ถŒํ•œ ๊ด€๋ฆฌ ํŒ์—…
  - ๊ต์‚ฌ/ํ•™์ƒ ์—ญํ•  ํ† ๊ธ€ ๋ฒ„ํŠผ
  - ์‚ฌ์šฉ์ž ๊ฒ€์ƒ‰(Autofill)์œผ๋กœ ์˜ˆ์™ธ ์ถ”๊ฐ€ (ํ—ˆ์šฉ/์ฐจ๋‹จ)
  - ์˜ˆ์™ธ ๋ชฉ๋ก ํ‘œ์‹œ ๋ฐ ์‚ญ์ œ
- admin/forms ํŽ˜์ด์ง€: ์ถœ๋ ฅ ์–‘์‹์— '๊ถŒํ•œ ์„ค์ •' ๋ฉ”๋‰ด ๋ฐ ํ…Œ์ด๋ธ” '๊ถŒํ•œ' ๋ฒ„ํŠผ ์ถ”๊ฐ€

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- ํ•™์ƒ ์—ญํ•  ์ง€์›: ํ•™์ƒ ๋กœ๊ทธ์ธ ์‹œ ๋ณธ์ธ ๋ฐ์ดํ„ฐ ์ž๋™ ๋กœ๋“œ (ํ•™์ƒ ์„ ํƒ UI ์ˆจ๊น€)
- ํ•™์ƒ์€ view ๊ถŒํ•œ์œผ๋กœ ๋ฌธ์„œ ์—ด๋žŒ (ํŽธ์ง‘ ๋ถˆ๊ฐ€)
- DocFormSelector ํŒ์—… ์‹ ๊ทœ: ํ‘œ์‹œํ•  ๋ฌธ์„œ ์„ ํƒ/ํ•ด์ œ ๊ด€๋ฆฌ
  - ์ „์ฒด ์„ ํƒ/ํ•ด์ œ, ๊ฒ€์ƒ‰ ๊ธฐ๋Šฅ
  - ์„ ํƒ ์ƒํƒœ localStorage ์ €์žฅ (ํ•™๊ต๋ณ„)
- ๋ฌธ์„œ ์„ ํƒ ๋“œ๋กญ๋‹ค์šด์— ์„ ํƒ๋œ ๋ฌธ์„œ๋งŒ ํ‘œ์‹œ
- ์กฐํšŒ ๊ฐ€๋Šฅํ•œ ๋ฌธ์„œ๊ฐ€ ์—†์„ ๋•Œ ์•ˆ๋‚ด ๋ฉ”์‹œ์ง€ ํ‘œ์‹œ
- ์•„์นด์ด๋ธŒ/์ˆ˜๊ฐ• ํ‰๊ฐ€ ์กฐํšŒ ์‹œ ์—๋Ÿฌ ํ•ธ๋“ค๋ง ๊ฐœ์„  (๋นˆ ๋ฐ์ดํ„ฐ fallback)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
devgoodway and others added 29 commits February 24, 2026 00:34
- AltDocsView: ๊ฒŒ์‹œ๊ธ€ ๋ชฉ๋ก(ํ…Œ์ด๋ธ”), ๊ธ€์“ฐ๊ธฐ/์ˆ˜์ •/์‚ญ์ œ ๊ธฐ๋Šฅ
- AltBoardView: ๋ฌธ์„œ ํƒญ ํ”Œ๋ ˆ์ด์Šคํ™€๋”๋ฅผ AltDocsView๋กœ ๊ต์ฒด

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Alt Board(boardMode === "alt")๋Š” ์ž์ฒด ์–‘์‹ ์‹œ์Šคํ…œ์„ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ
PostCreate ํŽ˜์ด์ง€์—์„œ ์„ค๋ฌธยท์˜ˆ์•ฝ ์ฒจ๋ถ€ ์นด๋“œ๋ฅผ ์กฐ๊ฑด๋ถ€๋กœ ์ˆจ๊น€ ์ฒ˜๋ฆฌ

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ์˜ˆ์•ฝ(Reservation) ์‹œ์Šคํ…œ ์ „์ฒด ์ œ๊ฑฐ (๋ชจ๋ธ, ์ปจํŠธ๋กค๋Ÿฌ, ๋ผ์šฐํŠธ, ํ”„๋ก ํŠธ์—”๋“œ)
- AltFormBuilder Google Forms ์Šคํƒ€์ผ ๋ฆฌ๋””์ž์ธ (์นด๋“œ ๊ธฐ๋ฐ˜ UI, ์ถ•์†Œ/ํ™•์žฅ, ํ”Œ๋กœํŒ… ํˆด๋ฐ”)
- AltFormRenderer ์ „๋ฉด ๊ฐœ์„  (16๊ฐœ ํ•„๋“œ ํƒ€์ž…, ์กฐ๊ฑด๋ถ€ ํ‘œ์‹œ, ์œ ํšจ์„ฑ ๊ฒ€์ฆ)
- AltSheetView ๊ธฐ๋Šฅ ํ™•์žฅ (ํ•„ํ„ฐ, ์ •๋ ฌ, ํŽ˜์ด์ง€๋„ค์ด์…˜, CSV ๋‚ด๋ณด๋‚ด๊ธฐ, ์ผ๊ด„ ํŽธ์ง‘)
- MergeEngine v2: ์กฐ๊ฑด๋ถ€ ๋ธ”๋ก, ํ•„ํ„ฐ/์ •๋ ฌ, ์ง‘๊ณ„ ํ•จ์ˆ˜, ๊ทธ๋ฃนํ•‘, ๋‚ ์งœ/์ˆซ์ž ํฌ๋งท
- ์ œ์ถœ ์ถ”์ (AltSubmissionTracker), ์ผ๊ด„ ์ธ์‡„(BatchPrintView), ์กฐํ•ฉ ์ƒ์„ฑ(CombinationGenerator) ์ถ”๊ฐ€
- ๊ฒŒ์‹œ๊ธ€ ๋จธ์ง€ ํ•„ํ„ฐ, _rawContent ์›๋ณธ ๋ณด์กด, MD ํŒŒ์ผ ๋‹ค์šด๋กœ๋“œ/์—…๋กœ๋“œ
- ๋งˆํฌ๋‹ค์šด ์—๋””ํ„ฐ toolbarExtra ํ™•์žฅ, ํ…œํ”Œ๋ฆฟ ๊ฐ€์ด๋“œ ๋ชจ๋‹ฌ

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ํ•™๊ต ๊ด€๋ฆฌ์ž๊ฐ€ ํ•™๊ต ์ „์ฒด ๋˜๋Š” ๊ฐœ๋ณ„ ๋ณด๋“œ ๋‹จ์œ„๋กœ ์•Œ๋ฆผ ์ด๋ฒคํŠธ๋ฅผ
ํ™œ์„ฑํ™”/๋น„ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ (๊ธฐ๋ณธ๊ฐ’: ๋น„ํ™œ์„ฑํ™”)
- School ๋ชจ๋ธ์— boardNotificationEvents ์ถ”๊ฐ€
- Board ๋ชจ๋ธ์— notificationEvents ์ถ”๊ฐ€
- isBoardNotificationEnabled 2๋‹จ๊ณ„ ์ฒดํฌ (ํ•™๊ตโ†’๋ณด๋“œ)
- 4๊ฐœ ์ปจํŠธ๋กค๋Ÿฌ์— ์•Œ๋ฆผ ๋ฐœ์†ก ์ „ ์ฒดํฌ ๋กœ์ง ์‚ฝ์ž…
- ํ•™๊ต ๊ด€๋ฆฌ ๋ณด๋“œ ํƒญ + ๋ณด๋“œ ๊ด€๋ฆฌ ํŒ์—…์— ToggleSwitch UI ์ถ”๊ฐ€
- ๊ณต์ง€์‚ฌํ•ญ ๋“ฑ role ์—†๋Š” ๋ณด๋“œ ์ง„์ž… ์‹œ alt-forms 403 โ†’ ๋นˆ ๋ฐฐ์—ด ๋ฐ˜ํ™˜

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ์•Œ๋ฆผ ๋“œ๋กญ๋‹ค์šด์—์„œ non-navigable ์•Œ๋ฆผ ํด๋ฆญ ์‹œ description ์ธ๋ผ์ธ ํ™•์žฅ
- navigable ์•Œ๋ฆผ(๊ฒŒ์‹œ๊ธ€, ์ˆ˜์—… ๋“ฑ)์€ ๊ธฐ์กด ํŽ˜์ด์ง€ ์ด๋™ ๋™์ž‘ ์œ ์ง€
- isLegacyNotification ๊ด€๋ จ ํ”„๋ก ํŠธ์—”๋“œ ์ฐธ์กฐ ๋ชจ๋‘ ์ œ๊ฑฐ
- TNotificationType, TRelatedEntity ํƒ€์ž… ๋ฐฑ์—”๋“œ ๋ชจ๋ธ๊ณผ ์ผ์น˜ํ•˜๋„๋ก ์—…๋ฐ์ดํŠธ

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- altForms: manager ์ž๋™ admin ๊ถŒํ•œ ์ œ๊ฑฐ
- mergeEngine: ๋ณตํ•ฉ ๊ฐ’(userSelect, approval ๋“ฑ) ๋ฌธ์ž์—ด ๋ณ€ํ™˜ ํ•จ์ˆ˜ ์ถ”๊ฐ€
- AltFormList: ์‘๋‹ตํ•˜๊ธฐ ๋ฒ„ํŠผ ์ถ”๊ฐ€
- AltFormRenderer: ๋‹ค์ค‘ ์‘๋‹ต ์‹œ ๋นˆ ํผ ์œ ์ง€, ์š”์ผ๋ณ„ ์ผ๊ด„ ๋‚ ์งœ ์„ ํƒ, ์Šน์ธ์ž๋ฅผ ๋ณด๋“œ ์ž‘์„ฑ์ž์—์„œ ์„ ํƒ
- AltSheetView: ๋ณตํ•ฉ ํƒ€์ž… ํ•„๋“œ ์ธ๋ผ์ธ ํŽธ์ง‘ ์ฐจ๋‹จ, ๋ณธ์ธ ์‘๋‹ต ์‚ญ์ œ ํ—ˆ์šฉ

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
์•„์นด๋ฐ๋ฏธ(owner) ์ˆ˜์ค€๊ณผ ํ•™๊ต(admin) ์ˆ˜์ค€์˜ 2๋‹จ๊ณ„ ๊ธฐ๋Šฅ ํ™œ์„ฑํ™” ์ฒด๊ณ„๋ฅผ ๊ตฌํ˜„.
๋ณด๋“œ ํ™œ์„ฑํ™”๋ฅผ owner ํŽ˜์ด์ง€์— ์ถ”๊ฐ€ํ•˜๊ณ , ํ•™๊ต ๊ด€๋ฆฌ์—์„œ ๊ฐ ๊ธฐ๋Šฅ ํƒญ ๋‚ด๋ถ€์—
ํ•™๊ต ๋‹จ์œ„ ํ† ๊ธ€์„ ๋ฐฐ์น˜ํ•˜์—ฌ ๋น„ํ™œ์„ฑํ™” ์‹œ UI ๋ฐ API ์ ‘๊ทผ์„ ์ฐจ๋‹จ.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
์–‘์‹(?form=id)๊ณผ ๊ธฐ๋ก(?sheet=id) URL ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ง์ ‘ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•˜๋„๋ก ๊ตฌํ˜„ํ•˜๊ณ ,
์–‘์‹ยท๊ธฐ๋ก ํ™”๋ฉด์— ๋งํฌ ๋ณต์‚ฌ ๋ฒ„ํŠผ ์ถ”๊ฐ€

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Tab ํ•ด์‹œ ๋„ค๋น„๊ฒŒ์ด์…˜ ์‹œ URL search params ์œ ์‹ค ์ˆ˜์ •
- ?form=id&mode=respond/edit ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ๋นŒ๋”/๋ Œ๋”๋Ÿฌ ๋ช…ํ™•ํžˆ ๊ตฌ๋ถ„
- ์Šน์ธ์ž ๋“œ๋กญ๋‹ค์šด ๊ฒ€์ƒ‰์–ด ์ž…๋ ฅ ์‹œ์—๋งŒ ํ‘œ์‹œ๋˜๋„๋ก ๋ณ€๊ฒฝ

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ๋ณด๋“œ ์ „์šฉ ์ฑ„ํŒ… ์‹œ์Šคํ…œ (BoardChatTab, boardChats ์ปจํŠธ๋กค๋Ÿฌ/์„œ๋น„์Šค)
- ๋ฉค๋ฒ„ ์‚ฌ์ด๋“œ๋ฐ” + ์ธ๋ผ์ธ DM ๋Œ€ํ™” (BoardDMPanel)
- AI ์ฑ—๋ด‡ Alter ํ†ตํ•ฉ (AIChatPanel, AIChatSession/Message ๋ชจ๋ธ)
- ๊ต์‚ฌ: Alter ์ง์ ‘ ๋Œ€ํ™” + DM์—์„œ ํ•™์ƒ AI ๋Œ€ํ™” ์—ด๋žŒ
- ํƒญ ๋ฏธ์ฝ์Œ ๋ฑƒ์ง€, ํด๋ฆฝ๋ณด๋“œ ์ด๋ฏธ์ง€ ๋ถ™์—ฌ๋„ฃ๊ธฐ
- ์ˆ˜์—… ๋ฉ˜ํ† ๋ง ํŽ˜์ด์ง€์— ๋ณด๋“œ ์ž„๋ฒ ๋””๋“œ ๋ Œ๋”๋ง

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- INDEX.md: ๋ณด๋“œ/์ฑ„ํŒ…/์„ค์ • ์„ค๋ช… ๊ฐฑ์‹ , Alt Form APIยทAI API ์ถ”๊ฐ€
- api-reference/overview.md: ์‹ ๊ทœ API ๋ฆฌ์†Œ์Šค 4๊ฐœ ์ถ”๊ฐ€
- api-reference/data-models.md: ์‹ ๊ทœ ๋ชจ๋ธ 9๊ฐœ ์ถ”๊ฐ€ (AltForm, AltSheet, AltSheetRow, AIChatSession, AIChatMessage, AIUsageLog, BoardFavorite, SurveyResponse, RequestStat) + ๊ด€๊ณ„๋„ ์—…๋ฐ์ดํŠธ
- architecture/overview.md: Alt Board, AI ํ†ตํ•ฉ, ๊ธฐ๋Šฅ ํ™œ์„ฑํ™” ์‹œ์Šคํ…œ ์„น์…˜ ์ถ”๊ฐ€
- developer-guide/project-structure.md: ์ปจํŠธ๋กค๋Ÿฌ/๋ผ์šฐํŠธ/๋ชจ๋ธ/์„œ๋น„์Šค ์ˆ˜ ๊ฐฑ์‹ 
- user-guide/boards.md: Alt Board ๊ฐ€์ด๋“œ ์ „๋ฉด ์žฌ์ž‘์„ฑ
- user-guide/chat.md: DM/๊ทธ๋ฃน/๋ณด๋“œ/AI ์ฑ„ํŒ… ๊ฐ€์ด๋“œ ์ „๋ฉด ์žฌ์ž‘์„ฑ
- user-guide/settings.md: ๊ธฐ๋Šฅ ํ™œ์„ฑํ™”(๊ด€๋ฆฌ์ž) ์„น์…˜ ์ถ”๊ฐ€
- CONTRIBUTING.md: Node.js 20 LTS ๋ฐ˜์˜

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace frontend/public/favicon.ico with an updated icon asset. No code changes; this updates the app's favicon displayed in browsers.
Change the PWA web manifest 'short_name' and 'name' from "Altsis" to "Altsis Next" to reflect the updated app branding/version.
Replace favicon and adjust public metadata: update index.html title to "Altsis Next" and noscript text to include "V2.0", and modify manifest.json name/short_name to "Altsis". These changes update branding/versioning for the frontend public assets.
Replace frontend/public/favicon.ico (binary updated), add frontend/public/favicon_v1.ico (new file, preserves previous favicon), and update frontend/public/manifest.json to set "short_name" and "name" to "Altsis Next" so the app displays the new branding while retaining the old favicon as favicon_v1.ico.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Replace scrollIntoView with direct scrollTop on the calendar
container to prevent parent scroll containers from being affected.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Change sidebar from position: absolute to position: fixed on mobile
and add padding-top: 56px to .content to account for the fixed bar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
The padding-top: 56px pushed the navbar below the sidebar, creating
a visible gap. The sidebar already covers the navbar on mobile, so
no padding offset is needed.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use 100dvh instead of 100vh for .section height so .content
does not scroll on mobile when the browser address bar changes
viewport size. This keeps .section below the fixed sidebar.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add stacking context to .viewer_container so WeeklyViewer header
z-index is contained within it and cannot overlap the calendar
sticky header (.top).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Use flex layout so .top stays at top and .viewer_container fills
remaining space. This eliminates the z-index stacking issue where
day headers could overlap the calendar header during scroll.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Without max-height, pages where the calendar parent has no defined
height (e.g. userSearchResult) cause the viewer to expand infinitely.
max-height: 75vh acts as a safety net alongside flex: 1.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Defer chat room creation until first message is sent (pending room)
- Show system message and remove participant when someone leaves
- Hard delete room, messages, and files when all participants leave
- Add archived rooms toggle in chat list with unarchive support
- Render system messages centered without sender info
- Add participant_left socket event handling

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
์ฑ„ํŒ…๋ฐฉ ๋ฉ”๋‰ด ๋“œ๋กญ๋‹ค์šด์— ์„ค์ •(Settings) ํ•ญ๋ชฉ์„ ์ถ”๊ฐ€ํ•˜์—ฌ
๊ธฐ์กด RoomSettings ์ปดํฌ๋„ŒํŠธ๋ฅผ ๋ฉ”๋‰ด์—์„œ ๋ฐ”๋กœ ์—ด ์ˆ˜ ์žˆ๋„๋ก ํ•จ

https://claude.ai/code/session_015EAj13i6X45X6nY1eX1ASw
๊ฐ ์ฑ„ํŒ…๋ฐฉ ๋ชฉ๋ก ํ•ญ๋ชฉ์— ์  3๊ฐœ(โ‹ฎ) ๋ฉ”๋‰ด ๋ฒ„ํŠผ์„ ์ถ”๊ฐ€ํ•˜์—ฌ
๋ชฉ๋ก์—์„œ ๋ฐ”๋กœ ๊ณ ์ •, ๋‚ด ํŒŒ์ผ, ๋ณด๊ด€, ์„ค์ •, ์ฑ„ํŒ…๋ฐฉ ๋‚˜๊ฐ€๊ธฐ
๊ธฐ๋Šฅ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•จ

https://claude.ai/code/session_015EAj13i6X45X6nY1eX1ASw
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants