- users module: profile + address CRUD behind use cases (users_profiles, users_addresses) - roles customer/admin on identity_users; role resolved from DB per request - shared auth contract (Authenticate, requireRole, requireOwnerOrAdmin) injected from composition root; users never imports identity - authorization runs before existence checks; address SQL scoped by user_id - @fastify/cookie registered once at app root (cross-module) - migrations 003_identity_roles + 004_users (reversible) - no new npm dependencies; tests: unit 52, integration 22 Gates: reviewer/security/qa APPROVED; verify.sh green
28 lines
854 B
TypeScript
28 lines
854 B
TypeScript
/**
|
|
* Profile use cases. Thin orchestration over ports; ownership/role checks
|
|
* happen in the API layer before these run.
|
|
*/
|
|
import type { ProfileRepository } from '../domain/ports.js';
|
|
import type { Profile, ProfilePatch } from '../domain/profile.js';
|
|
|
|
export class GetProfile {
|
|
constructor(private readonly profiles: ProfileRepository) {}
|
|
async execute(userId: string): Promise<Profile | undefined> {
|
|
return this.profiles.findByUserId(userId);
|
|
}
|
|
}
|
|
|
|
export class UpdateProfile {
|
|
constructor(private readonly profiles: ProfileRepository) {}
|
|
async execute(userId: string, patch: ProfilePatch): Promise<Profile> {
|
|
return this.profiles.upsert(userId, patch);
|
|
}
|
|
}
|
|
|
|
export class ListProfiles {
|
|
constructor(private readonly profiles: ProfileRepository) {}
|
|
async execute(): Promise<Profile[]> {
|
|
return this.profiles.list();
|
|
}
|
|
}
|