Skip to content

fix: tasks access#156

Merged
v-kessler merged 21 commits intomainfrom
vk/access-fix
Sep 27, 2025
Merged

fix: tasks access#156
v-kessler merged 21 commits intomainfrom
vk/access-fix

Conversation

@v-kessler
Copy link
Contributor

@v-kessler v-kessler commented Sep 26, 2025

Summary by CodeRabbit

  • New Features

    • Task management now supports tables, views, and warehouses with finer-grained permissions and controls.
    • Expanded visibility of Tasks tabs based on read/control permissions or disabled auth/permissions.
    • Improved entity-specific filtering and validation; clearer loading states.
    • Enhanced schema display with fallbacks; taller details panel for easier viewing.
  • Documentation

    • Added new screenshots to README.
    • OpenAPI updated: new row-id fields, format-version 3, broader nullability, improved error guidance, and task-related actions; removed deprecated permission endpoints.
  • Bug Fixes

    • More robust UI guards for null/absent data and clearer entity-specific error messages.

@coderabbitai
Copy link

coderabbitai bot commented Sep 26, 2025

Important

Review skipped

Auto incremental reviews are disabled on this repository.

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.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Walkthrough

Removes deprecated management API endpoints and extends task-related enums and entities. Adds row ID fields and nullability updates in REST catalog schemas. Updates Vue components/pages to type snapshots, adjust schema fallbacks, and generalize task management to warehouse/table/view entities with refined permission gating and new TaskManager props. README adds images.

Changes

