Skip to content

feat: Backend dashboard integration - API analytics + Journey Insights#15

Open
TalmizAhmed wants to merge 29 commits into
devfrom
backend-dsb
Open

feat: Backend dashboard integration - API analytics + Journey Insights#15
TalmizAhmed wants to merge 29 commits into
devfrom
backend-dsb

Conversation

@TalmizAhmed
Copy link
Copy Markdown

@TalmizAhmed TalmizAhmed commented Feb 10, 2026

@aem-code-sync
Copy link
Copy Markdown

aem-code-sync Bot commented Feb 10, 2026

Hello, I'm the AEM Code Sync Bot and I will run some actions to deploy your branch and validate page speed.
In case there are problems, just click a checkbox below to rerun the respective action.

  • Re-run PSI checks
  • Re-sync branch
Commits

@gemini-code-assist
Copy link
Copy Markdown

Summary of Changes

Hello @TalmizAhmed, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request introduces a new backend dashboard designed to enhance observability and debugging capabilities. It provides two primary functionalities: API Analytics for monitoring API performance and health, and Journey Search for tracing specific user journeys through logs. The dashboard leverages a new API client for backend communication and utilizes custom web components for a consistent and interactive user experience.

Highlights

  • New Backend Dashboard: Introduced a new 'Backend Dashboard' accessible via backend-dashboard.html, providing dedicated interfaces for API Analytics and Journey Search.
  • API Client Implementation: Implemented a robust API client (backend-api.js) to handle secure communication with backend services, including API key management and error parsing.
  • Reusable UI Components: Developed three reusable UI web components (ui-panel, ui-list, ui-status) to standardize the presentation of information and feedback across the dashboard.
  • API Analytics Functionality: Integrated dynamic filtering and sorting capabilities within the API Analytics tab, allowing users to analyze API performance metrics over custom date ranges and by various criteria.
  • Journey Search Functionality: Provided a Journey Search tab for querying logs by trace ID, time range, host, and index, with advanced options for detailed log investigation.

🧠 New Feature in Public Preview: You can now enable Memory to help Gemini Code Assist learn from your team's feedback. This makes future code reviews more consistent and personalized to your project's style. Click here to enable Memory in your admin console.

Changelog
  • backend-api.js
    • Added API_BASE_URL and DEFAULT_API_KEY constants.
    • Added functions getApiKey and setApiKey for local storage management.
    • Added parseError for consistent error handling from API responses.
    • Added searchLogs function for querying backend logs.
    • Added checkHealth function for API health checks.
    • Added getAnalyticsSummary function for fetching API analytics data.
  • backend-dashboard.css
    • Added styles for dashboard tabs, API key banner, journey search forms, and results display.
    • Added styles for API analytics dashboard layout, filters, metrics cards, and API route lists.
    • Included responsive media queries for API list display.
    • Defined @keyframes spin for loading spinners.
  • backend-dashboard.html
    • Added new HTML file for the backend dashboard.
    • Included links to style.css and backend-dashboard.css.
    • Integrated backend-dashboard.js as a module.
    • Structured the page with a title, navigation link, API key input, and tab buttons for "Journey Search" and "API Dashboard".
  • backend-dashboard.js
    • Imported custom UI components and backend API functions.
    • Implemented setupTabs for managing tab navigation between Journey Search and API Dashboard.
    • Implemented setupApiKeyField for API key input and persistence.
    • Developed renderApiDashboardTab to create and manage the API analytics interface, including date range picker, advanced filters, data fetching, and dynamic rendering of metrics and API lists with sorting.
    • Developed renderJourneyTab to create and manage the journey search interface, including form inputs, advanced options, log fetching, and results display.
  • components/ui-list.js
    • Added new custom element ui-list.
    • Implemented observedAttributes for title and count.
    • Rendered a shadow DOM structure with a header (title, count) and a slot for content.
    • Added CSS for styling the list component.
  • components/ui-panel.js
    • Added new custom element ui-panel.
    • Implemented observedAttributes for title.
    • Rendered a shadow DOM structure with a header (title, actions slot) and a body slot.
    • Added CSS for styling the panel component.
  • components/ui-status.js
    • Added new custom element ui-status.
    • Implemented observedAttributes for variant and message.
    • Rendered a shadow DOM structure for displaying status messages.
    • Added CSS for styling different status variants (info, error, success).
  • index.html
    • Added a new paragraph with a link to backend-dashboard.html under the main dashboard title.
  • style.css
    • Added new CSS rules for .page-links and .page-links a to style navigation links.
Activity
  • No human activity has been recorded on this pull request yet.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point by creating a comment using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

Copy link
Copy Markdown

@gemini-code-assist gemini-code-assist Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces a new backend dashboard with two main features: Journey Search and API Analytics. It adds the necessary HTML, CSS, and JavaScript for the dashboard, along with several new UI web components. The changes also include a new API client module for communicating with the backend.

