driver to user id

This commit is contained in:
2026-01-07 13:26:31 +01:00
parent 0db80fa98d
commit 94d60527f4
27 changed files with 856 additions and 1170 deletions

View File

@@ -0,0 +1,50 @@
import { Company } from '@core/identity/domain/entities/Company';
import { ICompanyRepository } from '@core/identity/domain/repositories/ICompanyRepository';
/**
* In-memory implementation of ICompanyRepository for testing
*/
export class InMemoryCompanyRepository implements ICompanyRepository {
private companies: Map<string, Company> = new Map();
create(company: Pick<Company, 'getName' | 'getOwnerUserId' | 'getContactEmail'>): Company {
// Create a new Company instance with generated ID
const contactEmail = company.getContactEmail();
return Company.create({
name: company.getName(),
ownerUserId: company.getOwnerUserId(),
...(contactEmail !== undefined ? { contactEmail } : {}),
});
}
async save(company: Company): Promise<void> {
this.companies.set(company.getId(), company);
}
async delete(id: string): Promise<void> {
this.companies.delete(id);
}
async findById(id: string): Promise<Company | null> {
return this.companies.get(id) || null;
}
async findByOwnerUserId(userId: string): Promise<Company | null> {
for (const company of this.companies.values()) {
if (company.getOwnerUserId().toString() === userId) {
return company;
}
}
return null;
}
// Helper method for testing to get all companies
getAll(): Company[] {
return Array.from(this.companies.values());
}
// Helper method for testing to clear all
clear(): void {
this.companies.clear();
}
}

View File

@@ -0,0 +1,19 @@
import { Entity, PrimaryGeneratedColumn, Column, CreateDateColumn } from 'typeorm';
@Entity('companies')
export class CompanyOrmEntity {
@PrimaryGeneratedColumn('uuid')
id!: string;
@Column({ type: 'varchar', length: 100 })
name!: string;
@Column({ name: 'owner_user_id', type: 'varchar' })
ownerUserId!: string;
@Column({ type: 'varchar', nullable: true })
contactEmail: string | null = null;
@CreateDateColumn({ name: 'created_at' })
createdAt!: Date;
}

View File

@@ -21,6 +21,9 @@ export class UserOrmEntity {
@Column({ type: 'text', nullable: true })
primaryDriverId!: string | null;
@Column({ name: 'company_id', type: 'text', nullable: true })
companyId!: string | null;
@CreateDateColumn({ type: 'timestamptz' })
createdAt!: Date;
}

View File

@@ -0,0 +1,25 @@
import { Company } from '@core/identity/domain/entities/Company';
import { CompanyOrmEntity } from '../entities/CompanyOrmEntity';
export class CompanyOrmMapper {
toDomain(entity: CompanyOrmEntity): Company {
const contactEmail = entity.contactEmail ?? undefined;
return Company.rehydrate({
id: entity.id,
name: entity.name,
ownerUserId: entity.ownerUserId,
...(contactEmail !== undefined ? { contactEmail } : {}),
createdAt: entity.createdAt,
});
}
toPersistence(domain: Company): CompanyOrmEntity {
const entity = new CompanyOrmEntity();
entity.id = domain.getId();
entity.name = domain.getName();
entity.ownerUserId = domain.getOwnerUserId().toString();
entity.contactEmail = domain.getContactEmail() ?? null;
// Note: createdAt is handled by @CreateDateColumn
return entity;
}
}

View File

@@ -17,6 +17,7 @@ export class UserOrmMapper {
assertNonEmptyString(entityName, 'passwordHash', entity.passwordHash);
assertOptionalStringOrNull(entityName, 'salt', entity.salt);
assertOptionalStringOrNull(entityName, 'primaryDriverId', entity.primaryDriverId);
assertOptionalStringOrNull(entityName, 'companyId', entity.companyId);
assertDate(entityName, 'createdAt', entity.createdAt);
} catch (error) {
if (error instanceof TypeOrmIdentitySchemaError) {
@@ -35,6 +36,7 @@ export class UserOrmMapper {
displayName: entity.displayName,
...(passwordHash ? { passwordHash } : {}),
...(entity.primaryDriverId ? { primaryDriverId: entity.primaryDriverId } : {}),
...(entity.companyId ? { companyId: entity.companyId } : {}),
});
} catch (error) {
const message = error instanceof Error ? error.message : 'Invalid persisted User';
@@ -50,6 +52,7 @@ export class UserOrmMapper {
entity.passwordHash = stored.passwordHash;
entity.salt = stored.salt ?? '';
entity.primaryDriverId = stored.primaryDriverId ?? null;
entity.companyId = stored.companyId ?? null;
entity.createdAt = stored.createdAt;
return entity;
}
@@ -62,6 +65,7 @@ export class UserOrmMapper {
passwordHash: entity.passwordHash,
...(entity.salt ? { salt: entity.salt } : {}),
primaryDriverId: entity.primaryDriverId ?? undefined,
companyId: entity.companyId ?? undefined,
createdAt: entity.createdAt,
};
}

View File

@@ -42,6 +42,7 @@ export class TypeOrmAuthRepository implements IAuthRepository {
entity.passwordHash = passwordHash;
entity.salt = '';
entity.primaryDriverId = user.getPrimaryDriverId() ?? null;
entity.companyId = user.getCompanyId() ?? null;
entity.createdAt = existing?.createdAt ?? new Date();
await repo.save(entity);

View File

@@ -0,0 +1,47 @@
import type { DataSource } from 'typeorm';
import { Company } from '@core/identity/domain/entities/Company';
import type { ICompanyRepository } from '@core/identity/domain/repositories/ICompanyRepository';
import { CompanyOrmEntity } from '../entities/CompanyOrmEntity';
import { CompanyOrmMapper } from '../mappers/CompanyOrmMapper';
export class TypeOrmCompanyRepository implements ICompanyRepository {
constructor(
private readonly dataSource: DataSource,
private readonly mapper: CompanyOrmMapper,
) {}
create(company: Pick<Company, 'getName' | 'getOwnerUserId' | 'getContactEmail'>): Company {
// Create a new Company instance with generated ID
const contactEmail = company.getContactEmail();
return Company.create({
name: company.getName(),
ownerUserId: company.getOwnerUserId(),
...(contactEmail !== undefined ? { contactEmail } : {}),
});
}
async save(company: Company): Promise<void> {
const repo = this.dataSource.getRepository(CompanyOrmEntity);
const entity = this.mapper.toPersistence(company);
await repo.save(entity);
}
async delete(id: string): Promise<void> {
const repo = this.dataSource.getRepository(CompanyOrmEntity);
await repo.delete(id);
}
async findById(id: string): Promise<Company | null> {
const repo = this.dataSource.getRepository(CompanyOrmEntity);
const entity = await repo.findOne({ where: { id } });
return entity ? this.mapper.toDomain(entity) : null;
}
async findByOwnerUserId(userId: string): Promise<Company | null> {
const repo = this.dataSource.getRepository(CompanyOrmEntity);
const entity = await repo.findOne({ where: { ownerUserId: userId } });
return entity ? this.mapper.toDomain(entity) : null;
}
}