svelt kit test
Some checks failed
Deploy to Production / Deploy (push) Failing after 4s

This commit is contained in:
Lectom C Han
2025-07-25 14:43:32 +09:00
commit dd89e5fc90
31 changed files with 6008 additions and 0 deletions

View File

@@ -0,0 +1,72 @@
# OIDC 인증 구현 트러블슈팅 (svelte-check)
`pnpm run check` 실행 시 발생한 타입 에러들에 대한 요약 및 해결 과정 기록. 모든 문제는 최종적으로 해결되었습니다.
---
## 1-6. `src/lib/server/auth.ts` 관련 타입 오류
- **파일**: `src/lib/server/auth.ts`
- **오류 요약**:
1. `unstorage` 및 관련 어댑터 import 오류
2. Lucia v3 생성자에 `env` 속성 사용 오류
3. `getUserAttributes` 콜백의 `data` 타입 추론 오류 (`{}`)
4. 더미 어댑터의 타입이 `Adapter` 인터페이스와 불일치
- **원인**: Lucia v3의 API와 타입 시스템에 대한 이해 부족. 데이터베이스 의존성을 제거하는 과정에서 `unstorage` 어댑터를 잘못 사용하려고 시도함.
- **해결 상태**: **완료**
- **해결책**:
1. `unstorage` 및 관련 패키지 의존성을 제거했습니다.
2. 데이터베이스 없이 OIDC 흐름을 테스트하기 위해, Lucia v3의 `Adapter` 인터페이스를 직접 구현하는 **더미 인메모리 어댑터**를 `auth.ts` 내에 작성했습니다.
3. 이 더미 어댑터는 `Map` 객체를 사용하여 세션과 사용자 정보를 메모리에 임시 저장합니다.
4. Lucia 생성자에서 v2 방식의 `env` 속성을 제거하고, `Adapter` 인터페이스에 맞게 `setUser`와 같은 불필요한 메서드를 제거했습니다.
5. `declare module 'lucia'`를 사용하여 `DatabaseUserAttributes` 타입을 명시적으로 정의함으로써, `getUserAttributes`의 타입 추론 오류를 해결했습니다.
---
## 7. `hooks.server.ts`의 `handleRequest` 오류
- **파일**: `src/hooks.server.ts`
- **오류 메시지**: `Property 'handleRequest' does not exist on type 'Lucia<...>'`
- **원인**: `lucia.handleRequest()`는 Lucia v2에서 사용하던 방식입니다. v3에서는 세션 유효성 검사와 쿠키 관리를 직접 처리해야 합니다.
- **해결 상태**: **완료**
- **해결책**: Lucia v3의 공식 문서에 따라 `hooks.server.ts``handle` 함수를 수정했습니다. 이제 모든 요청에서 `event.cookies`를 통해 세션 ID를 가져오고, `lucia.validateSession()`으로 유효성을 검증합니다. 검증 결과에 따라 `event.locals.user``event.locals.session`을 설정하고, 필요한 경우 세션 쿠키를 새로 생성하거나 비우는 로직을 추가했습니다.
---
## 8. `arctic` 모듈 선언 오류
- **파일**: `src/routes/login/callback/+page.server.ts`
- **오류 메시지**: `Cannot find module 'arctic' or its corresponding type declarations.`
- **원인**: `arctic` 패키지가 설치되지 않았습니다.
- **해결 상태**: **완료**
- **해결책**: `pnpm install arctic` 명령을 실행하여 의존성을 추가했습니다.
---
## 9. `logout` 라우트의 `redirect` 함수 오류
- **파일**: `src/routes/logout/+page.server.ts`
- **오류 메시지**: `Expected 2 arguments, but got 3.`
- **원인**: SvelteKit의 `redirect` 함수 API가 변경되었습니다. 더 이상 세 번째 인자로 헤더(쿠키 포함)를 전달할 수 없습니다.
- **해결 상태**: **완료**
- **해결책**: `redirect` 함수에서 헤더 인자를 제거하고, 대신 `event.cookies.set()`을 사용하여 로그아웃 시 세션 쿠키를 삭제하도록 로직을 변경했습니다.
---
## 추가 해결: `event.locals` 타입 오류
- **파일**: `src/app.d.ts`, `src/routes/**/+*.server.ts`
- **오류 메시지**: `Property 'user' does not exist on type 'Locals'.`
- **원인**: `hooks.server.ts`에서 `event.locals.user``event.locals.session`을 할당했지만, SvelteKit의 전역 타입 정의 파일(`app.d.ts`)에 해당 속성이 선언되지 않았습니다.
- **해결 상태**: **완료**
- **해결책**: `src/app.d.ts` 파일의 `App.Locals` 인터페이스에 `user: import('lucia').User | null;``session: import('lucia').Session | null;`를 추가하여 전역 타입을 확장했습니다.
---
## 추가 해결: 프론트엔드 컴포넌트 타입 오류
- **파일**: `src/routes/+layout.svelte`, `src/routes/+page.svelte`
- **오류 메시지**: `Property 'session' does not exist on type '{ user: User | null; }'.`
- **원인**: 서버 사이드(`+layout.server.ts`)에서 `data`로 전달하는 객체의 구조를 `{ session }`에서 `{ user }`로 변경했으나, 프론트엔드 컴포넌트에서는 여전히 `data.session`을 참조하고 있었습니다.
- **해결 상태**: **완료**
- **해결책**: `+layout.svelte``+page.svelte` 파일에서 `data.session`을 참조하는 모든 코드를 `data.user`를 참조하도록 수정했습니다.

