diff --git a/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts b/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts index e13b8e76..744d6434 100644 --- a/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts +++ b/src/modules/atproto/infrastructure/services/BlueskyProfileService.ts @@ -75,6 +75,7 @@ export class BlueskyProfileService implements IProfileService { avatarUrl: profile.avatar, bannerUrl: profile.banner, bio: profile.description, + labels: profile.labels, }; return ok(userProfile); diff --git a/src/modules/cards/application/mappers/ProfileMapper.ts b/src/modules/cards/application/mappers/ProfileMapper.ts index 1a59a8cd..b6414bd7 100644 --- a/src/modules/cards/application/mappers/ProfileMapper.ts +++ b/src/modules/cards/application/mappers/ProfileMapper.ts @@ -1,5 +1,5 @@ import { UserProfile } from '../../domain/services/IProfileService'; -import { User } from '@semble/types'; +import { User, Label } from '@semble/types'; /** * ProfileMapper - Centralizes mapping from domain UserProfile to API User DTOs @@ -28,6 +28,7 @@ export class ProfileMapper { collectionCount: profile.collectionCount, connectionCount: profile.connectionCount, connectionsByType: profile.connectionsByType, + labels: profile.labels, }; } @@ -46,6 +47,7 @@ export class ProfileMapper { followerCount?: number; followingCount?: number; followedCollectionsCount?: number; + labels?: Label[]; } { return { id: profile.id, @@ -58,6 +60,7 @@ export class ProfileMapper { followerCount: profile.followerCount, followingCount: profile.followingCount, followedCollectionsCount: profile.followedCollectionsCount, + labels: profile.labels, }; } diff --git a/src/modules/cards/domain/services/IProfileService.ts b/src/modules/cards/domain/services/IProfileService.ts index 1ecbebb6..9c91f8db 100644 --- a/src/modules/cards/domain/services/IProfileService.ts +++ b/src/modules/cards/domain/services/IProfileService.ts @@ -1,4 +1,5 @@ import { Result } from 'src/shared/core/Result'; +import { Label } from '@semble/types'; export interface IProfileService { getProfile(userId: string, callerId?: string): Promise>; @@ -20,4 +21,5 @@ export interface UserProfile { collectionCount?: number; connectionCount?: number; connectionsByType?: { total: number; [type: string]: number }; + labels?: Label[]; } diff --git a/src/types/src/api/common.ts b/src/types/src/api/common.ts index c5019131..04feb452 100644 --- a/src/types/src/api/common.ts +++ b/src/types/src/api/common.ts @@ -1,3 +1,26 @@ +// ATProto Label interface +export interface Label { + $type?: 'com.atproto.label.defs#label'; + /** The AT Protocol version of the label object. */ + ver?: number; + /** DID of the actor who created this label. */ + src: string; + /** AT URI of the record, repository (account), or other resource that this label applies to. */ + uri: string; + /** Optionally, CID specifying the specific version of 'uri' resource this label applies to. */ + cid?: string; + /** The short string name of the value or type of this label. */ + val: string; + /** If true, this is a negation label, overwriting a previous label. */ + neg?: boolean; + /** Timestamp when this label was created. */ + cts: string; + /** Timestamp at which this label expires (no longer applies). */ + exp?: string; + /** Signature of dag-cbor encoded label. */ + sig?: Uint8Array; +} + // Unified User/Profile interface - used across all endpoints export interface User { id: string; @@ -15,6 +38,7 @@ export interface User { collectionCount?: number; // Number of collections created by this user connectionCount?: number; // Total number of connections created by this user connectionsByType?: { total: number; [type: string]: number }; // Breakdown of connections by type + labels?: Label[]; // Moderation labels from ATProto } // Extended User interface for contributors with contribution count