Skip to content

[Feat] 문서 목록 조회 API - #154

Merged
Gimini-3 merged 5 commits into
developfrom
feature/153
Aug 13, 2026
Merged

[Feat] 문서 목록 조회 API#154
Gimini-3 merged 5 commits into
developfrom
feature/153

Conversation

@Gimini-3

@Gimini-3 Gimini-3 commented Aug 12, 2026

Copy link
Copy Markdown
Contributor

closes #153

배경

문서 도메인에는 업로드와 단건 인덱싱 상태 조회만 있고 사용자가 읽을 수 있는 문서 목록을 반환하는 API가 없었다. 업로드 후 documentId를 따로 기억하지 않으면 문서를 다시 찾아갈 방법이 없어 문서 화면을 구성할 수 없었다.

변경 내용

권한 쿼리를 복제하지 않고 상태 조건만 파라미터화

권한 판정은 검색 pre-filter가 쓰는 DocumentRepository의 UNION 쿼리에 이미 있다(OWNER / PUBLIC / USER 캐시 / ROLE live / DEPARTMENT live). 다만 d.status = 'INDEXED'가 하드코딩되어 있어 인덱싱 중이거나 실패한 문서를 목록에 노출할 수 없었다.

UNION 7개 브랜치짜리 쿼리를 목록용으로 복사하면 권한 정책이 두 벌이 되어 접근 경로가 추가될 때 한쪽만 고치는 사고가 나기 쉽다. d.status IN (:statuses)로 바꾸고 호출부에서 상태를 넘기는 방식으로 한 벌을 유지했다.

호출자 넘기는 상태
AccessibleDocumentQueryService (검색) INDEXED — 기존 동작 그대로
DocumentQueryService (목록) DELETED 제외 전체, 또는 요청한 단일 상태

권한 판정과 페이징 분리

읽을 수 있는 문서 ID를 먼저 구하고, 그 집합에 대해 JPQL 페이지 쿼리로 정렬·페이징만 수행한다. Document.currentVersionLAZY라 버전 번호·상태를 응답에 담기 위해 LEFT JOIN FETCH하고 countQuery를 분리했다. 읽을 수 있는 문서가 없으면 페이지 쿼리를 실행하지 않고 빈 응답을 반환한다.

정렬은 createdAt DESC, id DESC 고정이며 외부 sort 입력을 받지 않는다.

API

GET /api/documents?status=INDEXED&page=0&size=20
파라미터 필수 기본값 설명
status X 없음 지정 시 해당 상태만. 미지정 시 DELETED 제외 전체
page X 0 0부터 시작
size X 20 1~100

응답은 PageResponse<DocumentSummaryResponse>. 인덱싱이 끝난 버전이 없으면 currentVersionNo·currentVersionStatusnull이다.

에러 케이스는 설계 문서에 정리했다. 읽을 수 있는 문서가 없는 것은 정상 상태이므로 404가 아니라 빈 페이지를 반환하고, 권한 없는 문서는 존재 여부를 노출하지 않고 조용히 제외한다.

테스트

DocumentQueryServiceTest 4개(정상 페이지 / 권한 없을 때 문서 조회 스킵 / status 미지정 시 DELETED 제외 / status 지정), DocumentReadableIdsRepositoryTest 4개(@DataJpaTest로 실제 UNION 쿼리 검증) 추가.

상태 파라미터화가 검색 경로를 바꾸지 않았는지 AccessibleDocumentQueryServiceTest, SearchFacadeTest, DocumentIndexingCompletionIntegrationTest로 확인했다.

./gradlew build — 760개 테스트 전부 통과.

검색 pre-filter UNION 쿼리에 하드코딩된 status = 'INDEXED'를 파라미터로 바꿔
목록 조회에서도 재사용할 수 있게 한다. 쿼리를 복제하면 권한 정책이 두 벌이 되어
접근 경로가 추가될 때 한쪽만 고치는 사고가 나기 쉽다.

검색 호출부는 INDEXED만 넘겨 기존 동작을 그대로 유지한다.
목록 화면용 페이지 조회 쿼리도 함께 추가한다.
권한 pre-filter로 읽을 수 있는 문서 ID를 먼저 좁히고, 그 집합에 대해서만
정렬·페이징을 수행한다. 읽을 수 있는 문서가 없으면 페이지 쿼리를 실행하지 않는다.

