Skip to content

feat: update agreement action#16

Merged
hmbanan666 merged 2 commits into
mainfrom
agreement
Jul 24, 2025
Merged

feat: update agreement action#16
hmbanan666 merged 2 commits into
mainfrom
agreement

Conversation

@hmbanan666
Copy link
Copy Markdown
Collaborator

@hmbanan666 hmbanan666 commented Jul 24, 2025

Summary by CodeRabbit

  • New Features

    • Added dedicated pages for viewing and editing partner agreements and legal entities.
    • Introduced the ability to update partner agreements via a modal form with support for new fields (marketing fee, minimum marketing fee per month).
    • Navigation menu now displays agreement and legal entity submenus with localized labels and agreement end date badges.
  • Improvements

    • Enhanced partner agreement card to always display and provide direct access to the update modal.
    • Progress indicators for agreements now avoid negative values.
    • Agreement forms reset upon date changes to improve data consistency.
  • Bug Fixes

    • Required fields in agreement forms updated for consistency.
  • Localization

    • Added new Russian translations for partner agreement and legal entity titles.
  • Chores

    • Updated several package dependencies to newer versions.

@hmbanan666 hmbanan666 self-assigned this Jul 24, 2025
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Jul 24, 2025

Walkthrough

This update introduces new and refactored components for managing partner agreements and legal entities in a web application. It adds new pages for agreement and legal entity details, updates the partner agreement card to always display a single card with update functionality, and implements backend support for updating agreements. Localization and validation schemas are extended, and several UI and API enhancements are made.

Changes

File(s) Change Summary
app/components/PartnerAgreementCard.vue, app/components/PartnerCard.vue Refactored agreement card to always render a single card and updated progress calculation logic.
app/components/form/CreatePartnerAgreement.vue Added template ref to form, updated required fields, and reset form on date changes.
app/components/form/UpdatePartnerAgreement.vue New component for updating partner agreements with validation and API integration.
app/components/modal/UpdatePartnerAgreement.vue New modal component for updating agreements, integrating the update form and overlay logic.
app/pages/partner/[id].vue Added submenu items for agreement and legal entity with dynamic badge for agreement end date.
app/pages/partner/[id]/agreement.vue New page displaying active agreement and option to create a new one via modal.
app/pages/partner/[id]/index.vue Partner agreement card is now conditionally rendered only if an active agreement exists.
app/pages/partner/[id]/legal.vue New page for displaying partner legal entity information.
i18n/locales/ru-RU.json Added Russian translations for partner agreement and legal entity titles.
server/api/partner/agreement/id/[agreementId]/index.patch.ts New API route for updating partner agreements by ID with validation and error handling.
shared/services/partner.ts Extended update schema to include marketing fee fields.
packages/database/src/repository/partner.ts Added methods to find and update partner agreements in the repository.
pnpm-workspace.yaml Updated versions of several dependencies.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant PartnerAgreementCard
    participant ModalUpdatePartnerAgreement
    participant FormUpdatePartnerAgreement
    participant API_Server
    participant Database

    User->>PartnerAgreementCard: Clicks agreement card
    PartnerAgreementCard->>ModalUpdatePartnerAgreement: Opens modal with agreementId
    ModalUpdatePartnerAgreement->>FormUpdatePartnerAgreement: Renders form with agreementId
    User->>FormUpdatePartnerAgreement: Submits updated data
    FormUpdatePartnerAgreement->>API_Server: PATCH /partner/agreement/id/:agreementId
    API_Server->>Database: Validate and update agreement
    Database-->>API_Server: Return updated agreement
    API_Server-->>FormUpdatePartnerAgreement: Respond with success
    FormUpdatePartnerAgreement-->>ModalUpdatePartnerAgreement: Emit success event
    ModalUpdatePartnerAgreement->>PartnerAgreementCard: Close modal, refresh data
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • sushi-love/roll-stack#15: Introduces the initial PartnerAgreementCard.vue with conditional rendering and create modal; this PR directly refactors and builds upon that functionality.

Poem

In the warren of code, a new path appears,
Agreements and entities—no more hidden fears.
Cards now update with a gentle click,
Modals pop up, changes happen quick!
With schema and forms, and a badge or two,
The rabbit hops forward—new features in view!
🐇✨

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bae82a7 and e398afb.

