feat: refine portfolio content, contact, and supporting media

This commit is contained in:
2026-09-05 20:08:57 +03:00
parent 15bcdf7cec
commit 103427f95b
53 changed files with 824 additions and 204 deletions

View File

@@ -201,7 +201,12 @@ const portfolioContentSchema = z.object({
}).strict()).min(1),
contact: z.object({
introduction: visibleString,
email: z.email(),
email: z.object({ localPart: visibleString, domain: visibleString }).strict().refine(
({ localPart, domain }) => !localPart.includes('@') && !domain.includes('@') &&
z.email().safeParse(`${localPart}@${domain}`).success,
'Contact email parts must form a valid address.',
),
avatarAssetId: opaqueId.optional(),
social: z.array(z.object({
service: z.enum(['GitHub', 'GitLab', 'LinkedIn']),
url: httpUrl,
@@ -334,6 +339,7 @@ export const parseProductionInputSnapshot = (input: unknown): ProductionInputs =
const { content, manifest, site } = productionInputsSchema.parse(input);
const manifestIds = new Set(manifest.assets.map((asset) => asset.id));
const referencedAssetIds = [
...(content.contact.avatarAssetId === undefined ? [] : [content.contact.avatarAssetId]),
...content.projects.selected.flatMap((project) => project.assetIds),
...content.projects.additional.flatMap((project) => project.assetIds),
...content.toolkit.flatMap((group) => group.technologies.flatMap((technology) =>