65
docs/QNA_FEEDBACK_PRD.md Normal file
View File

@@ -0,0 +1,65 @@
# 제품 요구사항 문서 (PRD): Q&A 피드백 플랫폼
- **문서 버전**: 1.2
- **작성일**: 2025년 7월 25일
- **프로젝트명**: SvelteKit 기반 Q&A 피드백 플랫폼
---
## 1. 개요
### 1.1. 프로젝트 목표
사용자로부터 질문, 답변, 버그 리포트, 기능 제안 등 다양한 형태의 피드백을 체계적으로 수집하고 관리하기 위한 웹 애플리케이션을 구축한다. 사용자는 별도의 회원가입 절차 없이 기존에 사용하던 OIDC 계정을 통해 로그인하여 피드백을 손쉽게 제출할 수 있다.
### 1.2. 대상 사용자
- **피드백 제공자 (End-User)**: 서비스나 제품을 사용하는 모든 사용자. OIDC 계정을 통해 인증 후 피드백을 작성하고 제출할 수 있다.
### 1.3. 기대 효과
- 피드백 수집 프로세스 간소화 및 사용자 참여 증대
- 다양한 종류의 피드백을 '채널'별로 분류하여 체계적인 관리 가능
- 파일 첨부 기능을 통해 문제 상황이나 제안에 대한 상세 정보 확보
---
## 2. 기능 요구사항
### 2.1. 사용자 인증 (FR-1)
- **FR-1.1**: 사용자는 OIDC 제공자를 통해서만 인증(로그인)할 수 있다.
- **FR-1.2**: 시스템 내 자체적인 회원가입 기능은 제공하지 않는다.
- **FR-1.3**: OIDC 인증 성공 시, 사용자의 세션이 생성되어 로그인 상태가 유지되어야 한다.
- **FR-1.4**: 사용자는 명시적인 '로그아웃' 버튼을 통해 언제든지 세션을 종료할 수 있다.
- **FR-1.5**: OIDC 클라이언트 ID, 비밀키 등은 Cloudflare Pages의 환경 변수로 안전하게 관리되어야 한다.
### 2.2. Q&A 피드백 기능 (FR-2)
- **FR-2.1**: 인증된 사용자만 피드백 관련 기능(작성, 조회)을 사용할 수 있다.
- **FR-2.2**: 피드백 작성 폼은 다음 필드를 포함해야 한다: 채널, 제목, 내용, 파일 첨부.
- **FR-2.3**: '제출' 시, 로그인된 사용자 정보(ID, 이름 등)를 포함하여 백엔드 API로 전송해야 한다.
- **FR-2.4**: 피드백 생성 API는 `POST /api/projects/{projectId}/channels/{channelId}/feedbacks` 엔드포인트를 사용한다.
- **FR-2.5**: 피드백 목록 조회는 `GET /api/projects/{projectId}/channels/{channelId}/feedbacks` 엔드포인트를 사용한다.
- **FR-2.6**: 피드백 검색은 `GET /api/v2/projects/{projectId}/channels/{channelId}/feedbacks/search` 엔드포인트를 사용한다.
### 2.3. 데이터 구조 및 확장성 (FR-3)
- **FR-3.1**: 피드백 데이터는 백엔드 API 명세에 따라 유연한 JSON 구조로 전송된다.
- **FR-3.2**: API 호출에 필요한 `projectId`, `channelId`는 URL 경로의 일부로 동적으로 구성된다.
---
## 3. 비기능 요구사항
### 3.1. 보안 및 설정 (NFR-1)
- 모든 민감한 정보(OIDC 시크릿, API 키)는 소스 코드에 포함되지 않고, Cloudflare 환경 변수를 통해 안전하게 관리되어야 한다.
- SvelteKit의 서버 함수(Cloudflare Workers로 배포됨)가 API 키를 사용하여 백엔드 API를 호출하는 프록시 역할을 수행한다.
### 3.2. 기술 스택 (NFR-2)
- **프론트엔드**: SvelteKit, TypeScript, Tailwind CSS
- **배포**: Cloudflare Pages (정적 파일 + Cloudflare Workers)
### 3.3. 배포 (NFR-3)
- 프론트엔드 애플리케이션은 백엔드와 완전히 분리된 인프라에 독립적으로 배포된다.
- SvelteKit의 `@sveltejs/adapter-cloudflare`를 사용하여 Cloudflare Pages에 최적화된 형태로 빌드된다.
---
## 4. 범위 외 (Out of Scope)
- **관리자 대시보드**: 제출된 피드백을 관리하는 기능.
- **백엔드 API 및 데이터베이스 구현**: 이 문서에서는 프론트엔드 개발을 전제로 하며, 백엔드는 이미 존재하거나 별도로 개발되는 것으로 간주한다.