From d2854519f54219ac894a9c0629ef0b21273c245b Mon Sep 17 00:00:00 2001 From: KinjiKawaguchi Date: Thu, 12 Mar 2026 14:28:55 +0900 Subject: [PATCH 1/4] =?UTF-8?q?fix:=20Event.removeExhibitMemberId=E3=81=8C?= =?UTF-8?q?=E6=9C=AA=E5=AE=9F=E8=A3=85=E3=81=A0=E3=81=A3=E3=81=9F=E5=95=8F?= =?UTF-8?q?=E9=A1=8C=E3=82=92=E4=BF=AE=E6=AD=A3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 展示からメンバーを削除し、他の展示にも所属していなければ イベントのメンバー一覧からも削除する。 Co-Authored-By: Claude Opus 4.6 --- src/domain/aggregates/event/Event.ts | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/domain/aggregates/event/Event.ts b/src/domain/aggregates/event/Event.ts index f0cc4ff..1af95ae 100644 --- a/src/domain/aggregates/event/Event.ts +++ b/src/domain/aggregates/event/Event.ts @@ -135,7 +135,15 @@ export class Event { this.memberIds.add(memberId); } - public removeExhibitMemberId(exhibitId: string, memberId: string): void {} + public removeExhibitMemberId(exhibitId: string, memberId: string): void { + this.getExhibitOrThrow(exhibitId).removeMemberId(memberId); + const stillInOtherExhibit = this.exhibits.some((exhibit) => + exhibit.getMemberIds().includes(memberId), + ); + if (!stillInOtherExhibit) { + this.memberIds.delete(memberId); + } + } toSnapshot() { return { id: this.id, From eee1c6e8f954441960fb7a303c119663840ad5fa Mon Sep 17 00:00:00 2001 From: KinjiKawaguchi Date: Sat, 14 Mar 2026 20:36:15 +0900 Subject: [PATCH 2/4] =?UTF-8?q?fix:=20=E3=83=AC=E3=83=93=E3=83=A5=E3=83=BC?= =?UTF-8?q?=E6=8C=87=E6=91=98=E3=81=AB=E5=AF=BE=E5=BF=9C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Exhibit.hasMemberId()を追加しSet#hasベースで判定(Set→Array変換を回避) - removeExhibitMemberIdからEvent.memberIdsの削除を除去(展示所属とイベント参加の責務を分離) Co-Authored-By: Claude Opus 4.6 --- src/domain/aggregates/event/Event.ts | 8 +------- src/domain/aggregates/event/Exhibit.ts | 4 ++++ 2 files changed, 5 insertions(+), 7 deletions(-) diff --git a/src/domain/aggregates/event/Event.ts b/src/domain/aggregates/event/Event.ts index 1af95ae..f630fab 100644 --- a/src/domain/aggregates/event/Event.ts +++ b/src/domain/aggregates/event/Event.ts @@ -122,7 +122,7 @@ export class Event { public removeMemberId(memberId: string): void { for (const exhibit of this.exhibits) { - if (exhibit.getMemberIds().includes(memberId)) { + if (exhibit.hasMemberId(memberId)) { throw new ExhibitHasMemberException(exhibit.id, memberId); } } @@ -137,12 +137,6 @@ export class Event { public removeExhibitMemberId(exhibitId: string, memberId: string): void { this.getExhibitOrThrow(exhibitId).removeMemberId(memberId); - const stillInOtherExhibit = this.exhibits.some((exhibit) => - exhibit.getMemberIds().includes(memberId), - ); - if (!stillInOtherExhibit) { - this.memberIds.delete(memberId); - } } toSnapshot() { return { diff --git a/src/domain/aggregates/event/Exhibit.ts b/src/domain/aggregates/event/Exhibit.ts index b5b965a..e75b23b 100644 --- a/src/domain/aggregates/event/Exhibit.ts +++ b/src/domain/aggregates/event/Exhibit.ts @@ -95,6 +95,10 @@ export class Exhibit { this.memberIds.delete(memberId); } + public hasMemberId(memberId: string): boolean { + return this.memberIds.has(memberId); + } + private getLightningTalkOrThrow(): LightningTalk { if (!this.lightningTalk) { throw new LightningTalkNotFoundException( From f64dfb8cccc20fd4fd7850a4da8b90ef6f238e90 Mon Sep 17 00:00:00 2001 From: KinjiKawaguchi Date: Sat, 14 Mar 2026 20:45:12 +0900 Subject: [PATCH 3/4] =?UTF-8?q?fix:=20Exhibit.toSnapshot()=E3=81=ABmemberI?= =?UTF-8?q?ds=E3=82=92=E8=BF=BD=E5=8A=A0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- src/domain/aggregates/event/Exhibit.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/domain/aggregates/event/Exhibit.ts b/src/domain/aggregates/event/Exhibit.ts index e75b23b..d93b057 100644 --- a/src/domain/aggregates/event/Exhibit.ts +++ b/src/domain/aggregates/event/Exhibit.ts @@ -116,6 +116,7 @@ export class Exhibit { markdownContent: this.markdownContent, url: this.url, lightningTalk: this.lightningTalk?.toSnapshot(), + memberIds: Array.from(this.memberIds), }; } } From 1f61d815412fb5338d049208d645b6692b04de57 Mon Sep 17 00:00:00 2001 From: KinjiKawaguchi Date: Sat, 14 Mar 2026 21:42:46 +0900 Subject: [PATCH 4/4] =?UTF-8?q?docs:=20removeExhibitMemberId=E3=81=AE?= =?UTF-8?q?=E9=9D=9E=E5=AF=BE=E7=A7=B0=E6=80=A7=E3=81=AE=E6=84=8F=E5=9B=B3?= =?UTF-8?q?=E3=82=92=E3=82=B3=E3=83=A1=E3=83=B3=E3=83=88=E3=81=A7=E6=98=8E?= =?UTF-8?q?=E7=A4=BA?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.6 --- src/domain/aggregates/event/Event.ts | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/domain/aggregates/event/Event.ts b/src/domain/aggregates/event/Event.ts index f630fab..5ee6467 100644 --- a/src/domain/aggregates/event/Event.ts +++ b/src/domain/aggregates/event/Event.ts @@ -135,6 +135,9 @@ export class Event { this.memberIds.add(memberId); } + // NOTE: 展示からの削除のみ行い、Event.memberIdsは操作しない。 + // 「展示に所属していないがイベント参加者」という状態が有効なため、 + // イベント参加者からの削除はremoveMemberId()で明示的に行う。 public removeExhibitMemberId(exhibitId: string, memberId: string): void { this.getExhibitOrThrow(exhibitId).removeMemberId(memberId); }