feat: 홈과 주제의 최근 기록이 게시된 Open Question 을 담는다
질문을 게시해도 홈 최근 기록에 나오지 않았다. 백엔드가 담지 않은 것이 아니라 담을 수
없었다 — 계약의 `LatestEntry.entryType` 이 CASE/REFERENCE/PROJECT_ACTIVITY/RELEASE 넷만
허용했고, 계약 밖 값을 응답 매퍼에 넘기면 500 이 되어 홈 화면 전체를 못 쓰게 만들기 때문에
질의가 먼저 걸러 내고 있었다.
계약을 넓혔으므로(design-package ef49d3a) 걸러 낼 이유가 사라졌다. `LATEST_ENTRY_TYPES` 에
`QUESTION` 을 더한다. `pathOf` 는 이미 `/questions/{slug}` 를 만들고 있었고, projection 에도
질문 행이 `ACTIVE`/`PUBLIC` 으로 `navigation_path` 까지 채워진 채 들어 있었다 — 막고 있던
것은 이 `IN` 목록 하나였다.
`LATEST_ENTRY_TYPES` 는 홈과 주제 상세가 함께 쓴다. 두 목록의 의미가 같으므로 한 곳만
넓히면 둘 다 따라오고, 그것이 의도다. 두 화면 각각에 "게시한 Open Question 이 목록에
나온다"는 단언을 세워 둔다 — 유형 허용 목록만 검사하면 담기지 않아도 통과한다.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0189NzCryfeqDzS81EWidnBx
This commit is contained in:
co-authored by
Claude Opus 5
parent
c6d9d2d675
commit
edb0890dc8
+2
-2
@@ -180,8 +180,8 @@ public class JdbcPublicSiteQueryAdapter implements PublicSiteQueryPort {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 계약 {@code LatestEntry.entryType} 은 {@code CASE / REFERENCE / PROJECT_ACTIVITY / RELEASE} 네 값만
|
* 계약 {@code LatestEntry.entryType} 은 {@code CASE / REFERENCE / QUESTION / PROJECT_ACTIVITY /
|
||||||
* 허용한다. projection 에는 {@code QUESTION}·{@code PROJECT}·{@code PROJECT_DECISION}·{@code PROFILE} 도
|
* RELEASE} 다섯 값을 허용한다. projection 에는 {@code PROJECT}·{@code PROJECT_DECISION}·{@code PROFILE} 도
|
||||||
* 들어 있으므로 여기서 걸러야 한다 — 거르지 않으면 응답 매퍼가 계약 밖 값을 만나 500 이 되고, 그 500 은 홈 화면 전체를 못 쓰게 만든다.
|
* 들어 있으므로 여기서 걸러야 한다 — 거르지 않으면 응답 매퍼가 계약 밖 값을 만나 500 이 되고, 그 500 은 홈 화면 전체를 못 쓰게 만든다.
|
||||||
*
|
*
|
||||||
* <p>{@code RELEASE} 가 결과에 없는 것은 누락이 아니다. 릴리스는 Publication 파이프라인을 거치지 않고 자체 {@code
|
* <p>{@code RELEASE} 가 결과에 없는 것은 누락이 아니다. 릴리스는 Publication 파이프라인을 거치지 않고 자체 {@code
|
||||||
|
|||||||
+1
-1
@@ -16,7 +16,7 @@ final class PublicSql {
|
|||||||
* 조건도 한 곳에서 정의한다.
|
* 조건도 한 곳에서 정의한다.
|
||||||
*/
|
*/
|
||||||
static final String LATEST_ENTRY_TYPES =
|
static final String LATEST_ENTRY_TYPES =
|
||||||
" p.resource_type IN ('CASE', 'REFERENCE', 'PROJECT_ACTIVITY') ";
|
" p.resource_type IN ('CASE', 'REFERENCE', 'QUESTION', 'PROJECT_ACTIVITY') ";
|
||||||
|
|
||||||
private PublicSql() {}
|
private PublicSql() {}
|
||||||
|
|
||||||
|
|||||||
+20
-5
@@ -206,12 +206,21 @@ class PublicSitePersistenceIntegrationTest {
|
|||||||
.noneMatch(entry -> entry.title().contains("숨김"));
|
.noneMatch(entry -> entry.title().contains("숨김"));
|
||||||
assertThat(view.latestEntries())
|
assertThat(view.latestEntries())
|
||||||
.as(
|
.as(
|
||||||
"계약 LatestEntry.entryType 은 네 값만 허용한다 — projection 의 QUESTION/PROJECT 등이 섞이면"
|
"계약 LatestEntry.entryType 이 허용하는 값만 나와야 한다 — projection 의 PROJECT/PROJECT_DECISION"
|
||||||
+ " 응답 매퍼가 계약 밖 값을 만나 500 이 된다")
|
+ " 등이 섞이면 응답 매퍼가 계약 밖 값을 만나 500 이 되고, 그 500 은 홈 화면 전체를 못 쓰게 만든다")
|
||||||
.extracting("entryType")
|
.extracting("entryType")
|
||||||
.containsAnyOf("CASE", "REFERENCE", "PROJECT_ACTIVITY")
|
.containsAnyOf("CASE", "REFERENCE", "PROJECT_ACTIVITY")
|
||||||
.allSatisfy(
|
.allSatisfy(
|
||||||
type -> assertThat(type).isIn("CASE", "REFERENCE", "PROJECT_ACTIVITY", "RELEASE"));
|
type ->
|
||||||
|
assertThat(type)
|
||||||
|
.isIn("CASE", "REFERENCE", "QUESTION", "PROJECT_ACTIVITY", "RELEASE"));
|
||||||
|
assertThat(view.latestEntries())
|
||||||
|
.as("게시한 Open Question 도 최근 기록에 나와야 한다 — 목록에서 빠지면 게시한 사실이 어디에도 보이지 않는다")
|
||||||
|
.anySatisfy(
|
||||||
|
entry -> {
|
||||||
|
assertThat(entry.entryType()).isEqualTo("QUESTION");
|
||||||
|
assertThat(entry.path()).isEqualTo("/questions/reprocessing-latency");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -397,10 +406,16 @@ class PublicSitePersistenceIntegrationTest {
|
|||||||
assertThat(view.relatedProjects()).extracting("title").contains("Tech Log");
|
assertThat(view.relatedProjects()).extracting("title").contains("Tech Log");
|
||||||
assertThat(view.latestRecords()).isNotEmpty();
|
assertThat(view.latestRecords()).isNotEmpty();
|
||||||
assertThat(view.latestRecords())
|
assertThat(view.latestRecords())
|
||||||
.as("주제 상세의 최신 기록도 계약의 entryType 네 값을 벗어나면 안 된다")
|
.as("주제 상세의 최신 기록도 계약의 entryType 을 벗어나면 안 된다")
|
||||||
.extracting("entryType")
|
.extracting("entryType")
|
||||||
.allSatisfy(
|
.allSatisfy(
|
||||||
type -> assertThat(type).isIn("CASE", "REFERENCE", "PROJECT_ACTIVITY", "RELEASE"));
|
type ->
|
||||||
|
assertThat(type)
|
||||||
|
.isIn("CASE", "REFERENCE", "QUESTION", "PROJECT_ACTIVITY", "RELEASE"));
|
||||||
|
assertThat(view.latestRecords())
|
||||||
|
.as("주제와 홈은 같은 목록 의미를 쓴다 — 홈에 나오는 Open Question 이 여기서 빠지면 두 화면이 어긋난다")
|
||||||
|
.extracting("entryType")
|
||||||
|
.contains("QUESTION");
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# source: tech-log-design-package contracts/openapi/studio-v1.yaml @ 0ffbc28 (master)
|
# source: tech-log-design-package contracts/openapi/studio-v1.yaml @ 0ffbc28 (master)
|
||||||
18dd46898be64b07f7e826409d19347512613ee2e22420028a4a0644f50f37dd studio-v1.yaml
|
18dd46898be64b07f7e826409d19347512613ee2e22420028a4a0644f50f37dd studio-v1.yaml
|
||||||
# source: tech-log-design-package contracts/openapi/public-v1.yaml @ 0ffbc28 (master)
|
# source: tech-log-design-package contracts/openapi/public-v1.yaml @ ef49d3a (master)
|
||||||
79949b286e2b4d28333d3376945960a319d247b675b23a73f50b75ce10994c5e public-v1.yaml
|
7eb668e39e279e49767306dd36e1dd51302071c39d78495d21307bbd9676220e public-v1.yaml
|
||||||
# source: tech-log-design-package contracts/openapi/studio-management-v1.yaml @ 0ffbc28 (master)
|
# source: tech-log-design-package contracts/openapi/studio-management-v1.yaml @ 0ffbc28 (master)
|
||||||
72650735061fde627f5037571eb986cb758f44a546f065c88408399f8eec4a55 studio-management-v1.yaml
|
72650735061fde627f5037571eb986cb758f44a546f065c88408399f8eec4a55 studio-management-v1.yaml
|
||||||
|
|||||||
@@ -1022,6 +1022,7 @@ components:
|
|||||||
enum:
|
enum:
|
||||||
- CASE
|
- CASE
|
||||||
- REFERENCE
|
- REFERENCE
|
||||||
|
- QUESTION
|
||||||
- PROJECT_ACTIVITY
|
- PROJECT_ACTIVITY
|
||||||
- RELEASE
|
- RELEASE
|
||||||
title:
|
title:
|
||||||
|
|||||||
Reference in New Issue
Block a user