feat: implement pagination standardizer, user session service, and search results page#478
Open
Godbrand0 wants to merge 4 commits into
Open
Conversation
…arch results page Closes StellaBridge#441 — Add consistent pagination helpers (cursor support, Link headers, X-Total-Count) across all list endpoints via enhanced pagination.ts utility and new Fastify pagination middleware. Closes StellaBridge#440 — Create user session service with full lifecycle management: session creation with secure token hashing, expiry, device metadata, revocation (single + bulk), audit trail, and CRUD REST endpoints at /api/v1/sessions. Includes DB migration 024_user_sessions. Closes StellaBridge#438 — Build dedicated /search results page with URL-backed query params, grouped results by type, query highlighting, client-side pagination, type filter chips, sort controls (relevance/type/title), empty/loading states, and "View all results" link from the search modal.
|
@Godbrand0 Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
| }); | ||
|
|
||
| await this.addAudit(id, row.user_id, "revoked", actor, ipAddress, { reason }); | ||
| logger.info({ sessionId: id, actor, reason }, "Session revoked"); |
| await this.addAudit(row.id, userId, "revoked", actor, ipAddress, { bulk: true }); | ||
| } | ||
|
|
||
| logger.info({ userId, count: rows.length, actor }, "Bulk session revoke"); |
| }); | ||
|
|
||
| await this.addAudit(id, row.user_id, "revoked", actor, ipAddress, { reason }); | ||
| logger.info({ sessionId: id, actor, reason }, "Session revoked"); |
| await this.addAudit(row.id, userId, "revoked", actor, ipAddress, { bulk: true }); | ||
| } | ||
|
|
||
| logger.info({ userId, count: rows.length, actor }, "Bulk session revoke"); |
Backend:
- schemaDrift.ts: remove stray `const` keyword before expression statement
- migrationExamples.ts: suppress no-constant-condition for intentional while(true) loop
- email.service.ts: remove dangling comment+brace that closed the class too early, restoring class member declarations inside the class body
- telegram.formatter.ts: remove unnecessary escape chars \[ and \+ in regex
Frontend:
- MaintenanceBanner.tsx: drop unused SystemStatus type import
- Navbar.test.tsx: add missing queryClient instantiation; wire resetNotifications into beforeEach so it is used
- Navbar.tsx: remove four unused imports (NotificationsDrawer, UnreadCountBadge, useNotificationLiveUpdates, selectUnreadCount/useNotificationStore)
- DateRangePicker.test.tsx: remove unused within import; remove unused user variable in escape-key test
- RecentActivityTimeline.stories.tsx: remove unused useTimelineEvents import and unused mockEvents array
- useTimelineEvents.ts: remove unused AssetTimelineEvent/TransactionTimelineEvent type imports, BridgeTransaction import, and dead convertTransactionMessage function
- Dashboard.tsx: replace b: any with b: { status: string }
- NotificationPreferencesPage.tsx: remove unused usePreferences import
- SearchResultsPage.tsx: remove unused useNavigate import and navigate variable
- Settings.tsx: replace as any with explicit "compact" | "comfortable" | "spacious" cast
- test/factories.ts: replace as any with "degraded" | "healthy" cast for DependencyNodeStatus
| // Escape special characters used in markdown v2 | ||
| // Characters to escape: _ * [ ] ( ) ~ ` > # + - = | { } . ! | ||
| const specialChars = /([_*\[\]()~`>#\+\-=|{}.!])/g; | ||
| const specialChars = /([_*[\]()~`>#+-=|{}.!])/g; |
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ime30d Co-Authored-By: Claude Sonnet 4.6 <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.
Summary
Closes Implement API Pagination Standardizer #441 — API Pagination Standardizer: Enhanced
pagination.tsutility with cursor support, Link headers (first/prev/next/last),X-Total-Count/X-Total-Pages/X-Current-Pageresponse headers, and a reusable Fastify pagination middleware. StandardizedPaginationSchemaincommon.schema.tswith consistentpage/limit/offset/cursorfields and aDEFAULT_PAGE_LIMIT/MAX_PAGE_LIMITconstants exported from the utility.Closes Create User Session Service #440 — User Session Service: Full session lifecycle backend —
session.service.tswith secure SHA-256 token hashing, session creation, validation (auto-expire check + last-active refresh), single/bulk revocation, device metadata, and an audit log. DB migration024_user_sessionscreatesuser_sessionsandsession_audit_logtables. REST endpoints at/api/v1/sessions(create, list, get, validate, revoke, bulk-revoke, audit log, purge expired), all protected by scoped API key auth.Closes Build Search Results Page #438 — Search Results Page: Dedicated
/searchpage (SearchResultsPage.tsx) with URL-backed query params (?q=,?type=,?sort=,?order=,?page=), grouped results with query highlighting, type filter chips with live counts, sort controls (relevance / type / title with asc/desc toggle), paginated view, skeleton loaders, and an empty state. Search modal gets a "View all results →" footer link that navigates to this page.Test plan
/search?q=usdc— results appear grouped, highlighted, paginated?q=…&type=bridge&page=2— state restores from params/searchGET /api/v1/sessionsreturnsX-Total-Countand pagination metaPOST /api/v1/sessions→ creates session, returns opaque tokenPOST /api/v1/sessions/validatewith valid token → 200; expired/revoked → 401DELETE /api/v1/sessions/:idrevokes session; subsequent validate returns 401DELETE /api/v1/sessions/users/:userId/allbulk-revokes; audit log entries createdGET /api/v1/transactions?page=2&limit=10returnsLinkheader and meta