My review focuses on security, correctness, and maintainability. I've identified a critical security vulnerability with a hardcoded API key, as well as another high-severity issue with storing the key in localStorage. I also found a bug in one of the new web components and opportunities to improve code quality by reducing duplication and avoiding potentially unsafe practices like using innerHTML.

Comment thread backend-api.js Outdated
Comment thread components/ui-list.js
Comment thread backend-api.js Outdated
Comment thread backend-api.js Outdated
Comment thread backend-dashboard.html Outdated
Comment thread backend-dashboard.js Outdated
@aem-code-sync
Copy link
Copy Markdown

aem-code-sync Bot commented Feb 23, 2026

Page Scores Audits Google
📱 /index.html PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
🖥️ /index.html PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
📱 / PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI
🖥️ / PERFORMANCE A11Y SEO BEST PRACTICES SI FCP LCP TBT CLS PSI

@vdua
Copy link
Copy Markdown
Contributor

vdua commented Feb 23, 2026

The URL is completely broken. Do I need anything to test it ?

subodhkj and others added 2 commits March 25, 2026 11:09
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add inclusiveDayCount to date-utils.js and use it in app.js and api-analytics-tab.js
- Expand BACKEND_DEFAULTS with placeholder/maxLimit/hint per tab
- Update syncFormForTab to apply dynamic placeholder, max attr, and hint text
- Fix #backend-limit input to be dynamic (remove hardcoded max/placeholder)
- Add id="backend-limit-hint" span for per-tab dynamic hint updates
- Fix setLoading(false) in journey-tab.js to clear status message
- Update escapeHtml in api-analytics-tab.js to use createElement approach
- Fix #journey-id-input:focus border color to blue (#2563eb) for consistency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Add null guard in updateHeader/updateTitle/updateView so attributeChangedCallback
  is safe when fired before connectedCallback (before render() runs)
- Remove redundant title-text assignment at end of ui-list render() since
  updateHeader() in connectedCallback already handles it
- Call getDayDifference() once in renderMetrics to avoid double evaluation

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add braces around all single-line if/else bodies across
api-analytics-tab.js, app.js, backend-api.js, journey-tab.js,
utils/date-utils.js, and the three UI web components.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
subodhkj and others added 2 commits April 2, 2026 10:58
Switch from localhost:8002 to the Ethos stage deployment URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ort arrows

- Expandable detail row per route shows backend_errors as colored badges sorted by count
- Filter row below column headers: text search for route, min-threshold inputs for all numeric columns
- Filters update the body only (no focus loss while typing)
- Sort arrows indicate active column and direction
- Responsive breakpoint updated for new 7-column layout

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
subodhkj and others added 2 commits May 6, 2026 20:48
- Expand button: red circle badge (+/−) replaces invisible gray ▶ arrow
- Fix expand toggle logic (classList.toggle truthiness was inverted)
- Filter row: white bg with blue top accent border to separate from header
- Add funnel SVG icon in filter row leftmost cell
- Shorten placeholder text to fit narrow columns (min, min %, min ms)
- Hide browser number spinners on filter inputs
- Filter inputs: subtle background, cleaner focus ring

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
… in-flight queries

Root cause: renderFromURLParams() re-mounted renderApiDashboardTab() on every
handleParamUpdate() call (tab clicks, URL changes, domain updates), which created
a fresh state (analytics: null), orphaned the pending fetch, and immediately showed
the placeholder while the network request was still in flight.

Fix:
- app.js: persist apiTabContainer/journeyTabContainer so the module is mounted once;
  subsequent renderFromURLParams calls just move the same container back into
  urlResults via replaceChildren, preserving all state and in-flight requests
- api-analytics-tab.js: add queryId guard so aborted/stale promise callbacks
  cannot affect the loading state of a newer query (belt-and-suspenders)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- index.html: remove tab button, journey-id-input group, Search Logs button
- app.js: remove renderJourneyTab/searchLogs imports, journey from BACKEND_TABS
  and BACKEND_DEFAULTS, journeyTabApi/Container state, journey branch in
  renderFromURLParams, syncFormForTab journey refs, Search Logs click handler

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
subodhkj and others added 2 commits May 6, 2026 21:26
… layout

Normalise both error formats: plain number and { count, description } object.
Switch expanded error detail from flex badges to a compact table:
- Error Code | Count | Description (column only shown when descriptions exist)
- Rows sorted by count descending
- Both formats can coexist in the same error map

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…es and status column

- Restructure tab into Client Side API + Server Side API panels
- Client Side API: placeholder with shared/unique column breakdown and
  pointer to Error Analysis tab (integration coming)
