Skip to content

Conversation

@i-meant-to-be
Copy link
Contributor

@i-meant-to-be i-meant-to-be commented Sep 3, 2025

🚩 연관 이슈

closed #357

📝 작업 내용

리딩 제로 문제 수정

타종 입력 중 아래 3가지에 대한 리딩 제로 문제를 수정했습니다:

  • 타종 횟수

분과 초의 경우

// 0 <= x <= 59로 범위가 제한되는 분과 초에 사용하는 검증 함수
const getValidateTimeValue = (value: string) => {
  let num = parseInt(value, 10);
  if (isNaN(num)) {
    num = 0;
  }

  return Math.max(0, Math.min(59, num));
};

위 함수를 분과 초의 onChange 로직에 포함했습니다. 일단 조건문을 통해 NaN을 검증하여 값을 확실하게 숫자로 만들고, 숫자로 정해진 값을 min 함수와 max 함수를 통해 [0, 59]에 포함되도록 강제하였습니다.

타종 횟수의 경우

// Backspace 대응
if (value === '') {
  setBellInput((prev) => ({
    ...prev,
    count: 1,
  }));
  return;
}

// 마지막 입력 문자를 가져옴
const lastInput = value.slice(-1);
let newCount;

if (['1', '2', '3'].includes(lastInput)) {
  // 유효한 입력(1, 2, 3)이면 해당 값으로 설정
  newCount = lastInput;
} else {
  // 유효하지 않은 문자(알파벳, 1~3 이외 숫자 등)가 마지막에 입력된 경우 무시
  return;
}

사용자가 입력하는 가장 최신 문자는 무조건 문자열 끝에 배치된다는 점에 착안하여, 모든 입력이 무조건 문자열의 마지막 문자 1개로 치환되도록 개선하였습니다.

글만 봐서는 이해가 어려울 수 있어 예시를 첨부하겠습니다.

  • 기본값은 타종 1회이므로 e.target.value === "1"
  • 사용자가 종을 2번 치고 싶어서 2를 입력하면 e.target.value === "12"가 됨
  • 마지막 문자만 취해서 "2"로 업데이트

또한, 1, 2, 3 외 다른 입력에도 대응할 수 있게 다음 검증 조건도 추가했습니다:

  • 백스페이스로 인해 문자열이 비어버렸을 때 기본값 1로 초기화
  • 빈 문자열도 아니고 1, 2, 3도 아닐 경우 그냥 무시

타종 설정 저장 버그 수정

문제

기존에는 일반 타이머 생성 후 시간 총량제 타이머를 곧바로 생성하면, 일반 타이머의 타종 설정이 사라져서 새로 처음부터 작성해야 하는 문제가 있었습니다.

원인

이는 타이머 생성 시 가장 마지막으로 생성한 타이머 의 값을 그대로 가져오기 때문입니다. 문제가 발생하는 과정은 아래와 같습니다:

  • 일반 타이머 N을 생성하면, N의 데이터가 저장됨 (여기에는 타종 설정 포함)
  • 뒤이어 시간 총량제 타이머 T를 생성하면, N의 데이터를 T가 덮어씌움 (시간 총량제 타이머이므로 타종이 필요 없어서 설정도 없음)
  • 뒤이어 일반 타이머를 생성하려고 하면, N의 데이터가 T로 덮어씌워졌으므로 타종 설정도 증발해버림

해결책

세션 스토리지에 가장 마지막으로 추가한 일반 타이머의 타종 설정이 저장되도록 구현했습니다. 결론적으론 아래와 같이 동작합니다:

  • 기존 타이머 수정이라면, 수정 전 타이머의 타종 값 그대로 가져옴
  • 새로 생성한다면, 1) 세션 스토리지에 마지막 타종 설정 백업되어 있으면 그거 쓰고 2) 아니라면 기본값(30초 1회, 0초 2회) 사용

여담

가능한 기존의 백업-복원 로직을 최대한 활용해보려고 했으나, 그렇게 하려면 너무 수정 사항이 많아져서 세션 스토리지를 사용하는 쪽으로 가닥을 잡았습니다. 다른 제안이 있다면 언제든 편하게 의견 제시해주세요!

🏞️ 스크린샷 (선택)

없음

