Skip to content

Positioning redesign — implement docs/positioning/brief.md (14/16 tracks)#63

Closed
hb-agent wants to merge 0 commit into
stagingfrom
feat/positioning-redesign
Closed

Positioning redesign — implement docs/positioning/brief.md (14/16 tracks)#63
hb-agent wants to merge 0 commit into
stagingfrom
feat/positioning-redesign

Conversation

@hb-agent
Copy link
Copy Markdown
Collaborator

Summary

Deep-flow implementation of the positioning brief locked in docs/positioning/brief.md. 14 of 16 planned tracks landed in this PR; Tracks G (federation activity card) and I (group URL restructure) deferred to focused follow-up PRs due to size and risk. See docs/positioning-redesign/plan.md for the full status table.

Process

  • Plan at docs/positioning-redesign/plan.md (deep-flow per AGENTS.md §26).
  • Plan review with three parallel reviewer agents (substrate-positioning, AT-Proto correctness, frontend architecture); 7 critical + 17 important + 12 nits accepted. Decisions in docs/positioning-redesign/review-round-1.md.
  • Implementation in 14 atomic commits (one per track + shared useCurrentActor hook).
  • Local verification: tsc --noEmit clean, eslint clean (32 pre-existing warnings, 0 errors), next build clean (all routes).
  • Implementation review with two parallel reviewer agents (frontend code quality + substrate-positioning consistency on the actual shipped code); 8 critical + 7 important fixes applied. Decisions in docs/positioning-redesign/review-round-1-impl.md.

What changed (track-by-track)

Track Surface
0 useCurrentActor() hook — single source of truth for active identity
A Sign-in modal create-intent mode (heading, sub-line, button label, alt-toggle, remember-me hidden); prompt: "create" plumbed through /api/auth/login (best-effort hint per round-1 I7)
B Identity section in /settings: DID (copyable + PLC link), resolved PDS, profile URL, created date (only when !isFallback)
C First-run profile setup card — Bluesky-detected preview (Import / Fill fresh / Later) or simple setup CTA; detection via isFallback; data via /api/resolve-did (no client AT-Proto); import uses new mergeProfile() helper to preserve existing fields
D Group handle editing — replace "coming soon" placeholder with <UsernameCard groupDid=… /> (existing API endpoint, gated by admin role)
E Handle length uniformly 3–18 (groups: 2–32 → 3–18)
F Nav alignment: bottom-nav Explore · Feed · Create · Notifications · Profile; mobile sidebar + left rail add Apps/Build, rename Groups → Memberships; personal-only.ts route key renamed
H <SigningAs> compose-time identity guard component on /create, /settings/edit-profile, /groups/create. In group mode shows the group identity primary + operator handle secondary ("You (@yourhandle) will be recorded as the operator")
J Empty-state copy alignment to brief §9
K useUserProfile.isOwnProfile now follows useCurrentActor(), not personal DID — edit chrome follows active identity. Storage listener in OrgProvider for multi-tab sync. Auto-switch-on-removal toast signal (autoSwitchedFrom)
M Marketing landing page at / for unauth visitors: hero with locked headline + value-statement, apps strip, network-effects section with Arrived from an app? sub-block (brief §1.3 secondary audience), closing CTA. Authenticated users still redirect to /@<handle>
N Connected Apps section in /settings — empty-state UI ready to consume GET /api/oauth/clients/granted when backend ships (conscious override of brief §A28 per operator decision)
O Account section (Export your data via resolved PDS, Sign out, Delete account with substrate-honest copy distinguishing PLC tombstoning)
P Notifications surface verified — existing endorsement and activity-contributor reasons cover brief §6.14; group-invite + audit-alert categories need new backend reasons (flagged for follow-up)

Breaking changes

None. All changes are additive or modify component-internal behavior. Existing URLs unchanged (Track I — URL restructure — deferred).

Out of scope (follow-up PRs)

  • Track G — federation activity card (from {lexicon-author} + View on ↗) + AppAffiliationRow on profile hero + counts breakdown by app. The shared foundation (src/lib/atproto/curated-apps.ts with inferLexiconAuthor() per round-1 plan A1) shipped with Track M; the activity-card and profile-hero integrations remain. ~450 lines isolated change.
  • Track I — group URL restructure (universal /profile/[handleOrDid]/settings, middleware-rewrite for did: paths, 301 redirects, extracted /groups/<DID>/{members,audit}). Highest-risk structural change (~600 lines); isolated as its own PR per AGENTS.md §26 reviewability guidance.
  • Track C blob re-upload (round-1 A3) — Bluesky avatar/banner blobs from cdn.bsky.app need fetch + uploadBlob + new BlobRef. Users currently upload manually via /settings/edit-profile after import.
  • swapRecord concurrent-edit protection (round-1 A2) — mergeProfile() does read-modify-write without CID-based swap; race window is small and acceptable for v1.
  • Multi-tab sign-in-as-different-user race (round-1-impl D1) — storage sync covers active-org changes but not auth-cookie changes across tabs.

Test plan

  • Unauthenticated / shows the marketing landing page (not redirect to /search).
  • Authenticated / redirects to /@<handle> as before.
  • Closing CTA Get your portable account → opens the modal in create mode (heading: Create your account; sub-line; button: Create account).
  • Toggling "Already have an account? Sign in →" inside the modal returns to login mode with input focused.
  • /settings shows the new Identity section between Username and Email; DID is copyable; PDS host is the user's resolved PDS (not PDS_URL constant); Created date renders only when !isFallback.
  • On a fresh sign-in with no profile content, the first-run card appears at the top of the user's own profile. If app.bsky.actor.profile has populated fields, Import shows the preview. Import preserves any existing user-set fields (avatar/banner/pronouns) — verify via getRecord after.
  • Group settings (acting as a group, owner/admin role) shows <UsernameCard> for handle editing.
  • /groups/create rejects handles outside 3–18 chars.
  • Mobile bottom-nav shows Explore · Feed · Create · Notifications · Profile.
  • Mobile sidebar shows Apps and Build; Memberships renamed (not "Groups").
  • When acting as a group, viewing own personal profile shows NO edit chrome (brief §7.1).
  • When acting as a group, the <SigningAs> block on /create shows the group as primary identity and the operator handle in the secondary line.
  • Acting-as-group state syncs across tabs via the storage listener.
  • Empty-state copy matches the brief §9 table (feed quiet, profile memberships, etc.).
  • /settings shows Connected Apps (empty state visible) and Account section (Export · Sign out · Delete).
  • npx tsc --noEmit, npx eslint src/, and npx next build all pass.

🤖 Generated with Claude Code

@vercel
Copy link
Copy Markdown
Contributor

vercel Bot commented May 15, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
certified-app Ready Ready Preview, Comment May 16, 2026 6:24am

Request Review

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 15, 2026

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: af0e50c0-2cad-4894-b82b-9ad70246ac39

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/positioning-redesign

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@hb-agent hb-agent force-pushed the feat/positioning-redesign branch from 4fa9913 to 9552006 Compare May 16, 2026 06:35
@hb-agent hb-agent closed this May 16, 2026
@hb-agent hb-agent force-pushed the feat/positioning-redesign branch from 9552006 to 376987a Compare May 16, 2026 08:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant