mirror of
https://github.com/aaronpo97/the-biergarten-app.git
synced 2026-10-14 17:54:42 +00:00
8.8 KiB
8.8 KiB
Public user profile: data requirements
Covers /users/:id (routes/user-profile.tsx). Mirrors the format of
../breweries/BREWERY_HANDOFF.md.
Status legend
- ✅ Available: real data, wired up.
- ⚠️ Partial: schema/repository exists but no public read endpoint.
- ❌ Missing: no backend support; page shows filler or local-only state.
Header & sidebar
| Field | Status | Source | Gap |
|---|---|---|---|
| Username, name, joined date | ✅ | GET /api/user/{id}/profile (PublicUserProfileDto) |
|
isOwnProfile |
✅ | Compares the session's userAccountId to the route param |
|
| Bio | ⚠️ | FILLER_PROFILE_META.bio |
Social.UserProfile.Biography exists (IUserProfileRepository, UpdateBiographyHandler) but there's no query/controller route to read another user's profile — only a write path for the authenticated user's own. |
| Location | ❌ | FILLER_PROFILE_META.location |
No location field on UserAccount or UserProfile. |
| Avatar photo | ⚠️ | Initials placeholder (avatar-placeholder) |
Social.UserAvatar + UploadAvatarHandler exist but there's no GET endpoint to read a user's stored avatar back. |
| Cover photo | ❌ | Flat bg-base-300 block |
No cover-photo concept anywhere in the schema. |
| Following / Followers counts | ❌ | FILLER_PROFILE_META.following / .followers |
Social.UserFollow table exists but is unused by any query/controller — needs count queries (WHERE UserAccountID = ? / WHERE FollowingID = ?). |
| Breweries visited / Ratings given counts | ❌ | FILLER_PROFILE_META.breweriesVisited / .ratingsGiven |
Blocked on the same like/rating gaps called out in BREWERY_HANDOFF.md. |
Follow action
| Field | Status | Source | Gap |
|---|---|---|---|
| Follow / unfollow the profile | ❌ | Local component state | Social.UserFollow has no command/query/controller (create, delete, "am I following them" check) — mirrors the brewery-like gap. |
| Edit profile (own profile) | ✅ | Links to /account, the existing profile-edit surface |
Profile links from other pages
| Field | Status | Source | Gap |
|---|---|---|---|
| Commenter name links (brewery detail comments) | ⚠️ | CommentItem links only when comment.userAccountId is set |
FILLER_COMMENTS has no backing accounts, so those rows render as plain text; a comment added during the session by a signed-in user does carry a real GUID and links correctly. |
| Following-list person links (profile page) | ⚠️ | FollowingTab links only when f.userAccountId is set |
Same gap as above — FILLER_FOLLOWING's two person rows have no backing accounts, so they render as plain text until real follow data exists. |
Both components already support linking (see CommentItem.stories.tsx's WithLinkedAccount story); what's missing is real account IDs on the filler rows, which can't be faked without recreating the 404 this was fixed for. This resolves itself once (4) below closes and comments/follows are loader-backed.
Activity / Following / Liked tabs
| Field | Status | Source | Gap |
|---|---|---|---|
| Activity feed (ratings/likes/comments) | ❌ | FILLER_ACTIVITY |
No unified activity/timeline concept. Needs a query that unions ratings, likes, and comments across brewery/beer posts for a given user, ordered by time. |
| Following list (people + breweries) | ❌ | FILLER_FOLLOWING |
Needs a query over Social.UserFollow joined to Auth.UserAccount, plus (once the like/rating gaps close) a way to follow breweries specifically. |
| Liked list | ❌ | FILLER_LIKED |
Blocked on the BreweryPostLike/BeerPostLike gap in BREWERY_HANDOFF.md. |
| Unfollow from the Following tab | ❌ | Local component state (optimistic toggle) | Same Social.UserFollow gap as the header Follow action. |
Summary of backend work
- A public query + controller route to read a user's
Social.UserProfile.BiographybyUserAccountId(the write path already exists; only the public read is missing). - A public query + controller route to read a user's stored
Social.UserAvatar. - A location field on
UserAccountorUserProfile, and a cover-photo storage concept (mirrors the avatar gap). Social.UserFollowcommand/query/controller: follow, unfollow, "is following" check, and follower/following counts.- An activity/timeline query unioning ratings, likes, and comments for a user, ordered by time — depends on the like/rating/comment tables called out in
BREWERY_HANDOFF.mdexisting first. - Once (4) and the like/rating gaps close, swap
FILLER_PROFILE_META/FILLER_ACTIVITY/FILLER_FOLLOWING/FILLER_LIKED(utils/filler-user-profile.ts) and the localuseStateinroutes/user-profile.tsxfor loader data andauthorizedRequest-based mutations (seeauth.server.ts). Swapping in real (possibly empty) arrays is also what makes the Activity/FollowingEmptyStates reachable from the actual route — today they're only exercised by theEmptyStorybook stories, since the filler arrays are never empty.