feat: update agreement action#16
Conversation
WalkthroughThis 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
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
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
Note ⚡️ Unit Test Generation is now available in beta!Learn more here, or try it out under "Finishing Touches" below. 📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
⏰ 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)
✨ Finishing Touches🧪 Generate unit tests
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed 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)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Review the following changes in direct dependencies. Learn more about Socket for GitHub. |
There was a problem hiding this comment.
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
marketingFeeandminMarketingFeePerMonthfields 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
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis 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
agreementIdprop and bothsubmittedandsuccessevents 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 ConfirmedThe UI’s required fields now match the
createPartnerAgreementSchema:
internalId: requiredroyalty: requiredminRoyaltyPerMonth: requiredlumpSumPayment: requiredNo 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 verifiedThe
CreatePartnerAgreement.vuecomponent defines bothpartnerIdandlegalEntityIdas 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
undefinedornull, 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
agreementIdparameter with appropriate error handling and status code.
17-22: Correct body validation implementation.Proper use of the
updatePartnerAgreementSchemafor 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 methodThe
findAgreementmethod follows the established pattern and correctly uses the database query API with proper typing.
63-70: LGTM: Consistent update method implementationThe
updateAgreementmethod follows the same pattern as the existingupdatemethod, 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 componentThe 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 valuesThe 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 componentThe 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 dataThe 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 feedbackThe 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.
|
|
||
| export default defineEventHandler(async (event) => { | ||
| try { | ||
| // await hasPermission(event, 'product:edit') |
There was a problem hiding this comment.
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.
| // 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.
|



Summary by CodeRabbit
New Features
Improvements
Bug Fixes
Localization
Chores