import "reflect-metadata"; import { injectable } from "inversify"; import { NoopTracer, NoopLogger, type ITracer, type ILogger, } from "@repo/core-shared/instrumentation"; import type { IUsersRepository } from "../../application/repositories/users.repository.interface"; import type { User } from "../../entities/models/user"; const DEFAULT_SEED: User[] = [ { id: "1", username: "alice", passwordHash: "hashed_password_alice" }, { id: "2", username: "bob", passwordHash: "hashed_password_bob" }, ]; @injectable() export class MockUsersRepository implements IUsersRepository { private _users: User[]; private tracer: ITracer; private logger: ILogger; constructor( initialUsers: User[] = DEFAULT_SEED, tracer: ITracer = new NoopTracer(), logger: ILogger = new NoopLogger(), ) { this._users = [...initialUsers]; this.tracer = tracer; this.logger = logger; void this.logger; // currently unused; reserved for future mock-thrown captures } async getUser(id: string): Promise { return this.tracer.startSpan( { name: "users.getUser", op: "repository", attributes: { id } }, async (span) => { const found = this._users.find((u) => u.id === id); span.setAttribute("found", Boolean(found)); return found; }, ); } async getUserByUsername(username: string): Promise { return this.tracer.startSpan( { name: "users.getUserByUsername", op: "repository", attributes: { emailDomain: username.includes("@") ? (username.split("@")[1] ?? "(invalid)") : username }, }, async (span) => { const found = this._users.find((u) => u.username === username); span.setAttribute("found", Boolean(found)); return found; }, ); } async createUser(input: User): Promise { return this.tracer.startSpan( { name: "users.createUser", op: "repository", attributes: { id: input.id } }, async (span) => { this._users.push(input); span.setAttribute("created", true); return input; }, ); } }