-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Phase 0 Auth·CRUD 완료 (실계정 스모크 포함) #1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
34 commits
Select commit
Hold shift + click to select a range
d0afd8b
feat: Supabase 초기 스키마와 RLS를 추가
scs0209 9234061
feat(mobile): 매직링크 인증과 종목·엔트리 CRUD를 연결
scs0209 6de8434
feat(web): 매직링크 세션과 관심종목 조회를 연결
scs0209 d29caf5
docs: Phase 0 인증·CRUD 문서를 갱신
scs0209 b3d6ab7
feat(web): 콜백 경로 결정을 순수 함수로 분리
scs0209 a8064ff
test: 결과 중심으로 기준을 고정하고 CI를 추가
scs0209 f60953f
docs: 테스트 기준과 CI를 문서에 반영
scs0209 1f82854
fix: CI typecheck와 E2E shared 빌드 실패를 수정
scs0209 4379ad8
chore: 커밋 전 pnpm run ci를 Husky로 실행
scs0209 afc6773
fix: 매직링크 콜백·세션 교환 버그를 수정
scs0209 e74bb7f
fix: 차트 XSS·로그아웃 에러·조회 실패 표시를 수정
scs0209 cd05443
chore: 설정·문서·스크립트 정리
scs0209 0304857
feat(mobile): 이메일/비번·Google 로그인과 회원가입을 추가
scs0209 fdfcc2c
feat(web): 이메일/비번·Google 로그인과 회원가입을 추가
scs0209 f76d2a8
docs: 다중 Auth 방식을 문서에 반영
scs0209 7edf817
fix(web): 로그인 E2E를 비밀번호 탭 UI에 맞춘다
scs0209 3420c2a
chore: CI 토큰 권한 축소와 로컬 설정 정리
scs0209 1a4755c
fix: entries 업데이트 RLS와 테이블 GRANT를 보강
scs0209 26e29c1
feat: shared Database 타입을 웹·모바일에 연결
scs0209 e74b571
fix(web): 오픈 리다이렉트·세션 캐시·에러 표시를 보강
scs0209 6b833ab
update(mobile): 워치리스트 RHF·로드 레이스·Google 브라우저 연동
scs0209 43dfbb0
docs: Phase 0 보안·타입·Auth 보강을 포트폴리오에 반영
scs0209 36e713a
fix: set_updated_at 트리거에 search_path를 고정
scs0209 be8ba07
fix(web): 콜백 next 경로의 제어문자를 거부
scs0209 5aa20ed
update(mobile): CodeRabbit 잔여 UX·보안 이슈를 반영
scs0209 60456cf
chore: Database 타입을 gen:types로 재생성하고 CI에서 검증
scs0209 c0b47bd
docs: 전체 마이그레이션 적용과 타입 생성 절차를 명시
scs0209 951e27d
chore: 단위·컴포넌트 테스트 커버리지 리포트를 추가
scs0209 3841f95
docs: 커버리지 측정 방법과 Lines %를 문서에 반영
scs0209 c3c7e70
fix(ci): Database 타입 검사를 로컬 Supabase로 전환
scs0209 77602f5
fix(ci): Database 타입 비교에서 __InternalSupabase를 무시
scs0209 ca651a4
fix(mobile): 중복 종목 추가 시 동일 종목 메시지를 표시
scs0209 a821efa
chore(web): Sonda 번들 분석 스크립트를 추가
scs0209 10d7cb6
docs: Phase 0 실계정 스모크 완료로 마감
scs0209 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,35 @@ | ||
| --- | ||
| description: Ticker Journal 테스트 작성 기준. 테스트 추가·수정 전에 적용. | ||
| globs: | ||
| - "**/*.{test,spec}.{ts,tsx}" | ||
| - "**/e2e/**" | ||
| - docs/testing.md | ||
| alwaysApply: true | ||
| --- | ||
|
|
||
| # 테스트 작성 기준 | ||
|
|
||
| 소스 오브 트루스: `docs/testing.md`. 어긋나면 테스트를 만들지 않는다. | ||
|
|
||
| ## 먼저 고른다 | ||
|
|
||
| - 웹 사용자 플로우 (페이지 진입, 로그인 화면, 이동) → Playwright E2E | ||
| - 순수 함수 (Zod, HTML 빌더, `resolveAuthCallbackPath`) → 단위 | ||
| - 웹 순수 뷰 (props → 텍스트, 라우팅 없음) → RTL. Auth/폼/라우팅은 E2E | ||
| - 모바일 화면 → Maestro E2E (예정). Jest에서 expo-router/auth를 목킹해 목록을 그리지 않는다 | ||
|
|
||
| ## 금지 | ||
|
|
||
| - expo-router / `useFocusEffect`를 목킹한 뒤 화면 텍스트를 확인하는 테스트 | ||
| - `signInWithOtp` / `createTicker` 같은 I/O를 목킹한 뒤 `toHaveBeenCalled`만 하는 테스트 (로그인·CRUD 포함) | ||
| - E2E가 이미 보는 동작을 컴포넌트 테스트로 중복 | ||
| - 커버리지·건수 맞추기용 테스트 | ||
| - 매직링크 실메일 E2E (인박스 없음). 페이지가 뜨는 스모크만 | ||
|
|
||
| ## 설명 | ||
|
|
||
| `it`/`test` 문자열은 한국어. 예: `it('빈 심볼을 거부한다')`. `describe`는 대상 식별자 가능 (`CreateTickerSchema`). | ||
|
|
||
| ## assert | ||
|
|
||
| 사용자/호출자가 보는 것: 화면 텍스트, URL `Location`, 순수 함수 반환값. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,15 @@ | ||
| # Supabase (Phase 0+) | ||
| # 앱별 파일에 복사한다. | ||
| # - apps/mobile/.env → EXPO_PUBLIC_* | ||
| # - apps/web/.env → NEXT_PUBLIC_* | ||
|
|
||
| # Dashboard → Project Settings → API | ||
| EXPO_PUBLIC_SUPABASE_URL= | ||
| EXPO_PUBLIC_SUPABASE_KEY= | ||
|
|
||
| NEXT_PUBLIC_SUPABASE_URL= | ||
| NEXT_PUBLIC_SUPABASE_ANON_KEY= | ||
| EXPO_PUBLIC_SUPABASE_URL= | ||
| EXPO_PUBLIC_SUPABASE_ANON_KEY= | ||
|
|
||
| # Auth redirects (Supabase Dashboard → Authentication → URL Configuration) | ||
| # - mobile (dev build / 스토어): tickerjournal://auth/callback | ||
| # - mobile (Expo Go): Linking.createURL('auth/callback') 결과(exp://…)도 등록 | ||
| # - web: http://localhost:3000/auth/callback |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,58 @@ | ||
| name: CI | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| pull_request: | ||
|
|
||
| concurrency: | ||
| group: ci-${{ github.ref }} | ||
| cancel-in-progress: true | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| test: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
| - uses: pnpm/action-setup@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: pnpm | ||
| - run: pnpm install --frozen-lockfile | ||
| - run: pnpm check | ||
| - run: pnpm typecheck | ||
| - run: pnpm test:coverage | ||
| - uses: supabase/setup-cli@v1 | ||
| with: | ||
| version: latest | ||
| - name: Start local Supabase (migrations) | ||
| run: supabase start | ||
| - name: Check Database types match schema | ||
| env: | ||
| DB_TYPES_SOURCE: local | ||
| run: pnpm check:db-types | ||
| - name: Stop local Supabase | ||
| if: always() | ||
| run: supabase stop --no-backup | ||
|
|
||
| e2e: | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - uses: actions/checkout@v4 | ||
| with: | ||
| persist-credentials: false | ||
| - uses: pnpm/action-setup@v4 | ||
| - uses: actions/setup-node@v4 | ||
| with: | ||
| node-version: 22 | ||
| cache: pnpm | ||
| - run: pnpm install --frozen-lockfile | ||
| - run: pnpm --filter @ticker-journal/shared build | ||
| - run: pnpm --filter @ticker-journal/web exec playwright install --with-deps chromium | ||
| - run: pnpm test:e2e | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -21,3 +21,6 @@ playwright-report | |
| test-results | ||
| blob-report | ||
| .gstack/ | ||
| supabase/.temp/ | ||
| .sonda/ | ||
| apps/web/.sonda/ | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1 @@ | ||
| pnpm run ci |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,22 @@ | ||
| import { buildChartHtml } from '../lib/chart'; | ||
|
|
||
| describe('buildChartHtml', () => { | ||
| it('US 심볼에 TradingView 위젯을 넣는다', () => { | ||
| const html = buildChartHtml('US', 'aapl'); | ||
| expect(html).toContain('TradingView.widget'); | ||
| expect(html).toContain('symbol: "AAPL"'); | ||
| }); | ||
|
|
||
| it('US 심볼의 따옴표를 JS 문자열 밖으로 빼지 않는다', () => { | ||
| const html = buildChartHtml('US', "x');alert(1);//"); | ||
| expect(html).toContain('symbol: "X\');ALERT(1);//"'); | ||
| expect(html).not.toContain("symbol: '"); | ||
| }); | ||
|
|
||
| it('KR 심볼은 fallback HTML을 쓴다', () => { | ||
| const html = buildChartHtml('KR', '005930'); | ||
| expect(html).toContain('KR 차트 fallback'); | ||
| expect(html).toContain('005930'); | ||
| expect(html).not.toContain('TradingView.widget'); | ||
| }); | ||
| }); |
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,14 +1,50 @@ | ||
| import { Stack } from 'expo-router'; | ||
| import { Stack, useRouter } from 'expo-router'; | ||
| import { StatusBar } from 'expo-status-bar'; | ||
| import { Alert, Pressable, Text } from 'react-native'; | ||
|
|
||
| import { AuthProvider, useAuth } from '../lib/auth'; | ||
|
|
||
| const LogoutButton = () => { | ||
| const { session, signOut } = useAuth(); | ||
| const router = useRouter(); | ||
| if (!session) return null; | ||
|
|
||
| return ( | ||
| <Pressable | ||
| onPress={async () => { | ||
| try { | ||
| await signOut(); | ||
| router.replace('/login'); | ||
| } catch (err) { | ||
| Alert.alert('로그아웃 실패', err instanceof Error ? err.message : '다시 시도해 주세요.'); | ||
| } | ||
| }} | ||
|
Comment on lines
+14
to
+21
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win 로그아웃 오류를 처리하세요.
🤖 Prompt for AI Agents |
||
| accessibilityRole='button' | ||
| accessibilityLabel='로그아웃' | ||
| style={{ paddingHorizontal: 8 }} | ||
| > | ||
| <Text style={{ color: '#2563eb', fontSize: 14 }}>로그아웃</Text> | ||
| </Pressable> | ||
| ); | ||
| }; | ||
|
|
||
| export default function RootLayout() { | ||
| return ( | ||
| <> | ||
| <AuthProvider> | ||
| <StatusBar style='dark' /> | ||
| <Stack> | ||
| <Stack.Screen name='index' options={{ title: '관심종목' }} /> | ||
| <Stack.Screen name='login' options={{ headerShown: false }} /> | ||
| <Stack.Screen name='signup' options={{ headerShown: false }} /> | ||
| <Stack.Screen name='auth/callback' options={{ headerShown: false }} /> | ||
| <Stack.Screen | ||
| name='index' | ||
| options={{ | ||
| title: '관심종목', | ||
| headerRight: () => <LogoutButton />, | ||
| }} | ||
| /> | ||
| <Stack.Screen name='ticker/[id]' options={{ title: '종목' }} /> | ||
| </Stack> | ||
| </> | ||
| </AuthProvider> | ||
| ); | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| import { Redirect } from 'expo-router'; | ||
| import { ActivityIndicator, StyleSheet, Text, View } from 'react-native'; | ||
|
|
||
| import { useAuth } from '../../lib/auth'; | ||
|
|
||
| export default function AuthCallbackScreen() { | ||
| const { session, loading } = useAuth(); | ||
|
|
||
| if (!loading && session) { | ||
| return <Redirect href='/' />; | ||
| } | ||
|
|
||
| if (!loading && !session) { | ||
| return <Redirect href='/login' />; | ||
| } | ||
|
|
||
| return ( | ||
| <View style={styles.container}> | ||
| <ActivityIndicator /> | ||
| <Text style={styles.label}>로그인 처리 중…</Text> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| const styles = StyleSheet.create({ | ||
| container: { flex: 1, alignItems: 'center', justifyContent: 'center', gap: 12, backgroundColor: '#fff' }, | ||
| label: { fontSize: 14, color: '#666' }, | ||
| }); |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.