A social knowledge tool for researchers built on ATProto

Merge pull request #57 from cosmik-network/fix/note-card-editing

Fix/note card editing

authored by

Wesley Finck and committed by
GitHub
a6f57ec1 2c488f07

+44 -51
+3 -3
src/modules/atproto/infrastructure/__tests__/ATProtoCardPublisher.integration.test.ts
··· 144 144 // Create a note card 145 145 const noteCard = new CardBuilder() 146 146 .withCuratorId(curatorId.value) 147 - .withNoteCard('This is a test note for publishing', 'Test Note Title') 147 + .withNoteCard('This is a test note for publishing') 148 148 .buildOrThrow(); 149 149 150 150 // Add card to curator's library first ··· 201 201 // Create a note card with optional URL 202 202 const noteCard = new CardBuilder() 203 203 .withCuratorId(curatorId.value) 204 - .withNoteCard('This note references a URL', 'Note with URL') 204 + .withNoteCard('This note references a URL') 205 205 .withUrl(referenceUrl) 206 206 .buildOrThrow(); 207 207 ··· 302 302 // 2. Create a note card that references the parent URL card 303 303 const noteCard = new CardBuilder() 304 304 .withCuratorId(curatorId.value) 305 - .withNoteCard('This is my note about the parent article', 'My Notes') 305 + .withNoteCard('This is my note about the parent article') 306 306 .withParentCard(parentUrlCard.cardId) 307 307 .withUrl(parentUrl) // Optional: include the same URL as reference 308 308 .buildOrThrow();
-1
src/modules/cards/application/useCases/commands/UpdateNoteCardUseCase.ts
··· 110 110 // Create new card content with updated note 111 111 const updatedCardContentResult = CardContent.createNoteContent( 112 112 request.note, 113 - undefined, 114 113 curatorId, 115 114 ); 116 115 if (updatedCardContentResult.isErr()) {
-15
src/modules/cards/domain/Card.ts
··· 260 260 link.curatorId.equals(userId), 261 261 ); 262 262 } 263 - 264 - private getCardTitle(): string | undefined { 265 - if (this.isUrlCard) { 266 - const urlContent = this.props.content.content; 267 - if ('metadata' in urlContent) { 268 - return urlContent.metadata?.title; 269 - } 270 - } else if (this.isNoteCard) { 271 - const noteContent = this.props.content.content; 272 - if ('title' in noteContent) { 273 - return noteContent.title; 274 - } 275 - } 276 - return undefined; 277 - } 278 263 }
+1 -2
src/modules/cards/domain/CardFactory.ts
··· 17 17 export interface INoteCardInput { 18 18 type: CardTypeEnum.NOTE; 19 19 text: string; 20 - title?: string; 21 20 parentCardId?: string; 22 21 url?: string; 23 22 } ··· 160 159 input: INoteCardInput, 161 160 curatorId: CuratorId, 162 161 ): Result<CardContent, CardValidationError> { 163 - return CardContent.createNoteContent(input.text, input.title, curatorId); 162 + return CardContent.createNoteContent(input.text, curatorId); 164 163 } 165 164 166 165 // Type guards
+2 -3
src/modules/cards/domain/value-objects/CardContent.ts
··· 59 59 60 60 public static createNoteContent( 61 61 text: string, 62 - title?: string, 63 - curatorId?: CuratorId, 62 + curatorId: CuratorId, 64 63 ): Result<CardContent, CardContentValidationError> { 65 64 // Use provided curatorId or create a dummy one for backward compatibility 66 - const authorId = curatorId || CuratorId.create('did:plc:dummy').unwrap(); 65 + const authorId = curatorId; 67 66 const noteContentResult = NoteCardContent.create(authorId, text); 68 67 if (noteContentResult.isErr()) { 69 68 return err(
-5
src/modules/cards/domain/value-objects/content/NoteCardContent.ts
··· 27 27 return this.props.text; 28 28 } 29 29 30 - get title(): string | undefined { 31 - // For backward compatibility, we don't store title separately in the new model 32 - return undefined; 33 - } 34 - 35 30 get authorId(): CuratorId { 36 31 return this.props.authorId; 37 32 }
+4 -1
src/modules/cards/infrastructure/repositories/mappers/CardMapper.ts
··· 208 208 const noteData = data as NoteContentData; 209 209 const authorIdResult = CuratorId.create(noteData.authorId); 210 210 if (authorIdResult.isErr()) return err(authorIdResult.error); 211 - return CardContent.createNoteContent(noteData.text); 211 + return CardContent.createNoteContent( 212 + noteData.text, 213 + authorIdResult.value, 214 + ); 212 215 } 213 216 214 217 default:
+1
src/modules/cards/tests/application/GetCollectionPageUseCase.test.ts
··· 255 255 type: CardType.create(CardTypeEnum.NOTE).unwrap(), 256 256 content: CardContent.createNoteContent( 257 257 'This is my note about the article', 258 + curatorId, 258 259 ).unwrap(), 259 260 parentCardId: card.cardId, 260 261 url: url,
+1
src/modules/cards/tests/application/GetUrlCardViewUseCase.test.ts
··· 107 107 type: CardType.create(CardTypeEnum.NOTE).unwrap(), 108 108 content: CardContent.createNoteContent( 109 109 'This is my note about the article', 110 + curatorId, 110 111 ).unwrap(), 111 112 parentCardId: card.cardId, 112 113 url: url,
+4 -4
src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getCardsInCollection.integration.test.ts
··· 206 206 // Create note by collection author 207 207 const authorNote = new CardBuilder() 208 208 .withCuratorId(curatorId.value) 209 - .withNoteCard('Note by collection author', 'Author Note') 209 + .withNoteCard('Note by collection author') 210 210 .withParentCard(urlCard.cardId) 211 211 .buildOrThrow(); 212 212 ··· 217 217 // Create note by different user on the same URL card 218 218 const otherUserNote = new CardBuilder() 219 219 .withCuratorId(otherCuratorId.value) 220 - .withNoteCard('Note by other user', 'Other User Note') 220 + .withNoteCard('Note by other user') 221 221 .withParentCard(urlCard.cardId) 222 222 .buildOrThrow(); 223 223 ··· 278 278 // Create note by different user on the URL card (NO note by collection author) 279 279 const otherUserNote = new CardBuilder() 280 280 .withCuratorId(otherCuratorId.value) 281 - .withNoteCard('Note by other user only', 'Other User Note') 281 + .withNoteCard('Note by other user only') 282 282 .withParentCard(urlCard.cardId) 283 283 .buildOrThrow(); 284 284 ··· 342 342 // Create note card connected to the OTHER URL card (not in collection) 343 343 const noteCard = new CardBuilder() 344 344 .withCuratorId(curatorId.value) 345 - .withNoteCard('This note is for the other article', 'Other Note') 345 + .withNoteCard('This note is for the other article') 346 346 .withParentCard(otherUrlCard.cardId) 347 347 .buildOrThrow(); 348 348
+3 -4
src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardView.integration.test.ts
··· 88 88 // Create a note card 89 89 const noteCard = new CardBuilder() 90 90 .withCuratorId(curatorId.value) 91 - .withNoteCard('This is a note', 'Note Title') 91 + .withNoteCard('This is a note') 92 92 .buildOrThrow(); 93 93 94 94 await cardRepository.save(noteCard); ··· 570 570 .withCuratorId(curatorId.value) 571 571 .withNoteCard( 572 572 'This is my detailed analysis of the article. It covers several key points and provides additional insights.', 573 - 'My Analysis', 574 573 ) 575 574 .withParentCard(urlCard.cardId) 576 575 .buildOrThrow(); ··· 637 636 // Create note card connected to the SECOND URL card 638 637 const noteCard = new CardBuilder() 639 638 .withCuratorId(curatorId.value) 640 - .withNoteCard('This note is for article 2', 'Article 2 Notes') 639 + .withNoteCard('This note is for article 2') 641 640 .withParentCard(urlCard2.cardId) 642 641 .buildOrThrow(); 643 642 ··· 783 782 // Create note card 784 783 const noteCard = new CardBuilder() 785 784 .withCuratorId(curatorId.value) 786 - .withNoteCard('Test note', 'Note Title') 785 + .withNoteCard('Test note') 787 786 .buildOrThrow(); 788 787 789 788 await cardRepository.save(noteCard);
+2 -2
src/modules/cards/tests/infrastructure/DrizzleCardQueryRepository.getUrlCardsOfUser.integration.test.ts
··· 173 173 // Create note card connected to URL card 174 174 const noteCard = new CardBuilder() 175 175 .withCuratorId(curatorId.value) 176 - .withNoteCard('This is my note about the article', 'My Thoughts') 176 + .withNoteCard('This is my note about the article') 177 177 .withParentCard(urlCard.cardId) 178 178 .buildOrThrow(); 179 179 ··· 423 423 // Create connected note 424 424 const noteCard = new CardBuilder() 425 425 .withCuratorId(curatorId.value) 426 - .withNoteCard('Detailed analysis of the complex article', 'Analysis') 426 + .withNoteCard('Detailed analysis of the complex article') 427 427 .withParentCard(urlCard.cardId) 428 428 .buildOrThrow(); 429 429
+18 -7
src/modules/cards/tests/infrastructure/DrizzleCardRepository.integration.test.ts
··· 109 109 // Create a note card 110 110 const noteContent = CardContent.createNoteContent( 111 111 'This is a test note', 112 + curatorId, 112 113 ).unwrap(); 113 114 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 114 115 ··· 134 135 expect(retrievedCard?.content.noteContent?.text).toBe( 135 136 'This is a test note', 136 137 ); 137 - expect(retrievedCard?.content.noteContent?.title).toBeUndefined(); 138 138 }); 139 139 140 140 it('should save and retrieve a card with library memberships', async () => { 141 141 // Create a note card 142 142 const noteContent = CardContent.createNoteContent( 143 143 'Card with library memberships', 144 + curatorId, 144 145 ).unwrap(); 145 146 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 146 147 ··· 182 183 // Create a note card 183 184 const noteContent = CardContent.createNoteContent( 184 185 'Card for membership updates', 186 + curatorId, 185 187 ).unwrap(); 186 188 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 187 189 ··· 225 227 226 228 it('should delete a card and its library memberships', async () => { 227 229 // Create a card 228 - const noteContent = 229 - CardContent.createNoteContent('Card to delete').unwrap(); 230 + const noteContent = CardContent.createNoteContent( 231 + 'Card to delete', 232 + curatorId, 233 + ).unwrap(); 230 234 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 231 235 232 236 const cardResult = Card.create({ ··· 257 261 }); 258 262 259 263 it('should return null when card is not found', async () => { 260 - const noteContent = 261 - CardContent.createNoteContent('Non-existent card').unwrap(); 264 + const noteContent = CardContent.createNoteContent( 265 + 'Non-existent card', 266 + curatorId, 267 + ).unwrap(); 262 268 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 263 269 264 270 const nonExistentCardId = Card.create({ ··· 275 281 // Create a note card 276 282 const noteContent = CardContent.createNoteContent( 277 283 'Card for publishing test', 284 + curatorId, 278 285 ).unwrap(); 279 286 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 280 287 ··· 372 379 it('should not find note cards when searching by URL', async () => { 373 380 // Create a note card with a URL (but it's not a URL card type) 374 381 const url = URL.create('https://example.com/note-url').unwrap(); 375 - const noteContent = 376 - CardContent.createNoteContent('Note about a URL').unwrap(); 382 + const noteContent = CardContent.createNoteContent( 383 + 'Note about a URL', 384 + curatorId, 385 + ).unwrap(); 377 386 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 378 387 379 388 const cardResult = Card.create({ ··· 395 404 // Create a note card 396 405 const noteContent = CardContent.createNoteContent( 397 406 'Card for library count test', 407 + curatorId, 398 408 ).unwrap(); 399 409 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 400 410 ··· 449 459 // Create a note card with initial library memberships 450 460 const noteContent = CardContent.createNoteContent( 451 461 'Card with initial memberships', 462 + curatorId, 452 463 ).unwrap(); 453 464 const cardType = CardType.create(CardTypeEnum.NOTE).unwrap(); 454 465
+5 -4
src/modules/cards/tests/utils/builders/CardBuilder.ts
··· 45 45 if (curatorIdResult.isOk()) { 46 46 const contentResult = CardContent.createNoteContent( 47 47 'Default note text', 48 - undefined, 49 48 curatorIdResult.value, 50 49 ); 51 50 if (contentResult.isOk()) { ··· 101 100 return this; 102 101 } 103 102 104 - withNoteCard(text: string, title?: string): CardBuilder { 103 + withNoteCard(text: string): CardBuilder { 105 104 this._type = CardTypeEnum.NOTE; 106 - const contentResult = CardContent.createNoteContent(text, title); 105 + const contentResult = CardContent.createNoteContent( 106 + text, 107 + CuratorId.create(this._curatorId).unwrap(), 108 + ); 107 109 if (contentResult.isErr()) { 108 110 throw new Error( 109 111 `Failed to create note content: ${contentResult.error.message}`, ··· 138 140 } else if (this._type === CardTypeEnum.NOTE) { 139 141 const contentResult = CardContent.createNoteContent( 140 142 'Default note text', 141 - undefined, 142 143 curatorIdResult.value, 143 144 ); 144 145 if (contentResult.isErr()) {