Skip to content

feat: Apis overview v2#2947

Merged
chronark merged 45 commits intomainfrom
apis-overview-v2
Mar 13, 2025
Merged

feat: Apis overview v2#2947
chronark merged 45 commits intomainfrom
apis-overview-v2

Conversation

@ogzhanolguncu
Copy link
Contributor

@ogzhanolguncu ogzhanolguncu commented Mar 11, 2025

What does this PR do?

Fixes # (issue)

If there is not an issue for this, please create one first. This is used to tracking purposes and also helps use understand why this PR exists

Type of change

  • Bug fix (non-breaking change which fixes an issue)
  • Chore (refactoring code, technical debt, workflow improvements)
  • Enhancement (small improvements)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • This change requires a documentation update

How should this be tested?

  • Test A
  • Test B

Checklist

Required

  • Filled out the "How to test" section in this PR
  • Read Contributing Guide
  • Self-reviewed my own code
  • Commented on my code in hard-to-understand areas
  • Ran pnpm build
  • Ran pnpm fmt
  • Checked for warnings, there are none
  • Removed all console.logs
  • Merged the latest changes from main onto my branch with git pull origin main
  • My changes don't cause any responsiveness issues

Appreciated

  • If a UI change was made: Added a screen recording or screenshots to this PR
  • Updated the Unkey Docs if changes were necessary

Summary by CodeRabbit

  • New Features

    • Introduced a new custom hook for fetching verification timeseries data and a new schema for querying timeseries.
    • Added several new React components for log control, including filters, date-time selectors, and refresh functionalities.
    • Implemented a new loading and error display for timeseries charts, enhancing user feedback during data retrieval.
  • Improvements

    • Enhanced visual styling for various components, including tooltips and loading indicators, for a more cohesive user experience.
    • Optimized data fetching and processing with improved query structures and pagination handling for logs and timeseries data.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

♻️ Duplicate comments (1)
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/log-details/index.tsx (1)

61-64: 🛠️ Refactor suggestion

Handle timezone issues with date parsing more robustly

The current implementation has a specific regex replace for a timezone issue (3NZ to 3Z), which is fragile and may break with future API changes or different time formats.

-  const createdAt = metaData?.createdAt
-    ? formatDate(metaData.createdAt.replace(/3NZ$/, "3Z"))
-    : "N/A";
+  const createdAt = metaData?.createdAt
+    ? formatDate(normalizeISOTimestamp(metaData.createdAt))
+    : "N/A";

+// Add this helper function
+const normalizeISOTimestamp = (timestamp: string): string => {
+  // Check if the timestamp follows ISO 8601 format
+  if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}/.test(timestamp)) {
+    return timestamp;
+  }
+  
+  // Normalize timezone part
+  return timestamp.replace(/(\d)([A-Z]{2})Z$/, "$1Z");
+};

This approach handles more timezone edge cases while keeping the specific fix you needed.

🧹 Nitpick comments (13)
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/outcome-popover.tsx (4)

16-23: Consider adding null/undefined check for outcomeCounts.

The code filters entries correctly, but doesn't handle cases where outcomeCounts might be undefined or null. Consider adding a defensive check.

