@@ -7,6 +7,8 @@ import { Effect } from "effect";
77
88import { OrchestrationCommandInvariantError } from "./Errors.ts" ;
99import {
10+ getProjectsToArchive ,
11+ getThreadsToArchive ,
1012 requireProject ,
1113 requireProjectAbsent ,
1214 requireThread ,
@@ -65,7 +67,7 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
6567 projectId : command . projectId ,
6668 } ) ;
6769
68- return {
70+ const projectCreatedEvent : Omit < OrchestrationEvent , "sequence" > = {
6971 ...withEventBase ( {
7072 aggregateKind : "project" ,
7173 aggregateId : command . projectId ,
@@ -83,6 +85,29 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
8385 updatedAt : command . createdAt ,
8486 } ,
8587 } ;
88+
89+ // Auto-archive oldest projects when limit is reached
90+ const projectsToArchive = getProjectsToArchive ( readModel ) ;
91+ if ( projectsToArchive . length === 0 ) {
92+ return projectCreatedEvent ;
93+ }
94+
95+ const archiveEvents : Omit < OrchestrationEvent , "sequence" > [ ] = projectsToArchive . map (
96+ ( project ) => ( {
97+ ...withEventBase ( {
98+ aggregateKind : "project" as const ,
99+ aggregateId : project . id ,
100+ occurredAt : command . createdAt ,
101+ commandId : command . commandId ,
102+ } ) ,
103+ type : "project.deleted" as const ,
104+ payload : {
105+ projectId : project . id ,
106+ deletedAt : command . createdAt ,
107+ } ,
108+ } ) ,
109+ ) ;
110+ return [ ...archiveEvents , projectCreatedEvent ] ;
86111 }
87112
88113 case "project.meta.update" : {
@@ -144,7 +169,8 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
144169 command,
145170 threadId : command . threadId ,
146171 } ) ;
147- return {
172+
173+ const threadCreatedEvent : Omit < OrchestrationEvent , "sequence" > = {
148174 ...withEventBase ( {
149175 aggregateKind : "thread" ,
150176 aggregateId : command . threadId ,
@@ -165,6 +191,29 @@ export const decideOrchestrationCommand = Effect.fn("decideOrchestrationCommand"
165191 updatedAt : command . createdAt ,
166192 } ,
167193 } ;
194+
195+ // Auto-archive oldest threads in the project when limit is reached
196+ const threadsToArchive = getThreadsToArchive ( readModel , command . projectId ) ;
197+ if ( threadsToArchive . length === 0 ) {
198+ return threadCreatedEvent ;
199+ }
200+
201+ const archiveEvents : Omit < OrchestrationEvent , "sequence" > [ ] = threadsToArchive . map (
202+ ( thread ) => ( {
203+ ...withEventBase ( {
204+ aggregateKind : "thread" as const ,
205+ aggregateId : thread . id ,
206+ occurredAt : command . createdAt ,
207+ commandId : command . commandId ,
208+ } ) ,
209+ type : "thread.deleted" as const ,
210+ payload : {
211+ threadId : thread . id ,
212+ deletedAt : command . createdAt ,
213+ } ,
214+ } ) ,
215+ ) ;
216+ return [ ...archiveEvents , threadCreatedEvent ] ;
168217 }
169218
170219 case "thread.delete" : {
0 commit comments