🗣️ 리뷰 요구사항 (선택)

없음

Summary by CodeRabbit

  • New Features

    • 벨 설정이 세션에 자동 저장·복원되어 재방문 시 이전 설정이 유지됩니다.
    • NORMAL 타이머 제출 시 현재 벨 설정이 함께 저장됩니다.
    • 분/초 입력을 숫자 전용 필드로 개선하고, 레이블(분/초·횟수)을 명확화했습니다.
  • Bug Fixes

    • 잘못된 입력을 방지: 분/초는 0–59로 자동 보정, 벨 횟수는 1–3으로 제한하며 빈 입력 시 기본값으로 복구됩니다.

@i-meant-to-be i-meant-to-be self-assigned this Sep 3, 2025
@i-meant-to-be i-meant-to-be added the fix 버그 수정 label Sep 3, 2025
@coderabbitai
Copy link

coderabbitai bot commented Sep 3, 2025

Walkthrough

TimerCreationContent.tsx updates bell configuration handling: initializes from initData or sessionStorage defaults, validates and sanitizes bell inputs (minutes/seconds and count), persists bell configs to sessionStorage on NORMAL timer submission, and replaces number inputs with numeric text inputs. Minor logging removed and constants added.

Changes

Cohort / File(s) Summary
Bell config persistence & input validation
src/page/TableComposition/components/TimerCreationContent/TimerCreationContent.tsx
Added sessionStorage persistence (SAVED_BELL_CONFIGS_KEY), default bell options, initialization from saved or initData.bell, save-on-submit for NORMAL type. Introduced handleBellCountChange (1–3) and getValidateTimeValue (0–59). Switched to numeric text inputs for 분/초, sanitized onChange handlers, removed verbose logs.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor User
  participant Component as TimerCreationContent
  participant Storage as sessionStorage

  Note over Component: Initialization
  Component->>Storage: getItem('savedBellInputConfigs')
  alt Saved configs exist
    Storage-->>Component: Parsed bell configs
    Component->>Component: Set bells from storage
  else No saved configs
    alt initData.bell exists
      Component->>Component: Set bells from initData.bell
    else
      Component->>Component: Set bells from defaultBellConfig
    end
  end

  Note over User,Component: Editing inputs
  User->>Component: Change min/sec fields
  Component->>Component: getValidateTimeValue (0–59)
  User->>Component: Change count field
  Component->>Component: handleBellCountChange (1–3)

  Note over Component,Storage: Submit (NORMAL)
  User->>Component: Submit timer (NORMAL)
  Component->>Storage: setItem('savedBellInputConfigs', bells)
  Component->>Component: onSubmit(...)
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Assessment against linked issues

