Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 17 additions & 6 deletions ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Architecture Map

Last updated: 2026-02-23
Last updated: 2026-08-05

## System Purpose

Expand All @@ -22,6 +22,10 @@ Current state: viewer/state API is implemented in this repository; downstream S2
- `GET /viewer/{docId}`: HTML viewer UI entrypoint (loading/failed/ready) that embeds PDF.js.
- `ArtifactController` (`src/main/java/com/clearfolio/viewer/controller/ArtifactController.java`)
- `GET /artifacts/{docId}.pdf`: serves PDF bytes for SUCCEEDED jobs with basic HTTP Range support.
- `HealthController` (`src/main/java/com/clearfolio/viewer/controller/HealthController.java`)
- `GET /healthz`: process liveness from Spring Boot `LivenessState`.
- `GET /readyz`: traffic readiness from Spring Boot `ReadinessState`.
- Probe payloads disclose only a controlled state label and use `Cache-Control: no-store`.
- `DefaultDocumentConversionService` (`src/main/java/com/clearfolio/viewer/service/DefaultDocumentConversionService.java`)
- Validation, content hash generation, dedupe lookup, repository persistence, worker enqueue.
- PDF passthrough: uploads that declare PDF (extension/content type) and carry the `%PDF-` magic header are seeded into the artifact store as-is, so the original bytes are served instead of a generated placeholder.
Expand All @@ -46,6 +50,13 @@ Current state: viewer/state API is implemented in this repository; downstream S2
- `ViewerBootstrapResponse` (`src/main/java/com/clearfolio/viewer/api/ViewerBootstrapResponse.java`)
- Includes deterministic `sourceExtension` and `rendererAdapter` metadata for viewer adapter bootstrap.

## Availability Model

- Liveness and readiness are separate operational contracts.
- Liveness determines restart eligibility and must not depend on shared external services.
- Readiness determines whether this instance receives traffic and may later include instance-local startup-recovery or overload signals through Spring availability events.
- The accepted ADR and Kubernetes example are in `docs/operations/2026-08-05-availability-probes.md`.

## State Model

- Status values: `SUBMITTED`, `PROCESSING`, `SUCCEEDED`, `FAILED`.
Expand All @@ -54,11 +65,10 @@ Current state: viewer/state API is implemented in this repository; downstream S2
## Operational Gates

- Build and test gates are defined in `AGENTS.md` and include:
- `mvn -DskipTests compile`
- `mvn test`
- JaCoCo line/branch 100% for `com.clearfolio.viewer.*`
- JavaDoc gate: `mvn -q -DskipTests javadoc:javadoc`
- Markdown lint for changed docs
- `mvn -B --no-transfer-progress verify` as the single complete merge-evidence command.
- JaCoCo 100% production line and branch coverage for `com.clearfolio.viewer.*` within the `verify` lifecycle.
- Warning-free public Javadoc validation within the same `verify` lifecycle.
- Markdown lint for changed documentation.

Mandatory AC list (exact):

Expand All @@ -85,5 +95,6 @@ Optional tracks:
- `docs/diagrams/status-flow.md`
- `docs/diagrams/preview-flow.md`
- `docs/diagrams/retry-deadletter-flow.md`
- `docs/operations/2026-08-05-availability-probes.md`
- `docs/engineering/acceptance-criteria.md`
- `docs/workflow/one-day-delivery-plan.md`
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
### Added

- **UI UX 개선**: 'Details' 버튼 클릭 시, 작업 상세 정보 로드 중에 사용자가 명시적인 로딩 상태를 확인할 수 있도록 'Loading...' 텍스트와 비활성화 상태를 표시하도록 추가했습니다.
- `GET /readyz` traffic-readiness probe를 추가하고 기존 `GET /healthz`를 Spring Boot `LivenessState` 기반 process-liveness probe로 명확히 분리했습니다. 두 경로는 `ApplicationAvailability` 상태를 사용하고 성공·실패 상태 코드와 제한된 응답 payload를 결정적 테스트로 고정합니다.
- **관리자용 단건 작업 삭제 및 재시도 API 추가**
- 특정 변환 작업을 삭제할 수 있는 `DELETE /api/v1/admin/convert/jobs/{jobId}` 엔드포인트를 추가했습니다.
- 실패(dead-lettered) 상태인 작업을 관리자가 재시도 큐에 등록할 수 있는 `POST /api/v1/admin/convert/jobs/{jobId}/retry` 엔드포인트를 추가했습니다.
Expand All @@ -24,6 +25,7 @@

### Security

- `/healthz`와 `/readyz`는 tenant, document, queue, dependency, credential, build 또는 exception 세부정보를 노출하지 않고 `Cache-Control: no-store`를 사용합니다. Liveness에는 shared external service 의존성을 추가하지 않아 외부 장애가 restart cascade로 증폭되는 것을 방지합니다.
- Maven XML 테스트 보고서 검증기는 각 `testsuite`의 `tests`, `skipped`, `failures`, `errors` 속성을 모두 필수 증거로 요구합니다. 누락된 결과 수를 암묵적으로 0으로 간주하지 않고 fail closed 처리하며, 각 속성 누락 회귀 테스트를 추가했습니다.
- Maven XML 테스트 보고서 검증기는 UTF-8만 허용하고 UTF-8 BOM은 수용하며, NUL 바이트·DTD·엔터티 선언을 파싱 전에 거부합니다. UTF-16 같은 대체 인코딩으로 위험 선언을 바이트 검사에서 숨기는 우회와 외부 엔터티 읽기·엔터티 확장형 서비스 거부를 회귀 테스트로 차단했습니다.
- Maven XML 테스트 보고서 검증기는 파일당 16 MiB 상한을 적용하고 한 번의 제한된 읽기로 실제 입력 크기를 검증합니다. 테스트 코드가 보고서 파일을 교체하거나 확장해도 크기 사전검사와 파싱 사이의 경쟁 조건을 이용할 수 없습니다.
Expand Down
Loading
Loading