Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/design/fit-start-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ flowchart TD
- `store:false`, 자동 재시도 없음, 공급자 대기 25초, 최대 출력 1,600토큰. 서버는 요청 본문이나 공급자 오류 메시지를 로그로 남기지 않는다.
- 대화 원문을 DB나 localStorage에 저장하지 않는다. 이 탭의 React 메모리에만 유지하며 새로고침 또는 ‘대화 지우고 다시 시작’으로 지워진다. 안내 숨김 여부만 localStorage에 보관한다. AI 호출 통계에는 비용, 토큰, 시간과 성공 여부를 `guide` 작업으로 저장한다.
- 창을 다시 열거나 탭으로 돌아오면 연습실을 확인한다. 확인 전에는 기존 대화를 숨기며 소유자가 바뀌면 대화, 입력과 선택을 초기화한다. POST도 현재 연습실 헤더를 검사한다.
- DB 사용량 제한: 개인 분당 3회 및 24시간 비로그인 2회/로그인 20회, 접속망 24시간 40회. 기존 서비스 공용 시간당 40회/24시간 100회 제한도 적용한다. 문제 생성, 풀이 검토의 개인 한도는 소비하지 않는다. 비로그인은 접속망에서도 24시간 2회를 적용한다. 연결 실패도 시도 횟수에는 포함한다.
- DB 사용량 제한: 개인 분당 3회 및 24시간 비로그인 2회/로그인 20회, 접속망 24시간 40회. 가이드 전용 서비스 공용 한도(시간당 40회/24시간 150회)를 적용하며, 문제 생성·풀이 검토·프로젝트 분석이 쓰는 AI 공용 한도와 개인 한도는 소비하지 않는다. 비로그인은 접속망에서도 24시간 2회를 적용한다. AI 호출이 실패해 기본 추천으로 대체되면 개인 24시간 한도(비로그인 접속망 한도 포함)를 되돌린다. 분당, 접속망과 가이드 공용 한도는 반복 실패를 제한하기 위해 그대로 센다.
- 접속망 식별과 사용량 원자성은 기존 SQLite/PostgreSQL 계약을 재사용한다. 쿠키를 지워도 접속망과 전체 한도는 남지만 이것이 모든 남용을 차단한다는 의미는 아니다.
- 이 기능은 기록 저장이나 문제 생성이 없는 대화이므로 별도 작업 테이블을 추가하지 않았다. 클라이언트 중복 전송을 막고 자동 재시도하지 않지만, 응답 유실 뒤 사용자가 다시 요청하면 별도 유료 호출이 될 수 있다. 중지·닫기는 늦은 응답을 UI에 적용하지 않으며 이미 발생한 공급자 비용의 취소를 보장하지 않는다.

Expand Down
2 changes: 1 addition & 1 deletion docs/development.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ npm start
QuickJS 0.32.0의 파일명을 바꿀 때에는 복사 스크립트와 Worker 경로를 함께 갱신하세요.

브라우저 Worker가 QuickJS를 실행하며 서버에는 사용자 코드를 실행하는 API가 없습니다.
한 테스트당 600ms, 16MiB 힙, 256KiB 스택, 출력 1,600자 제한과 전체 12초 Worker 종료를 적용합니다.
한 테스트당 600ms, 16MiB 힙, 256KiB 스택, 출력 1,600자 제한과 실행 환경 준비(최대 30초) 후 12초 Worker 종료를 적용합니다.
새 런타임을 테스트마다 만들며 DOM, 네트워크, 파일 시스템, 타이머나 모듈 로더를 노출하지 않습니다.
입력은 교육용 JavaScript 함수에 한정합니다. 모바일의 메모리 부족이나 WASM 차단 시에도 초안은 보존됩니다.

Expand Down
4 changes: 2 additions & 2 deletions docs/engineering.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ AI 호출 결과는 `ai_runs`에 모델, 프롬프트 버전, 성공 여부, 지

`generation_usage`는 계정, 요청 ID와 한국 날짜를 기록합니다. 비로그인 하루 2회, 로그인 하루 6회이며 00:00 KST에 갱신됩니다. PostgreSQL은 계정별 advisory lock, SQLite는 `BEGIN IMMEDIATE`로 동시 요청을 직렬화합니다. 먼저 자리를 예약하고 생성 문제 저장과 같은 트랜잭션에서 완료 처리합니다. 실패 예약은 반환하고 프로세스가 중단되면 150초 후 만료합니다. 완료 요청 재시도는 기존 문제를 반환하며 추가 차감하지 않습니다. 로그아웃, 쿠키 변경과 서버 재시작은 완료된 사용량을 초기화하지 않습니다.

