fix: Decision 미리보기가 열리도록 프로젝트 공개 경로를 catalog 에 싣는다

Decision 문서는 즉시 미리보기가 어떤 문서에서도 열리지 않았다.

Decision 의 공개 주소는 자기 slug 가 아니라 `<프로젝트 경로>/decisions#<slug>` 다.
그래서 렌더 모델이 프로젝트의 공개 경로를 요구하는데, PROJECT catalog 는 그 자리를
언제나 null 로 돌려주고 있었다 — 게시된 프로젝트인지 아닌지와 무관하게 상수 null
이었다. 미리보기는 "PROJECT public path is required" 로 멈췄고, 화면에는 무엇이
모자란지 나오지 않았다.

게시된 프로젝트만 경로를 싣는다. 게시되지 않았으면 공개 주소가 실제로 없고, 없는
주소를 지어내면 미리보기가 보여 준 링크가 게시 뒤에 달라진다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XEHXspz4rv5pB5wiiSsVDu
This commit is contained in:
DongHyeonka
2026-08-24 17:25:31 +09:00
co-authored by Claude Opus 5
parent a7e2b7d7fe
commit bd66fb3610
2 changed files with 47 additions and 3 deletions
@@ -68,11 +68,25 @@ public class JdbcCatalogQueryAdapter implements CatalogQueryPort {
.list();
}
/**
* 프로젝트의 공개 경로를 함께 싣는다.
*
* <p>여기서 {@code publicPath} 를 늘 null 로 두었더니 Decision 의 즉시 미리보기가 어떤 문서에서도 열리지 않았다. Decision 의 공개
* 주소는 자기 slug 가 아니라 {@code <프로젝트 경로>/decisions#<slug>} 라, 렌더 모델이 프로젝트 경로를 요구한다 — 그것이 비어 있으면
* "PROJECT public path is required" 로 미리보기 전체가 멈춘다. 화면에는 무엇이 모자란지 나오지 않는다.
*
* <p>게시되지 않은 프로젝트는 여전히 null 이다. 그때는 공개 주소가 실제로 없고, 없는 주소를 지어내면 미리보기가 보여 주는 링크가 게시 뒤에 달라진다.
*/
private List<CatalogEntryView> searchProjects(String pattern, int limit) {
return jdbcClient
.sql(
"SELECT id, name, updated_at FROM project "
+ "WHERE lower(name) LIKE :pattern ORDER BY name LIMIT :limit")
"SELECT pr.id, pr.name, pr.updated_at, p.navigation_path"
+ " FROM project pr"
+ " LEFT JOIN public_resource_projection p"
+ " ON p.resource_type = 'PROJECT' AND p.resource_id = pr.id"
+ " AND "
+ PUBLICLY_VISIBLE
+ " WHERE lower(pr.name) LIKE :pattern ORDER BY pr.name LIMIT :limit")
.param("pattern", pattern)
.param("limit", limit)
.query(
@@ -82,7 +96,7 @@ public class JdbcCatalogQueryAdapter implements CatalogQueryPort {
CatalogEntryType.PROJECT,
rs.getString("name"),
"PROJECT",
null,
rs.getString("navigation_path"),
"project:" + rs.getTimestamp("updated_at").toInstant()))
.list();
}
@@ -785,4 +785,34 @@ class ManagementPersistenceIntegrationTest {
.single())
.isZero();
}
/**
* Decision 의 공개 주소는 자기 slug 가 아니라 프로젝트 주소 아래에 있다. 그래서 편집기가 Decision 을 미리 그리려면 이 목록이 프로젝트의 공개 경로를
* 알고 있어야 한다 — 한동안 늘 null 이었고, 그동안 Decision 은 어떤 문서에서도 즉시 미리보기가 열리지 않았다.
*/
@Test
void projectCatalogCarriesThePublicPathOfPublishedProjectsOnly() {
ProjectEditView open = projects.create(new CreateProjectCommand("Catalog Published", "test"));
jdbcClient
.sql("UPDATE project SET slug = 'catalog-published' WHERE id = :id")
.param("id", open.id())
.update();
ProjectEditView loaded = projects.find(open.id()).orElseThrow();
assertThat(projects.publish(loaded.id(), loaded.version(), "PUBLIC", "test")).isPresent();
ProjectEditView hidden = projects.create(new CreateProjectCommand("Catalog Hidden", "test"));
var entries = catalog.search(CatalogEntryType.PROJECT, "catalog", null, 50).items();
assertThat(entries)
.filteredOn(entry -> entry.id().equals(open.id()))
.singleElement()
.satisfies(
entry -> assertThat(entry.publicPath()).isEqualTo("/projects/catalog-published"));
// 게시되지 않은 프로젝트는 공개 주소가 실제로 없다. 지어내면 미리보기가 보여 준 링크가 게시 뒤에 달라진다.
assertThat(entries)
.filteredOn(entry -> entry.id().equals(hidden.id()))
.singleElement()
.satisfies(entry -> assertThat(entry.publicPath()).isNull());
}
}