-
Notifications
You must be signed in to change notification settings - Fork 2.8k
Add changeHistoryLog #3010
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
Add changeHistoryLog #3010
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@coderabbitai full review |
WalkthroughAdds partner profile change history tracking: new Zod schema, a JSON Changes
Sequence Diagram(s)sequenceDiagram
participant U as User
participant A as update-partner-profile
participant DB as Database
participant S as Stripe API
U->>A: Submit partner update (country/profileType)
A->>A: Compare incoming vs stored country/profileType
alt No country/profileType change
A->>DB: Update other fields (no history, keep stripeConnectId)
DB-->>A: OK
else country/profileType changed
A->>A: Append change entries to changeHistoryLog (from/to + changedAt)
alt Payouts enabled
A->>S: Delete Stripe Connect account (if exists)
S-->>A: Deleted/OK
A->>DB: Update partner: set stripeConnectId = null + persist changeHistoryLog
else Payouts not enabled
A->>DB: Update partner: persist changeHistoryLog (stripeConnectId unchanged)
end
DB-->>A: Updated
end
A-->>U: Response (updated partner)
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes
Possibly related PRs
Suggested reviewers
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning)
✅ Passed checks (2 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
📜 Recent review detailsConfiguration used: CodeRabbit UI Review profile: CHILL Plan: Pro 📒 Files selected for processing (3)
🚧 Files skipped from review as they are similar to previous changes (2)
🔇 Additional comments (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. Comment |
✅ Actions performedFull review triggered. |
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 (1)
apps/web/lib/zod/schemas/partner-profile.ts (1)
177-192: Use discriminatedUnion and strict objects for faster, safer parsing.Current union works; a discriminated union on field improves inference and performance and .strict() prevents stray keys. Optional: default to [].
Apply:
-export const partnerProfileChangeHistoryLogSchema = z.array( - z.union([ - z.object({ - field: z.literal("country"), - from: z.string().nullable(), - to: z.string().nullable(), - changedAt: z.coerce.date(), - }), - z.object({ - field: z.literal("profileType"), - from: z.nativeEnum(PartnerProfileType), - to: z.nativeEnum(PartnerProfileType), - changedAt: z.coerce.date(), - }), - ]), -); +export const partnerProfileChangeHistoryLogSchema = z + .array( + z.discriminatedUnion("field", [ + z + .object({ + field: z.literal("country"), + from: z.string().nullable(), + to: z.string().nullable(), + changedAt: z.coerce.date(), + }) + .strict(), + z + .object({ + field: z.literal("profileType"), + from: z.nativeEnum(PartnerProfileType), + to: z.nativeEnum(PartnerProfileType), + changedAt: z.coerce.date(), + }) + .strict(), + ]), + ) + .default([]);
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/web/lib/actions/partners/update-partner-profile.ts(2 hunks)apps/web/lib/zod/schemas/partner-profile.ts(2 hunks)packages/prisma/schema/partner.prisma(1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
apps/web/lib/zod/schemas/partner-profile.ts (1)
packages/prisma/client.ts (1)
PartnerProfileType(22-22)
apps/web/lib/actions/partners/update-partner-profile.ts (3)
apps/web/lib/zod/schemas/partner-profile.ts (1)
partnerProfileChangeHistoryLogSchema(177-192)apps/web/lib/stripe/index.ts (1)
stripe(4-10)packages/prisma/index.ts (1)
prisma(3-9)
⏰ 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 (3)
apps/web/lib/zod/schemas/partner-profile.ts (1)
7-7: LGTM on import.apps/web/lib/actions/partners/update-partner-profile.ts (1)
8-9: LGTM on new imports.packages/prisma/schema/partner.prisma (1)
61-61: Verify db push is used for schema deployment.The schema field
changeHistoryLog Json?is defined and will be deployed viaprisma db push(no separate migration file needed in this project's architecture). Code properly validates and uses it withpartnerProfileChangeHistoryLogSchema, initializing as empty array for existing partners. No backfill script required since the field is optional.However, confirm the schema change will be applied by running
pnpm run pushin the prisma package before deployment. The architectural suggestions in the original comment (dedicated table vs JSON, retention caps) remain valid considerations for future scale.
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
♻️ Duplicate comments (2)
apps/web/lib/actions/partners/update-partner-profile.ts (2)
279-282: Parse defensively to avoid crashes on malformed JSON.Switch to safeParse with fallback to [] to avoid throwing if the stored JSON is malformed. This was already suggested in earlier feedback.
283-290: Null-safe assignment for country “to”.Use
input.country ?? nullinstead of a string assertion. This matches the schema’s.nullable()and avoids incorrect typing. Previously noted; echoing for completeness.- to: input.country as string, + to: input.country ?? null,
🧹 Nitpick comments (3)
packages/prisma/schema/partner.prisma (1)
61-61: Consider defaulting JSON and/or making it non-null.To reduce null checks and parsing pitfalls, consider storing an empty array by default and making this non-null (DB default jsonb '[]', then NOT NULL). If you prefer keeping it nullable, ensure all reads use safeParse with fallback.
apps/web/lib/zod/schemas/partner-profile.ts (1)
177-192: Use discriminated union and export the type.Improves inference and narrowing; keeps shape explicit.
-export const partnerProfileChangeHistoryLogSchema = z.array( - z.union([ - z.object({ - field: z.literal("country"), - from: z.string().nullable(), - to: z.string().nullable(), - changedAt: z.coerce.date(), - }), - z.object({ - field: z.literal("profileType"), - from: z.nativeEnum(PartnerProfileType), - to: z.nativeEnum(PartnerProfileType), - changedAt: z.coerce.date(), - }), - ]), -); +export const partnerProfileChangeHistoryLogSchema = z.array( + z.discriminatedUnion("field", [ + z.object({ + field: z.literal("country"), + from: z.string().nullable(), + to: z.string().nullable(), + changedAt: z.coerce.date(), + }), + z.object({ + field: z.literal("profileType"), + from: z.nativeEnum(PartnerProfileType), + to: z.nativeEnum(PartnerProfileType), + changedAt: z.coerce.date(), + }), + ]), +); + +export type PartnerProfileChangeHistoryLog = z.infer< + typeof partnerProfileChangeHistoryLogSchema +>;apps/web/lib/actions/partners/update-partner-profile.ts (1)
301-314: Reorder DB update before Stripe deletion; make deletion idempotent and async.Avoid inconsistent audit/state if the later update fails, and don’t fail the entire action on already-deleted accounts.
- if (partner.stripeConnectId) { - await stripe.accounts.del(partner.stripeConnectId); - } - - await prisma.partner.update({ + // First persist app state + history + await prisma.partner.update({ where: { id: partner.id, }, data: { stripeConnectId: null, changeHistoryLog: partnerChangeHistoryLog, }, }); + + // Then delete the Stripe account best-effort (idempotent) + if (partner.stripeConnectId) { + waitUntil( + (async () => { + try { + await stripe.accounts.del(partner.stripeConnectId!); + } catch (err: any) { + // Treat not found as success; rethrow others + const code = err?.statusCode ?? err?.raw?.statusCode; + if (code !== 404) throw err; + } + })(), + ); + }Optional: cap history length to prevent unbounded growth.
- if (countryChanged) { + if (countryChanged) { partnerChangeHistoryLog.push({ /* ... */ }); + // keep last 100 + if (partnerChangeHistoryLog.length > 100) { + partnerChangeHistoryLog.splice(0, partnerChangeHistoryLog.length - 100); + } }If you prefer stronger consistency, wrap a re-read/merge in a short transaction to avoid lost updates when multiple writers appear in the future. I can provide a transactional snippet if useful.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
apps/web/lib/actions/partners/update-partner-profile.ts(2 hunks)apps/web/lib/zod/schemas/partner-profile.ts(2 hunks)packages/prisma/schema/partner.prisma(1 hunks)
🔇 Additional comments (4)
apps/web/lib/zod/schemas/partner-profile.ts (1)
7-7: LGTM — needed enum import.apps/web/lib/actions/partners/update-partner-profile.ts (3)
8-10: LGTM — imports are appropriate.
268-270: Good early exit. Prevents unnecessary work when no compliance fields changed.
272-276: Guard is correct. Clear message and early block when payouts already enabled.
Summary by CodeRabbit