📒 Files selected for processing (2)
  • apps/web-app/app/pages/partner/[id].vue (2 hunks)
  • apps/web-app/app/pages/partner/[id]/legal.vue (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • apps/web-app/app/pages/partner/[id]/legal.vue
  • apps/web-app/app/pages/partner/[id].vue
⏰ 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: build
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch agreement

🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

Copy link
Copy Markdown

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

🧹 Nitpick comments (1)
apps/web-app/shared/services/partner.ts (1)

37-38: Schema additions look good, but consider reviewing error message semantics.

The new marketingFee and minMarketingFeePerMonth fields follow the established pattern correctly with proper validation constraints.

However, the error message 'error.length.invalid' seems semantically incorrect for numeric validation - it suggests string length validation rather than numeric value validation.

Consider using a more semantically appropriate error message for numeric fields:

- marketingFee: type('number >= 0 | undefined').describe('error.length.invalid').optional(),
- minMarketingFeePerMonth: type('number >= 0 | undefined').describe('error.length.invalid').optional(),
+ marketingFee: type('number >= 0 | undefined').describe('error.value.invalid').optional(),
+ minMarketingFeePerMonth: type('number >= 0 | undefined').describe('error.value.invalid').optional(),
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 702727a and bae82a7.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (14)
  • apps/web-app/app/components/PartnerAgreementCard.vue (3 hunks)
  • apps/web-app/app/components/PartnerCard.vue (1 hunks)
  • apps/web-app/app/components/form/CreatePartnerAgreement.vue (6 hunks)
  • apps/web-app/app/components/form/UpdatePartnerAgreement.vue (1 hunks)
  • apps/web-app/app/components/modal/UpdatePartnerAgreement.vue (1 hunks)
  • apps/web-app/app/pages/partner/[id].vue (2 hunks)
  • apps/web-app/app/pages/partner/[id]/agreement.vue (1 hunks)
  • apps/web-app/app/pages/partner/[id]/index.vue (1 hunks)
  • apps/web-app/app/pages/partner/[id]/legal.vue (1 hunks)
  • apps/web-app/i18n/locales/ru-RU.json (1 hunks)
  • apps/web-app/server/api/partner/agreement/id/[agreementId]/index.patch.ts (1 hunks)
  • apps/web-app/shared/services/partner.ts (1 hunks)
  • packages/database/src/repository/partner.ts (2 hunks)
  • pnpm-workspace.yaml (3 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (2)
apps/web-app/server/api/partner/agreement/id/[agreementId]/index.patch.ts (1)
apps/web-app/shared/services/partner.ts (1)
  • updatePartnerAgreementSchema (31-42)
packages/database/src/repository/partner.ts (2)
packages/database/src/types.ts (1)
  • PartnerAgreementDraft (19-19)
packages/database/src/tables.ts (1)
  • partnerAgreements (101-115)
🪛 ESLint
apps/web-app/app/pages/partner/[id].vue

[error] 52-52: 'activeAgreementTo' was used before it was defined.

(no-use-before-define)

⏰ 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: build
🔇 Additional comments (25)
apps/web-app/app/pages/partner/[id]/index.vue (1)

49-51: LGTM! Good defensive programming and component simplification.

The conditional rendering ensures the PartnerAgreementCard only displays when there's an active agreement, and the simplified prop passing aligns well with the component refactoring. This prevents rendering empty or invalid states.

apps/web-app/app/components/PartnerCard.vue (1)

80-82: LGTM! Excellent defensive programming to prevent negative progress values.

The change ensures that expired agreements display 0% progress instead of negative percentages, which improves user experience and maintains logical consistency in the UI.

apps/web-app/i18n/locales/ru-RU.json (1)

142-147: LGTM! Appropriate localization additions for new partner features.

The new translation keys follow the established naming convention and provide proper Russian translations for the partner agreement and legal entity functionality.

pnpm-workspace.yaml (1)

6-6: Package version updates look reasonable, but verify compatibility.

The version bumps appear to be routine maintenance with patch/minor updates that should support the new partner agreement features.

Since multiple packages were updated simultaneously, please ensure the new versions work well together and don't introduce any compatibility issues by running the application and testing the new partner agreement functionality.

Also applies to: 21-23, 63-64

apps/web-app/app/components/modal/UpdatePartnerAgreement.vue (2)

1-11: LGTM! Clean modal template implementation.

The template correctly sets up the modal structure with proper event handling. The form receives the required agreementId prop and both submitted and success events appropriately close the modal overlay.


13-19: Well-structured script setup.

The TypeScript prop definition is correct and the overlay composable usage follows established patterns. The implementation is clean and minimal.

apps/web-app/app/pages/partner/[id]/legal.vue (1)

11-21: Script implementation looks good.

Proper use of composables, reactive data access through Pinia store, and correct route parameter handling. The computed property efficiently finds the partner by ID.

apps/web-app/app/components/form/CreatePartnerAgreement.vue (5)

3-3: Good addition of template ref.

The form template ref enables programmatic access to the form instance, which is properly utilized in the watchers for clearing validation errors.


31-33: Appropriate change to make end date optional.

Making the end date field optional is logical since agreements may not always have predetermined end dates.


136-136: Good use of template ref for form access.

The template ref correctly provides access to the form instance for programmatic operations.


160-162: Excellent addition of form clearing on date changes.

Clearing form validation when dates change prevents stale validation errors and improves user experience. The optional chaining provides safety.

Also applies to: 167-169


48-52: Validation Schema Alignment Confirmed

The UI’s required fields now match the createPartnerAgreementSchema:

  • internalId: required
  • royalty: required
  • minRoyaltyPerMonth: required
  • lumpSumPayment: required

No further changes needed.

apps/web-app/app/pages/partner/[id]/agreement.vue (2)

19-34: Well-structured script setup.

Proper use of composables, clean modal creation through overlay system, and correct page title configuration. The implementation follows established patterns.


8-15: Null handling in CreatePartnerAgreement modal verified

The CreatePartnerAgreement.vue component defines both partnerId and legalEntityId as optional props and uses the ?? '' fallback when binding them to the <FormCreatePartnerAgreement>:

File: apps/web-app/app/components/modal/CreatePartnerAgreement.vue

<FormCreatePartnerAgreement
  :partner-id="partnerId ?? ''"
  :legal-entity-id="legalEntityId ?? ''"
  …
/>

This ensures that if either ID is undefined or null, an empty string is passed instead, and the modal handles missing values gracefully.

apps/web-app/server/api/partner/agreement/id/[agreementId]/index.patch.ts (4)

9-16: Proper parameter validation.

Correct validation of the required agreementId parameter with appropriate error handling and status code.


17-22: Correct body validation implementation.

Proper use of the updatePartnerAgreementSchema for request validation with appropriate arktype error handling. The optional fields in the schema are well-suited for PATCH operations.


23-31: Excellent database operation pattern.

Good practice to verify the agreement exists before updating, with appropriate error handling. The repository pattern usage is correct and the flow is secure.


33-39: Clean response and error handling.

Simple but adequate success response for a PATCH operation. Good use of centralized error handling with errorResolver.

packages/database/src/repository/partner.ts (2)

16-20: LGTM: Well-structured repository method

The findAgreement method follows the established pattern and correctly uses the database query API with proper typing.


63-70: LGTM: Consistent update method implementation

The updateAgreement method follows the same pattern as the existing update method, properly handling partial updates with correct typing and returning the updated record.

apps/web-app/app/components/PartnerAgreementCard.vue (2)

2-2: LGTM: Good refactoring to single-purpose component

The component is now focused on displaying and updating agreements, with the click handler properly opening the update modal. The prop simplification to require a non-null agreement makes the component's contract clearer.


66-68: Good fix for negative progress values

The update to prevent negative progress values by returning zero when the calculated result is negative is a good defensive programming practice.

apps/web-app/app/components/form/UpdatePartnerAgreement.vue (3)

1-73: LGTM: Well-structured form component

The form implementation follows Vue best practices with proper validation, state management, and event handling. The use of toast notifications and internationalization enhances the user experience.


89-100: Good state initialization from existing agreement data

The state initialization properly extracts values from the existing agreement, with appropriate handling of nullable fields using nullish coalescing for the comment field.


102-120: Robust error handling and user feedback

The submit handler includes proper error handling with try/catch, user feedback through toast notifications, and appropriate event emission. The store update after successful submission ensures data consistency.

Comment thread apps/web-app/app/pages/partner/[id].vue Outdated
Comment thread apps/web-app/app/pages/partner/[id]/legal.vue Outdated

export default defineEventHandler(async (event) => {
try {
// await hasPermission(event, 'product:edit')
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Critical: Missing authorization check.

The commented out permission check await hasPermission(event, 'product:edit') suggests this endpoint should have authorization. Partner agreement updates are sensitive operations that require proper access control.

Uncomment and implement the permission check:

-    // await hasPermission(event, 'product:edit')
+    await hasPermission(event, 'product:edit')

Or implement appropriate authorization for agreement updates.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
// await hasPermission(event, 'product:edit')
await hasPermission(event, 'product:edit')
🤖 Prompt for AI Agents
In apps/web-app/server/api/partner/agreement/id/[agreementId]/index.patch.ts at
line 7, the authorization check using hasPermission is commented out, leaving
the endpoint unprotected. Uncomment the line with await hasPermission(event,
'product:edit') to enforce permission checks before proceeding with the update.
Ensure this check runs early in the handler to prevent unauthorized access to
partner agreement updates.

@sonarqubecloud
Copy link
Copy Markdown

@hmbanan666 hmbanan666 merged commit 78de34c into main Jul 24, 2025
8 checks passed
@hmbanan666 hmbanan666 deleted the agreement branch July 24, 2025 11:58
@coderabbitai coderabbitai Bot mentioned this pull request Jul 24, 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.

1 participant