AI 풀이 검토, 코드 AI 질문, 실습 AI 코치는 각각 비로그인 2회/로그인 30회이며 첫 사용부터 24시간 기준입니다. 비로그인은 접속망별로도 기능당 2회를 적용해 쿠키 재발급을 통한 반복 체험을 제한합니다. 접속망은 생성 30회, 검토 40회, 전체는 시간당 40회와 24시간당 100회를 공유합니다. 이 공용 보호 한도는 실패도 차감하므로 개인 생성 잔여량보다 먼저 제한될 수 있습니다. Vercel의 공식 IP 헤더를 HMAC 처리하고 다른 호스트의 임의 전달 헤더는 신뢰하지 않습니다. 계정당 제한은 한 사람이 여러 계정을 만드는 행위까지 탐지하는 장치는 아닙니다.
AI 풀이 검토, 코드 AI 질문, 실습 AI 코치는 각각 비로그인 2회/로그인 30회이며 첫 사용부터 24시간 기준입니다. 비로그인은 접속망별로도 기능당 2회를 적용해 쿠키 재발급을 통한 반복 체험을 제한합니다. 접속망은 생성 30회, 검토 40회, 전체는 시간당 40회와 24시간당 100회를 공유합니다. 이 공용 보호 한도는 실패도 차감하므로 개인 생성 잔여량보다 먼저 제한될 수 있습니다. 풀이 검토와 코드 AI 질문은 제공자 호출이나 응답 검증이 실패해 결과를 저장하지 못하면 개인(게스트는 접속망별 포함) 횟수를 돌려줍니다. Vercel의 공식 IP 헤더를 HMAC 처리하고 다른 호스트의 임의 전달 헤더는 신뢰하지 않습니다. 신뢰할 IP가 없는 자체 호스팅에서는 모든 방문자가 한 접속망으로 묶이지 않도록 AI 기능의 접속망별 한도를 생략하고 개인·전체 한도만 적용합니다. 계정당 제한은 한 사람이 여러 계정을 만드는 행위까지 탐지하는 장치는 아닙니다.

사용량에는 모델별 단가를 적용합니다. Sol은 2026-09-13 확인한 표준 문맥의 프로모션 단가(입력 $4, 캐시 입력 $0.40, 출력 $20 / 백만 토큰)를 사용하며 실제 청구액이 아닙니다. 제공자 가격 변경 시 갱신해야 합니다. 현재 웹 백업은 최대 4,000,000바이트, 문제 2,500개, 풀이 10,000개, 입문 기록 500개와 프로젝트 500개이며 복원의 신규 문제/제출 수와 횟수에도 별도 한도를 둡니다. 인증 비밀키와 세션은 사용자용 JSON 백업에 포함하지 않습니다.

Expand Down Expand Up @@ -459,7 +459,7 @@ flowchart LR

이번 범위는 외부 의존성이 없는 교육용 JavaScript 함수 12개다. **별도 Web Worker의 QuickJS 0.32.0 WASM 런타임**을 선택했다. 메인 UI와 분리하고 브라우저/Node 호스트 기능을 VM에 바인딩하지 않는다. 한 테스트마다 새 런타임을 만들며, 외부 모듈 로더, DOM, 네트워크, 타이머, 파일 시스템을 제공하지 않는다. 비동기 검색 테스트는 타이머 대신 Promise를 지정 순서로 완료시켜 재현한다.

