fix issues in core
This commit is contained in:
@@ -4,13 +4,12 @@
|
||||
* Manages user session using cookies. This is a placeholder implementation.
|
||||
*/
|
||||
|
||||
import type { AuthenticatedUserDTO } from '@core/identity/application/dto/AuthenticatedUserDTO';
|
||||
import type { AuthSessionDTO } from '@core/identity/application/dto/AuthSessionDTO';
|
||||
import type { IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort';
|
||||
import { Logger } from '@core/shared/application';
|
||||
import type { AuthenticatedUser } from '@core/identity/application/ports/IdentityProviderPort';
|
||||
import type { AuthSession, IdentitySessionPort } from '@core/identity/application/ports/IdentitySessionPort';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
|
||||
export class CookieIdentitySessionAdapter implements IdentitySessionPort {
|
||||
private currentSession: AuthSessionDTO | null = null;
|
||||
private currentSession: AuthSession | null = null;
|
||||
|
||||
constructor(private readonly logger: Logger) {
|
||||
this.logger.info('CookieIdentitySessionAdapter initialized.');
|
||||
@@ -18,14 +17,14 @@ export class CookieIdentitySessionAdapter implements IdentitySessionPort {
|
||||
// For demo, we'll start with no session.
|
||||
}
|
||||
|
||||
async getCurrentSession(): Promise<AuthSessionDTO | null> {
|
||||
async getCurrentSession(): Promise<AuthSession | null> {
|
||||
this.logger.debug('[CookieIdentitySessionAdapter] Getting current session.');
|
||||
return Promise.resolve(this.currentSession);
|
||||
}
|
||||
|
||||
async createSession(user: AuthenticatedUserDTO): Promise<AuthSessionDTO> {
|
||||
async createSession(user: AuthenticatedUser): Promise<AuthSession> {
|
||||
this.logger.debug(`[CookieIdentitySessionAdapter] Creating session for user: ${user.id}`);
|
||||
const newSession: AuthSessionDTO = {
|
||||
const newSession: AuthSession = {
|
||||
user: user,
|
||||
issuedAt: Date.now(),
|
||||
expiresAt: Date.now() + 3600 * 1000, // 1 hour expiration
|
||||
|
||||
146
adapters/social/persistence/inmemory/InMemorySocialAndFeed.ts
Normal file
146
adapters/social/persistence/inmemory/InMemorySocialAndFeed.ts
Normal file
@@ -0,0 +1,146 @@
|
||||
import type { Driver } from '@core/racing/domain/entities/Driver';
|
||||
import type { Logger } from '@core/shared/application';
|
||||
import type { IFeedRepository } from '@core/social/domain/repositories/IFeedRepository';
|
||||
import type { ISocialGraphRepository } from '@core/social/domain/repositories/ISocialGraphRepository';
|
||||
import type { FeedItem } from '@core/social/domain/types/FeedItem';
|
||||
|
||||
export type Friendship = {
|
||||
driverId: string;
|
||||
friendId: string;
|
||||
};
|
||||
|
||||
export type RacingSeedData = {
|
||||
drivers: Driver[];
|
||||
friendships: Friendship[];
|
||||
feedEvents: FeedItem[];
|
||||
};
|
||||
|
||||
export class InMemoryFeedRepository implements IFeedRepository {
|
||||
private readonly feedEvents: FeedItem[];
|
||||
private readonly friendships: Friendship[];
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(logger: Logger, seed: RacingSeedData) {
|
||||
this.logger = logger;
|
||||
this.logger.info('InMemoryFeedRepository initialized.');
|
||||
this.feedEvents = seed.feedEvents;
|
||||
this.friendships = seed.friendships;
|
||||
}
|
||||
|
||||
async getFeedForDriver(driverId: string, limit?: number): Promise<FeedItem[]> {
|
||||
this.logger.debug(`Getting feed for driver: ${driverId}, limit: ${limit}`);
|
||||
try {
|
||||
const friendIds = new Set(
|
||||
this.friendships
|
||||
.filter((f) => f.driverId === driverId)
|
||||
.map((f) => f.friendId),
|
||||
);
|
||||
|
||||
const items = this.feedEvents.filter((item) => {
|
||||
if (item.actorDriverId && friendIds.has(item.actorDriverId)) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
});
|
||||
|
||||
const sorted = items
|
||||
.slice()
|
||||
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
||||
|
||||
this.logger.info(`Found ${sorted.length} feed items for driver: ${driverId}.`);
|
||||
return typeof limit === 'number' ? sorted.slice(0, limit) : sorted;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting feed for driver ${driverId}:`, error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getGlobalFeed(limit?: number): Promise<FeedItem[]> {
|
||||
this.logger.debug(`Getting global feed, limit: ${limit}`);
|
||||
try {
|
||||
const sorted = this.feedEvents
|
||||
.slice()
|
||||
.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
|
||||
|
||||
this.logger.info(`Found ${sorted.length} global feed items.`);
|
||||
return typeof limit === 'number' ? sorted.slice(0, limit) : sorted;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting global feed:`, error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class InMemorySocialGraphRepository implements ISocialGraphRepository {
|
||||
private readonly friendships: Friendship[];
|
||||
private readonly driversById: Map<string, Driver>;
|
||||
private readonly logger: Logger;
|
||||
|
||||
constructor(logger: Logger, seed: RacingSeedData) {
|
||||
this.logger = logger;
|
||||
this.logger.info('InMemorySocialGraphRepository initialized.');
|
||||
this.friendships = seed.friendships;
|
||||
this.driversById = new Map(seed.drivers.map((d) => [d.id, d]));
|
||||
}
|
||||
|
||||
async getFriendIds(driverId: string): Promise<string[]> {
|
||||
this.logger.debug(`Getting friend IDs for driver: ${driverId}`);
|
||||
try {
|
||||
const friendIds = this.friendships
|
||||
.filter((f) => f.driverId === driverId)
|
||||
.map((f) => f.friendId);
|
||||
this.logger.info(`Found ${friendIds.length} friend IDs for driver: ${driverId}.`);
|
||||
return friendIds;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting friend IDs for driver ${driverId}:`, error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getFriends(driverId: string): Promise<Driver[]> {
|
||||
this.logger.debug(`Getting friends for driver: ${driverId}`);
|
||||
try {
|
||||
const ids = await this.getFriendIds(driverId);
|
||||
const friends = ids
|
||||
.map((id) => this.driversById.get(id))
|
||||
.filter((d): d is Driver => Boolean(d));
|
||||
this.logger.info(`Found ${friends.length} friends for driver: ${driverId}.`);
|
||||
return friends;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting friends for driver ${driverId}:`, error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async getSuggestedFriends(driverId: string, limit?: number): Promise<Driver[]> {
|
||||
this.logger.debug(`Getting suggested friends for driver: ${driverId}, limit: ${limit}`);
|
||||
try {
|
||||
const directFriendIds = new Set(await this.getFriendIds(driverId));
|
||||
const suggestions = new Map<string, number>();
|
||||
|
||||
for (const friendship of this.friendships) {
|
||||
if (!directFriendIds.has(friendship.driverId)) continue;
|
||||
const friendOfFriendId = friendship.friendId;
|
||||
if (friendOfFriendId === driverId) continue;
|
||||
if (directFriendIds.has(friendOfFriendId)) continue;
|
||||
|
||||
suggestions.set(friendOfFriendId, (suggestions.get(friendOfFriendId) ?? 0) + 1);
|
||||
}
|
||||
|
||||
const rankedIds = Array.from(suggestions.entries())
|
||||
.sort((a, b) => b[1] - a[1])
|
||||
.map(([id]) => id);
|
||||
|
||||
const drivers = rankedIds
|
||||
.map((id) => this.driversById.get(id))
|
||||
.filter((d): d is Driver => Boolean(d));
|
||||
|
||||
const result = typeof limit === 'number' ? drivers.slice(0, limit) : drivers;
|
||||
this.logger.info(`Found ${result.length} suggested friends for driver: ${driverId}.`);
|
||||
return result;
|
||||
} catch (error) {
|
||||
this.logger.error(`Error getting suggested friends for driver ${driverId}:`, error as Error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user