feat: add dedicated model photo separate from avatar

Adds a `photo` field to the users table (and a migration) that serves
as a dedicated profile/card image for models. This is now used in model
cards and on the model single page, while `avatar` is reserved for
comments, article authors, and the user profile page.

- DB: `photo` column on `users` with FK to `files`
- GraphQL: exposed on ModelType, UserType, AdminUserDetailType; photoId arg on adminUpdateUser
- Services: photo field in MODELS_QUERY, MODEL_BY_SLUG_QUERY, ADMIN_GET/UPDATE_USER
- Frontend: model cards and single page use `photo ?? avatar` fallback
- Admin: model photo upload section in user edit page

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-03-08 10:54:27 +01:00
parent 2980c0b637
commit 4d81266cb1
10 changed files with 56 additions and 3 deletions

View File

@@ -134,6 +134,7 @@ builder.mutationField("adminUpdateUser", (t) =>
artistName: t.arg.string(),
avatarId: t.arg.string(),
bannerId: t.arg.string(),
photoId: t.arg.string(),
},
resolve: async (_root, args, ctx) => {
requireAdmin(ctx);
@@ -149,6 +150,7 @@ builder.mutationField("adminUpdateUser", (t) =>
updates.artist_name = args.artistName;
if (args.avatarId !== undefined && args.avatarId !== null) updates.avatar = args.avatarId;
if (args.bannerId !== undefined && args.bannerId !== null) updates.banner = args.bannerId;
if (args.photoId !== undefined && args.photoId !== null) updates.photo = args.photoId;
const updated = await ctx.db
.update(users)