실행당 600ms, VM 힙 16MiB, 스택 256KiB 및 출력 1,600자 제한이 있다. 브라우저 쪽에서는 전체 12초 제한과 취소 시 Worker 강제 종료를 추가한다. 메모리 수치는 VM 힙 제한이며 브라우저 전체 메모리 상한을 뜻하지 않는다. WASM 로딩 실패, 무한 루프, 해결되지 않는 Promise, 문법 오류와 메모리 부족은 오류 결과로 처리한다. 초안 저장은 실행 성공에 의존하지 않는다.
실행당 600ms, VM 힙 16MiB, 스택 256KiB 및 출력 1,600자 제한이 있다. 브라우저 쪽에서는 실행 환경 준비(최대 30초)가 끝난 뒤 12초 제한과 취소 시 Worker 강제 종료를 추가한다. 느린 WASM 로딩은 반복문 시간 초과가 아니라 준비 실패로 안내한다. 메모리 수치는 VM 힙 제한이며 브라우저 전체 메모리 상한을 뜻하지 않는다. WASM 로딩 실패, 무한 루프, 해결되지 않는 Promise, 문법 오류와 메모리 부족은 오류 결과로 처리한다. 초안 저장은 실행 성공에 의존하지 않는다.

비용은 WASM 초기 다운로드, 런타임 차이와 지원 환경의 제한이다. DOM/프레임워크, 네트워크, 타이머나 라이브러리가 필요한 코드는 지원하지 않는다. 다른 분야의 일반 문제는 기존 정적 리뷰를 유지한다. 실행 파일과 라이선스 고지는 postinstall에서 `public/quickjs/`에 복사하며 외부 CDN을 사용하지 않는다. [QuickJS 바인딩 공식 문서](https://github.com/justjake/quickjs-emscripten)의 런타임 제한과 Promise job API를 사용한다.

Expand Down
2 changes: 1 addition & 1 deletion docs/learning-experiments.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
3. ‘두 코드로 실험 실행’을 누르면 원본과 현재 수정 코드에서 같은 표현식을 각각 실행한다. 결과는 나란히 표시하며 통과/실패 점수를 붙이지 않는다. 문법 오류나 끝나지 않는 작업은 실행 오류로 표시한다.
4. 마지막 실행의 입력, 예상, 코드 식별값과 두 결과를 기존 학습 저장에 함께 보관한다. 코드나 실행 조건이 달라졌으면 이전 기록이라고 표시한다. 새 실행은 마지막 결과를 갱신한다.

실행 자체는 추가 AI 호출을 만들지 않는다. 원본·수정 코드는 각각 새 Worker와 QuickJS 런타임에서 실행되며 서로의 전역 변수나 변이된 입력을 공유하지 않는다. 한쪽 함수에 오류가 있어도 다른 쪽 결과를 볼 수 있다. 기존 VM 실행당 600ms, 힙 16MiB, 결과 1,600자 제한을 사용하고, 각 Worker는 최대 12초 후 종료된다. 네트워크, DOM, 타이머, 호스트 파일 접근은 제공하지 않는다. 사용자 코드와 AI 제안 표현식을 서버에서 실행하지 않는다.
실행 자체는 추가 AI 호출을 만들지 않는다. 원본·수정 코드는 각각 새 Worker와 QuickJS 런타임에서 실행되며 서로의 전역 변수나 변이된 입력을 공유하지 않는다. 한쪽 함수에 오류가 있어도 다른 쪽 결과를 볼 수 있다. 기존 VM 실행당 600ms, 힙 16MiB, 결과 1,600자 제한을 사용하고, 각 Worker는 실행 환경 준비 후 최대 12초가 지나면 종료된다. 네트워크, DOM, 타이머, 호스트 파일 접근은 제공하지 않는다. 사용자 코드와 AI 제안 표현식을 서버에서 실행하지 않는다.

## 저장과 비동기 작업

Expand Down
2 changes: 1 addition & 1 deletion docs/project-ai-workshop.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ AI 워크숍 홈과 `/learn/ai` 상단에서 공개 소스 저장소 또는 GitH

## 이용 흐름과 저장

새 저장소 분석 후 학습 생성으로 진행한다. 기존 분석이 있으면 바로 학습을 만들 수 있다. 새 분석 1회와 학습 생성 1회가 프로젝트 분석 한도를 공유한다. 이미 생성된 학습을 조회하거나 답변을 저장할 때는 AI를 다시 호출하지 않는다.
새 저장소는 입력 화면에서 분석 1회와 학습 생성 1회 사용을 안내하고, 제출하면 분석을 마친 뒤 학습 생성까지 이어서 진행한다. AI 워크숍 홈의 저장소 입력도 같은 안내 후 제출하면 이 화면에서 바로 분석을 시작한다. 이 자동 진행은 제출한 탭에서 한 번만 일어나며 링크나 새로고침으로는 시작하지 않는다. 기존 분석이 있으면 학습 만들기 버튼으로 생성한다. 없는 분석 ID로 열면 다른 프로젝트를 선택하거나 새로 분석하는 화면으로 안내한다. 새 분석 1회와 학습 생성 1회가 프로젝트 분석 한도를 공유한다. 이미 생성된 학습을 조회하거나 답변을 저장할 때는 AI를 다시 호출하지 않는다.

코드 근거 → 관련 개념 수업 → 내 프로젝트 실험 계획 → 확인 문제와 적용 기록 순서다. 관련 수업에서 원래 프로젝트의 주제로 돌아오는 링크를 제공한다. 기록은 저장 버튼으로 서버에 보관하며 수정할 수 있다. 다른 창에서 기록을 바꾸면 리비전 충돌을 알리고 서버 기록을 불러올 수 있다. 기본 수업의 진도는 기존처럼 브라우저에 저장한다.

Expand Down
2 changes: 1 addition & 1 deletion docs/project-check.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
- 개인 한도 외 접속망당 분석 10회/평가 20회/24시간, 기존 AI 전체 40회/시간 및 100회/24시간을 함께 적용한다.
- 주소 읽기는 개인 5회/분, 접속망 20회/분으로 제한한다.
- 프로젝트 질문 생성과 평가에서는 페이지 읽기 실패와 근거 부족은 AI 한도를 차감하지 않는다. AI 호출 전 한도를 원자적으로 소비하며, 호출을 시작한 뒤 실패하거나 응답이 유실돼도 환급하지 않는다. 외부 호출 비용 발생 여부를 확정할 수 없기 때문이다. 자동 유료 재시도는 없다.
- 같은 요청 ID와 같은 입력의 완료 결과는 재사용한다. 진행 중 중복 요청은 409로 알리고 같은 ID를 다른 내용으로 재사용하면 거절한다. 수동 재시도는 이전 입력을 보존한다.
- 같은 요청 ID와 같은 입력의 완료 결과는 재사용한다. 진행 중 중복 요청은 409로 알리고 같은 ID를 다른 내용으로 재사용하면 거절한다. 다만 분석별로 ID가 정해진 답변 평가와 코드 대화는 이전 시도가 실패했으면 수정한 답변으로 다시 요청할 수 있다. 수동 재시도는 이전 입력을 보존한다.
- `ai_runs`에 project 작업의 실제 모델, 입력/캐시/출력 토큰, 예상 달러 비용과 지연 시간을 기록한다. URL이나 답변을 로그에 출력하지 않는다.

## 데이터와 주소 수집
Expand Down
3 changes: 2 additions & 1 deletion docs/project-classes.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,8 @@
- 다른 탭에서 돌아오면 이미 불러온 목록을 갱신하면서 검색어와 불러온 페이지 범위를 유지한다. 검색어는 계정별 sessionStorage에 보관해 상세 화면에서 목록으로 돌아와도 복원한다. 상세 화면도 최신 진도를 반영하며 편집 중인 이름과 메모는 유지한다. 편집 시작 시점의 리비전으로 충돌을 검사한다.
- 상세 화면에서 과정별 진도와 이어하기 링크를 제공한다. 준비하지 않은 과정은 생성 화면으로 이동하며 기존 사용량 정책을 따른다.
- 복습은 설계 질문의 이전 답변과 생성된 확인 문제를 다시 살펴보되 기존 제출 결과는 바꾸지 않는 흐름이다. 객관식 정답과 해설은 선택 후 표시한다. 복습 위치, 문제별 메모, 선택과 해설 공개 상태는 계정과 클래스별로 구분해 이 브라우저의 localStorage에 보관한다. 화면을 나가거나 새로고침해도 이어서 복습할 수 있다. 다른 기기 동기화와 서버 백업에는 포함하지 않는다. 기존 답변과 학습 진도를 덮어쓰지 않으며 브라우저 저장 실패 시 안내한다. Web Locks로 탭 간 저장을 직렬화하고 저장 직전에 최신 기록과 병합한다. 같은 문제의 메모가 충돌하면 다른 탭의 메모도 별도로 보관해 표시한다. 잠금이나 브라우저 저장을 사용할 수 없으면 미저장 상태를 안내한다. 실패한 변경은 화면의 대기 목록에 보존하고 다음 저장에 함께 재시도한다. 저장에 성공한 변경만 대기 목록에서 제거하므로 같은 복습 화면 안에서 다른 문제로 이동해도 미저장 메모를 유지한다. 이 대기 목록은 메모리에만 있어 저장에 성공하기 전에 새로고침하거나 화면을 닫으면 미저장 변경은 복구할 수 없다. AI 호출은 없다.
- 삭제 전 클래스와 함께 지워지는 기록을 확인한다. 분석, 평가, 실습, AI 학습, 중간 생성 단계가 함께 삭제되며 실제 저장소에는 영향을 주지 않는다.
- 보완 답변은 원래 분석의 클래스에 속한다. 목록과 분석 이력에 별도 클래스로 표시하지 않고 원래 클래스 화면에서 연다. 코드 이해 훈련, 서비스 동작 실습, AI 활용 학습과 기초 개념 연습은 원래 분석의 기록을 그대로 사용해 다시 생성하지 않는다. 보완은 원래 분석당 합계 3번까지 가능하다.
- 삭제 전 클래스와 함께 지워지는 기록을 확인한다. 분석, 보완 답변, 평가, 실습, AI 학습, 중간 생성 단계가 함께 삭제되며 실제 저장소에는 영향을 주지 않는다. 어느 화면에서 삭제해도 이 브라우저에 남은 답변 초안, 복습 기록, 선택 상태와 분석 알림을 함께 정리한다.
- 최신 코드 분석은 별도 클래스를 만든다. 기존 클래스는 그대로 유지한다. 같은 저장소 주소의 분석 기록을 날짜와 함께 연결하며, 주소 끝의 슬래시와 .git 표기는 같은 주소로 취급한다. 탭 복귀와 백업 가져오기 후 이력의 기존 조회 범위를 갱신한다. 다른 브랜치 경로나 별칭 주소까지 합치지는 않는다. 버전 간 차이를 자동 비교하거나 기존 진도를 새 코드에 이관하지는 않는다.

## 소유권과 데이터
Expand Down
2 changes: 1 addition & 1 deletion docs/sandbox-integrity.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ JSON의 변환 규칙 자체는 [ECMAScript 명세](https://tc39.es/ecma262/mult

`NaN`, 무한대, undefined, 함수, Symbol, BigInt, Date, Map, 순환 참조, 배열의 빈 자리와 지원하지 않는 속성은 오류로 안내한다. 결과를 직렬화하기 위해 getter나 `toJSON`을 호출하지 않는다. 학습자 코드나 테스트 표현식 자체에서 속성을 읽는 동작까지 금지하는 것은 아니다. 예를 들어 Date가 필요하면 함수가 비교할 문자열이나 숫자를 직접 반환하면 된다.

출력은 1,600자, 방문 항목은 1,000개, 중첩은 40단계로 제한한다. 기존의 테스트별 0.6초, 메모리 16MB, 스택 256KB와 브라우저 Worker의 전체 12초 중단 제한을 유지한다. 무한 반복, 끝나지 않는 Promise와 실행 예산을 소모하는 Proxy도 오류로 종료한다. 각 테스트는 새 런타임과 컨텍스트를 사용하고 핸들을 정리한다. DOM, 네트워크, 타이머, 모듈 로더나 호스트 함수를 추가하지 않았다. [QuickJS 라이브러리의 컨텍스트·메모리 계약](https://github.com/justjake/quickjs-emscripten)을 따른다.
출력은 1,600자, 방문 항목은 1,000개, 중첩은 40단계로 제한한다. 기존의 테스트별 0.6초, 메모리 16MB, 스택 256KB와 브라우저 Worker의 12초 중단 제한(실행 환경 준비 후부터 측정)을 유지한다. 무한 반복, 끝나지 않는 Promise와 실행 예산을 소모하는 Proxy도 오류로 종료한다. 각 테스트는 새 런타임과 컨텍스트를 사용하고 핸들을 정리한다. DOM, 네트워크, 타이머, 모듈 로더나 호스트 함수를 추가하지 않았다. [QuickJS 라이브러리의 컨텍스트·메모리 계약](https://github.com/justjake/quickjs-emscripten)을 따른다.

## 기존 기록과 사용자 안내

Expand Down
Loading
Loading