Skip to content

[#362] 프로젝트 대본 일괄 수정 및 전체 조회 API 추가#363

Merged
PeraSite merged 3 commits intodevfrom
codex/feat-roro-bulk-edit
Feb 18, 2026
Merged

[#362] 프로젝트 대본 일괄 수정 및 전체 조회 API 추가#363
PeraSite merged 3 commits intodevfrom
codex/feat-roro-bulk-edit

Conversation

@PeraSite
Copy link
Copy Markdown
Collaborator

@PeraSite PeraSite commented Feb 18, 2026

🔗 관련 이슈

✨ 변경 내용

  • GET /presentations/:projectId/scripts를 추가해 프로젝트 전체 대본 조회를 지원합니다.
  • PATCH /presentations/:projectId/scripts/bulk-edit를 추가해 여러 슬라이드 대본 일괄 수정을 지원합니다.
  • Bulk edit payload validation을 추가했습니다.
    • 빈 scripts 배열
    • 잘못된 slideId 형식
    • 중복 slideId
    • 프로젝트 미소속 slideId
  • Script 에러 코드를 bulk edit 시나리오(SC003~SC005)로 정리했습니다.
  • controller/service/repository를 확장해 프로젝트 단위 대본 조회/수정 집계를 구성했습니다.
  • script controller/service 테스트를 bulk edit 흐름 기준으로 보강했습니다.

✅ 체크리스트

  • 로컬에서 빌드/테스트 통과
  • 관련 문서(README, API 문서 등) 업데이트
  • Breaking Change 여부 확인 (있다면 아래에 명시)

⚠️ Breaking Change (선택)

  • 기존 POST /presentations/:projectId/scripts/import 경로 제거로 인해 해당 엔드포인트를 호출하던 클라이언트는 신규 bulk edit 계약으로 전환이 필요합니다.

📌 기타 참고 사항 (선택)

  • 실행 테스트: npm test -- tests/script

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @PeraSite, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

이 PR은 프로젝트 대본 관리 기능을 대폭 개선합니다. 사용자는 이제 특정 프로젝트의 모든 슬라이드 대본을 한 번에 조회할 수 있으며, 여러 슬라이드의 대본을 효율적으로 일괄 수정할 수 있게 됩니다. 이는 대본 작업의 생산성을 향상시키고, 데이터 일관성을 보장하기 위한 강력한 유효성 검사 로직을 포함합니다.

Highlights

  • 새로운 API 엔드포인트 추가: 프로젝트 전체 대본을 조회하는 GET /presentations/:projectId/scripts와 여러 슬라이드 대본을 한 번에 수정하는 PATCH /presentations/:projectId/scripts/bulk-edit 두 가지 새로운 API 엔드포인트가 추가되었습니다.
  • 일괄 수정 유효성 검사 강화: 일괄 대본 수정 요청 본문(payload)에 대한 강력한 유효성 검사 로직이 구현되었습니다. 이는 빈 스크립트 배열, 잘못된 슬라이드 ID 형식, 중복된 슬라이드 ID, 그리고 프로젝트에 속하지 않은 슬라이드 ID를 효과적으로 감지합니다.
  • 스크립트 에러 코드 정리: 일괄 수정 시나리오에 특화된 새로운 스크립트 에러 코드(SC003~SC005)가 추가되어 에러 처리가 더욱 명확해졌습니다.
  • 기존 API 경로 제거 (Breaking Change): 기존 POST /presentations/:projectId/scripts/import 경로가 제거되었습니다. 해당 엔드포인트를 사용하던 클라이언트는 새로운 일괄 수정 API로 전환해야 합니다.
  • 테스트 커버리지 확장: 새로 추가된 컨트롤러 및 서비스 로직에 대한 테스트 코드가 작성 및 보강되어 기능의 안정성을 확보했습니다.
Changelog
  • src/controllers/script.controller.js
    • processBulkEditProjectScriptsprocessGetProjectScripts 서비스 함수를 임포트했습니다.
    • handleGetProjectScriptshandleBulkEditProjectScripts 컨트롤러 함수를 추가하여 새로운 API 엔드포인트를 처리하도록 확장했습니다.
  • src/errors/script.error.js
    • 일괄 수정과 관련된 새로운 에러 클래스(ScriptBulkEditPayloadError, ScriptBulkEditDuplicateSlideError, ScriptBulkEditSlideNotFoundError)를 정의했습니다.
  • src/repositories/script.repository.js
    • 프로젝트에 속한 슬라이드와 해당 대본을 조회하는 getProjectSlidesWithScripts 함수를 추가했습니다.
  • src/routes/project.route.js
    • 프로젝트 전체 대본 조회 (GET /presentations/:projectId/scripts) 및 프로젝트 대본 일괄 수정 (PATCH /presentations/:projectId/scripts/bulk-edit)을 위한 새로운 라우트를 추가했습니다.
  • src/services/script.service.js
    • 일괄 수정 요청 본문을 정규화하고 유효성을 검사하는 normalizeBulkEditScripts 함수를 추가했습니다.
    • 프로젝트 대본을 조회하는 processGetProjectScripts 함수를 추가했습니다.
    • 대본을 일괄 수정하는 processBulkEditProjectScripts 함수를 추가했습니다.
    • 관련 에러 클래스 및 리포지토리 함수를 임포트했습니다.
  • tests/script/script.bulk-edit.service.test.js
    • 새로운 일괄 수정 서비스 로직에 대한 단위 테스트 파일을 추가하여, 대본 조회 및 일괄 수정 기능의 정확성과 에러 처리 로직을 검증했습니다.
  • tests/script/script.controller.test.js
    • 스크립트 컨트롤러 테스트 파일에 handleGetProjectScriptshandleBulkEditProjectScripts에 대한 테스트 케이스를 추가하여, 새로운 API 엔드포인트의 동작을 확인했습니다.
Activity
  • 프로젝트 전체 대본 조회 및 일괄 수정 API 엔드포인트가 구현되었습니다.
  • 일괄 수정 요청에 대한 상세한 유효성 검사 로직이 추가되었습니다.
  • 스크립트 관련 에러 코드가 일괄 수정 시나리오에 맞춰 확장 및 정리되었습니다.
  • 컨트롤러, 서비스, 리포지토리 계층이 새로운 기능 지원을 위해 확장되었습니다.
  • 새로운 서비스 로직 및 컨트롤러 엔드포인트에 대한 테스트 코드가 작성 및 보강되었습니다.
  • 로컬 빌드 및 테스트가 성공적으로 완료되었습니다.
  • 관련 문서(API 문서 등) 업데이트가 확인되었습니다.
  • 기존 POST /presentations/:projectId/scripts/import 엔드포인트 제거로 인한 Breaking Change가 명시되었습니다.
  • npm test -- tests/script 명령어를 통한 실행 테스트 방법이 제공되었습니다.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

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

Code Review

이번 PR은 프로젝트의 모든 대본을 조회하고 일괄 수정하는 API를 추가하는 내용이네요. 전반적으로 기능 구현이 잘 이루어졌고, 특히 페이로드 유효성 검사와 에러 처리가 꼼꼼하게 추가된 점이 좋습니다. 테스트 코드도 잘 작성되어 신뢰성을 높여줍니다. 몇 가지 성능 및 사용성 개선을 위한 제안 사항을 리뷰 코멘트로 남겼으니 확인해 보시면 좋겠습니다.

Comment thread src/services/script.service.js Outdated
Comment on lines +145 to +152
const invalidSlide = normalizedScripts.find((item) => !projectSlideIds.has(item.slideId));

if (invalidSlide) {
throw new ScriptBulkEditSlideNotFoundError({
projectId,
slideId: invalidSlide.slideId,
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

현재 구현에서는 find를 사용하여 프로젝트에 속하지 않는 첫 번째 슬라이드 ID만 찾아 에러를 발생시키고 있습니다. 만약 여러 개의 유효하지 않은 슬라이드 ID가 포함된 경우, 사용자는 한 번에 하나의 에러만 피드백 받고 수정을 반복해야 하므로 불편할 수 있습니다. filter를 사용하여 모든 유효하지 않은 슬라이드 ID를 한 번에 찾아 알려주면 개발자 경험을 개선할 수 있습니다.

Suggested change
const invalidSlide = normalizedScripts.find((item) => !projectSlideIds.has(item.slideId));
if (invalidSlide) {
throw new ScriptBulkEditSlideNotFoundError({
projectId,
slideId: invalidSlide.slideId,
});
}
const invalidSlideIds = normalizedScripts
.filter((item) => !projectSlideIds.has(item.slideId))
.map((item) => item.slideId);
if (invalidSlideIds.length > 0) {
throw new ScriptBulkEditSlideNotFoundError({
projectId,
slideIds: invalidSlideIds,
});
}

Comment thread src/services/script.service.js Outdated
Comment on lines +158 to +168
for (const item of normalizedScripts) {
const { isUpdated } = await processScriptUpdate(item.slideId, item.scriptText);

if (isUpdated) {
updatedSlideCount += 1;
updatedSlideIds.push(item.slideId);
continue;
}

unchangedSlideCount += 1;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

medium

대본 일괄 수정 시 for 루프 내에서 await를 사용하여 각 대본을 순차적으로 업데이트하고 있습니다. 대본이 많을 경우 이로 인해 API 응답 시간이 길어질 수 있습니다. 각 슬라이드의 대본 업데이트는 서로 독립적이므로 Promise.all을 사용하여 병렬로 처리하면 성능을 크게 향상시킬 수 있습니다. 아래와 같이 수정하는 것을 제안합니다.

  const updatePromises = normalizedScripts.map((item) =>
    processScriptUpdate(item.slideId, item.scriptText),
  );
  const updateResults = await Promise.all(updatePromises);

  updateResults.forEach((result, index) => {
    if (result.isUpdated) {
      updatedSlideCount++;
      updatedSlideIds.push(normalizedScripts[index].slideId);
    } else {
      unchangedSlideCount++;
    }
  });

@PeraSite PeraSite merged commit fe707f1 into dev Feb 18, 2026
@PeraSite PeraSite deleted the codex/feat-roro-bulk-edit branch February 18, 2026 05:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[feat][로로] 프로젝트 대본 일괄 수정 및 전체 대본 조회 API 추가

1 participant