feat(ADM-018): completed feature

This commit is contained in:
chattie
2026-08-17 22:23:10 +02:00
parent cf1c69fc8b
commit d595b4871f
871 changed files with 47411 additions and 281 deletions

View File

@@ -8,7 +8,7 @@ import type pg from 'pg';
import { parseJson } from '../../../shared/http-input.js';
import { AppError } from '../../../shared/errors.js';
import { requireOwnerOrAdmin, requireRole, type Authenticate } from '../../../shared/auth.js';
import { GetProfile, ListProfiles, UpdateProfile } from '../application/profile-use-cases.js';
import { GetCustomer, GetProfile, ListCustomers, ListProfiles, UpdateProfile } from '../application/profile-use-cases.js';
import {
CreateAddress,
DeleteAddress,
@@ -18,7 +18,7 @@ import {
import { PgProfileRepository } from '../infrastructure/pg-profile-repository.js';
import { PgAddressRepository } from '../infrastructure/pg-address-repository.js';
import type { Address } from '../domain/address.js';
import type { Profile } from '../domain/profile.js';
import type { CustomerSummary, Profile } from '../domain/profile.js';
export interface UsersRoutesDeps {
pool: pg.Pool;
@@ -61,8 +61,10 @@ export async function registerUsersRoutes(
const profiles = new PgProfileRepository(deps.pool);
const addresses = new PgAddressRepository(deps.pool);
const getProfile = new GetProfile(profiles);
const getCustomer = new GetCustomer(profiles);
const updateProfile = new UpdateProfile(profiles);
const listProfiles = new ListProfiles(profiles);
const listCustomers = new ListCustomers(profiles);
const listAddresses = new ListAddresses(addresses);
const createAddress = new CreateAddress(addresses);
const updateAddress = new UpdateAddress(addresses);
@@ -71,19 +73,26 @@ export async function registerUsersRoutes(
app.get('/users', async (request, reply) => {
const user = await deps.authenticate(request);
requireRole(user, 'admin');
const items = await listProfiles.execute();
return reply.send({ items: items.map(serializeProfile) });
const query = request.query as Record<string, string | undefined>;
const q = query.q || undefined;
const offset = Math.max(0, parseInt(query.offset ?? '0', 10) || 0);
const limit = Math.min(100, Math.max(1, parseInt(query.limit ?? '20', 10) || 20));
const result = await listCustomers.execute({ q, offset, limit });
return reply.send({
items: result.items.map(serializeCustomer),
total: result.total,
});
});
app.get('/users/:id', async (request, reply) => {
const user = await deps.authenticate(request);
const { id } = parseJson(uuidParamSchema, request.params);
requireOwnerOrAdmin(user, id);
const profile = await getProfile.execute(id);
if (!profile) {
throw new AppError(404, 'NOT_FOUND', 'Profile not found');
const customer = await getCustomer.execute(id);
if (!customer) {
throw new AppError(404, 'NOT_FOUND', 'Customer not found');
}
return reply.send(serializeProfile(profile));
return reply.send(serializeCustomer(customer));
});
app.patch('/users/:id', async (request, reply) => {
@@ -146,6 +155,17 @@ function serializeProfile(profile: Profile) {
};
}
function serializeCustomer(c: CustomerSummary) {
return {
id: c.userId,
email: c.email,
role: c.role,
displayName: c.displayName,
phone: c.phone,
createdAt: c.createdAt.toISOString(),
};
}
function serializeAddress(address: Address) {
return {
id: address.id,