Skip to content

feat: implement pagination standardizer, user session service, and search results page#478

Open
Godbrand0 wants to merge 4 commits into
StellaBridge:mainfrom
Godbrand0:feature/backend-pagination-session-frontend-search
Open

feat: implement pagination standardizer, user session service, and search results page#478
Godbrand0 wants to merge 4 commits into
StellaBridge:mainfrom
Godbrand0:feature/backend-pagination-session-frontend-search

Conversation

@Godbrand0
Copy link
Copy Markdown
Contributor

Summary

  • Closes Implement API Pagination Standardizer #441 — API Pagination Standardizer: Enhanced pagination.ts utility with cursor support, Link headers (first/prev/next/last), X-Total-Count / X-Total-Pages / X-Current-Page response headers, and a reusable Fastify pagination middleware. Standardized PaginationSchema in common.schema.ts with consistent page/limit/offset/cursor fields and a DEFAULT_PAGE_LIMIT/MAX_PAGE_LIMIT constants exported from the utility.

  • Closes Create User Session Service #440 — User Session Service: Full session lifecycle backend — session.service.ts with secure SHA-256 token hashing, session creation, validation (auto-expire check + last-active refresh), single/bulk revocation, device metadata, and an audit log. DB migration 024_user_sessions creates user_sessions and session_audit_log tables. 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 /search page (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

  • Navigate to /search?q=usdc — results appear grouped, highlighted, paginated
  • Change type filter chips — list filters correctly, count badges update
  • Click sort controls — order changes and is reflected in URL
  • Paste a URL with ?q=…&type=bridge&page=2 — state restores from params
  • Search modal: type 3+ chars → "View all results →" appears in footer and navigates to /search
  • GET /api/v1/sessions returns X-Total-Count and pagination meta
  • POST /api/v1/sessions → creates session, returns opaque token
  • POST /api/v1/sessions/validate with valid token → 200; expired/revoked → 401
  • DELETE /api/v1/sessions/:id revokes session; subsequent validate returns 401
  • DELETE /api/v1/sessions/users/:userId/all bulk-revokes; audit log entries created
  • Pagination: GET /api/v1/transactions?page=2&limit=10 returns Link header and meta

…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.
@drips-wave
Copy link
Copy Markdown

drips-wave Bot commented May 30, 2026

@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! 🚀

Learn more about application limits

});

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;
Godbrand0 and others added 2 commits May 30, 2026 07:15
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ime30d

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

Implement API Pagination Standardizer Create User Session Service Build Search Results Page

2 participants