- Server Side API: renamed columns (API Route→Endpoint, Failed→Failures)
- Add Performance badge column (High/Medium/Low based on failure_rate + avg_time_ms)
- Add Status column showing top backend error code inline
- Move Max Time into expand row alongside full backend errors table
- Add performance_level filter (All/High/Medium/Low select)
- Remove max_time_ms filter (column no longer in main table)
- Update subtitle to reflect end-to-end client+server scope
- Update metric card labels (Total Calls, Failures, Endpoints)
- Responsive breakpoint: hide columns 5+ on mobile via nth-child(n+5)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replaces the placeholder in the Client Side API panel with a real
table sourced from RUM missingresource events. Data is processed
directly from rawData bundles and displayed sorted by page-view
frequency, matching the Error Analysis → Missing Resources style.

- Columns: #, Resource URL, Type, Status, Page Views, % of Views, Performance
- Resource type badges (image/javascript/css/json/others)
- Filter bar: URL text search, type select, performance level select
- Sort on all columns (click header)
- Performance levels use same High/Medium/Low thresholds (40%/10% of max weight)
- Both panels now always visible; Server Side shows "Click Run Query"
  placeholder until queried (removes the full-page placeholder)
- app.js passes currentData to setClientData() after mounting API tab

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…lter UI

Client Side API table redesign:
- Pagination: 25 rows/page default, selector (10/25/50/100), first/prev/next/last
  nav buttons with SVG icons, "Page X of Y" + "A–B of N" counters
- Status code filter: dropdown dynamically populated from data, sorted by
  frequency so the most common codes appear first
- Performance legend: inline bar below toolbar showing exact thresholds
  (High ≥40% of peak views, Medium ≥10%, Low <10%) with live counts
- Toolbar redesign:
  · Search: full-width input with magnifier icon, focus ring
  · Type filter: pill buttons (All / Image / JS / CSS / JSON / Other) with
    per-type counts, colored active states per type
  · Status + Performance: labeled select dropdowns in bordered wrapper
  · Clear filters: red accent button visible only when filters are active
  · Result count: right-aligned "N of M resources"
- Sort headers: SVG dual-chevron icons (blue = active direction, gray = inactive)
- Partial re-render: filter/sort/page changes update only the client panel,
  server section is left untouched (no focus loss on typing)
- setClientData collects unique status codes sorted by global frequency

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cation

Adds a third panel to the API Analytics tab showing loadresource timing
data from RUM bundles. Each resource shows Median/p75/p95/Mean/Observations
with time values color-coded (green fast <250ms, amber moderate, red slow
≥1s) and a High/Medium/Low performance badge based on mean load time.

Includes search, type pills, performance filter, sortable columns,
pagination, and partial re-render (updateLoadSection) so Client Side API
and Server Side API panels are not disturbed on interaction.

Also fixes setClientData null-data path to reset loadResources alongside
clientResources.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
subodhkj and others added 3 commits May 15, 2026 18:02
Three fixes:
1. Override #url-results .loading-container styles so #api-loading renders
   as a slim inline banner (blue-tinted strip) instead of a large white card
   that visually clashes with the panel layout below it.
2. Change "RUM data not loaded" hint to a neutral loading message since the
   data is simply still in-flight, not permanently missing.
3. Push fresh RUM data to the API tab's client panels from within loadData()
   itself so panels populate immediately when data arrives, regardless of
   whether the tab was active before the load completed.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two defensive fixes for the null-state panels:

1. In the startup catch block, set currentData = currentData || [] so that
   if loadData() throws (network error, timeout, etc.) the API tab panels
   show "no data found" instead of staying permanently in the null/loading
   state while currentData remains undefined.

2. In renderFromURLParams, when the API tab mounts and currentData is not
   yet available (race condition where tab switch beats the async data load),
   kick off a loadData() call and push the result to setClientData once it
   resolves. Previously this path silently left both panels in null state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ntData

Production RUM bundles can have numeric or object values for e.source even
when the field is truthy. Calling e.source.toLowerCase() on a non-string
throws a TypeError which, because handleParamUpdate does not await
renderFromURLParams, silently becomes an unhandled promise rejection and
leaves both Client Side API and Resource Load Times panels permanently in
null state.

Fixes:
- Introduce srcStr() helper that coerces e.source to string before calling
  toLowerCase(), applied to both missingresource and loadresource filter
  chains.
- Wrap the entire setClientData processing body in try/catch so any future
  JS error falls back to showing the empty-data state rather than leaving
  panels stuck in the null/loading state with no user-visible indication of
  what went wrong. Error is logged to console for debugging.
- Also apply String() coercion to statusCode.trim() check to be consistent.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…ners

Each of the three panels now shows its own inline spinner. The Server Side
API panel shows a spinner immediately when Run Query is pressed (no flicker
on client/load panels). Removed the separate #api-loading banner that was
appearing as a 4th element above the panels.

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.

3 participants