정렬은 createdAt DESC, id DESC로 고정한다. 정렬 키를 외부에 열어두면
인덱스 없는 컬럼 정렬 요청이 그대로 DB로 흘러가고 응답 계약도 불안정해진다.
GET /api/documents로 로그인 사용자가 읽을 수 있는 문서를 페이지 조회한다.
@validated로 page는 0 이상, size는 1~100 범위를 검증한다.
목록 조회의 권한 필터, status 기본값과 명시 지정 동작을 단위 테스트로 검증하고
상태 파라미터가 실제 UNION 쿼리에 반영되는지 @DataJpaTest로 확인한다.

Repository 테스트는 seed 데이터에 PUBLIC·INDEXED 문서가 있어 모든 사용자
조회 결과에 포함되므로, 테스트가 생성한 문서만 포함·제외로 검증한다.

상태 파라미터화로 시그니처가 바뀐 기존 검색 테스트 호출부도 함께 맞춘다.
@Gimini-3 Gimini-3 added the ✨ Feature 기능 개발 label Aug 12, 2026
@coderabbitai

coderabbitai Bot commented Aug 12, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

문서 목록 조회 API를 추가했습니다. 사용자의 읽기 권한을 먼저 확인한 뒤 상태 필터, 고정 정렬, 페이지네이션을 적용합니다. 검색은 기존처럼 INDEXED 상태만 조회합니다. 문서 요약 응답과 Repository·서비스·컨트롤러 테스트를 추가했습니다.

Changes

문서 목록 조회 API

Layer / File(s) Summary
목록 API와 응답 계약
src/main/java/com/opensource/docgrid/domain/document/controller/DocumentQueryController.java, src/main/java/com/opensource/docgrid/domain/document/converter/DocumentSummaryConverter.java, src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java, docs/design/...
GET /api/documents를 추가했습니다. 상태, 페이지 번호, 페이지 크기를 받습니다. 문서 요약 응답은 현재 버전이 없을 때 버전 필드를 null로 반환합니다.
권한 필터와 페이지 조회
src/main/java/com/opensource/docgrid/domain/document/repository/DocumentRepository.java, src/main/java/com/opensource/docgrid/domain/document/service/query/DocumentQueryService.java
읽을 수 있는 문서 ID 조회에 상태 조건을 적용합니다. 문서가 없으면 빈 페이지를 반환합니다. 문서가 있으면 currentVersion을 포함해 createdAt DESC, id DESC로 페이징합니다.
검색 상태 제한 유지
src/main/java/com/opensource/docgrid/domain/search/service/query/AccessibleDocumentQueryService.java, src/test/java/com/opensource/docgrid/domain/search/service/query/AccessibleDocumentQueryServiceTest.java, src/test/java/com/opensource/docgrid/domain/embedding/integration/DocumentIndexingCompletionIntegrationTest.java
검색 전체 조회와 컬렉션 조회에 INDEXED 상태 조건을 전달합니다. 관련 검색 및 인덱싱 완료 테스트를 갱신했습니다.
목록 및 Repository 동작 검증
src/test/java/com/opensource/docgrid/domain/document/repository/DocumentReadableIdsRepositoryTest.java, src/test/java/com/opensource/docgrid/domain/document/service/query/DocumentQueryServiceTest.java
상태별 권한 필터, soft delete 제외, 컬렉션 조회, 빈 페이지, 기본 상태 목록, 지정 상태 목록, 응답 변환과 페이지 메타데이터를 검증합니다.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant DocumentQueryController
  participant DocumentQueryService
  participant DocumentRepository
  participant DocumentSummaryConverter

  Client->>DocumentQueryController: GET /api/documents?status&page&size
  DocumentQueryController->>DocumentQueryService: getMyDocuments(userId, status, page, size)
  DocumentQueryService->>DocumentRepository: readable document IDs with statuses
  DocumentRepository-->>DocumentQueryService: accessible IDs
  DocumentQueryService->>DocumentRepository: paged documents with currentVersion
  DocumentRepository-->>DocumentQueryService: Page<Document>
  DocumentQueryService->>DocumentSummaryConverter: convert each document
  DocumentSummaryConverter-->>DocumentQueryService: DocumentSummaryResponse
  DocumentQueryService-->>DocumentQueryController: PageResponse
  DocumentQueryController-->>Client: document summary page