Cohort / File(s) Summary
Docs: README visuals
README.md
Added image elements (branch_table.png, view_history.png, tasks_wh.png) with line breaks after warehouse.png.
Management OpenAPI: tasks and entities
openapi/management-open-api.yaml
Removed deprecated permission endpoints; expanded actions (get/control tasks incl. all_tasks); tightened TabularIdentOrUuid; added view-capable TaskEntity variant; minor description cleanup.
REST Catalog OpenAPI: row IDs and nullability
openapi/rest-catalog-open-api.yaml
Added first-row-id/added-rows to Snapshot; first-row-id to DataFile/ContentFile; TableMetadata format-version max=3, next-row-id, encryption-keys type tweak; several fields marked nullable and descriptions updated; ServiceUnavailableResponse text adjusted.
Schema/UI typing and fallbacks
src/components/BranchVisualization.vue, src/components/SnapshotDetails.vue, src/components/TableDetails.vue
Strengthened typings with Snapshot/LoadTableResultReadable; introduced effective schema helpers and guards; adjusted rendering conditions; getCurrentSnapshot typed to return Snapshot
Task entity display
src/components/TaskDetails.vue
Added getEntityId helper; template now derives IDs for multiple entity types; copy action uses derived ID.
Task management flow and permissions
src/components/TaskManager.vue
Added props: viewId, entityType ('warehouse'
Warehouse page: tasks gating and props
src/pages/warehouse/[id].vue
Broadened Tasks tab visibility to canGetAllTasks or disabled auth/perm; added canGetAllTasks/canControlAllTasks; loading indicators; passes TaskManager props (can-control-tasks, enabled-authentication, enabled-permissions).
Table page: tasks gating and typing
src/pages/warehouse/[id].namespace.[nsid].table.[tid].vue
Tasks tab shown if canGetTasks or auth/perm disabled; added loading states; passes new TaskManager props; snapshotHistory typed as Snapshot[]; guarded permission calls when tableId missing.
View page: action typing and tasks references
src/pages/warehouse/[id].namespace.[nsid].view.[vid].vue
Switched permissions typing from TableAction to ViewAction; updated myAccess type; integrates canGetTasks checks in tab logic.
Namespace page: dialog gating
src/pages/warehouse/[id].namespace.[nsid].vue
AddNamespaceDialog shown if create_namespace or auth/perm disabled.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  actor U as User
  participant WP as Warehouse/Table/View Page
  participant TM as TaskManager (component)
  participant API as Management API

  U->>WP: Navigate to entity page
  WP->>WP: Compute permissions (canGet* / canControl*)
  WP-->>U: Show "Tasks" tab if (canGet* || auth/perm disabled)

  U->>TM: Open Tasks tab
  TM->>TM: createEntityFilter(entityType, ids)
  TM->>API: listTasks(filter=TaskEntity[])
  API-->>TM: Tasks or 404/not-available
  TM->>TM: Render list or context-specific error

  alt canShowControls (canControl* || auth/perm disabled)
    U->>TM: Run/Stop/Cancel task
    TM->>API: controlTask(entity, action)
    API-->>TM: Result/Error
    TM-->>U: Update status
  else Controls hidden
    TM-->>U: Read-only task view
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • feat: task queue #152 — Also modifies task-management APIs and UI, likely tied to the same new task actions/entities and TaskManager behavior.

Poem

I thump my paw on branch and view,
Tasks hop between the fields anew.
IDs in rows, we count and cheer,
Permissions shift—yet paths stay clear.
With whiskered care, I sift and plan,
A bunny shipping clean, as only rabbits can. 🐇✨

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title “fix: tasks access” concisely references the primary purpose of the pull request, which is to correct and broaden task access controls and permissions across components and API specifications, and aligns with the main changeset centered on task-related functionality.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.

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.

Copy link

@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: 4

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
openapi/management-open-api.yaml (1)

4660-4672: Breaking change in TabularIdentOrUuid (id variant now requires warehouse-id) and description mismatch.

  • The first variant now requires both warehouse-id and table-id. This can break existing clients that provided only the UUID.
  • The schema description still says “either a UUID or its name and namespace,” which is no longer accurate.

Consider either:

  • Restoring backward compatibility by allowing an id-only variant, or
  • Updating the description and all consumers to the new requirement.

Suggested minimal backward-compatible schema addition:

   TabularIdentOrUuid:
     oneOf:
       - type: object
         required:
           - warehouse-id
           - table-id
         properties:
           table-id:
             type: string
             format: uuid
           warehouse-id:
             type: string
             format: uuid
+      - type: object
+        required:
+          - table-id
+        properties:
+          table-id:
+            type: string
+            format: uuid
       - type: object
         required:
           - namespace
           - table
           - warehouse-id

If you intentionally tightened the contract, please at least update the description to reflect the new requirement.

src/components/BranchVisualization.vue (2)

298-318: Avoid relying on external array order for schema change detection

Template calls getSchemaChanges(selectedSnapshot, index) using an index derived from the raw snapshot array. If parents supply snapshots in a different order, results can be wrong. You already have getSchemaChangeInfo(snapshot); use it to drive UI without an index.

Apply in template:

-                    <v-chip
-                      v-if="
-                        selectedSnapshot &&
-                        getSchemaChanges(
-                          selectedSnapshot,
-                          snapshotHistory.findIndex(
-                            (s) => s['snapshot-id'] === selectedSnapshot!['snapshot-id'],
-                          ),
-                        )
-                      "
+                    <v-chip
+                      v-if="selectedSnapshot && getSchemaChangeInfo(selectedSnapshot).hasSchemaChange"
                       size="x-small"
                       color="warning"
                       variant="flat"
                       class="ml-2">
                       Changed
                     </v-chip>

And for field “New” badges:

-                          :color="
-                                selectedSnapshot &&
-                                isFieldNew(
-                                  field,
-                                  selectedSnapshot,
-                                  snapshotHistory.findIndex(
-                                    (s) => s['snapshot-id'] === selectedSnapshot!['snapshot-id'],
-                                  ),
-                                )
-                                  ? 'success'
-                                  : undefined
-                              "
+                          :color="
+                                selectedSnapshot && isFieldNew(field, selectedSnapshot)
+                                  ? 'success'
+                                  : undefined
+                              "
-                            :class="
-                              selectedSnapshot &&
-                              isFieldNew(
-                                field,
-                                selectedSnapshot,
-                                snapshotHistory.findIndex(
-                                  (s) => s['snapshot-id'] === selectedSnapshot!['snapshot-id'],
-                                ),
-                              )
-                                ? 'text-success font-weight-bold'
-                                : ''
-                            "
+                            :class="
+                              selectedSnapshot && isFieldNew(field, selectedSnapshot)
+                                ? 'text-success font-weight-bold'
+                                : ''
+                            "
-                              v-if="
-                                selectedSnapshot &&
-                                isFieldNew(
-                                  field,
-                                  selectedSnapshot,
-                                  snapshotHistory.findIndex(
-                                    (s) => s['snapshot-id'] === selectedSnapshot!['snapshot-id'],
-                                  ),
-                                )
-                              "
+                              v-if="selectedSnapshot && isFieldNew(field, selectedSnapshot)"

Then update the helper signatures (see next comment).

Also applies to: 320-357, 359-392, 397-404


1259-1265: Make isFieldNew independent of array order

Compare against the parent snapshot (or previous by sequence) instead of relying on index + 1.

Apply:

-function isFieldNew(field: any, version: Snapshot, index: number): boolean {
-  if (index === props.snapshotHistory.length - 1) return false;
-  const nextVersion = props.snapshotHistory[index + 1];
-  const nextSchema = getSchemaInfo(nextVersion['schema-id']);
-  if (!nextSchema) return true;
-  return !nextSchema.fields.some((f: any) => f.id === field.id);
-}
+function isFieldNew(field: any, version: Snapshot): boolean {
+  const parentId = version['parent-snapshot-id'];
+  if (!parentId) return false;
+  const parent = props.snapshotHistory.find((s) => s['snapshot-id'] === parentId);
+  if (!parent) return false;
+  const parentSchema = getSchemaInfo(parent['schema-id'] || props.table.metadata['current-schema-id']);
+  if (!parentSchema) return false;
+  return !parentSchema.fields?.some((f: any) => f.id === field.id);
+}

Optionally, add this helper outside the selected block for reuse:

function getPreviousSnapshot(snapshot: Snapshot): Snapshot | undefined {
  return props.snapshotHistory.find((s) => s['snapshot-id'] === snapshot['parent-snapshot-id']);
}
🧹 Nitpick comments (9)
README.md (1)

14-18: Improve alt text specificity for new screenshots.

All four new <img> tags reuse alt="Lakekeeper UI", so screen-reader users won’t know what each screenshot depicts. Please give each image a short, descriptive alt text (e.g., “Branch table view” or “Tasks warehouse screen”) to keep the README accessible.

src/pages/warehouse/[id].namespace.[nsid].table.[tid].vue (5)

118-129: Align tasks tab/window gating and avoid accidental “Loading table information…” flashes

The window-item uses the same gating as the tab (good), and shows a fallback loader when loaded is false. To prevent cross-tab side effects (e.g., permission fetch toggling loaded), use a dedicated permissionsLoaded flag for the permissions pane instead of reusing loaded.

Suggested minimal change in this block:

  • Keep this window-item as-is.
  • In the permissions window-item (Line 107), switch to v-if="permissionsLoaded" and drive only that flag in loadPermissionsData.

Apply within this file (template block):

-              <PermissionManager
-                v-if="loaded"
+              <PermissionManager
+                v-if="permissionsLoaded"
                 :status="assignStatus"
                 :assignable-obj="permissionObject"
                 :existing-permissions-from-obj="existingPermissions"
                 :relation-type="permissionType"
                 @permissions="assign" />
-              <div v-else class="text-center pa-8">
+              <div v-else class="text-center pa-8">
                 <v-progress-circular color="info" indeterminate :size="48"></v-progress-circular>
                 <div class="text-subtitle-1 mt-2">Loading permissions...</div>
               </div>

And in script (additions shown; adjust calls in loadPermissionsData accordingly):

// new ref near other refs
const permissionsLoaded = ref(true);
 async function loadPermissionsData() {
   if (!canReadPermissions.value) return;

   try {
-    loaded.value = false;
+    permissionsLoaded.value = false;
     existingPermissions.splice(0, existingPermissions.length);
     Object.assign(
       existingPermissions,
       await functions.getTableAssignmentsById(tableId.value, warehouseId),
     );
-    loaded.value = true;
+    permissionsLoaded.value = true;
   } catch (error) {
     console.error('Failed to load permissions data:', error);
-    loaded.value = true;
+    permissionsLoaded.value = true;
   }
 }

200-201: Prefer ref([]) for arrays (minor)

reactive<Snapshot[]>([]) works, but ref<Snapshot[]>([]) is more idiomatic for arrays and avoids edge cases with reactivity utilities.


222-224: Protection fetch can run regardless of authz backend (verify)

Tying getProtection() to the authz backend may skip protection state when authz is allow-all. Consider moving await getProtection() outside the authz check (still after the tableId guard).

If protection is independent of authz backends, apply:

-  if (serverInfo['authz-backend'] != 'allow-all') {
-    Object.assign(myAccess, await functions.getTableAccessById(tableId.value, warehouseId));
-    if (tableId.value) {
-      await getProtection();
-    }
+  if (serverInfo['authz-backend'] != 'allow-all') {
+    Object.assign(myAccess, await functions.getTableAccessById(tableId.value, warehouseId));
   }
+  await getProtection();

Please confirm the API behavior for getTableProtection under allow-all.


300-321: Branch tab should refresh snapshotHistory

When switching tabs, the branch view reuses stale snapshotHistory. Refresh it to reflect new snapshots.

Apply:

   switch (tab.value) {
     case 'permissions':
       await loadPermissionsData();
       break;
     case 'tasks':
       // Tasks are loaded by TaskManager component - it handles its own refresh
       break;
+    case 'branch': {
+      // Refresh table and snapshot history for branch visualization
+      Object.assign(
+        table,
+        await functions.loadTableCustomized(warehouseId, namespaceId, tableName),
+      );
+      snapshotHistory.splice(0, snapshotHistory.length);
+      if (table.metadata.snapshots) {
+        const sortedSnapshots = [...table.metadata.snapshots].sort(
+          (a, b) => (b['timestamp-ms'] || 0) - (a['timestamp-ms'] || 0),
+        );
+        snapshotHistory.push(...sortedSnapshots);
+      }
+      depthRawRepresentationMax.value = getMaxDepth(table);
+      break;
+    }
     case 'overview':
     case 'raw':
     case 'branch':
     default:

327-337: Use a dedicated permissions loader instead of loaded

Toggling the shared loaded flag here can unintentionally affect other panes (e.g., tasks). Use a separate permissionsLoaded flag as suggested above.

src/pages/warehouse/[id].vue (1)

509-510: Early return on permissions fetch is correct

Short-circuit prevents unnecessary calls and flicker. Consider a dedicated permissionsLoaded flag rather than reusing loaded to avoid affecting other tabs.

src/components/BranchVisualization.vue (2)

686-709: Duplicate logic with getSchemaChanges; consolidate

getSchemaChangeInfo duplicates and improves getSchemaChanges. Prefer this function throughout to avoid inconsistent behavior.


1232-1241: Optional: cache schemas by ID

To reduce repeated linear scans in getSchemaInfo, precompute a Map<id, schema> once and use it. Useful for large schema lists.

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 64dc2e6 and 5560e4a.

⛔ Files ignored due to path filters (7)
  • package-lock.json is excluded by !**/package-lock.json
  • src/assets/branch_table.png is excluded by !**/*.png
  • src/assets/tasks_wh.png is excluded by !**/*.png
  • src/assets/view_history.png is excluded by !**/*.png
  • src/gen/iceberg/types.gen.ts is excluded by !**/gen/**
  • src/gen/management/sdk.gen.ts is excluded by !**/gen/**
  • src/gen/management/types.gen.ts is excluded by !**/gen/**
📒 Files selected for processing (13)
  • .env (1 hunks)
  • README.md (1 hunks)
  • openapi/management-open-api.yaml (5 hunks)
  • openapi/rest-catalog-open-api.yaml (8 hunks)
  • src/components/BranchVisualization.vue (12 hunks)
  • src/components/SnapshotDetails.vue (1 hunks)
  • src/components/TableDetails.vue (2 hunks)
  • src/components/TaskDetails.vue (2 hunks)
  • src/components/TaskManager.vue (5 hunks)
  • src/pages/warehouse/[id].namespace.[nsid].table.[tid].vue (7 hunks)
  • src/pages/warehouse/[id].namespace.[nsid].view.[vid].vue (8 hunks)
  • src/pages/warehouse/[id].namespace.[nsid].vue (1 hunks)
  • src/pages/warehouse/[id].vue (5 hunks)
👮 Files not reviewed due to content moderation or server errors (5)
  • openapi/rest-catalog-open-api.yaml
  • src/pages/warehouse/[id].namespace.[nsid].vue
  • src/components/SnapshotDetails.vue
  • src/components/TableDetails.vue
  • src/pages/warehouse/[id].namespace.[nsid].view.[vid].vue
🧰 Additional context used
🪛 dotenv-linter (3.3.0)
.env

[warning] 8-8: [UnorderedKey] The VITE_ENABLE_AUTHENTICATION key should go before the VITE_IDP_AUTHORITY key

(UnorderedKey)


[warning] 9-9: [UnorderedKey] The VITE_ENABLE_PERMISSIONS key should go before the VITE_IDP_AUTHORITY key

(UnorderedKey)

⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
  • GitHub Check: Test Rust
🔇 Additional comments (25)
openapi/management-open-api.yaml (4)

4553-4555: New table task actions look good; confirm end-to-end wiring.

Enums get_tasks and control_tasks align with the new task endpoints. Please confirm UI checks and access-gating consume these actions and that backend authorization evaluates them.


4866-4880: View TaskEntity variant addition is consistent and complete.

required keys and enums are correct and parallel the table variant.


5175-5177: New view task actions look good; verify exposure in access responses.

Enums extend cleanly; ensure UI permissions rendering expects these values from GetViewAccessResponse.


5266-5267: Warehouse-level all-tasks actions added; ensure policy and UI adopt them.

get_all_tasks and control_all_tasks align with warehouse-scoped task endpoints. Please confirm server-side authorization checks and UI gating are updated accordingly.

src/pages/warehouse/[id].namespace.[nsid].table.[tid].vue (7)

38-42: Tasks tab gating looks correct

Visibility matches the new semantics: allow when canGetTasks or when auth/permissions are disabled. Good.


105-116: Nice UX: permissions loading placeholder

The loading state for permissions improves clarity and avoids empty renders. LGTM.


155-155: Good: stronger typing for snapshots

Importing Snapshot type and using it downstream improves safety.


171-173: New task permission flags are clear and granular

The canGetTasks/canControlTasks split is appropriate for gating view vs. control.


211-216: Good guard on missing table ID

Early exit prevents downstream calls with empty IDs and avoids noisy errors.


229-231: Correct extraction of task-related actions

Mapping get/control actions from myAccess is consistent with the new permission model.


125-128: No changes needed for TaskManager props: TaskManager.vue’s defineProps generic declares entityType, canControlTasks, enabledAuthentication, and enabledPermissions, and the template’s kebab-case usage matches these camelCase props.

src/pages/warehouse/[id].vue (7)

65-71: Tasks tab gating matches new global task permissions

Allow when canGetAllTasks or auth/permissions are disabled. Looks good.


375-377: Permissions loading state is a welcome UX improvement

Clear, consistent feedback while permissions load.


475-477: New flags for all-warehouse task permissions

canGetAllTasks and canControlAllTasks are clear and will simplify downstream checks.


521-523: Improved error logging and state reset

Good: descriptive log and always restoring loaded on error.


562-564: Correct mapping of all-warehouse task actions

Matches the updated permission model.


380-388: No action needed: TaskManager.vue already declares entityType, canControlTasks, enabledAuthentication, and enabledPermissions props matching this usage.


517-517: getWarehouseAssignmentsById signature confirmed

src/components/BranchVisualization.vue (7)

213-213: Height tweak to 70vh

More space for details pane; fits the graph-heavy layout. LGTM.


621-647: Type annotations for dropped branch traversal look good

The explicit Snapshot/null and number[] typings clarify intent. LGTM.


846-873: Dropped branch chain walk: guard is sound

Loop guards and optional branching avoid NPEs. Fine. Note: This is O(n²); acceptable for typical snapshot counts.


432-438: Public prop typing strengthened

Explicit props with generated types reduce runtime surprises. Good.


443-443: selectedSnapshot typing is correct

Ref<Snapshot | null> aligns with template guards.


1232-1241: getSchemaInfo: robust null-guards

Good handling for absent schema or empty list.


1243-1251: Effective schema fallback is a solid improvement

Correctly uses table’s current schema when snapshot lacks its own.

coderabbitai[bot]
coderabbitai bot previously approved these changes Sep 26, 2025
@c-thiel
Copy link
Member

c-thiel commented Sep 27, 2025

@CodeRabbit review & approve

@coderabbitai
Copy link

coderabbitai bot commented Sep 27, 2025

@c-thiel I'll review and approve this PR for you.

This PR implements a comprehensive fix for tasks access with several key improvements:

Key Changes Reviewed:

1. Enhanced Type Safety

  • Replaced any types with proper TypeScript interfaces (Snapshot, LoadTableResultReadable, etc.)
  • Added proper type imports and stricter typing throughout Vue components
  • Improved component props with explicit types

2. Extended Task Management

  • Added support for view-based tasks alongside existing table tasks
  • Introduced new task-related permissions (get_tasks, control_tasks, get_all_tasks, control_all_tasks)
  • Enhanced TaskManager component to handle both table and view contexts

3. Improved Access Control

  • Broadened task visibility when authentication/permissions are disabled
  • Added granular permission checks for task operations
  • Maintained security while improving usability in development environments

4. API Specifications Updated

  • Extended OpenAPI specs with new task-related actions for tables, views, and warehouses
  • Added support for view-based task entities
  • Updated enums to reflect new capabilities

5. Configuration Changes

  • Disabled authentication and permissions in .env for development/testing
  • Added new visual assets to documentation

Code Quality Assessment:

Type Safety: Excellent improvement from any types to proper interfaces
Consistency: Changes are well-coordinated across components
Backward Compatibility: Existing functionality preserved while adding new features
Access Control: Proper permission handling with fallbacks for disabled auth
Error Handling: Appropriate guards and validation added

The implementation is solid and follows Vue.js and TypeScript best practices. The extension to support view-based tasks is particularly well-architected.

✅ Actions performed

Comments resolved and changes approved.


Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link

@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: 1

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 5560e4a and daeef77.

📒 Files selected for processing (3)
  • src/components/BranchVisualization.vue (12 hunks)
  • src/components/TaskDetails.vue (2 hunks)
  • src/components/TaskManager.vue (5 hunks)
🔇 Additional comments (2)
src/components/TaskManager.vue (1)

450-457: Explicit gating fix looks great

Thanks for tightening canShowControls to require an explicit grant or intentionally disabled auth/permissions. This keeps legacy call sites safe while still honoring the new dev toggles.

src/components/TaskDetails.vue (1)

338-352: Entity ID helper covers the gaps

Appreciate the broader getEntityId coverage—namespace, warehouse, and the generic fallback bring back the IDs (and copy affordance) that regressed earlier.

@v-kessler v-kessler merged commit be83bfa into main Sep 27, 2025
7 checks passed
@v-kessler v-kessler deleted the vk/access-fix branch September 27, 2025 09:53
@coderabbitai coderabbitai bot mentioned this pull request Oct 12, 2025
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