diff --git a/.claude/settings.local.json b/.claude/settings.local.json deleted file mode 100644 index 725b4574..00000000 --- a/.claude/settings.local.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "permissions": { - "allow": [ - "Bash(grep:*)", - "Bash(tree:*)", - "Bash(find:*)", - "Bash(git mv:*)", - "Bash(wc:*)", - "Bash(npx tsc:*)", - "Bash(git add:*)", - "Bash(git commit:*)" - ] - } -} diff --git a/.github/ISSUE_TEMPLATE/bug_issue.yml b/.github/ISSUE_TEMPLATE/bug_issue.yml deleted file mode 100644 index a44d8e43..00000000 --- a/.github/ISSUE_TEMPLATE/bug_issue.yml +++ /dev/null @@ -1,33 +0,0 @@ -name: '버그 제보' -description: Bug Issue 작성 기본 양식입니다. -labels: ['🐞 Fix'] -title: '[fix] ' -body: - - type: markdown - attributes: - value: | - 작성 예시 : "[fix] 버튼 컴포넌트 버그 수정" - - type: textarea - id: bug-description - attributes: - label: 버그 설명 - description: 버그가 언제/어떻게 발생했는지 명확하게 적어주세요. - placeholder: 설명을 적어주세요. - validations: - required: true - - type: textarea - id: reproduction - attributes: - label: 재현 방법 - description: 버그가 재현되는 상황을 설명해주세요. - placeholder: 설명을 적어주세요. - validations: - required: true - - type: textarea - id: expected - attributes: - label: 기대했던 정상 동작 - description: 기대했던 정상적인 동작에 대해서 설명해주세요. - placeholder: 설명을 적어주세요. - validations: - required: true diff --git a/.github/ISSUE_TEMPLATE/feature_issue.yml b/.github/ISSUE_TEMPLATE/feature_issue.yml deleted file mode 100644 index e9ab468f..00000000 --- a/.github/ISSUE_TEMPLATE/feature_issue.yml +++ /dev/null @@ -1,25 +0,0 @@ -name: '기능 추가' -description: 기능 추가 Issue 작성 양식입니다. -labels: ['✨ Feature'] -title: '[feat] ' -body: - - type: markdown - attributes: - value: | - 작성 예시 : "[feat] 버튼 컴포넌트 만들기" - - type: textarea - id: feature-description - attributes: - label: 작업 설명 - description: 어떠한 기능을 추가하시는 건지 적어주세요. - placeholder: 설명을 적어주세요. - validations: - required: true - - type: textarea - id: approach - attributes: - label: 접근 방법 - description: 고려하신 방법이나, 접근에 대해서 설명해주세요. - placeholder: 설명을 적어주세요. - validations: - required: true diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 843738a5..9ae31a0f 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,46 +1,37 @@ - - - - + + + + -## 📌 Related Issue Number +## Summary - + -- Closes #1 +## Linear ---- + + -## Checklist +- -- [ ] 🎋 base 브랜치를 제대로 설정했나요? -- [ ] 🖌️ PR 제목은 형식에 맞게 잘 작성했나요? -- [ ] 🏗️ 빌드는 성공했나요? (pnpm build) -- [ ] 🧹 불필요한 코드는 제거했나요? e.g. console.log -- [ ] 🙇♂️ 리뷰어를 지정했나요? -- [ ] 🏷️ 라벨은 등록했나요? +## Changes ---- +- +- +- -## ✅ Key Changes +## Testing -> 이번 PR에서 작업한 내용을 간략히 설명해주세요 + -1. 내용1 - - 설명 -2. 내용2 - - 설명 +- ---- +## Risk / Impact -## 💡 New Insights & Learnings +- 영향 범위: +- 확인이 필요한 부분: +- 배포 시 유의사항: -- *** +## Screenshots / Video -## 📢 To Reviewers - -- *** - -## 📸 Screenshot or Video (Optional) - - + diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index be1265b2..92449635 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,39 +3,37 @@ name: CI on: pull_request: branches: + - develop - main - - pre-production jobs: ci: runs-on: ubuntu-latest - env: - NEXT_PUBLIC_API_BASE_URL: ${{ secrets.NEXT_PUBLIC_API_BASE_URL }} - steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: '20' - - - name: Install pnpm - run: npm install -g pnpm + cache: 'pnpm' - name: Install dependencies - run: pnpm install + run: pnpm install --frozen-lockfile - - name: Run Lint - run: pnpm lint + - name: Run lint + run: pnpm ci:lint - - name: Check Prettier formatting - run: pnpm prettier --check "**/*.{js,ts,tsx,jsx,mjs,hbs,json,css,md}" + - name: Check formatting + run: pnpm format:check - - name: TypeScript Check - run: pnpm tsc --noEmit + - name: Type check + run: pnpm ci:typecheck - name: Build project - run: pnpm build + run: pnpm ci:build diff --git a/.github/workflows/expo-deploy.yml b/.github/workflows/expo-deploy.yml deleted file mode 100644 index 101851f6..00000000 --- a/.github/workflows/expo-deploy.yml +++ /dev/null @@ -1,140 +0,0 @@ -name: Deploy to EC2 and Notify Slack - -on: - push: - branches: - - native - -jobs: - deploy: - runs-on: ubuntu-latest - - steps: - - name: Checkout code - uses: actions/checkout@v4 - - - name: Deploy to EC2 - uses: appleboy/ssh-action@master - env: - REPO_PATH: /home/ubuntu/Pointer - with: - host: ${{ secrets.EC2_HOST }} - username: ${{ secrets.EC2_USER }} - key: ${{ secrets.EC2_SSH_KEY }} - envs: REPO_PATH - script: | - cd $REPO_PATH - echo "Pulling latest changes..." - git pull origin native - - echo "Installing dependencies..." - cd apps/native - npm install - pm2 restart expo - - echo "✅ Deployment completed!" - - - name: Prepare commit message - if: always() - id: commit - run: | - COMMIT_MSG=$(echo '${{ github.event.head_commit.message }}' | head -n 1 | sed 's/"/\\"/g' | sed "s/'/\\'/g") - echo "message=$COMMIT_MSG" >> $GITHUB_OUTPUT - - - name: Notify Slack - Success - if: success() - uses: slackapi/slack-github-action@v1.26.0 - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - with: - payload: | - { - "text": "✅ Expo Deployment Success", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "✅ Expo Deployment Successful" - } - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Repository:* ${{ github.repository }}" - }, - { - "type": "mrkdwn", - "text": "*Branch:* ${{ github.ref_name }}" - }, - { - "type": "mrkdwn", - "text": "*Author:* ${{ github.event.head_commit.author.name }}" - }, - { - "type": "mrkdwn", - "text": "*Commit:* ${{ steps.commit.outputs.message }}" - } - ] - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "<${{ github.event.head_commit.url }}|View Commit>" - } - } - ] - } - - - name: Notify Slack - Failure - if: failure() - uses: slackapi/slack-github-action@v1.26.0 - env: - SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} - SLACK_WEBHOOK_TYPE: INCOMING_WEBHOOK - with: - payload: | - { - "text": "❌ Expo Deployment Failed", - "blocks": [ - { - "type": "header", - "text": { - "type": "plain_text", - "text": "❌ Expo Deployment Failed" - } - }, - { - "type": "section", - "fields": [ - { - "type": "mrkdwn", - "text": "*Repository:* ${{ github.repository }}" - }, - { - "type": "mrkdwn", - "text": "*Branch:* ${{ github.ref_name }}" - }, - { - "type": "mrkdwn", - "text": "*Author:* ${{ github.event.head_commit.author.name }}" - }, - { - "type": "mrkdwn", - "text": "*Commit:* ${{ steps.commit.outputs.message }}" - } - ] - }, - { - "type": "section", - "text": { - "type": "mrkdwn", - "text": "⚠️ Check the <${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}|workflow logs>" - } - } - ] - } diff --git a/.github/workflows/pre-production.yml b/.github/workflows/pre-production.yml deleted file mode 100644 index 5575aef6..00000000 --- a/.github/workflows/pre-production.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Synchronize to forked repo -on: - push: - branches: - - pre-production - -jobs: - sync: - name: Sync forked repo - runs-on: ubuntu-latest - - steps: - - name: Checkout pre-production - uses: actions/checkout@v4 - with: - token: ${{ secrets.FORKED_REPO_TOKEN }} - fetch-depth: 0 - ref: pre-production - - - name: Add remote-url - run: | - git remote add forked-repo https://gudusol:${{ secrets.FORKED_REPO_TOKEN }}@github.com/gudusol/mopl - git config user.name gudusol - git config user.email ${{ secrets.EMAIL }} - - - name: Push changes to forked-repo - run: | - git push -f forked-repo pre-production - - - name: Clean up - run: | - git remote remove forked-repo diff --git a/.github/workflows/production.yml b/.github/workflows/production.yml deleted file mode 100644 index 5be09a7c..00000000 --- a/.github/workflows/production.yml +++ /dev/null @@ -1,32 +0,0 @@ -name: Synchronize to forked repo -on: - push: - branches: - - production - -jobs: - sync: - name: Sync forked repo - runs-on: ubuntu-latest - - steps: - - name: Checkout production - uses: actions/checkout@v4 - with: - token: ${{ secrets.FORKED_REPO_TOKEN }} - fetch-depth: 0 - ref: production - - - name: Add remote-url - run: | - git remote add forked-repo https://gudusol:${{ secrets.FORKED_REPO_TOKEN }}@github.com/gudusol/mopl - git config user.name gudusol - git config user.email ${{ secrets.EMAIL }} - - - name: Push changes to forked-repo - run: | - git push -f forked-repo production - - - name: Clean up - run: | - git remote remove forked-repo diff --git a/.gitignore b/.gitignore index 96fab4fe..30d937fe 100644 --- a/.gitignore +++ b/.gitignore @@ -36,3 +36,8 @@ yarn-error.log* # Misc .DS_Store *.pem + +CLAUDE.md +AGENTS.md +.claude +.omc diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000..a3fd891b --- /dev/null +++ b/.prettierignore @@ -0,0 +1,18 @@ +node_modules +.github +.pnp +.pnp.js +.turbo +.next +out +build +dist +coverage + +apps/native/ios/Pods +apps/native/ios/build +apps/native/android/.gradle +apps/native/android/build +apps/native/android/app/.cxx + +apps/admin/src/routeTree.gen.ts diff --git a/apps/admin/src/apis/controller/concept/index.ts b/apps/admin/src/apis/controller/concept/index.ts index 386bc4ed..c389174a 100644 --- a/apps/admin/src/apis/controller/concept/index.ts +++ b/apps/admin/src/apis/controller/concept/index.ts @@ -16,4 +16,4 @@ export { postConceptCategory, putConcept, putConceptCategory, -}; \ No newline at end of file +}; diff --git a/apps/admin/src/apis/controller/qna/deleteQnaChat.ts b/apps/admin/src/apis/controller/qna/deleteQnaChat.ts index b208a75d..4e7e467e 100644 --- a/apps/admin/src/apis/controller/qna/deleteQnaChat.ts +++ b/apps/admin/src/apis/controller/qna/deleteQnaChat.ts @@ -5,4 +5,3 @@ const deleteQnaChat = () => { }; export default deleteQnaChat; - diff --git a/apps/admin/src/apis/controller/qna/getQna.ts b/apps/admin/src/apis/controller/qna/getQna.ts index a591d7d4..a4537077 100644 --- a/apps/admin/src/apis/controller/qna/getQna.ts +++ b/apps/admin/src/apis/controller/qna/getQna.ts @@ -13,4 +13,3 @@ const getQna = (params?: GetQnaParams) => { }; export default getQna; - diff --git a/apps/admin/src/apis/controller/qna/getQnaById.ts b/apps/admin/src/apis/controller/qna/getQnaById.ts index d5d1e866..6b93b00f 100644 --- a/apps/admin/src/apis/controller/qna/getQnaById.ts +++ b/apps/admin/src/apis/controller/qna/getQnaById.ts @@ -19,4 +19,3 @@ const getQnaById = ({ qnaId, enabled = true }: GetQnaByIdParams) => { }; export default getQnaById; - diff --git a/apps/admin/src/apis/controller/qna/index.ts b/apps/admin/src/apis/controller/qna/index.ts index f7f5e4ed..092ce537 100644 --- a/apps/admin/src/apis/controller/qna/index.ts +++ b/apps/admin/src/apis/controller/qna/index.ts @@ -6,4 +6,3 @@ import putQnaChat from './putQnaChat'; import useSubscribeQna from './useSubscribeQna'; export { deleteQnaChat, getQna, getQnaById, postQnaChat, putQnaChat, useSubscribeQna }; - diff --git a/apps/admin/src/apis/controller/qna/postQnaChat.ts b/apps/admin/src/apis/controller/qna/postQnaChat.ts index ee07f60b..595313a1 100644 --- a/apps/admin/src/apis/controller/qna/postQnaChat.ts +++ b/apps/admin/src/apis/controller/qna/postQnaChat.ts @@ -5,4 +5,3 @@ const postQnaChat = () => { }; export default postQnaChat; - diff --git a/apps/admin/src/apis/controller/qna/putQnaChat.ts b/apps/admin/src/apis/controller/qna/putQnaChat.ts index 1986586b..69153d1b 100644 --- a/apps/admin/src/apis/controller/qna/putQnaChat.ts +++ b/apps/admin/src/apis/controller/qna/putQnaChat.ts @@ -5,4 +5,3 @@ const putQnaChat = () => { }; export default putQnaChat; - diff --git a/apps/admin/src/apis/controller/qna/useSubscribeQna.ts b/apps/admin/src/apis/controller/qna/useSubscribeQna.ts index be6a44fc..7485ddb3 100644 --- a/apps/admin/src/apis/controller/qna/useSubscribeQna.ts +++ b/apps/admin/src/apis/controller/qna/useSubscribeQna.ts @@ -69,12 +69,24 @@ const useSubscribeQna = ({ const onConnectionStatusChangeRef = useRef(onConnectionStatusChange); // 콜백 refs를 최신 값으로 동기화 - useEffect(() => { onChatEventRef.current = onChatEvent; }, [onChatEvent]); - useEffect(() => { onReadStatusEventRef.current = onReadStatusEvent; }, [onReadStatusEvent]); - useEffect(() => { onHeartbeatRef.current = onHeartbeat; }, [onHeartbeat]); - useEffect(() => { onErrorRef.current = onError; }, [onError]); - useEffect(() => { onOpenRef.current = onOpen; }, [onOpen]); - useEffect(() => { onConnectionStatusChangeRef.current = onConnectionStatusChange; }, [onConnectionStatusChange]); + useEffect(() => { + onChatEventRef.current = onChatEvent; + }, [onChatEvent]); + useEffect(() => { + onReadStatusEventRef.current = onReadStatusEvent; + }, [onReadStatusEvent]); + useEffect(() => { + onHeartbeatRef.current = onHeartbeat; + }, [onHeartbeat]); + useEffect(() => { + onErrorRef.current = onError; + }, [onError]); + useEffect(() => { + onOpenRef.current = onOpen; + }, [onOpen]); + useEffect(() => { + onConnectionStatusChangeRef.current = onConnectionStatusChange; + }, [onConnectionStatusChange]); // Refs for stable function references const connectRef = useRef<() => void>(() => {}); diff --git a/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx b/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx index 29bc84c0..d7d245f3 100644 --- a/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx +++ b/apps/admin/src/components/common/Modals/CreatePracticeTestModal.tsx @@ -54,7 +54,7 @@ const CreatePracticeTestModal = ({ onClose }: Props) => { {/* Header */}
- 이 카테고리에 속한 모든 개념 태그에 적용됩니다. -
+이 카테고리에 속한 모든 개념 태그에 적용됩니다.