Objective Addressed Explanation
리딩 제로 문제 수정 (#357) 리딩 제로 입력 처리/표시 방식이 구체적으로 명시되지 않아 정상화 여부를 단정하기 어려움.
종소리 설정이 저장되지 않고 초기화되는 문제 수정 (#357)

Assessment against linked issues: Out-of-scope changes

(해당 없음)

Possibly related PRs

Suggested reviewers

  • jaeml06
  • useon

Poem

딩-동, 내 종소리 메모해 두었네—퐁퐁!
분과 초를 다듬고, 횟수는 세어 퐁퐁퐁!
세션 바구니에 쏙 저장해,
다음에도 또 울리게.
토끼는 귀 쫑긋, 타이머는 똑딱—종!

✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/#357

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore or @coderabbit ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (7)
src/page/TableComposition/components/TimerCreationContent/TimerCreationContent.tsx (7)

71-71: 세션 스토리지 키에 네임스페이스/버전 태깅을 권장합니다.

다른 기능과의 키 충돌 방지 및 향후 마이그레이션(스키마 변경)을 쉽게 하려면 키에 제품 네임스페이스와 버전을 포함하세요.

-const SAVED_BELL_CONFIGS_KEY = 'savedBellInputConfigs';
+const SAVED_BELL_CONFIGS_KEY = 'debate-timer:bells:v1';

332-332: 세션 스토리지 저장 시 예외 처리와 빈 배열 처리 정책을 명확히 해주세요.

Quota/프라이빗 모드 등에서 setItem이 throw될 수 있습니다. 또한 bells가 빈 배열일 때 기존 백업을 덮어쓸지(빈으로 유지) 제거할지(디폴트로 복귀) 정책 결정을 권장합니다.

-      sessionStorage.setItem(SAVED_BELL_CONFIGS_KEY, JSON.stringify(bells));
+      try {
+        if (bells.length > 0) {
+          sessionStorage.setItem(SAVED_BELL_CONFIGS_KEY, JSON.stringify(bells));
+        } else {
+          // 정책 1) 빈 배열 저장을 원치 않으면 제거하여 디폴트로 폴백
+          // sessionStorage.removeItem(SAVED_BELL_CONFIGS_KEY);
+          // 정책 2) '빈 설정 유지'가 의도라면 아래 한 줄만 두고 remove는 제거
+          sessionStorage.setItem(SAVED_BELL_CONFIGS_KEY, JSON.stringify(bells));
+        }
+      } catch {
+        // 저장 실패는 무시(UX 영향 최소화)
+      }

정책(빈 배열 유지 vs 디폴트 복귀) 방향 알려주시면 코드 제안 반영해 드리겠습니다.


434-467: 횟수 입력 처리 단순화/일관화(숫자 클램프 1–3).

마지막 문자만 취하는 대신 시간 입력과 동일한 전략(숫자만 취득 → 정수화 → 범위 클램프)을 사용하면 간결하고 예측 가능한 UX가 됩니다.

-  const handleBellCountChange = useCallback(
-    (e: React.ChangeEvent<HTMLInputElement>) => {
-      const value = e.target.value;
-
-      // Backspace 대응
-      if (value === '') {
-        setBellInput((prev) => ({
-          ...prev,
-          count: 1,
-        }));
-        return;
-      }
-
-      // 마지막 입력 문자를 가져옴
-      const lastInput = value.slice(-1);
-      let newCount;
-
-      if (['1', '2', '3'].includes(lastInput)) {
-        // 유효한 입력(1, 2, 3)이면 해당 값으로 설정
-        newCount = lastInput;
-      } else {
-        // 유효하지 않은 문자(알파벳, 1~3 이외 숫자 등)가 마지막에 입력된 경우 무시
-        return;
-      }
-
-      setBellInput((prev) => ({
-        ...prev,
-        count: Number(newCount),
-      }));
-    },
-    [],
-  );
+  const handleBellCountChange = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
+    const digits = e.target.value.replace(/[^0-9]/g, '');
+    const next = digits === '' ? 1 : Math.max(1, Math.min(3, parseInt(digits, 10)));
+    setBellInput((prev) => ({ ...prev, count: next }));
+  }, []);

468-477: getValidateTimeValue 범용화(문자/숫자 입력 모두 허용).

타입을 확장해 재사용성을 조금 높이고 Number.isFinite로 안전성을 확보하세요.

-  const getValidateTimeValue = (value: string) => {
-    let num = parseInt(value, 10);
-    if (isNaN(num)) {
-      num = 0;
-    }
-
-    return Math.max(0, Math.min(59, num));
-  };
+  const getValidateTimeValue = (value: string | number) => {
+    const n = typeof value === 'number' ? value : parseInt(value, 10);
+    const num = Number.isFinite(n) ? n : 0;
+    return Math.max(0, Math.min(59, num));
+  };

724-739: 분 입력 UX/접근성 소폭 개선 제안.

maxLength로 과입력을 사전 차단하고, 스크린리더를 위해 aria-label을 추가하세요.

-                      <input
+                      <input
                         type="text"
                         inputMode="numeric"
                         pattern="[0-9]*"
                         className="w-[60px] rounded-[4px] border border-default-border p-[8px]"
+                        maxLength={2}
+                        aria-label="종소리 분"
                         value={bellInput.min}
                         onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                           const safeValue = e.target.value.replace(
                             /[^0-9]/g,
                             '',
                           );

745-760: 초 입력도 동일하게 UX/접근성 개선.

-                      <input
+                      <input
                         type="text"
                         inputMode="numeric"
                         pattern="[0-9]*"
                         className="w-[60px] rounded-[4px] border border-default-border p-[8px]"
