feat(admin): espace « Utilisateurs » pour créer des comptes #144

Merged
kyuno merged 3 commits from feat/admin-user-accounts into main 2026-09-10 21:48:31 +02:00
2 changed files with 49 additions and 0 deletions
Showing only changes of commit 9123f6358e - Show all commits

View file

@ -17,6 +17,24 @@ export const adminLoginSchema = z.object({
/** Inferred TS type for {@link adminLoginSchema}'s validated output. */
export type AdminLoginInput = z.infer<typeof adminLoginSchema>;
/**
* Payload accepted by `POST /admin/api/users` — an operator provisioning an
* end-user account by hand (test accounts, pre-registration, support). Its
* own contract, not a re-export of `signupSchema` (same stance as
* {@link adminLoginSchema} vs `loginSchema`), and notably **without a
* `password` field**: the server generates a one-time temporary password
* and returns it once (see `apps/api`'s `admin-users.service.ts`). The
* name/email rules mirror `signupSchema` so a hand-created account is
* indistinguishable from a self-signed-up one afterwards.
*/
export const adminCreateUserSchema = z.object({
firstName: z.string().trim().min(1, "Le prénom est requis").max(100),
lastName: z.string().trim().min(1, "Le nom est requis").max(100),
email: z.string().trim().toLowerCase().email("Email invalide"),
});
/** Inferred TS type for {@link adminCreateUserSchema}'s validated output. */
export type AdminCreateUserInput = z.infer<typeof adminCreateUserSchema>;
/**
* Query params for `GET /admin/api/metrics` — `?days=` bounds how far back the
* time-series go (and how many daily buckets they carry). Coerced from the

View file

@ -15,6 +15,37 @@ export interface AdminUserView {
lastLoginAt: string | null;
}
/**
* One row of `GET /admin/api/users` — an end-user account as shown in the
* admin's user list. Declared by hand rather than derived from the Prisma
* `UserProfile` type (same reason as {@link AdminUserView} / {@link
* SafeUserProfile}: apps/web must not depend on `@prisma/client`), and
* deliberately *not* {@link SafeUserProfile}: this view drops `tokenVersion`
* (internal) and adds `householdName` (resolved server-side) + `createdAt`.
* `householdName` is `null` when the account belongs to no household;
* `createdAt` is an ISO 8601 string.
*/
export interface AdminUserListItemView {
id: number;
firstName: string;
lastName: string;
email: string;
householdName: string | null;
createdAt: string;
}
/**
* Response of `POST /admin/api/users`. Carries the freshly-created account
* plus the **one-time** temporary password the server generated for it —
* never stored in plain text, never retrievable again, so the operator must
* copy it now and relay it to the user out of band.
*/
export interface AdminUserCreatedView {
user: AdminUserListItemView;
/** Plain-text temporary password, shown exactly once. */
temporaryPassword: string;
}
/** One `{ key, count }` breakdown row — e.g. recipes per source, corrections per status. */
export interface MetricsBreakdownRow {
key: string;