Skip to content

feat: search relevance, CGS repo-targeting + import/destroy, ePDS auth polish, UI fixes - #192

Merged
holkexyz merged 5 commits into
stagingfrom
feat/search-cgs-epds-ui-improvements
Jun 17, 2026
Merged

feat: search relevance, CGS repo-targeting + import/destroy, ePDS auth polish, UI fixes#192
holkexyz merged 5 commits into
stagingfrom
feat/search-cgs-epds-ui-improvements

Conversation

@holkexyz

Copy link
Copy Markdown
Member

Draft. Bundles four independent areas from one working session; each is in its own commit and could be split into separate PRs if preferred.

1. Search — relevance ranking + paste-to-jump resilience

Activity search depends entirely on the magic-indexer, which returns matches in keyset (recency) order with no relevance score.

  • src/lib/search/rank.ts — pure, unit-tested client ranking (NFD diacritic fold, field-weighted primary/secondary via max(), total boost capped 0.15, query-length gate, stable ties, de-dupe + people field-merge). Prefers a server _score if one ever ships.
  • src/lib/search/parse-search-intent.ts — pasted at-URI / DID / handle / app-URL → a direct "Jump to" that bypasses the indexer.
  • global-search fetches wide, re-ranks, slices; adds the pinned jump row + intent-aware Enter.

Does not change which records are searchable (indexer-side, see magic-indexer#224) — only ordering + an identifier-jump path.

2. Groups (CGS) — repo-targeting migration + import/destroy

  • Targeting migration (the upstream aud-overload is deprecated, CGS fix: don't force OAuth consent screen on every email login #27): proxy to the service DID via certified_group_service; name the group with an explicit repo (querystring for queries/body-less, body for procedures). updateHandle stays on the legacy proxy (stock method, no repo field).
  • group.importPOST /api/groups/import + a focused /groups/import page that converts the signed-in account into a group (CGS requires the token iss to be that account) and a cross-link from /groups/create.
  • group.destroyPOST /api/groups/[groupDid]/destroy + an owner-only Danger zone → Remove group in org settings.
  • putAnyRecord→admin (CGS Update legal pages: account deletion contact + date #13): verified no UI change needed — all group-record edit affordances already require owner/admin.

3. Auth (ePDS)

4. UI fixes

  • AppDialogHeader opt-in center prop; enabled on the funding-receipt and rights modals.
  • Back button no longer exits to an external page: in-app depth tracking lifted into ViewTransitionProvider so the default transitionBack() falls back to / (fixes the desktop top-bar Back; removes the navbar's redundant local copy).

Verification

  • npx tsc --noEmit clean; npm run lint unchanged at 65 warnings / 0 errors; vitest 718/718 pass (incl. 34 new search tests).

Needs live verification before merge

  • The CGS audrepo migration is mechanical per docs/aud-migration.md but can't be runtime-tested here — verify a real group write/read against staging CGS (blast radius is all group operations; the legacy form still works upstream, so it can be staged safely).
  • group.import does not yet enforce MAX_SELF_CREATED_ORGS (noted in-code; small abuse surface).

🤖 Generated with Claude Code

holkexyz and others added 4 commits June 17, 2026 21:08
The activity search depends entirely on the magic-indexer, which returns
matches in keyset (recency) order with no relevance score. Re-rank the
fetched candidate set client-side and add a direct-jump affordance for
pasted identifiers.

- src/lib/search/rank.ts: pure, unit-tested lexical ranking (NFD
  diacritic fold, field-weighted primary/secondary scoring via max(),
  total additive boost capped at 0.15, query-length gate, stable
  tie-ordering, de-dupe + people field-merge). Prefers a server _score
  when one is available.
- src/lib/search/parse-search-intent.ts: recognises a pasted at-URI /
  DID / handle / app URL and yields a direct "Jump to" target that
  bypasses the indexer (resolve-* enrichment gated to complete ids).
- src/lib/search/constants.ts: shared SEARCH_DEBOUNCE_MS (de-duplicated
  from the two search components) + fetch-wide sizing.
- global-search: fetch wide, re-rank certs, slice; pinned paste-to-jump
  row; intent-aware Enter. cert-search reuses the shared debounce const.

Does not change which records are searchable (that is indexer-side,
tracked in magic-indexer#224); it improves ordering of already-indexed
results and adds an identifier-jump path.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Adopt the certified-group-service #27 migration and the two new
lifecycle operations.

- Targeting migration (aud-overload is deprecated upstream):
  createGroupAgent now proxies to the service DID via
  `certified_group_service`, so the JWT `aud` is the service DID, and
  each call names the group with an explicit `repo` (querystring for
  queries/body-less, body for procedures). `updateHandle` stays on the
  legacy proxy — a stock method with no `repo` field CGS targets via aud.
- group.import: POST /api/groups/import + importGroup() promote the
  signed-in account into a group (CGS requires the token iss to be that
  account), with a focused /groups/import page (clearly names the account
  being converted) and a cross-link from /groups/create.
- group.destroy: POST /api/groups/[groupDid]/destroy + destroyGroup(),
  surfaced as an owner-only "Danger zone -> Remove group" in org settings.

The aud->repo change is mechanical per CGS docs/aud-migration.md but
should be verified against a live group session before merge (blast
radius is all group writes; the legacy form still works upstream).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- Add `favicon_url` to the OAuth client metadata so ePDS auth/consent
  pages show the Certified brandmark in the browser tab.
- Handle ePDS's clean-exit redirect (#154): when the provider returns a
  standard OAuth `error` param instead of a code (denied consent,
  expired PAR, walked away), the callback handler now returns a
  retryable failure and the callback page offers "Try signing in again"
  instead of a dead-end error.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
- AppDialogHeader gains an opt-in `center` prop (symmetric padding so
  the title is centered while leaving room for the close X); enabled on
  the funding-receipt and rights detail modals.
- Lift in-app navigation-depth tracking into ViewTransitionProvider so
  the default transitionBack() pushes "/" instead of router.back() when
  the user entered on the current page (direct link / external referrer
  / refresh). This fixes the desktop top-bar Back button walking out to
  an external page; the mobile navbar's now-redundant local counter is
  removed (avoids double-patching history.pushState).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

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

Project Deployment Actions Updated (UTC)
certified-app Ready Ready Preview, Comment Jun 17, 2026 7:13pm

Request Review

@coderabbitai

coderabbitai Bot commented Jun 17, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

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: 1386fa26-396e-4b60-a83c-25bd42ede617

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/search-cgs-epds-ui-improvements

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.

mergePeopleByDid infers a single T from its first argument, so the two
source arrays must share a type. Annotate both with a common Person
shape (handle/description optional) — mirrors real usage where both
people sources are normalized to one Actor shape before merge. Fixes the
CI `typecheck:test` failure (tsc -p tsconfig.test.json), which checks
test files that the default typecheck excludes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@holkexyz
holkexyz marked this pull request as ready for review June 17, 2026 19:15
@holkexyz
holkexyz merged commit 6d74295 into staging Jun 17, 2026
4 checks passed
@holkexyz
holkexyz deleted the feat/search-cgs-epds-ui-improvements branch June 17, 2026 19:15
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