Loading

Possibly related PRs

  • DocGrid/backend#19: 권한 필터링된 문서 ID 조회와 접근 캐시 동작을 재사용합니다.
  • DocGrid/backend#57: DocumentRepository의 상태 파라미터화와 검색 pre-filter 흐름이 직접 연결됩니다.
  • DocGrid/backend#87: INDEXED 상태와 문서 인덱싱 상태 전환을 공유합니다.
🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Issue #153의 API, 상태 필터, 권한 재사용, 페이징, 응답, 테스트 및 문서화 요구사항을 모두 반영합니다.
Out of Scope Changes check ✅ Passed 변경 사항이 문서 목록 조회 API 구현과 관련 테스트 및 설계 문서 범위에 포함됩니다.
Title check ✅ Passed 제목이 문서 목록 조회 API 추가라는 PR의 핵심 변경을 명확하고 간결하게 설명합니다.
Description check ✅ Passed 배경, 변경 내용, API 형식, 테스트 결과와 연결 이슈를 구체적으로 설명해 전반적으로 템플릿 요구사항을 충족합니다.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/153

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

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java (1)

12-25: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

신규 Java 타입에 클래스 수준 주석을 추가하십시오.

  • src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java#L12-L25: 목록 API 응답 DTO의 역할, 포함 범위, 불변 응답 계약을 설명하는 주석을 추가하십시오.
  • src/main/java/com/opensource/docgrid/domain/document/converter/DocumentSummaryConverter.java#L9-L10: Document를 목록 응답 DTO로 변환하는 책임과 경계를 설명하는 주석을 추가하십시오.

As per coding guidelines: “Every newly created class, interface, or record must have a class-level comment explaining its role, responsibility, and boundary.”

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java`
around lines 12 - 25, Add class-level comments to DocumentSummaryResponse and
DocumentSummaryConverter. In
src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java
lines 12-25, document the list API response DTO’s role, included scope, and
immutable response contract; in
src/main/java/com/opensource/docgrid/domain/document/converter/DocumentSummaryConverter.java
lines 9-10, document its responsibility and boundary for converting Document
instances into list response DTOs.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In
`@src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java`:
- Around line 12-25: Add class-level comments to DocumentSummaryResponse and
DocumentSummaryConverter. In
src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java
lines 12-25, document the list API response DTO’s role, included scope, and
immutable response contract; in
src/main/java/com/opensource/docgrid/domain/document/converter/DocumentSummaryConverter.java
lines 9-10, document its responsibility and boundary for converting Document
instances into list response DTOs.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: ddd1ac1e-2ad7-495c-8cc1-b2b8034c19e2

📥 Commits

Reviewing files that changed from the base of the PR and between 2e45c49 and c56b583.

📒 Files selected for processing (11)
  • docs/design/gimin-#153-document-list-api.md
  • src/main/java/com/opensource/docgrid/domain/document/controller/DocumentQueryController.java
  • src/main/java/com/opensource/docgrid/domain/document/converter/DocumentSummaryConverter.java
  • src/main/java/com/opensource/docgrid/domain/document/dto/response/DocumentSummaryResponse.java
  • src/main/java/com/opensource/docgrid/domain/document/repository/DocumentRepository.java
  • src/main/java/com/opensource/docgrid/domain/document/service/query/DocumentQueryService.java
  • src/main/java/com/opensource/docgrid/domain/search/service/query/AccessibleDocumentQueryService.java
  • src/test/java/com/opensource/docgrid/domain/document/repository/DocumentReadableIdsRepositoryTest.java
  • src/test/java/com/opensource/docgrid/domain/document/service/query/DocumentQueryServiceTest.java
  • src/test/java/com/opensource/docgrid/domain/embedding/integration/DocumentIndexingCompletionIntegrationTest.java
  • src/test/java/com/opensource/docgrid/domain/search/service/query/AccessibleDocumentQueryServiceTest.java

@Gimini-3
Gimini-3 merged commit a23c800 into develop Aug 13, 2026
1 check passed
@Gimini-3 Gimini-3 self-assigned this Aug 13, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

✨ Feature 기능 개발

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feat] 문서 목록 조회 API

1 participant