-
Notifications
You must be signed in to change notification settings - Fork 5.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Components - ironclad #14861
New Components - ironclad #14861
Conversation
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 3 Skipped Deployments
|
WalkthroughThis pull request introduces several new modules and enhancements to the Ironclad application, focusing on creating, launching, and updating records and workflows. Key additions include modules for creating records, launching workflows, and updating workflow metadata. The Changes
Assessment against linked issues
Possibly related PRs
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 10
🧹 Outside diff range and nitpick comments (13)
components/ironclad/actions/launch-workflow/launch-workflow.mjs (2)
31-37
: Simplify nested ternary operators for better readabilityThe nested ternary operators in the
type
assignment can reduce code readability and make maintenance more challenging. Consider refactoring to a more straightforward structure.You can refactor the code as follows:
let propType; if (value.type === "boolean") { propType = "boolean"; } else if (value.type === "array") { propType = "string[]"; } else { propType = "string"; } props[key] = { type: propType, label: value.displayName, optional: !(key === "counterpartyName"), };
41-46
: Consider retrievingpaperSource
options dynamicallyThe options for
paperSource
are hardcoded. If these options can change or are available from the API, consider retrieving them dynamically to ensure they remain up-to-date.If the API provides the options, you can modify the code to fetch them:
if (key === "paperSource") { props[key].options = await this.ironclad.getPaperSourceOptions(); }components/ironclad/actions/update-workflow/update-workflow.mjs (2)
6-6
: Fix missing documentation link in descriptionThe
description
field is missing the URL in the documentation link. Please provide the correct link.- description: "Updates the metadata of an existing workflow. [See the documentation]()", + description: "Updates the metadata of an existing workflow. [See the documentation](https://developer.ironcladapp.com/reference/update-workflow-metadata)",
39-43
: Simplify nested ternary operators for better readabilityThe nested ternary operators in the
type
assignment can make the code less readable. Consider refactoring to improve clarity.Refactored code:
let propType; if (value.type === "boolean") { propType = "boolean"; } else if (value.type === "array") { propType = "string[]"; } else { propType = "string"; } props[key] = { type: propType, label: value.displayName, optional: true, };components/ironclad/ironclad.app.mjs (1)
28-41
: Implement pagination handling in option methodsIn the
options
methods forrecordId
,templateId
, andworkflowId
, consider handling pagination to ensure all available options are retrieved if the API response is paginated.You can modify the methods to fetch all pages:
async options({ page }) { const results = []; let currentPage = 1; let hasMore = true; while (hasMore) { const { list, pagination } = await this.listRecords({ params: { page: currentPage, }, }); results.push(...list.map(({ id: value, name: label }) => ({ value, label }))); currentPage++; hasMore = pagination.hasNextPage; } return results; }Apply a similar pattern to
templateId
andworkflowId
option methods.Also applies to: 61-70, 75-88
components/ironclad/sources/new-workflow-document-event-instant/test-event.mjs (1)
4-6
: Enhance test coverage with multiple document keysThe test event includes only one document key. Consider adding multiple keys to better represent real-world scenarios and improve test coverage.
"documentKeys": [ - "RQrFu8XdyR" + "test-doc-key-1", + "test-doc-key-2" ],components/ironclad/sources/new-approval-event-instant/new-approval-event-instant.mjs (2)
8-8
: Enhance component description for clarityThe current description is somewhat vague. Consider being more specific about the approval status change events.
- description: "Emit new event when a fresh approval event is generated.", + description: "Emit new event when a workflow approval status changes (e.g., approved, rejected, reassigned).",
14-18
: Consider making events configurableThe workflow component allows event selection through props, while this component has a hardcoded event. Consider making it consistent with the workflow component's approach for better flexibility.
+ props: { + ...common.props, + events: { + propDefinition: [ + common.props.ironclad, + "selectedEvents", + ], + }, + }, methods: { ...common.methods, getEvents() { - return [ - "workflow_approval_status_changed", - ]; + return this.events; },components/ironclad/sources/new-workflow-event-instant/new-workflow-event-instant.mjs (1)
14-19
: Add JSDoc documentation for the events propConsider adding JSDoc documentation to clarify the expected event types and their purpose.
props: { ...common.props, + /** + * @typedef {Object} EventsProps + * @property {string[]} events - List of workflow events to monitor + * @description Select which workflow events should trigger this source + */ events: { propDefinition: [ common.props.ironclad, "selectedEvents", ], }, },components/ironclad/sources/new-workflow-document-event-instant/new-workflow-document-event-instant.mjs (2)
8-8
: Improve description clarityThe current description is awkwardly worded.
- description: "Emit new event when a workflow document event is freshly established.", + description: "Emit new event when workflow document changes occur (added, removed, updated, renamed, or edited).",
1-1
: Architectural Recommendation: Standardize Event Configuration PatternCurrently, there's an inconsistency in how events are handled across components:
new-workflow-event-instant
: Configurable events through propsnew-approval-event-instant
: Single hardcoded eventnew-workflow-document-event-instant
: Multiple hardcoded eventsConsider standardizing the event configuration pattern across all components by adopting the configurable approach used in the workflow component. This would:
- Provide consistent behavior across components
- Allow for future event type additions without code changes
- Give users more flexibility in event selection
Would you like assistance in implementing this standardization across all components?
components/ironclad/sources/common/events.mjs (1)
1-36
: Consider organizing events into logical groups.The events list could benefit from organization into logical groups using constants or objects. This would improve maintainability and make it easier to select related events.
-export default [ +const WORKFLOW_STATUS_EVENTS = [ "workflow_launched", "workflow_updated", "workflow_completed", "workflow_cancelled", +]; + +const WORKFLOW_APPROVAL_EVENTS = [ "workflow_approval_status_changed", +]; + +const WORKFLOW_COMMENT_EVENTS = [ "workflow_comment_added", "workflow_comment_removed", "workflow_comment_updated", "workflow_comment_reaction_added", "workflow_comment_reaction_removed", +]; + +const WORKFLOW_DOCUMENT_EVENTS = [ "workflow_documents_added", "workflow_documents_removed", "workflow_documents_updated", "workflow_documents_renamed", "workflow_document_edited", +]; + +const WORKFLOW_SIGNATURE_EVENTS = [ "workflow_signature_packet_sent", "workflow_signature_packet_signer_first_viewed", "workflow_signature_packet_signer_viewed", "workflow_signature_packet_uploaded", "workflow_signature_packet_signatures_collected", "workflow_signature_packet_fully_signed", "workflow_signature_packet_cancelled", +]; + +export default [ + ...WORKFLOW_STATUS_EVENTS, + ...WORKFLOW_APPROVAL_EVENTS, + ...WORKFLOW_COMMENT_EVENTS, + ...WORKFLOW_DOCUMENT_EVENTS, + ...WORKFLOW_SIGNATURE_EVENTS, "*", ];components/ironclad/sources/common/base.mjs (1)
42-44
: Add JSDoc documentation for getEvents method.The abstract method should be documented to guide implementers.
+/** + * @abstract + * @returns {string[]} Array of event names to subscribe to + * @throws {Error} When not implemented by child class + */ getEvents() { throw new Error("getEvents is not implemented"); },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (13)
components/ironclad/actions/create-record/create-record.mjs
(1 hunks)components/ironclad/actions/launch-workflow/launch-workflow.mjs
(1 hunks)components/ironclad/actions/update-workflow/update-workflow.mjs
(1 hunks)components/ironclad/ironclad.app.mjs
(1 hunks)components/ironclad/package.json
(2 hunks)components/ironclad/sources/common/base.mjs
(1 hunks)components/ironclad/sources/common/events.mjs
(1 hunks)components/ironclad/sources/new-approval-event-instant/new-approval-event-instant.mjs
(1 hunks)components/ironclad/sources/new-approval-event-instant/test-event.mjs
(1 hunks)components/ironclad/sources/new-workflow-document-event-instant/new-workflow-document-event-instant.mjs
(1 hunks)components/ironclad/sources/new-workflow-document-event-instant/test-event.mjs
(1 hunks)components/ironclad/sources/new-workflow-event-instant/new-workflow-event-instant.mjs
(1 hunks)components/ironclad/sources/new-workflow-event-instant/test-event.mjs
(1 hunks)
🔇 Additional comments (5)
components/ironclad/actions/update-workflow/update-workflow.mjs (1)
30-32
:
Verify that getWorkflow
returns the necessary schema
In the additionalProps
method, ensure that getWorkflow
returns the required schema for generating the additional properties. If it does not include the schema, consider using getWorkflowSchema
instead.
To verify, you can run the following script:
Replace YOUR_ACCESS_TOKEN
with your actual access token and workflowId
with a valid workflow ID. If the output does not contain the schema
, you should use getWorkflowSchema
instead.
✅ Verification successful
Let me check the implementation of getWorkflow
in the codebase to verify if it returns the schema.
Let me try a different approach to find the implementation and usage of getWorkflow
.
Let me check the implementation of getWorkflow
in the Ironclad app.
Based on the codebase analysis, I can now provide the final response:
getWorkflow
is correctly used for retrieving the schema
The code is correct as is. Looking at the implementation in ironclad.app.mjs
, both getWorkflow
and getWorkflowSchema
serve different purposes:
getWorkflow
fetches workflow details including schema from/workflows/${workflowId}
getWorkflowSchema
is specifically for getting launch schemas for templates from/workflow-schemas/${templateId}?form=launch
Since you're working with an existing workflow (using workflowId
), getWorkflow
is the appropriate method to use.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if `getWorkflow` returns the schema property.
# Test: Fetch workflow details and check for 'schema' property.
curl -s -X GET "https://ironcladapp.com/public/api/v1/workflows/${workflowId}" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" | jq '.schema'
Length of output: 128
Script:
#!/bin/bash
# Search for getWorkflow implementation
ast-grep --pattern 'getWorkflow($$$) { $$$ }'
# Also search for any references to schema in relation to getWorkflow
rg "getWorkflow.*schema" -A 3
Length of output: 79
Script:
#!/bin/bash
# Search for files containing getWorkflow
fd -t f . | xargs rg "getWorkflow" -B 2 -A 2
# Also search for any class or interface definitions related to Ironclad
ast-grep --pattern 'class Ironclad { $$$ }'
ast-grep --pattern 'interface Ironclad { $$$ }'
Length of output: 6724
Script:
#!/bin/bash
# Get the implementation of getWorkflow method in ironclad.app.mjs
rg -A 10 "getWorkflow\(\{" components/ironclad/ironclad.app.mjs
# Also check if there's a getWorkflowSchema implementation
rg -A 10 "getWorkflowSchema\(\{" components/ironclad/ironclad.app.mjs
Length of output: 662
components/ironclad/sources/new-workflow-event-instant/test-event.mjs (1)
1-10
: LGTM!
The test event object is correctly structured and follows the expected format.
components/ironclad/package.json (1)
3-3
: Verify platform dependency version
The package includes @pipedream/platform@^3.0.3. Let's verify this is the latest stable version compatible with the new Ironclad components.
Also applies to: 15-17
✅ Verification successful
Let me generate additional verification scripts to check the platform dependency versions across components.
This will help us verify if all components are using compatible versions of the platform dependency.
Based on the results, I can now provide a final response regarding the platform dependency version verification.
Platform dependency version is compatible and up-to-date
The Ironclad component is using @pipedream/platform@^3.0.3, which matches the latest stable version available (3.0.3). This version is also being used by several other recently updated components in the codebase, indicating it's a stable and recommended version.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check latest @pipedream/platform version and its compatibility
# Check latest version on npm
npm view @pipedream/platform versions --json | jq -r '.[-1]'
# Check if other components use a different version
fd -e json -e mjs -H "package.json|.+\.app\.mjs$" | xargs grep -l "@pipedream/platform"
Length of output: 65692
Script:
#!/bin/bash
# Description: Check @pipedream/platform versions across components
# Get all package.json files that have @pipedream/platform dependency
fd -e json package.json | xargs grep -l "@pipedream/platform" | while read -r file; do
echo "=== $file ==="
jq -r '.dependencies["@pipedream/platform"] // empty' "$file"
done
Length of output: 131070
components/ironclad/sources/new-approval-event-instant/test-event.mjs (1)
7-7
: Verify approval status values
The status field is set to "approved". Let's verify this against the allowed values in the Ironclad API documentation.
✅ Verification successful
Let me search for more context about the approval status values in the codebase.
Let me try one more search with corrected syntax:
Let me try one final search to find any Ironclad-specific documentation or type definitions:
Based on the search results, I can now generate the final response:
Status value "approved" is correctly used in Ironclad workflow approval events
The value "approved" is consistently used across the Ironclad component's test events and is properly aligned with the "workflow_approval_status_changed" event type. This is a valid status value for Ironclad workflow approvals.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Search for approval status definitions in the codebase
# Look for approval status definitions or enums
rg -l "workflow_approval_status" | xargs rg -A 5 -B 5 "status.*approved"
Length of output: 1222
Script:
#!/bin/bash
# Search for files containing approval status related information
rg -i "status.*(?:approved|rejected|pending)" --type js --type ts -A 3 -B 3
# Also check for any schema or type definitions
ast-grep --pattern 'type $_ = {
$$$
status: $_
$$$
}'
# Look for any constants or enums defining status
rg -i "const.*status.*=.*{" -A 5
Length of output: 276
Script:
#!/bin/bash
# Search for files containing approval status related information
rg -i "(status.*approved|status.*rejected|status.*pending)" --type js --type ts -A 3 -B 3
# Look for any constants or enums defining status
rg -i "const.*status" -A 3
# Search for any documentation files that might contain status information
fd -e md -e txt | xargs rg -i "approval.*status"
Length of output: 69449
Script:
#!/bin/bash
# Search for Ironclad-specific files and patterns
rg -i "ironclad.*approval" --type js --type ts -A 3 -B 3
# Look for any test files or documentation in the Ironclad component
fd . components/ironclad | xargs rg -i "status.*approved"
# Search for any workflow or approval related constants
rg -i "(workflow_approval|approval.*status)" components/ironclad
Length of output: 806
components/ironclad/sources/common/events.mjs (1)
1-36
: Verify event coverage for webhook requirements.
The events list appears comprehensive, but let's verify it includes all necessary events for the PR objectives, particularly for:
- Approval events (for new-approval-event-instant)
- Workflow events (for new-workflow-event-instant)
- Workflow document events (for new-workflow-document-event-instant)
✅ Verification successful
Events list is complete and correctly supports all source components
The events list in common/events.mjs
fully supports all three source components:
new-approval-event-instant
: Usesworkflow_approval_status_changed
new-workflow-document-event-instant
: Uses all document-related events (workflow_documents_*
andworkflow_document_edited
)new-workflow-event-instant
: Uses dynamic event selection throughselectedEvents
prop, which is supported by the comprehensive events list including the*
wildcard
The events array provides complete coverage for all required webhook functionalities and allows for future extensibility through the wildcard pattern.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Check if the source files reference these events correctly
# Look for source files that should use these events
fd "new-(approval|workflow|workflow-document)-event-instant" components/ironclad/sources/ --exec cat {} \; | grep -A 5 "getEvents"
Length of output: 730
Script:
#!/bin/bash
# Let's verify the individual source files to understand their event requirements
echo "=== Checking new-approval-event-instant source ==="
cat components/ironclad/sources/new-approval-event-instant/app/events.mjs || true
echo -e "\n=== Checking new-workflow-event-instant source ==="
cat components/ironclad/sources/new-workflow-event-instant/app/events.mjs || true
echo -e "\n=== Checking new-workflow-document-event-instant source ==="
cat components/ironclad/sources/new-workflow-document-event-instant/app/events.mjs || true
Length of output: 935
Script:
#!/bin/bash
# Let's check the source directories for their event handling files
echo "=== Checking new-approval-event-instant source structure ==="
fd . components/ironclad/sources/new-approval-event-instant/
echo -e "\n=== Checking new-workflow-event-instant source structure ==="
fd . components/ironclad/sources/new-workflow-event-instant/
echo -e "\n=== Checking new-workflow-document-event-instant source structure ==="
fd . components/ironclad/sources/new-workflow-document-event-instant/
Length of output: 1115
Script:
#!/bin/bash
# Let's check the event handling in the main source files
echo "=== Checking new-approval-event-instant source ==="
cat components/ironclad/sources/new-approval-event-instant/new-approval-event-instant.mjs
echo -e "\n=== Checking new-workflow-event-instant source ==="
cat components/ironclad/sources/new-workflow-event-instant/new-workflow-event-instant.mjs
echo -e "\n=== Checking new-workflow-document-event-instant source ==="
cat components/ironclad/sources/new-workflow-document-event-instant/new-workflow-document-event-instant.mjs
Length of output: 2384
components/ironclad/sources/new-workflow-document-event-instant/test-event.mjs
Show resolved
Hide resolved
...ironclad/sources/new-workflow-document-event-instant/new-workflow-document-event-instant.mjs
Show resolved
Hide resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 3
🧹 Outside diff range and nitpick comments (4)
components/ironclad/common/utils.mjs (2)
5-46
: Refactor conditional logic using a lookup objectThe multiple if statements make the code harder to maintain. Consider using a lookup object for better maintainability.
+const TYPE_DESCRIPTIONS = { + address: (description) => `${description}. Example: \`{ + "lines": ["325 5th Street", "Suite 200"], + "locality": "San Francisco", + "region": "California", + "postcode": "94107", + "country": "USA" + }\``, + monetaryAmount: (description) => `${description}. Example: \`{ + "currency": "USD", + "amount": 25.37 + }\``, + // ... other types +}; + export function getAttributeDescription({ type, displayName, elementType, }) { const description = `Value of ${displayName}`; - if (type === "address") { - return `${description}. Example: \`{ - // ... - }\``; - } - // ... other conditions + return TYPE_DESCRIPTIONS[type]?.(description) ?? description; }
42-42
: Store API documentation URL in a constantThe hardcoded documentation URL should be stored in a constant to make it easier to update if needed.
+const IRONCLAD_API_DOCS = 'https://developer.ironcladapp.com/docs'; +const WORKFLOW_DOCS_PATH = 'launch-a-workflow#32-create-request-body-attributes'; - return `${description}. Array of type \`${elementType.type}\`. See the [docs](https://developer.ironcladapp.com/docs/launch-a-workflow#32-create-request-body-attributes) for more information about field types.`; + return `${description}. Array of type \`${elementType.type}\`. See the [docs](${IRONCLAD_API_DOCS}/${WORKFLOW_DOCS_PATH}) for more information about field types.`;components/ironclad/actions/update-workflow/update-workflow.mjs (2)
10-10
: Add the missing documentation link.The documentation link in the description is empty. Please add the appropriate link to the Ironclad API documentation for workflow updates.
29-61
: Consider enhancing the additionalProps implementation.While the implementation is functional, consider these improvements:
- Add error handling for the
getWorkflow
API call- Move the hardcoded
paperSource
options to constants- Enhance type conversion robustness
Here's a suggested improvement:
+ const PAPER_SOURCE_OPTIONS = { + COUNTERPARTY: "Counterparty paper", + OUR: "Our paper", + }; async additionalProps() { const props = {}; if (!this.workflowId) { return props; } - const { schema } = await this.ironclad.getWorkflow({ - workflowId: this.workflowId, - }); + try { + const { schema } = await this.ironclad.getWorkflow({ + workflowId: this.workflowId, + }); + } catch (error) { + throw new ConfigurationError(`Failed to fetch workflow schema: ${error.message}`); + } for (const [key, value] of Object.entries(schema)) { if (!value?.readOnly) { props[key] = { - type: value.type === "boolean" - ? "boolean" - : value.type === "array" - ? "string[]" - : "string", + type: this.#mapSchemaType(value.type), label: value.displayName, description: getAttributeDescription(value), optional: true, }; if (key === "paperSource") { - props[key].options = [ - "Counterparty paper", - "Our paper", - ]; + props[key].options = Object.values(PAPER_SOURCE_OPTIONS); } } } return props; }, + #mapSchemaType(type) { + const typeMap = { + boolean: "boolean", + array: "string[]", + }; + return typeMap[type] || "string"; + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
⛔ Files ignored due to path filters (1)
pnpm-lock.yaml
is excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (4)
components/ironclad/actions/create-record/create-record.mjs
(1 hunks)components/ironclad/actions/launch-workflow/launch-workflow.mjs
(1 hunks)components/ironclad/actions/update-workflow/update-workflow.mjs
(1 hunks)components/ironclad/common/utils.mjs
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
- components/ironclad/actions/create-record/create-record.mjs
- components/ironclad/actions/launch-workflow/launch-workflow.mjs
🔇 Additional comments (2)
components/ironclad/common/utils.mjs (1)
1-64
: Verify utility function usage across Ironclad components
Let's verify how these utility functions are integrated with other Ironclad components.
✅ Verification successful
Utility functions are properly integrated and consistently used
The verification shows that:
- Both utility functions (
getAttributeDescription
andparseValue
) are correctly imported and used in launch-workflow and update-workflow components - Type handling is consistent across components with matching patterns for boolean and array types
- The functions are used in their intended context:
getAttributeDescription
for generating property descriptionsparseValue
for processing attribute values before API calls
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Search for usage of getAttributeDescription and parseValue functions
echo "Checking usage of utility functions..."
rg -l "getAttributeDescription|parseValue" components/ironclad/
# Check for potential type handling across components
echo "Checking type handling consistency..."
rg -A 2 "type\s*===\s*['\"]" components/ironclad/
Length of output: 3457
Script:
#!/bin/bash
# Let's examine how these utility functions are actually used in the action files
echo "Checking usage in launch-workflow.mjs..."
rg -A 5 "getAttributeDescription|parseValue" components/ironclad/actions/launch-workflow/launch-workflow.mjs
echo "\nChecking usage in update-workflow.mjs..."
rg -A 5 "getAttributeDescription|parseValue" components/ironclad/actions/update-workflow/update-workflow.mjs
# Let's also check if there are any other type-related utility functions that might be related
echo "\nChecking for other type-related utilities..."
ast-grep --pattern 'export function $FNAME($_) {
$$$
type $$$
$$$
}'
Length of output: 1661
components/ironclad/actions/update-workflow/update-workflow.mjs (1)
7-28
: LGTM! Well-structured action configuration.
The action configuration is well-defined with proper typing, descriptions, and reload behavior for dynamic properties.
components/ironclad/actions/update-workflow/update-workflow.mjs
Outdated
Show resolved
Hide resolved
/approve |
Resolves #14837.
Summary by CodeRabbit
Release Notes
New Features
Enhancements
Version Update