This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

Merge branch 'development' of https://github.com/cosmik-network/semble into development

+227
+114
src/modules/cards/infrastructure/repositories/query-services/CollectionCardQueryService.ts
··· 12 12 import { collections, collectionCards } from '../schema/collection.sql'; 13 13 import { libraryMemberships } from '../schema/libraryMembership.sql'; 14 14 import { publishedRecords } from '../schema/publishedRecord.sql'; 15 + import { connections } from '../schema/connection.sql'; 15 16 import { CardMapper } from '../mappers/CardMapper'; 16 17 import { CardTypeEnum } from '../../../domain/value-objects/CardType'; 17 18 ··· 280 281 }); 281 282 } 282 283 284 + // Get connection counts for each URL (total connections where URL is source or target) 285 + // Query connections where URLs are sources 286 + const sourceConnectionCountsQuery = this.db 287 + .select({ 288 + url: connections.sourceValue, 289 + count: count(), 290 + }) 291 + .from(connections) 292 + .where( 293 + and( 294 + eq(connections.sourceType, 'URL'), 295 + inArray(connections.sourceValue, urls), 296 + eq(connections.targetType, 'URL'), // Only URL-to-URL connections 297 + ), 298 + ) 299 + .groupBy(connections.sourceValue); 300 + 301 + // Query connections where URLs are targets 302 + const targetConnectionCountsQuery = this.db 303 + .select({ 304 + url: connections.targetValue, 305 + count: count(), 306 + }) 307 + .from(connections) 308 + .where( 309 + and( 310 + eq(connections.targetType, 'URL'), 311 + inArray(connections.targetValue, urls), 312 + eq(connections.sourceType, 'URL'), // Only URL-to-URL connections 313 + ), 314 + ) 315 + .groupBy(connections.targetValue); 316 + 317 + const [sourceConnectionCounts, targetConnectionCounts] = 318 + await Promise.all([ 319 + sourceConnectionCountsQuery, 320 + targetConnectionCountsQuery, 321 + ]); 322 + 323 + // Build map of URL to connection count (combining source and target counts) 324 + const urlConnectionCountMap = new Map<string, number>(); 325 + sourceConnectionCounts.forEach((row) => { 326 + if (row.url) { 327 + urlConnectionCountMap.set(row.url, Number(row.count)); 328 + } 329 + }); 330 + targetConnectionCounts.forEach((row) => { 331 + if (row.url) { 332 + urlConnectionCountMap.set( 333 + row.url, 334 + (urlConnectionCountMap.get(row.url) || 0) + Number(row.count), 335 + ); 336 + } 337 + }); 338 + 339 + // Get URLs that calling user has connections with (if callingUserId provided) 340 + let urlIsConnectedMap: Map<string, boolean> | undefined; 341 + if (callingUserId) { 342 + urlIsConnectedMap = new Map(); 343 + 344 + // Query for URLs where user's connections have them as source 345 + const userSourceConnectionsQuery = this.db 346 + .select({ 347 + url: connections.sourceValue, 348 + }) 349 + .from(connections) 350 + .where( 351 + and( 352 + eq(connections.curatorId, callingUserId), 353 + eq(connections.sourceType, 'URL'), 354 + inArray(connections.sourceValue, urls), 355 + eq(connections.targetType, 'URL'), 356 + ), 357 + ); 358 + 359 + // Query for URLs where user's connections have them as target 360 + const userTargetConnectionsQuery = this.db 361 + .select({ 362 + url: connections.targetValue, 363 + }) 364 + .from(connections) 365 + .where( 366 + and( 367 + eq(connections.curatorId, callingUserId), 368 + eq(connections.targetType, 'URL'), 369 + inArray(connections.targetValue, urls), 370 + eq(connections.sourceType, 'URL'), 371 + ), 372 + ); 373 + 374 + const [userSourceConnections, userTargetConnections] = 375 + await Promise.all([ 376 + userSourceConnectionsQuery, 377 + userTargetConnectionsQuery, 378 + ]); 379 + 380 + // Mark URLs as connected if they appear in either source or target 381 + [...userSourceConnections, ...userTargetConnections].forEach((row) => { 382 + if (row.url) { 383 + urlIsConnectedMap!.set(row.url, true); 384 + } 385 + }); 386 + } 387 + 283 388 // Get total count 284 389 const totalCountResult = await this.db 285 390 .select({ count: count() }) ··· 304 409 // Get urlInLibrary from the map (undefined if callingUserId not provided) 305 410 const urlInLibrary = urlInLibraryMap?.get(card.url || ''); 306 411 412 + // Get urlConnectionCount from the map 413 + const urlConnectionCount = 414 + urlConnectionCountMap.get(card.url || '') || 0; 415 + 416 + // Get urlIsConnected from the map (undefined if callingUserId not provided) 417 + const urlIsConnected = urlIsConnectedMap?.get(card.url || ''); 418 + 307 419 return { 308 420 id: card.id, 309 421 authorId: card.authorId, ··· 313 425 libraryCount: card.libraryCount, 314 426 urlLibraryCount, 315 427 urlInLibrary, 428 + urlConnectionCount, 429 + urlIsConnected, 316 430 createdAt: card.createdAt, 317 431 updatedAt: card.updatedAt, 318 432 note: note
+113
src/modules/cards/infrastructure/repositories/query-services/UrlCardQueryService.ts
··· 1394 1394 }); 1395 1395 } 1396 1396 1397 + // Get connection counts for each URL (total connections where URL is source or target) 1398 + // Query connections where URLs are sources 1399 + const sourceConnectionCountsQuery = this.db 1400 + .select({ 1401 + url: connections.sourceValue, 1402 + count: count(), 1403 + }) 1404 + .from(connections) 1405 + .where( 1406 + and( 1407 + eq(connections.sourceType, 'URL'), 1408 + inArray(connections.sourceValue, urls), 1409 + eq(connections.targetType, 'URL'), // Only URL-to-URL connections 1410 + ), 1411 + ) 1412 + .groupBy(connections.sourceValue); 1413 + 1414 + // Query connections where URLs are targets 1415 + const targetConnectionCountsQuery = this.db 1416 + .select({ 1417 + url: connections.targetValue, 1418 + count: count(), 1419 + }) 1420 + .from(connections) 1421 + .where( 1422 + and( 1423 + eq(connections.targetType, 'URL'), 1424 + inArray(connections.targetValue, urls), 1425 + eq(connections.sourceType, 'URL'), // Only URL-to-URL connections 1426 + ), 1427 + ) 1428 + .groupBy(connections.targetValue); 1429 + 1430 + const [sourceConnectionCounts, targetConnectionCounts] = 1431 + await Promise.all([ 1432 + sourceConnectionCountsQuery, 1433 + targetConnectionCountsQuery, 1434 + ]); 1435 + 1436 + // Build map of URL to connection count (combining source and target counts) 1437 + const urlConnectionCountMap = new Map<string, number>(); 1438 + sourceConnectionCounts.forEach((row) => { 1439 + if (row.url) { 1440 + urlConnectionCountMap.set(row.url, Number(row.count)); 1441 + } 1442 + }); 1443 + targetConnectionCounts.forEach((row) => { 1444 + if (row.url) { 1445 + urlConnectionCountMap.set( 1446 + row.url, 1447 + (urlConnectionCountMap.get(row.url) || 0) + Number(row.count), 1448 + ); 1449 + } 1450 + }); 1451 + 1452 + // Get URLs that calling user has connections with (if callingUserId provided) 1453 + let urlIsConnectedMap: Map<string, boolean> | undefined; 1454 + if (callingUserId) { 1455 + urlIsConnectedMap = new Map(); 1456 + 1457 + // Query for URLs where user's connections have them as source 1458 + const userSourceConnectionsQuery = this.db 1459 + .select({ 1460 + url: connections.sourceValue, 1461 + }) 1462 + .from(connections) 1463 + .where( 1464 + and( 1465 + eq(connections.curatorId, callingUserId), 1466 + eq(connections.sourceType, 'URL'), 1467 + inArray(connections.sourceValue, urls), 1468 + eq(connections.targetType, 'URL'), 1469 + ), 1470 + ); 1471 + 1472 + // Query for URLs where user's connections have them as target 1473 + const userTargetConnectionsQuery = this.db 1474 + .select({ 1475 + url: connections.targetValue, 1476 + }) 1477 + .from(connections) 1478 + .where( 1479 + and( 1480 + eq(connections.curatorId, callingUserId), 1481 + eq(connections.targetType, 'URL'), 1482 + inArray(connections.targetValue, urls), 1483 + eq(connections.sourceType, 'URL'), 1484 + ), 1485 + ); 1486 + 1487 + const [userSourceConnections, userTargetConnections] = 1488 + await Promise.all([ 1489 + userSourceConnectionsQuery, 1490 + userTargetConnectionsQuery, 1491 + ]); 1492 + 1493 + // Mark URLs as connected if they appear in either source or target 1494 + [...userSourceConnections, ...userTargetConnections].forEach((row) => { 1495 + if (row.url) { 1496 + urlIsConnectedMap!.set(row.url, true); 1497 + } 1498 + }); 1499 + } 1500 + 1397 1501 // Build result map 1398 1502 const resultMap = new Map<string, UrlCardView>(); 1399 1503 ··· 1409 1513 // Get urlInLibrary from map 1410 1514 const urlInLibrary = urlInLibraryMap?.get(card.url || ''); 1411 1515 1516 + // Get urlConnectionCount from map 1517 + const urlConnectionCount = 1518 + urlConnectionCountMap.get(card.url || '') || 0; 1519 + 1520 + // Get urlIsConnected from map 1521 + const urlIsConnected = urlIsConnectedMap?.get(card.url || ''); 1522 + 1412 1523 const rawCardData = { 1413 1524 id: card.id, 1414 1525 authorId: card.authorId, ··· 1418 1529 libraryCount: card.libraryCount, 1419 1530 urlLibraryCount, 1420 1531 urlInLibrary, 1532 + urlConnectionCount, 1533 + urlIsConnected, 1421 1534 createdAt: card.createdAt, 1422 1535 updatedAt: card.updatedAt, 1423 1536 note: note