[cleanup] Point coach avatar editing at the function that exists (closes #22) - #39
Merged
Merged
Conversation
CoachAvatarEdit POSTed {prompt, style, count} to `/motivational-images` and
expected {images: []}. That endpoint is `sendMotivationalImages(event, context)`
— a Cloud Scheduler background job. It is not an HTTP handler, takes no such
body and returns no such shape, so the Generate button could never have worked.
Closes #22.
The component is NOT orphaned: App.jsx routes /my-coaches/:coachId/avatar to it
and CoachEdit.jsx:384 navigates there, so this is a repoint rather than a
delete.
Repointing meant changing the interaction, not just the URL. The real generator
is PhotoMaker, which restyles a real face and cannot invent one from a
description — `generateCoachAvatars` calls `storeSelfie` unconditionally, so a
photo is required. The UI now asks for one, and the description becomes optional
steering on top of the style's own prompt. The request matches the JSON path the
generator actually implements ({coachId, selfie_base64, selfie_mime, style,
prompt}) and reads {avatars, failedStyles} back.
Details that follow from matching the real contract:
- The style list mirrors AVATAR_STYLES in avatar-generation.js, including the
model's own "Disney Charactor" misspelling. The previous list (realistic,
professional, cartoon, fitness, athletic) matched nothing server-side and
was never rendered anyway — the generator silently falls back to every
style when it does not recognise one.
- Partial success is surfaced. The generator returns `failedStyles` alongside
whatever succeeded; a short grid is otherwise unexplained.
- Errors come from the generator's own message rather than a generic toast.
- The VITE_COACH_AVATAR_GENERATOR_URL override is honoured, as AvatarUpload
already does. Without it this component would break in any deploy that
points the generator at its own URL.
- The default prompt ("A ... fitness coach") is gone. It assumed the
fitness-era product and overrode the style the creator picked.
Also removes a second phantom endpoint found while checking for other bad
callers: CoachBuilderContext POSTed to `/coach-avatar-generator/save-avatar`,
which has never existed either — the generator does not route on path, so the
request could only ever be read as a malformed generation request. It was
redundant as well as dead, since the insert directly above it already persists
avatar_url, avatar_style and original_selfie_url. It could not even fail
honestly: `fetch` does not reject on a 4xx, so its catch almost never ran, and
when it did it told the creator the avatar had failed to save after the insert
had saved it.
Verified: webapp builds clean; no caller in webapp/, mobile/src or mobile/app
invokes /motivational-images or /save-avatar as an HTTP endpoint any more. The
generation round trip itself is unverified against a live generator — it needs
Replicate and GCS credentials, which the local stack does not carry.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #22.
CoachAvatarEditPOSTed{prompt, style, count}to/motivational-imagesand expected{images: []}. That endpoint issendMotivationalImages(event, context)— a Cloud Scheduler background job. Not an HTTP handler, takes no such body, returns no such shape. The Generate button could never have worked.It is not orphaned — step 1 of the issue
App.jsx:130routes/my-coaches/:coachId/avatarto it andCoachEdit.jsx:384navigates there. So this is a repoint, not a delete.Repointing meant changing the interaction, not just the URL
The real generator is PhotoMaker: it restyles a real face and cannot invent one from a description.
generateCoachAvatarscallsstoreSelfieunconditionally, so a photo is required. There is no prompt-only avatar generation anywhere in the backend — the old UI was asking for something that does not exist.So the Generate tab now takes a photo, and the description becomes optional steering on top of the style's own prompt. The request matches the JSON path the generator implements:
Details that fall out of matching the real contract:
AVATAR_STYLESinavatar-generation.js, including the model's own"Disney Charactor"misspelling. The old list (realistic,professional,cartoon,fitness,athletic) matched nothing server-side — and was never rendered anyway. The generator silently falls back to every style when it does not recognise one, so a wrong string is an expensive no-op, not an error.failedStylescomes back alongside whatever succeeded; a short grid is otherwise unexplained.VITE_COACH_AVATAR_GENERATOR_URLis honoured, asAvatarUploadalready does. Without it this component breaks in any deploy pointing the generator at its own URL."A ... fitness coach"assumed the fitness-era product and overrode the creator's chosen style.A second phantom endpoint, found via step 4
Checking for other bad callers turned up
CoachBuilderContext.jsx:533POSTing to/coach-avatar-generator/save-avatar— which has never existed either. The generator does not route on path, so that request could only ever be read as a malformed generation request.It was redundant as well as dead: the
insertdirectly above it already persistsavatar_url,avatar_styleandoriginal_selfie_url. And it could not fail honestly —fetchdoes not reject on a 4xx, so its catch almost never ran, and when it did it told the creator "the avatar failed to save" after the insert had already saved it. Removed.Verification
webappbuilds cleanwebapp/,mobile/srcormobile/appinvokes/motivational-imagesor/save-avataras an HTTP endpoint any moreNot verified: the generation round trip against a live generator. It needs Replicate and GCS credentials the local stack does not carry, so the contract is matched by reading
functions/coach-avatar-generator/index.jsrather than by running it. Worth a manual pass on a deploy that has those keys.Noted, not fixed
coach-avatar-generatorhas no authorization — CORS is*and no token is checked, so anyone can burn Replicate credits generating avatars for anycoachId. Out of scope here; it belongs with the #25 sweep.🤖 Generated with Claude Code