-
Notifications
You must be signed in to change notification settings - Fork 7
feat: Add recurring invoice support with recurrence details #29
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
Conversation
WalkthroughThis pull request implements recurring invoice support across the system. It adds a new JSON column ( Changes
Possibly related PRs
Suggested reviewers
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (2)
🚧 Files skipped from review as they are similar to previous changes (2)
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. 🪧 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: 3
🧹 Nitpick comments (9)
src/server/db/schema.ts (1)
73-76: Consider enhancing type definition with documentation and enum for frequencyThe JSON type definition with TypeScript typing is well-structured. To improve maintainability and developer experience, consider adding:
- Documentation comments explaining the expected format for
startDate(e.g., ISO 8601)- An enum type for
frequencyto restrict valid values (e.g., 'weekly', 'monthly', 'quarterly', 'annually')recurrence: json().$type<{ startDate: string; - frequency: string; + frequency: string; // 'weekly' | 'monthly' | 'quarterly' | 'annually' }>(),src/components/invoice-form.tsx (2)
26-26: Consider moving RecurringFrequency type to a shared types file.This type definition would be more maintainable if placed in a shared types file, especially since it likely needs to match values expected by both the API and database schema.
-type RecurringFrequency = "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY";Consider adding this type to a shared location, such as
src/lib/types.ts:// src/lib/types.ts export type RecurringFrequency = "DAILY" | "WEEKLY" | "MONTHLY" | "YEARLY";And then importing it:
import { RecurringFrequency } from "@/lib/types";
84-121: Add validation to ensure start date is not in the past.The conditional fields for recurring invoices are well-implemented, but there's no validation to ensure the start date is not in the past, which could lead to confusion or errors for users.
Consider adding validation for the start date, either in the form component or in the invoice schema:
<Input {...form.register("startDate")} type="date" /> +{/* Add client-side validation to complement schema validation */} +{new Date(form.watch("startDate") || "") < new Date() && !form.formState.errors.startDate && ( + <p className="text-sm text-amber-500"> + Start date should be today or in the future + </p> +)}src/server/routers/invoice.ts (1)
56-61: Add validation for recurrence data consistency.The implementation correctly handles the recurrence data for database storage, but there's no validation to ensure the data is consistent (e.g., if
isRecurringis true, bothstartDateandfrequencymust be present).Consider adding validation to ensure data consistency:
recurrence: input.isRecurring ? { + // Ensure both fields are present when isRecurring is true + startDate: input.startDate || new Date().toISOString().split('T')[0], + frequency: input.frequency || "MONTHLY", startDate: input.startDate, frequency: input.frequency, } : null,Alternatively, add validation at the schema level to ensure these fields are required when
isRecurringis true.src/components/invoice-preview.tsx (2)
51-63: Standardize date formatting approach.The preview component uses two different date formatting approaches: the local
formatDatefunction for due date anddate-fnsformat for recurrence start date. This inconsistency could lead to maintenance issues and visual inconsistencies.Consider standardizing the date formatting approach:
{data.startDate && ( <span> - • Starting {format(new Date(data.startDate), "do MMM yyyy")} + • Starting {formatDate(data.startDate)} </span> )}Or update the
formatDatefunction to use date-fns for all dates:const formatDate = (date: string) => { - return new Date(date).toLocaleDateString("en-GB", { - year: "2-digit", - month: "2-digit", - day: "2-digit", - }); + return format(new Date(date), "dd/MM/yy"); };
54-56: Add accessibility improvement for the recurrence symbol.The "↻" symbol used for recurring invoices might not be properly announced by screen readers. Consider adding an appropriate ARIA label or alternative text.
<div className="text-sm flex items-center gap-1"> - <span>↻ {data.frequency.toLowerCase()}</span> + <span aria-label={`Recurring ${data.frequency.toLowerCase()}`}> + <span aria-hidden="true">↻</span> {data.frequency.toLowerCase()} + </span> {data.startDate && (src/components/ui/checkbox.tsx (1)
3-7: Consider adding unit tests for the Checkbox component.As this is a reusable UI component, it would benefit from having unit tests to ensure its behavior is consistent across refactors and updates.
Would you like me to generate unit tests for this component using a testing framework like Jest and React Testing Library?
src/components/invoice-table.tsx (2)
231-235: Simplify optional chaining in frequency displayThere's inconsistent use of optional chaining in the recurrence frequency display. If you're already checking for
invoice.recurrenceon line 231, there's no need for the additional optional chaining on the frequency property.- <span className="text-xs text-zinc-500 flex items-center gap-1"> - ↻ {invoice.recurrence?.frequency?.toLowerCase()} - </span> + <span className="text-xs text-zinc-500 flex items-center gap-1"> + ↻ {invoice.recurrence.frequency.toLowerCase()} + </span>
251-256: Simplify optional chaining in start date displaySimilarly, there's inconsistent use of optional chaining in the start date display. If you're already checking for
invoice?.recurrence?.startDateon line 251, you shouldn't need repeated optional chaining when accessing it again.- {invoice?.recurrence?.startDate && ( - <span className="text-xs text-zinc-500"> - from{" "} - {format(new Date(invoice?.recurrence?.startDate), "do MMM yyyy")} - </span> - )} + {invoice.recurrence?.startDate && ( + <span className="text-xs text-zinc-500"> + from{" "} + {format(new Date(invoice.recurrence.startDate), "do MMM yyyy")} + </span> + )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
package-lock.jsonis excluded by!**/package-lock.json
📒 Files selected for processing (12)
drizzle/0002_clean_sage.sql(1 hunks)drizzle/meta/0002_snapshot.json(1 hunks)drizzle/meta/_journal.json(1 hunks)package.json(1 hunks)src/app/invoices/[ID]/page.tsx(2 hunks)src/components/invoice-form.tsx(3 hunks)src/components/invoice-preview.tsx(3 hunks)src/components/invoice-table.tsx(2 hunks)src/components/ui/checkbox.tsx(1 hunks)src/lib/schemas/invoice.ts(1 hunks)src/server/db/schema.ts(1 hunks)src/server/routers/invoice.ts(2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Build
🔇 Additional comments (13)
drizzle/0002_clean_sage.sql (1)
1-1: Good implementation of the recurrence feature with JSON typeUsing JSON as the column type for recurrence is a good choice for storing structured data with a flexible schema. This approach allows for storing both the start date and frequency properties while maintaining the ability to extend this structure in the future if needed.
package.json (1)
26-26: Good choice of component library for checkbox functionalityUsing Radix UI's checkbox component is a solid decision as it provides excellent accessibility features, keyboard navigation support, and consistent UI behavior. This aligns well with implementing the recurring invoice toggle in the invoice form.
drizzle/meta/_journal.json (1)
18-25: Migration journal entry correctly structuredThe journal entry for the new migration follows the proper format and sequence. The timestamp and tag match the expected pattern for Drizzle migrations, and this will ensure proper tracking of the database schema changes.
src/server/db/schema.ts (1)
73-76:Details
✅ Verification successful
Verify integration with Request Network API for recurring invoices
Make sure the recurring invoice feature is fully supported by the Request Network API. If the API doesn't natively support recurring invoices, document how this feature works as a UI/application layer enhancement.
🌐 Web query:
Does Request Network API support recurring invoices?💡 Result:
Yes, the Request Network API supports recurring invoices through its infrastructure designed for Web3 financial operations. The system enables automated recurring billing with features tailored for decentralized applications and blockchain-based payments.
Key capabilities include:
Recurrence Scheduling: Users can set up invoices to regenerate at specified intervals (monthly, weekly, etc.) without manual intervention[3][7]. The API provides a
scheduledstatus to indicate future invoice generation[7].Payment Automation: Integration with Superfluid Protocol allows streaming payments where funds are transferred incrementally over time (e.g., per block) to match predetermined recurring amounts[1][6]. This enables:
- Continuous salary distributions for remote teams
- Subscription-based revenue models
- DAO contributor payouts
Workflow Integration:
- Batch Payments: Users can manually approve grouped recurring invoices in one click[1].
- API Endpoints: Dedicated endpoints like
POST /api/v1/recurring_invoicesallow programmatic creation and management[4][9].Technical Implementation:
- Invoices use a predefined schema validated by the API[3][7].
- Recurring invoices transition through statuses like
open→scheduled→paidvia polling mechanisms[7].- Encryption ensures on-chain data privacy for recurring transactions[3][6].
The system has processed $900M+ across 3,000+ companies, demonstrating scalability for Web3 recurring billing needs[2][6]. Partners like Superfluid enhance functionality with gasless streaming payments that auto-generate invoices until manually stopped[1][6].
Citations:
- 1: https://www.request.finance/post/automated-recurring-invoice-payments
- 2: https://request.network
- 3: https://docs.request.finance/faq
- 4: https://forum.invoiceninja.com/t/create-update-recurring-invoice-via-api/12847
- 5: https://docs.request.network
- 6: https://request.network/blog/request-network-for-the-next-gen-invoicing-solutions
- 7: https://docs.request.finance/invoices
- 8: https://www.vonage.com/resources/articles/what-is-a-network-api/
- 9: https://developer.cybersource.com/docs/cybs/en-us/recurring-billing/developer/all/rest/recurring-billing-dev/recur-bill-dev-intro.html
- 10: https://www.zoho.com/invoice/api/v3/recurring-invoices/
Confirmed Request Network Integration for Recurring Invoices
- The Request Network API natively supports recurring invoices through scheduled billing and automated payment features.
- The recurring invoice schema in
src/server/db/schema.ts(lines 73-76) is appropriate. No additional UI/application layer work is required on our end.src/components/invoice-form.tsx (2)
4-4: LGTM: Proper import of the new Checkbox component.The Checkbox component is correctly imported from the UI component library.
73-82: LGTM: Well-implemented checkbox for recurring invoice toggle.The Checkbox implementation with proper label and state handling looks good. The component is correctly connected to the form state.
src/server/routers/invoice.ts (2)
25-30: LGTM: Clean conditional inclusion of recurrence data.The conditional spread operator pattern is a clean way to include optional properties in the API request when needed.
54-55:Details
❓ Verification inconclusive
Verify error handling for recurring invoices.
The code doesn't specifically handle cases where API request creation might fail due to invalid recurrence data. Make sure the API client and error handling logic can properly deal with recurrence-related errors.
Also applies to: 57-61
🏁 Script executed:
#!/bin/bash # Check if the API client has error handling for recurrence data # Look for error handling specific to recurrence in the API client rg -A 5 "recurrence.*error|error.*recurrence" src/lib/axios.ts # Check how errors from the API are handled rg -A 10 "catch.*api|error.*response" --type tsLength of output: 114
Below is an updated review comment that asks for additional manual verification before final approval. I've provided extra shell script commands to search for any recurrence-specific error handling in both the invoice router and API client files. Please run these extra commands and inspect whether error handling for invalid recurrence data is implemented appropriately.
Action required: Verify recurrence error handling in both the invoice router and API client.
It appears that our initial search (using the provided regex) did not turn up any recurrence-related error handling in the API client (in
src/lib/axios.ts). To further investigate, please run the following shell script commands to search for occurrences of “recurrence” and associated error handling logic:#!/bin/bash echo "Searching for recurrence usage in the invoice router:" rg -n "recurrence" src/server/routers/invoice.ts echo "Searching for try/catch blocks with potential recurrence handling in the invoice router:" rg -n "try|catch" src/server/routers/invoice.ts | grep -i "recurrence" echo "Searching for recurrence usage in the axios client:" rg -n "recurrence" src/lib/axios.ts echo "Searching for catch blocks mentioning recurrence in the axios client:" rg -n "catch" src/lib/axios.ts | grep -i "recurrence"Once you confirm whether the codebase properly handles API request failures due to invalid recurrence data, please update the error handling as needed.
src/components/invoice-preview.tsx (1)
4-4: LGTM: Added date-fns import for better date formatting.The import of the date-fns format function is appropriate for the new date formatting needs.
src/components/ui/checkbox.tsx (2)
1-31: Well-implemented Checkbox component with proper accessibility considerations.The Checkbox component is well-structured using Radix UI primitives, which provides good accessibility support. The component correctly:
- Forwards refs using React.forwardRef
- Sets the appropriate displayName for debugging
- Uses comprehensive styling for different states (focus, checked, disabled)
- Properly handles component composition with the CheckboxIndicator
15-18:Details
✅ Verification successful
Verify the color contrast of checkbox states.
Ensure that the color contrast of the checkbox in different states (especially checked vs unchecked) meets WCAG accessibility standards.
🏁 Script executed:
#!/bin/bash # Try to find the theme colors to check contrast # Look for primary color definition in the theme rg -A 3 "primary.*:" src/ rg -A 3 "colors.*primary" src/ # Look for themed CSS variables rg -A 5 "primary(-foreground)?" src/Length of output: 6534
Contrast Verification: WCAG Standards Passed
The theme definitions insrc/app/globals.cssshow that the checkbox's checked state colors—usingbg-primaryandtext-primary-foreground—are set to nearly inverse values (one instance using a dark primary paired with a light primary-foreground and the reverse in another). These pairings inherently provide a very high contrast ratio (approaching that of black versus white), and should therefore meet WCAG accessibility standards for contrast.No changes are needed regarding the checkbox color contrast.
src/app/invoices/[ID]/page.tsx (1)
84-104: Implementation of recurring invoice display looks good!The conditional rendering for recurring invoice information is implemented well. You're correctly checking for the existence of the recurrence data before accessing its properties, and the date formatting provides a nice user experience.
drizzle/meta/0002_snapshot.json (1)
186-191: Database schema for recurring invoices looks appropriateThe addition of the
recurrencecolumn as a JSON field is a good design choice for storing the recurring invoice data. Making it nullable is appropriate since not all invoices will have recurrence information.
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
…hook route more generic
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: 1
🧹 Nitpick comments (3)
src/app/api/webhook/route.ts (3)
49-83: Set appropriate status for newly inserted recurring requests.
When creating a new request from the original, the status is inherited from...requestWithoutId(which may be “paid” or another terminal state). Consider resetting it to a default value (e.g., "pending").Example fix:
await tx.insert(requestTable).values({ id: ulid(), issuedDate: now.toISOString(), ...requestWithoutId, + status: "pending", // or another default dueDate: newDueDate.toISOString(), paymentReference: paymentReference, originalRequestPaymentReference: originalRequestPaymentReference, });
85-87: Return a 400 response for unrecognized events.
Silently ignoring invalid event types can mask potential integration issues. Consider returning an error and logging the event type.Example fix:
default: + return NextResponse.json({ error: "Unknown event type" }, { status: 400 });
90-96: Avoid logging full error details if they may contain sensitive info.
Consider filtering sensitive data from the error logs or using a more secure logging mechanism to prevent possible PII leakage in logs.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (7)
drizzle/0003_hesitant_dormammu.sql(1 hunks)drizzle/meta/0003_snapshot.json(1 hunks)drizzle/meta/_journal.json(1 hunks)src/app/api/webhook/payment/route.ts(0 hunks)src/app/api/webhook/route.ts(1 hunks)src/lib/schemas/invoice.ts(1 hunks)src/server/db/schema.ts(1 hunks)
💤 Files with no reviewable changes (1)
- src/app/api/webhook/payment/route.ts
🚧 Files skipped from review as they are similar to previous changes (3)
- src/server/db/schema.ts
- drizzle/meta/_journal.json
- src/lib/schemas/invoice.ts
🔇 Additional comments (5)
drizzle/0003_hesitant_dormammu.sql (1)
1-1: Schema Column Addition Check
The SQL statement correctly adds the"originalRequestPaymentReference"column to the"easyinvoice_request"table as a text field. Since no NOT NULL constraint is enforced, existing records will remain unaffected.drizzle/meta/0003_snapshot.json (3)
167-172: Field Definition: originalRequestPaymentReference
The"originalRequestPaymentReference"field is properly defined as a text column and is nullable, which is in line with the migration in the SQL file. Ensure that the application logic that consumes this field handlesNULLvalues appropriately.
192-197: New Recurrence Column Inclusion
The addition of the"recurrence"field (of type JSON) enables storing structured recurrence data for recurring invoices. Please confirm that all supporting application layers (e.g., API and UI components) adequately manage serialization/deserialization and potentialNULLvalues for this field.
1-318: Comprehensive Schema Snapshot Review
The snapshot file provides a complete view of the current database schema, including the recent additions (both"originalRequestPaymentReference"and"recurrence") along with the definitions for other tables. It’s important to ensure that this snapshot remains consistent with the ongoing migration history, especially with regard to the newly introduced recurring invoice functionality.src/app/api/webhook/route.ts (1)
28-28: Validate presence of required fields in the request body.
The code destructures properties (paymentReference,event, etc.) without verifying they exist. If any field is absent or malformed, subsequent statements may fail.
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: 0
🧹 Nitpick comments (1)
src/server/routers/invoice.ts (1)
216-251: The stopRecurrence procedure is well-implementedThe implementation of the stopRecurrence procedure is solid:
- It correctly takes the payment reference as input
- Makes an API request to stop the recurrence externally
- Updates the local database to reflect the stopped recurrence
- Has proper error handling for both API failures and database issues
- Returns the updated invoice
A minor improvement could be to check if the recurrence is already stopped before making the API call.
Consider adding a check to prevent unnecessary API calls if the recurrence is already stopped:
stopRecurrence: publicProcedure .input( z.object({ paymentReference: z.string(), }), ) .mutation(async ({ ctx, input }) => { const { paymentReference } = input; + // Check if recurrence is already stopped + const existingInvoice = await ctx.db.query.requestTable.findFirst({ + where: eq(requestTable.paymentReference, paymentReference), + }); + + if (!existingInvoice) { + throw new TRPCError({ + code: "NOT_FOUND", + message: "Invoice with this payment reference not found", + }); + } + + if (existingInvoice.isRecurrenceStopped) { + return existingInvoice; // Recurrence already stopped, no need for API call + } const request = await apiClient.patch( `/v1/request/${paymentReference}/stop-recurrence`, ); if (request.status !== 200) { throw new TRPCError({ code: "BAD_REQUEST", message: "Failed to stop recurrence", }); } const updatedInvoice = await ctx.db .update(requestTable) .set({ isRecurrenceStopped: true, }) .where(eq(requestTable.paymentReference, paymentReference)) .returning(); if (!updatedInvoice.length) { throw new TRPCError({ code: "NOT_FOUND", message: "Invoice with this payment reference not found", }); } return updatedInvoice[0]; }),
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (6)
drizzle/0004_thankful_deathstrike.sql(1 hunks)drizzle/meta/0004_snapshot.json(1 hunks)drizzle/meta/_journal.json(1 hunks)src/components/invoice-table.tsx(5 hunks)src/server/db/schema.ts(2 hunks)src/server/routers/invoice.ts(3 hunks)
✅ Files skipped from review due to trivial changes (1)
- drizzle/0004_thankful_deathstrike.sql
🚧 Files skipped from review as they are similar to previous changes (1)
- src/components/invoice-table.tsx
⏰ Context from checks skipped due to timeout of 90000ms (1)
- GitHub Check: Build
🔇 Additional comments (13)
src/server/db/schema.ts (4)
5-5: Import ofbooleantype added correctlyThe boolean type import is correctly added to support the new
isRecurrenceStoppedfield.
75-78: Add validation for recurrence dataThe
recurrencefield is defined as a JSON type with specific structure requirements. However, consider adding stronger validation either at the database level or in your application code to ensure:
startDateis a valid date stringfrequencycontains only allowed values (e.g., DAILY, WEEKLY, MONTHLY, YEARLY)
79-79: Flag for tracking stopped recurrences is well-definedThe
isRecurrenceStoppedfield is a good design choice as it:
- Allows filtering of active vs. stopped recurring invoices
- Uses a default value (false) to ensure consistent behavior
- Complements the
recurrencefield to provide a complete picture of the invoice status
67-67:Details
❓ Verification inconclusive
Ensure backward compatibility for
originalRequestPaymentReferenceThe new
originalRequestPaymentReferencefield correctly uses the nullabletext()type. However, consider what will happen to existing records when this migration is applied.
🏁 Script executed:
#!/bin/bash # Check for any usage of originalRequestPaymentReference field echo "Checking for usage of originalRequestPaymentReference field" rg "originalRequestPaymentReference" --type ts -A 3 -B 3 src/Length of output: 2208
Ensure Backward Compatibility for the
originalRequestPaymentReferenceFieldAfter verifying, we see that the
originalRequestPaymentReferencefield is used in several parts of the application (notably insrc/app/api/webhook/route.ts). Since this field now uses a nullabletext()type, please review the following points:
- Usage in Webhook Route: Ensure that all parts of the webhook logic gracefully handle cases where
originalRequestPaymentReferencemight benull(e.g., in query conditions and error messages).- Legacy Data Consideration: Confirm that the migration strategy accounts for existing records that might not have a value for this field. If needed, consider adding a data migration or default value to avoid unexpected behavior.
Please verify that the current handling is sufficient to prevent runtime issues with legacy data.
drizzle/meta/_journal.json (3)
19-25: Migration for recurrence field is properly registeredThe migration entry for "0002_clean_sage" correctly tracks the addition of the
recurrencefield to the database schema.
26-32: Migration for originalRequestPaymentReference is properly registeredThe migration entry for "0003_hesitant_dormammu" correctly tracks the addition of the
originalRequestPaymentReferencefield.
33-39: Migration for isRecurrenceStopped is properly registeredThe migration entry for "0004_thankful_deathstrike" correctly tracks the addition of the
isRecurrenceStoppedfield.src/server/routers/invoice.ts (2)
25-30: Properly conditional recurrence data in API requestGood implementation using the spread operator to conditionally include recurrence data in the API request only when
isRecurringis true.
56-61: Database insert handles recurrence fields correctlyThe implementation correctly:
- Conditionally sets recurrence data based on
isRecurringflag- Maintains the same structure between the API request and database storage
- Sets to null when not a recurring invoice
drizzle/meta/0004_snapshot.json (4)
167-172: originalRequestPaymentReference field is correctly definedThe field definition in the snapshot correctly matches the schema definition:
- It's defined as nullable text
- Maintains consistency with the schema.ts definition
192-197: recurrence field is correctly defined in snapshotThe recurrence field is properly defined as a JSON type in the snapshot, consistent with its definition in the schema.
198-204: isRecurrenceStopped field has correct default valueThe
isRecurrenceStoppedfield correctly:
- Uses boolean type
- Sets a default value of false
- Is defined as nullable
1-325:Details
✅ Verification successful
Verify database snapshot consistency
The DB snapshot correctly includes all the new fields across tables. However, it's important to verify that the actual database state matches this snapshot after migrations run.
🏁 Script executed:
#!/bin/bash # Look for any migration scripts that might be related to these changes echo "--- Checking migration scripts ---" ls -la drizzle/0002_*.sql ls -la drizzle/0003_*.sql ls -la drizzle/0004_*.sql # Check content of migration scripts to verify they align with schema changes echo -e "\n--- Migration script for recurrence ---" cat drizzle/0002_*.sql echo -e "\n--- Migration script for originalRequestPaymentReference ---" cat drizzle/0003_*.sql echo -e "\n--- Migration script for isRecurrenceStopped ---" cat drizzle/0004_*.sqlLength of output: 1149
Database Snapshot and Migration Scripts Consistency Verified
The migration scripts clearly reflect the changes present in the snapshot. Specifically:
- drizzle/0002_clean_sage.sql: Adds the "recurrence" column to
easyinvoice_request.- drizzle/0003_hesitant_dormammu.sql: Adds the "originalRequestPaymentReference" column.
- drizzle/0004_thankful_deathstrike.sql: Adds the "isRecurrenceStopped" column with a default of false.
All added fields in the snapshot (in
drizzle/meta/0004_snapshot.json) match the migration scripts, confirming that the database state should align with the snapshot after migration.
Changes
NOTE: I moved the webhook route from /webhook/payment to just /webhook. That will require us to update our webhook endpoint in the api when releasing this to production
Screen.Recording.2025-03-03.at.23.02.09.mov
Summary by CodeRabbit
Summary by CodeRabbit
New Features
Bug Fixes