- export const OutcomesPopover = ({ outcomeCounts, isSelected }: OutcomesPopoverProps) => {
+ export const OutcomesPopover = ({ outcomeCounts = {}, isSelected }: OutcomesPopoverProps) => {
  const allOutcomeEntries = Object.entries(outcomeCounts).filter(([_, count]) => count > 0);

1-9: Consider organizing imports by source/type.

While the imports work correctly, consider organizing them by source (internal vs external) or by type (components vs utilities) for better maintainability.


25-25: Extract CSS constants to a separate file for reusability.

The containerStyle string constant might be useful in other components. Consider moving it to a shared styles file to promote reuse and consistency.


91-92: Consider using template literals with cn utility for className combination.

Using string interpolation with backticks alongside size-[10px] might be better combined using the cn() utility for consistency with the rest of the codebase.

- <div
-   className={`size-[10px] ${getOutcomeColor(outcome)} rounded-[2px] shadow-sm`}
- />
+ <div
+   className={cn("size-[10px] rounded-[2px] shadow-sm", getOutcomeColor(outcome))}
+ />
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/log-details/index.tsx (4)

87-88: Improve metadata display with fallback message

The current implementation displays "" when metadata is null, but this could be improved with a more descriptive message and better styling.

-  const metaString = metaData ? JSON.stringify(metaData, null, 2) : "<EMPTY>";
+  const metaString = metaData 
+    ? JSON.stringify(metaData, null, 2) 
+    : "No metadata available for this key";

92-93: Replace shadow-2xl with drop-shadow-2xl for consistency

Line 52 uses drop-shadow-2xl but line 92 uses shadow-2xl. For UI consistency, it's better to use the same shadow style.

-      className="absolute right-0 bg-gray-1 dark:bg-black font-mono shadow-2xl overflow-y-auto z-20 p-4"
+      className="absolute right-0 bg-gray-1 dark:bg-black font-mono drop-shadow-2xl overflow-y-auto z-20 p-4"

109-121: Add ISO string format option to formatDate function

The current implementation only formats dates as locale strings, but in some cases, you might want to display ISO format dates for better precision or consistency.

-const formatDate = (date: string | number | Date | null): string => {
+const formatDate = (date: string | number | Date | null, format: 'locale' | 'iso' = 'locale'): string => {
  if (!date) {
    return "N/A";
  }
  try {
-    if (date instanceof Date) {
-      return date.toLocaleString();
-    }
-    return new Date(date).toLocaleString();
+    const dateObj = date instanceof Date ? date : new Date(date);
+    if (isNaN(dateObj.getTime())) {
+      return "Invalid Date";
+    }
+    return format === 'locale' ? dateObj.toLocaleString() : dateObj.toISOString();
  } catch {
    return "Invalid Date";
  }
};

69-80: Add tooltips for truncated or technical values

For complex or potentially long values like rate limits and remaining requests, consider adding tooltips to provide additional context or full values when truncated.

The rate limit and remaining values could benefit from tooltips that explain what they mean or show the full value when truncated, improving user experience for non-technical users.

apps/dashboard/components/navbar-popover.tsx (3)

159-160: Avoid non-null assertions for better type safety.

The non-null assertions on rowVirtualizer! could potentially cause runtime errors if there's any edge case where useVirtual is true but rowVirtualizer is null.

- style={{
-   height: `${rowVirtualizer!.getTotalSize()}px`,
- }}
+ style={{
+   height: `${rowVirtualizer?.getTotalSize() || 0}px`,
+ }}

- {rowVirtualizer!.getVirtualItems().map((virtualRow) => {
+ {rowVirtualizer?.getVirtualItems().map((virtualRow) => {

Also applies to: 162-162


142-154: Consider extracting complex conditional styling logic.

The conditional styling and layout logic is becoming complex. Consider extracting this into utility functions or variables for better maintainability.

+ // Extract styling logic for clarity
+ const getContainerStyles = () => {
+   return {
+     height: useVirtual ? maxHeight : shouldScroll ? maxHeight : "auto",
+     maxHeight: maxHeight,
+     width: "100%",
+   };
+ };
+
+ const getContainerClassNames = () => {
+   return cn(
+     "w-full",
+     shouldScroll ? "overflow-auto" : "overflow-visible",
+     useVirtual ? "" : "flex flex-col gap-1",
+   );
+ };

  <div
    ref={listRef}
-   className={cn(
-     "w-full",
-     shouldScroll ? "overflow-auto" : "overflow-visible",
-     useVirtual ? "" : "flex flex-col gap-1",
-   )}
-   style={{
-     height: useVirtual ? maxHeight : shouldScroll ? maxHeight : "auto",
-     maxHeight: maxHeight,
-     width: "100%",
-   }}
+   className={getContainerClassNames()}
+   style={getContainerStyles()}
  >

53-55: Consider relative sizing for height calculations.

The fixed maximum height of 200px might not be optimal for all screen sizes. Consider using a relative sizing approach based on the viewport height.

- const exactHeight = items.length * 36;
- const maxHeight = Math.min(exactHeight, 200);
+ // Item height in pixels
+ const ITEM_HEIGHT = 36;
+ // Maximum number of visible items or use percentage of viewport height
+ const MAX_VISIBLE_ITEMS = 5.5;
+ const exactHeight = items.length * ITEM_HEIGHT;
+ const maxHeight = Math.min(exactHeight, MAX_VISIBLE_ITEMS * ITEM_HEIGHT);
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/controls/components/logs-datetime/index.tsx (2)

9-18: Consider simplifying the initial state

The component initializes title to null and then sets it to "Last 12 hours" using useEffect. For cleaner code, consider initializing it directly.

- const [title, setTitle] = useState<string | null>(null);
+ const [title, setTitle] = useState<string>("Last 12 hours");

- useEffect(() => {
-   if (!title) {
-     setTitle("Last 12 hours");
-   }
- }, [title]);

69-71: Consider documenting the filter condition

The code filters out options that end with "m" (minute-based options). Consider adding a brief comment explaining this design decision for better maintainability.

customOptions={DEFAULT_OPTIONS.filter(
+  // Filter out minute-based options for a cleaner interface
  (option) => !option.value || !option.value.endsWith("m"),
)}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 82e87d7 and ef48101.

📒 Files selected for processing (8)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/controls/components/logs-datetime/index.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/log-details/index.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/outcome-popover.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/logs-client.tsx (1 hunks)
  • apps/dashboard/components/logs/datetime/constants.ts (2 hunks)
  • apps/dashboard/components/logs/datetime/datetime-popover.tsx (7 hunks)
  • apps/dashboard/components/navbar-popover.tsx (7 hunks)
  • apps/dashboard/lib/trpc/routers/utils/granularity.ts (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (3)
  • apps/dashboard/lib/trpc/routers/utils/granularity.ts
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/logs-client.tsx
  • apps/dashboard/components/logs/datetime/datetime-popover.tsx
🧰 Additional context used
🧠 Learnings (1)
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/controls/components/logs-datetime/index.tsx (1)
Learnt from: ogzhanolguncu
PR: unkeyed/unkey#2825
File: apps/dashboard/app/(app)/logs-v2/components/controls/components/logs-datetime/index.tsx:0-0
Timestamp: 2025-03-12T13:07:07.472Z
Learning: In the logs dashboard, keyboard shortcuts that toggle UI elements (like popovers) should be implemented in the component that owns the state being toggled, not in the presentational wrapper components. For example, the 'T' shortcut for toggling the datetime filter is implemented in DatetimePopover, not in LogsDateTime.
⏰ Context from checks skipped due to timeout of 90000ms (17)
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Test Packages / Test ./packages/api
  • GitHub Check: Test Packages / Test ./packages/nextjs
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test Packages / Test ./internal/billing
  • GitHub Check: Test Packages / Test ./internal/hash
  • GitHub Check: Test Packages / Test ./internal/id
  • GitHub Check: Test Packages / Test ./packages/hono
  • GitHub Check: Test Packages / Test ./packages/cache
  • GitHub Check: Test Packages / Test ./internal/encryption
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Test Packages / Test ./internal/keys
  • GitHub Check: Test Packages / Test ./internal/resend
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Build / Build
  • GitHub Check: autofix
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (15)
apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/outcome-popover.tsx (3)

11-14: Props type definition is clear and concise.

The TypeScript interface appropriately defines the component's expected props with descriptive types.


25-42: Clean implementation for single-outcome display.

Good use of conditional rendering with early return pattern when there's exactly one non-valid outcome. The badge component includes appropriate styling and accessibility features with the title attribute.


44-107: Well-structured popover implementation for multiple outcomes.

The implementation for displaying multiple outcomes is well organized with:

  • Good use of the Popover component
  • Proper event propagation handling with e.stopPropagation()
  • Clean conditional styling based on the isSelected state
  • Accessible UI with descriptive titles
  • Clear presentation of outcome counts and proper pluralization

The component correctly maps through the outcomes and displays them with appropriate styling.

apps/dashboard/app/(app)/apis/[apiId]/_overview/components/table/components/log-details/index.tsx (2)

1-10: LGTM! Well-structured imports

The imports are well-organized, separating client directive, local components, and external packages.


31-58: Excellent component structure with appropriate null checks

The component has good error handling with appropriate null checks and early returns, showing fallback UI when necessary.

apps/dashboard/components/navbar-popover.tsx (6)

5-5: Good addition of virtualization support.

Adding the useVirtualizer import from @tanstack/react-virtual is a solid choice for implementing virtualization to handle large lists efficiently.


28-33: Well-documented new property.

The JSDoc comments for the virtualizationThreshold property clearly explain its purpose and default value, making it easier for other developers to understand and use the component.


47-67: Good implementation of conditional virtualization.

The code properly determines when to use virtualization based on the item count and threshold. The height calculations and setup for the virtualizer are well thought out.


114-128: Well-implemented focus management.

The effect hooks appropriately handle scrolling to focused items and setting initial focus when the popover opens or closes, which is important for keyboard navigation.


236-256: Good title attribute addition for truncated labels.

Adding the title attribute to show the full text when labels are truncated is a nice accessibility improvement.


141-193: Verify keyboard navigation accessibility with virtualization.

While the implementation looks solid, it's important to ensure that keyboard navigation remains fully accessible with the virtualized list. Consider testing with screen readers and keyboard-only navigation to verify accessibility compliance.

apps/dashboard/components/logs/datetime/constants.ts (1)

3-3: LGTM! Improved naming clarity

Renaming OPTIONS to DEFAULT_OPTIONS makes the purpose of this constant clearer, indicating these are default options that could potentially be overridden. The corresponding update to CUSTOM_OPTION_ID maintains consistency.

Also applies to: 96-96

apps/dashboard/app/(app)/apis/[apiId]/_overview/components/controls/components/logs-datetime/index.tsx (3)

19-28: LGTM! Effective filter extraction

Good job extracting relevant time-related values from filters and constructing the timeValues object using array methods.


33-66: LGTM! Well-structured filter handling logic

The date-time change handler properly manages filter states based on different conditions. The approach of first removing existing time filters and then adding new ones ensures clean state transitions.


73-90: LGTM! Accessible button implementation

Good implementation of the button with proper accessibility attributes and visual feedback based on the title's state. The keyboard shortcut hint is a nice touch.

I notice from the retrieved learning that keyboard shortcuts for toggling UI elements should be implemented in components that own the state (DatetimePopover), which appears to be followed here.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (2)
apps/dashboard/components/logs/overview-charts/overview-area-chart-error.tsx (1)

67-76: Consider implementing actual time placeholders.

The footer currently shows "--:--" for all time labels. Consider enhancing this to show realistic time placeholders that give users a better sense of the expected time range, even in error states.

-      <div className="h-8 border-t border-b border-gray-4 px-1 py-2 text-accent-9 font-mono text-xxs w-full flex justify-between">
-        {Array(5)
-          .fill(0)
-          .map((_, i) => (
-            // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
-            <div key={i} className="z-10">
-              --:--
-            </div>
-          ))}
-      </div>
+      <div className="h-8 border-t border-b border-gray-4 px-1 py-2 text-accent-9 font-mono text-xxs w-full flex justify-between">
+        {Array(5)
+          .fill(0)
+          .map((_, i) => {
+            // biome-ignore lint/suspicious/noArrayIndexKey: Array of fixed length
+            return (
+              <div key={i} className="z-10">
+                {i === 0 ? "00:00" : i === 4 ? "23:59" : "--:--"}
+              </div>
+            );
+          })}
+      </div>
apps/dashboard/components/logs/overview-charts/overview-area-chart.tsx (1)

286-297: Consider adding fallback time markers.

When data is empty, the footer doesn't display any time markers. Consider adding fallback time markers similar to the error component to maintain consistent UI layout.

      <div className="h-8 border-t border-b border-gray-4 px-1 py-2 text-accent-9 font-mono text-xxs w-full flex justify-between ">
        {data.length > 0
          ? calculateTimePoints(
              data[0]?.originalTimestamp ?? Date.now(),
              data.at(-1)?.originalTimestamp ?? Date.now(),
            ).map((time, i) => (
              // biome-ignore lint/suspicious/noArrayIndexKey: <explanation>
              <div key={i} className="z-10">
                {formatTimestampLabel(time)}
              </div>
            ))
-          : null}
+          : Array(5)
+              .fill(0)
+              .map((_, i) => (
+                // biome-ignore lint/suspicious/noArrayIndexKey: Array of fixed length
+                <div key={i} className="z-10">
+                  {i === 0 ? "00:00" : i === 4 ? "23:59" : "--:--"}
+                </div>
+              ))}
      </div>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ef48101 and 984d34a.

📒 Files selected for processing (6)
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/charts/index.tsx (1 hunks)
  • apps/dashboard/app/(app)/apis/[apiId]/loading.tsx (0 hunks)
  • apps/dashboard/app/(app)/settings/root-keys/new/client.tsx (1 hunks)
  • apps/dashboard/components/logs/overview-charts/overview-area-chart-error.tsx (1 hunks)
  • apps/dashboard/components/logs/overview-charts/overview-area-chart-loader.tsx (1 hunks)
  • apps/dashboard/components/logs/overview-charts/overview-area-chart.tsx (6 hunks)
💤 Files with no reviewable changes (1)
  • apps/dashboard/app/(app)/apis/[apiId]/loading.tsx
✅ Files skipped from review due to trivial changes (1)
  • apps/dashboard/app/(app)/settings/root-keys/new/client.tsx
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/dashboard/components/logs/overview-charts/overview-area-chart-loader.tsx
  • apps/dashboard/app/(app)/apis/[apiId]/_overview/components/charts/index.tsx
⏰ Context from checks skipped due to timeout of 90000ms (7)
  • GitHub Check: Test Packages / Test ./internal/clickhouse
  • GitHub Check: Test Go API Local / Test
  • GitHub Check: Test API / API Test Local
  • GitHub Check: Build / Build
  • GitHub Check: autofix
  • GitHub Check: Test Agent Local / test_agent_local
  • GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (14)
apps/dashboard/components/logs/overview-charts/overview-area-chart-error.tsx (5)

4-6: Well-structured type definition.

The TimeseriesChartErrorProps type clearly defines the expected props for this component, making it reusable and type-safe.


8-16: Good implementation of default values.

The component properly sets default values for showRightSide and reverse properties, ensuring consistent behavior even when these optional properties aren't explicitly provided.


28-35: Well-implemented conditional rendering.

The component correctly handles the reverse layout by conditionally rendering the metrics color indicators at the beginning of the range label.


44-56: Flexible right-side section implementation.

The conditional rendering of the right side section with metric data is well implemented, allowing for different visualization layouts based on the needs of the parent component.


60-64: Clear error state visualization.

The centered error message with clean text styling provides a good user experience when data can't be retrieved.

apps/dashboard/components/logs/overview-charts/overview-area-chart.tsx (9)

28-33: Well-defined chart metric type.

The ChartMetric type definition provides a flexible structure for defining chart metrics with appropriate properties including an optional formatter for customizing value display.


35-41: Comprehensive chart labels type definition.

The TimeseriesChartLabels type provides a clear and flexible structure for defining chart labels and metrics, with optional properties for layout control.


43-51: Good props interface update.

The props interface has been renamed from LogsTimeseriesAreaChartProps to TimeseriesAreaChartProps and now includes the required labels prop, improving the component's flexibility and reusability.


114-119: Clean error and loading state handling.

The error and loading states now utilize dedicated components, passing through the labels props to maintain consistency in the UI. This improves maintainability and separation of concerns.


122-135: Excellent dynamic metrics calculation.

The code has been refactored to dynamically calculate statistics for each metric instead of hardcoding specific metrics. This significantly improves flexibility and maintainability.


138-166: Well-implemented dynamic header section.

The header section now dynamically renders based on the metrics provided in the labels prop, with proper support for reverse layout. The formatting of min/max values respects custom formatters defined in the metrics.


169-185: Flexible right-side metrics display.

The right side of the header now dynamically renders metrics with their values and styling based on the provided labels.metrics array, making the component much more adaptable to different data visualization needs.


199-213: Dynamic gradient definitions for chart areas.

The code now dynamically generates gradient definitions for each metric, eliminating hardcoded values and improving maintainability.


260-272: Dynamic rendering of chart areas.

The component now dynamically renders Area components for each metric defined in the labels, significantly improving the component's flexibility and reducing code duplication.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🧹 Nitpick comments (3)
apps/dashboard/components/logs/refresh-button/index.tsx (3)

1-1: Consider the cross-feature dependency implications.

The RatelimitOverviewTooltip component is being imported from the ratelimits feature area, which creates a cross-feature dependency. While component reuse is generally good for consistency, consider whether this creates a tight coupling between features that should be more independent.

If this tooltip component contains generic functionality, consider moving it to a shared components folder instead.


54-54: Consider using React Fragment instead of div.

The div wrapper doesn't seem to have styling or functional purpose. Consider using a React Fragment (<>...</>) to avoid unnecessary DOM nesting.

-      <div>
+      <>
         <Button
           ...
         </Button>
-      </div>
+      </>

62-62: Consider extracting styles to design system.

The button styling is applied directly via className. For better maintainability and consistency, consider extracting these styles to your design system or using existing style tokens/variants.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 984d34a and 259e1e8.

📒 Files selected for processing (2)
  • apps/dashboard/app/(app)/settings/root-keys/new/client.tsx (2 hunks)
  • apps/dashboard/components/logs/refresh-button/index.tsx (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/dashboard/app/(app)/settings/root-keys/new/client.tsx
🔇 Additional comments (2)
apps/dashboard/components/logs/refresh-button/index.tsx (2)

49-53: Good addition of contextual feedback.

The tooltip provides helpful information to users about why refresh might be unavailable, improving the overall user experience. The disabled logic ensures the tooltip only appears when refresh is unavailable.


59-59: Excellent improvement to keyboard shortcut discoverability.

Adding the keyboard shortcut information to the title improves discoverability and provides better UX for users who hover over the button.

@chronark chronark merged commit 75e10f6 into main Mar 13, 2025
28 of 30 checks passed
@chronark chronark deleted the apis-overview-v2 branch March 13, 2025 16:16
@coderabbitai coderabbitai bot mentioned this pull request May 12, 2025
18 tasks
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.

2 participants