@@ -35,7 +35,8 @@ import type { SessionContext } from '../auth/middleware.js';
3535import { applyTagsForEntity , type TagAssignmentInput , type TagNamespace } from './tag.write.js' ;
3636import type { PrivateStore } from '../store/private/index.js' ;
3737import { cascadeRename } from './reference-cascade.js' ;
38- import { purgeableProjects , purgeProject } from './project-purge.js' ;
38+ import { purgePeople } from './person-purge.js' ;
39+ import { purgeableProjects } from './project-purge.js' ;
3940import { rekeyAttachment , upsertMoved } from './slug-rename.js' ;
4041
4142function nowIso ( ) : string {
@@ -282,80 +283,7 @@ export class PersonWriteService {
282283 if ( ! existing ) throw new ApiNotFoundError ( `Person '${ slug } ' not found` ) ;
283284
284285 const stateApply = new StateApply ( ) ;
285- const personId = existing . id ;
286-
287- // 0. Projects only this person touched go first, whole (computed before
288- // anything is deleted). Every id deleted is tracked so the person's
289- // own cascade below skips what the project purge already removed.
290- const deleted = new Set < string > ( ) ;
291- for ( const project of purgeableProjects ( this . #state, existing ) ) {
292- await purgeProject ( tx , this . #state, stateApply , project , deleted ) ;
293- }
294-
295- // 1. Delete the person record.
296- await tx . public . people . delete ( existing ) ;
297- stateApply . removePerson ( personId , existing . slug ) ;
298-
299- // 2. Cascade-delete project-memberships.
300- const membershipIds = this . #state. membershipsByPerson . get ( existing . slug ) ?? new Set < string > ( ) ;
301- for ( const mId of membershipIds ) {
302- const m = this . #state. projectMemberships . get ( mId ) ;
303- if ( m && ! deleted . has ( m . id ) ) {
304- await tx . public [ 'project-memberships' ] . delete ( m ) ;
305- stateApply . removeMembership ( m ) ;
306- }
307- }
308-
309- // 3. Cascade-delete help-wanted-interest.
310- for ( const interest of this . #state. helpWantedInterest . values ( ) ) {
311- if ( interest . personSlug === existing . slug && ! deleted . has ( interest . id ) ) {
312- await tx . public [ 'help-wanted-interest' ] . delete ( interest ) ;
313- stateApply . removeInterest ( interest ) ;
314- }
315- }
316-
317- // 3b. Cascade-delete event RSVPs (path: year/eventSlug/personSlug).
318- for ( const rsvpId of this . #state. rsvpsByPerson . get ( existing . slug ) ?? new Set < string > ( ) ) {
319- const rsvp = this . #state. eventRsvps . get ( rsvpId ) ;
320- if ( rsvp && ! deleted . has ( rsvp . id ) ) {
321- await tx . public [ 'event-rsvps' ] . delete ( rsvp ) ;
322- stateApply . removeEventRsvp ( rsvp ) ;
323- }
324- }
325-
326- // 4. Cascade-delete person tag-assignments.
327- const taIds = this . #state. tagAssignmentsByTaggable . get ( personId ) ?? new Set < string > ( ) ;
328- for ( const taId of taIds ) {
329- const ta = this . #state. tagAssignments . get ( taId ) ;
330- if ( ta && ta . taggableType === 'person' ) {
331- await tx . public [ 'tag-assignments' ] . delete ( ta ) ;
332- stateApply . removeTagAssignment ( ta ) ;
333- }
334- }
335-
336- // 5. Delete authored project-updates.
337- for ( const update of this . #state. projectUpdates . values ( ) ) {
338- if ( update . authorId === personId && ! deleted . has ( update . id ) ) {
339- await tx . public [ 'project-updates' ] . delete ( update ) ;
340- stateApply . removeProjectUpdate ( update ) ;
341- }
342- }
343-
344- // 6. Delete posted project-buzz.
345- for ( const buzz of this . #state. projectBuzz . values ( ) ) {
346- if ( buzz . postedById === personId && ! deleted . has ( buzz . id ) ) {
347- await tx . public [ 'project-buzz' ] . delete ( buzz ) ;
348- stateApply . removeProjectBuzz ( buzz ) ;
349- }
350- }
351-
352- // 7. Delete authored blog-posts.
353- for ( const post of this . #state. blogPosts . values ( ) ) {
354- if ( post . authorId === personId ) {
355- await tx . public [ 'blog-posts' ] . delete ( post ) ;
356- stateApply . removeBlogPost ( post ) ;
357- }
358- }
286+ await purgePeople ( tx , this . #state, stateApply , [ existing ] ) ;
359287
360288 return { stateApply } ;
361289 }
@@ -371,7 +299,7 @@ export class PersonWriteService {
371299 const person = id ? this . #state. people . get ( id ) : undefined ;
372300 if ( ! person ) throw new ApiNotFoundError ( `Person '${ slug } ' not found` ) ;
373301 return {
374- projects : purgeableProjects ( this . #state, person ) . map ( ( p ) => ( { slug : p . slug , title : p . title } ) ) ,
302+ projects : purgeableProjects ( this . #state, [ person ] ) . map ( ( p ) => ( { slug : p . slug , title : p . title } ) ) ,
375303 } ;
376304 }
377305
0 commit comments