feat: add profile fields for local users

DB→domain→API→AP→frontend end-to-end. Fields stored as
JSONB, exposed via PATCH /users/me, serialized as AP
PropertyValue attachment. Editor in federation settings,
display on profile card.
This commit is contained in:
2026-05-29 13:54:25 +02:00
parent 14a869cc8d
commit 805bd9534f
19 changed files with 224 additions and 27 deletions

View File

@@ -1,6 +1,12 @@
import { cache } from "react";
import { z } from "zod";
export const ProfileFieldSchema = z.object({
name: z.string(),
value: z.string(),
});
export type ProfileField = z.infer<typeof ProfileFieldSchema>;
export const UserSchema = z.object({
id: z.string().uuid(),
username: z.string(),
@@ -9,6 +15,7 @@ export const UserSchema = z.object({
avatarUrl: z.string().nullable(),
headerUrl: z.string().nullable(),
customCss: z.string().nullable(),
profileFields: z.array(ProfileFieldSchema).default([]),
local: z.boolean(),
isFollowedByViewer: z.boolean(),
joinedAt: z.coerce.date().nullable(),
@@ -16,12 +23,6 @@ export const UserSchema = z.object({
export const MeSchema = UserSchema;
export const ProfileFieldSchema = z.object({
name: z.string(),
value: z.string(),
});
export type ProfileField = z.infer<typeof ProfileFieldSchema>;
export const RemoteActorSchema = z.object({
handle: z.string(),
displayName: z.string().nullable(),
@@ -77,6 +78,7 @@ export const UpdateProfileSchema = z.object({
displayName: z.string().max(50).optional(),
bio: z.string().max(4000).optional(),
customCss: z.string().optional(),
profileFields: z.array(ProfileFieldSchema).max(4).optional(),
});
export const SearchResultsSchema = z.object({