+                        maxLength={2}
+                        aria-label="종소리 초"
                         value={bellInput.sec}
                         onChange={(e: React.ChangeEvent<HTMLInputElement>) => {
                           const safeValue = e.target.value.replace(
                             /[^0-9]/g,
                             '',
                           );

769-774: 횟수 입력 패턴 지정 및 접근성 보강.

숫자 키패드 유도는 이미 잘 하셨고, 패턴/최대 길이를 추가하면 더 견고해집니다.

-                      <input
+                      <input
                         type="text"
                         inputMode="numeric"
+                        pattern="[1-3]"
+                        maxLength={1}
+                        aria-label="종소리 횟수"
                         className="w-[60px] rounded-[4px] border border-default-border p-[8px]"
                         value={bellInput.count}
                         onChange={handleBellCountChange}
                         placeholder="횟수"
                       />
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 1f8c384 and 793d0f0.

📒 Files selected for processing (1)
  • src/page/TableComposition/components/TimerCreationContent/TimerCreationContent.tsx (7 hunks)
🧰 Additional context used
🧠 Learnings (1)
📓 Common learnings
Learnt from: i-meant-to-be
PR: debate-timer/debate-timer-fe#359
File: src/page/TableComposition/components/TimerCreationContent/TimerCreationContent.tsx:745-758
Timestamp: 2025-09-03T14:25:28.427Z
Learning: 사용자 i-meant-to-be는 PR #359에서 종소리 입력들(분, 초, 횟수 등)에 관한 리뷰를 생략하고 다른 PR에서 정리할 예정이라고 명시했다. 이런 입력 처리 로직 개선은 별도 PR로 분리하는 것을 선호한다.
🔇 Additional comments (1)
src/page/TableComposition/components/TimerCreationContent/TimerCreationContent.tsx (1)

200-206: 프로퍼티 타입 및 getInitialBells 로직을 직접 확인해보고 싶습니다. 확인 후 다시 코멘트 드리겠습니다.

Comment on lines +185 to +195
// 이전 종소리 설정
const rawBellConfigData = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
const defaultBellConfig: BellInputConfig[] = [
{ type: 'BEFORE_END', min: 0, sec: 30, count: 1 },
{ type: 'BEFORE_END', min: 0, sec: 0, count: 2 },
];
const savedBellOptions: BellInputConfig[] =
rawBellConfigData === null
? defaultBellConfig
: JSON.parse(rawBellConfigData);

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

JSON.parse 예외 미처리로 최초 렌더 크래시 위험이 있습니다.

세션 스토리지가 비정상 값(손상/수작업 편집)을 담고 있으면 JSON.parse에서 throw되어 컴포넌트가 초기 렌더 단계에서 터집니다. try/catch로 디폴트 폴백하세요.

-  const rawBellConfigData = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
-  const defaultBellConfig: BellInputConfig[] = [
+  const defaultBellConfig: BellInputConfig[] = [
     { type: 'BEFORE_END', min: 0, sec: 30, count: 1 },
     { type: 'BEFORE_END', min: 0, sec: 0, count: 2 },
   ];
-  const savedBellOptions: BellInputConfig[] =
-    rawBellConfigData === null
-      ? defaultBellConfig
-      : JSON.parse(rawBellConfigData);
+  let savedBellOptions: BellInputConfig[] = defaultBellConfig;
+  try {
+    const raw = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
+    if (raw) {
+      const parsed = JSON.parse(raw);
+      if (Array.isArray(parsed)) {
+        savedBellOptions = parsed as BellInputConfig[];
+      }
+    }
+  } catch {
+    // 손상된 값이면 안전하게 디폴트로 폴백
+    savedBellOptions = defaultBellConfig;
+  }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// 이전 종소리 설정
const rawBellConfigData = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
const defaultBellConfig: BellInputConfig[] = [
{ type: 'BEFORE_END', min: 0, sec: 30, count: 1 },
{ type: 'BEFORE_END', min: 0, sec: 0, count: 2 },
];
const savedBellOptions: BellInputConfig[] =
rawBellConfigData === null
? defaultBellConfig
: JSON.parse(rawBellConfigData);
// 이전 종소리 설정
const defaultBellConfig: BellInputConfig[] = [
{ type: 'BEFORE_END', min: 0, sec: 30, count: 1 },
{ type: 'BEFORE_END', min: 0, sec: 0, count: 2 },
];
let savedBellOptions: BellInputConfig[] = defaultBellConfig;
try {
const raw = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
if (raw) {
const parsed = JSON.parse(raw);
if (Array.isArray(parsed)) {
savedBellOptions = parsed as BellInputConfig[];
}
}
} catch {
// 손상된 값이면 안전하게 디폴트로 폴백
savedBellOptions = defaultBellConfig;
}
🤖 Prompt for AI Agents
In
src/page/TableComposition/components/TimerCreationContent/TimerCreationContent.tsx
around lines 185 to 195, JSON.parse on sessionStorage data can throw on
corrupted values causing initial render crashes; wrap the parse in a try/catch,
and on any error fall back to defaultBellConfig (optionally remove the bad
sessionStorage item) so savedBellOptions is always a valid BellInputConfig[].

Copy link
Contributor

@jaeml06 jaeml06 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

image 확인했습니다. 기능은 정상작동하는 것을 확인했습니다. 지금 발견한거지만 ClearInput뭐가 중첩된거 같은데 원래부터 이렇게 보였나요? 또한 예전에 TimeInputGroup.tsx에서 const validateTime = (value: string) => value === '' ? 0 : Math.max(0, Math.min(59, Number(value))); 으로 분초에 대한 leadingzero문제를 해결했었습니다. 지금이랑 로직은 같으니 그대로 가도 좋을 것 같아요

: 'time-based-timer';

// 이전 종소리 설정
const rawBellConfigData = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

이 부분을 통해서 session에 데이터를 저장해서 이전 벨 설정을 따라가는데, useState나 ref가 아니라 session스토리지를 선택하신 이유가 궁금합니다.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 숀의 이유가 궁금합니다 !! 새로고침 후에도 유지하기 위해서라면 세션도 좋은 선택지가 될 수 있겠네요 ㅎㅎㅎ

Copy link
Contributor Author

@i-meant-to-be i-meant-to-be Sep 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

제가 정확히는 이렇다라고 확정지어 말씀드리긴 애매하긴 한데, 만약 이 코드에서 useState나 ref를 사용하게 되면 타임박스 추가 모달이 닫혔을 때 정보가 다 사라져버릴 거라고 생각했어요. 그런데 우리는 모달 닫아도 이전 타임박스의 종소리 정보가 기억되기를 원하잖아요? 그럼 세션 스토리지에 저장하는게 현재로서는 가장 나은 선택지라고 생각했습니다.

Copy link
Contributor

@useon useon left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

정상 작동하는 것 확인했습니다 !! 001 이렇게 입력되거나 .이 입력되는 문제가 사라지고 이제 잘 입력되네요 !!! PR도 간결하고 잘 설명해 주셔서 이해하기 편했습니다 !! 디테일 챙겨주셔서 감사해요 숀 !!! 일단 동작에는 문제 없고 질문 하나만 남겼습니다 ㅎㅎ 어프루브 ~!

: 'time-based-timer';

// 이전 종소리 설정
const rawBellConfigData = sessionStorage.getItem(SAVED_BELL_CONFIGS_KEY);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 숀의 이유가 궁금합니다 !! 새로고침 후에도 유지하기 위해서라면 세션도 좋은 선택지가 될 수 있겠네요 ㅎㅎㅎ

@i-meant-to-be
Copy link
Contributor Author

/noti

확인했습니다. 기능은 정상작동하는 것을 확인했습니다. 지금 발견한거지만 ClearInput뭐가 중첩된거 같은데 원래부터 이렇게 보였나요?

image

이 부분 해결해 뒀는데요. 원인은 <input>typenumber로 지정할 경우 텍스트 필드 오른쪽 끝에 수를 +1, -1할 수 있는 화살표 버튼이 기본으로 나타나기 때문입니다. 이 화살표 버튼 가리는 스타일 태그 붙여서 병합 진행하겠습니다!

@i-meant-to-be i-meant-to-be merged commit b7af2ad into develop Sep 6, 2025
1 check passed
@i-meant-to-be i-meant-to-be deleted the fix/#357 branch September 6, 2025 14:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

fix 버그 수정

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

[FIX] 종소리 관련 오류 수정

4 participants