Appearance
Epic 2 — Talent Profile
BE-TALENT-001 — Extend TalentProfile schema (full spec fields)
- [x] Implemented
Files:
- Edit:
prisma/schema.prisma— add all missing fields - Run:
pnpm db:migrate - Edit:
src/graphql/schema/index.ts— add fields toTalentProfiletype andUpdateTalentProfileInput - Edit:
src/graphql/resolvers/talent.ts
New fields to add to TalentProfile:
prisma
dateOfBirth DateTime?
nationality String[] @default([])
race String?
tattoos Boolean @default(false)
piercings Boolean @default(false)
specialPhysicalSkills String[] @default([])
languages Json? // [{ language, proficiency, accents }]
talentHierarchy Json? // { primary, skills[], specialties[] }
experienceEntries Json? // [{ productionType, subtype, genre, title, year, role }]
notableWorks Json? // [{ title, role, year, platform }]
awards Json? // [{ name, year, category }]
affiliations Json? // { studios[], networks[], productionHouses[] }
willingToRelocate Boolean @default(false)
relocateConditions String?
availabilityType String @default("AVAILABLE") // AVAILABLE | UNAVAILABLE | FREELANCE
profileCompleteness Int @default(0)
headlinePhoto String?BE-TALENT-002 — Dream jobs / dream roles (OMDb-backed tags)
- [x] Implemented
Files:
- Edit:
prisma/schema.prisma— replacedreamGigs String[]onTalentProfileand add equivalent field toPetOwnerProfile - Run:
pnpm db:migrate - Edit:
src/graphql/schema/index.ts— addDreamJobtype, input, and resolvers - Edit:
src/graphql/resolvers/talent.ts - Create:
src/graphql/resolvers/petOwner.ts— same mutations for PetOwnerProfile
Schema change:
Replace dreamGigs String[] on TalentProfile (and add the equivalent field on PetOwnerProfile) with a JSON array of structured entries:
prisma
dreamJobs Json? // DreamJobEntry[] — see type belowEach entry is a JSON object stored inline (no separate table needed at this scale):
ts
type DreamJobEntry = {
imdbId: string; // e.g. "tt0944947"
title: string; // "Game of Thrones"
type: 'movie' | 'series' | 'episode';
year: string; // "2011–2019"
posterUrl: string | null;
role?: string; // optional: specific character/role name the user wants
}New GraphQL mutation (both Talent and PetOwner):
graphql
updateDreamJobs(jobs: [DreamJobInput!]!): TalentProfile! # or PetOwnerProfile!graphql
input DreamJobInput {
imdbId: String!
title: String!
type: String!
year: String!
posterUrl: String
role: String
}Notes:
- The OMDb API (
https://www.omdbapi.com) is the public interface to IMDb data. It has a free tier (1,000 req/day) and a paid tier. Requires an API key stored asOMDB_API_KEYin the backend.env. - Search is done client-side via a direct call to the OMDb API from the frontend (avoids proxying search traffic through the backend). The backend only stores the final selected entries.
- Guard: max 20 dream jobs per profile.
- Migration: the existing
dreamGigs String[]data should be preserved as-is in adreamGigsLegacy String[]field until a data migration script converts free-text entries.
BE-TALENT-003 — Profile completeness score calculation
- [x] Implemented
Files:
- Create:
src/services/talent/completeness.ts - Edit:
src/services/talent/index.ts— call completeness update after any profile update
Description: After every updateTalentProfile, recalculate and store profileCompleteness (0–100). Scoring weights: headlinePhoto (15), displayName+bio (10), primaryCategory+skills (15), location (5), languages (5), physicalAttributes (10), experienceEntries (15), notableWorks (10), mediaItems/reel (15).
BE-TALENT-003 — Talent profile photo upload
- [x] Implemented
Files:
- Edit:
src/services/media/index.ts— implementuploadProfilePhoto(userId, file)with S3 put + CDN URL - Edit:
src/graphql/schema/index.ts— adduploadProfilePhoto(file: Upload!): String! - Edit:
src/graphql/resolvers/talent.ts
Description: Upload profile photo to S3 (castyou-media/profile-photos/{userId}.{ext}). Return CDN URL. Update TalentProfile.headlinePhoto. Max size 5 MB. Accepted: jpg, png, webp.
FE-TALENT-001 — Talent profile view page
- [x] Implemented
Files:
- Create:
apps/app/src/pages/talent/TalentProfilePage.tsx - Create:
apps/app/src/lib/queries/talent.ts—GET_TALENT_PROFILEquery - Create:
apps/app/src/hooks/useTalentProfile.ts - Edit:
apps/app/src/App.tsx— add route/talent/:id
Description: Public view of a talent's full profile (seen by producers). Sections: hero (photo, name, category, location, match score), about/bio, physical attributes, skills hierarchy, languages/accents, experience, notable works, demo reel player, social links. All layout components from @castyou/design-system. Matches the "Detalhes" screens in Figma (Jornada Talento flow).
FE-TALENT-002 — Talent profile editor (multi-step form)
- [x] Implemented
Files:
- Create:
apps/app/src/pages/profile/TalentEditPage.tsx - Create:
apps/app/src/pages/profile/steps/BasicInfoStep.tsx - Create:
apps/app/src/pages/profile/steps/PhysicalStep.tsx - Create:
apps/app/src/pages/profile/steps/ProfessionalStep.tsx - Create:
apps/app/src/pages/profile/steps/ExperienceStep.tsx - Create:
apps/app/src/pages/profile/steps/LocationAvailabilityStep.tsx - Create:
apps/app/src/pages/profile/steps/MediaStep.tsx - Create:
apps/app/src/hooks/useUpdateTalentProfile.ts
Description: Multi-step form to edit all talent profile fields. Each step is a separate component. Progress indicator at top (use ProgressRing from DS). Auto-save draft to localStorage between steps. Submit calls updateTalentProfile mutation. All inputs from @castyou/design-system: Input, Textarea, Select, MultiSelect, Chip, FileUpload.
FE-TALENT-003 — My Profile page (authenticated talent view)
- [x] Implemented
Files:
- Edit:
apps/app/src/pages/profile/ProfilePage.tsx— replace placeholder with real profile display
Description: Replace the "Profile coming soon" placeholder with the real talent's own profile view. Shows ProgressRing with completeness %, sections matching the public view but with "Edit" buttons per section. Shows EmptyState for incomplete sections with prompts to fill in. Shows the "Change Password" modal already in the file.
FE-TALENT-006 — Extend talent profile view & editor for new spec fields
- [x] Implemented
Files:
- Edit:
apps/app/src/pages/talent/TalentProfilePage.tsx— add new sections: Verbal Proficiency, Location & Availability extended, Equipment - Edit:
apps/app/src/pages/profile/steps/BasicInfoStep.tsx— add gender, username - Edit:
apps/app/src/pages/profile/steps/ProfessionalStep.tsx— add yearsOfExperience, trainingEducation - Edit:
apps/app/src/pages/profile/steps/LocationAvailabilityStep.tsx— add homeCity, preferredProjectTypes, salaryExpectation, passportVisa, backgroundCheck, equipment - Create:
apps/app/src/pages/profile/steps/VerbalProficiencyStep.tsx— accentDialect picker - Edit:
apps/app/src/lib/queries/talent.ts— add new fields to GET_TALENT_PROFILE query - Edit:
apps/app/src/hooks/useUpdateTalentProfile.ts
New profile sections (view page):
- Verbal Proficiency: accent/dialect chips (e.g. "British RP", "Southern US")
- Location & Availability (extended): hometown, preferred project types, salary range, passport/visa info, background check badge, owned/preferred equipment chips
- Username: shown as
@handlein profile header
New form steps (editor):
BasicInfoStep: add username field (uniqueness validated on blur), gender dropdownProfessionalStep: add years of experience number input, trainingEducation repeater (institution, type, year)VerbalProficiencyStep(new step): MultiSelect for accent/dialect from a curated listLocationAvailabilityStep: add homeCity input, preferredProjectTypes MultiSelect, salary range inputs (min/max + currency + period), passportVisa MultiSelect, backgroundCheckClear toggle, ownedEquipment/preferredEquipment MultiSelect
BE-TALENT-004 — TalentProfile missing fields (2.2 spec gap)
- [x] Implemented
Files:
- Edit:
prisma/schema.prisma— add missing columns toTalentProfileandusernameunique toUser - Run:
pnpm db:migrate - Edit:
src/graphql/schema/index.ts— expose new fields onTalentProfiletype andUpdateTalentProfileInput - Edit:
src/graphql/resolvers/talent.ts - Create:
src/__tests__/resolvers/talent-missing-fields.test.ts
Fields to add:
prisma
// On User model
username String? @unique
// On TalentProfile model
gender String? // e.g. "Male", "Female", "Non-binary", "Prefer not to say"
accentDialect String[] @default([]) // e.g. ["British RP", "Southern US"]
yearsOfExperience Int?
trainingEducation Json? // [{ institution, type, year }] — acting schools, academies, conservatoriesGraphQL additions:
graphql
# TalentProfile type
gender: String
accentDialect: [String!]!
yearsOfExperience: Int
trainingEducation: JSON
# User type
username: String
# UpdateTalentProfileInput
gender: String
accentDialect: [String!]
yearsOfExperience: Int
trainingEducation: JSONNotes:
usernamelives onUser(notTalentProfile) so it's platform-unique across all user types.accentDialectcovers the entire Verbal Proficiency section from the spec (Accent / Dialect Proficiency).trainingEducationis separate fromcertifications— it stores formal schooling entries, not licenses.- Reviews & Ratings are deferred: they require a separate
TalentReviewmodel authored by producers (out of scope for this ticket).
BE-TALENT-005 — TalentProfile Location & Availability extended fields
- [x] Implemented
Files:
- Edit:
prisma/schema.prisma— add columns toTalentProfile - Run:
pnpm db:migrate - Edit:
src/graphql/schema/index.ts— add fields toTalentProfiletype andUpdateTalentProfileInput - Edit:
src/graphql/resolvers/talent.ts - Create:
src/__tests__/resolvers/talent-location.test.ts
Fields to add:
prisma
homeCity String?
preferredProjectTypes Json? // { productionTypes[], subtypes[], genres[] }
salaryExpectation Json? // { min, max, currency, period: "PER_DAY"|"PER_WEEK"|"PER_PROJECT" }
passportVisa Json? // { passports: String[], visas: String[], workPermits: String[] }
backgroundCheckClear Boolean @default(false)
ownedEquipment String[] @default([])
preferredEquipment String[] @default([])Notes:
homeCityis distinct fromlocation(current city) — talent may be based in London but living in NYC.salaryExpectationfeeds directly into discover-feed matching factor 1 (salary alignment).passportVisafeeds into matching factor 2 (work authorization) — more granular than the existingworkAuthorization String[].backgroundCheckClearand equipment fields are needed for commercial, stunt, and technical production roles.