Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Pull request overview
This PR transitions the membership renewal system from a calendar year-based model to a rolling 12-month model where memberships expire one year from the purchase date. The change aligns with a constitutional amendment mentioned in the updated email template, which becomes effective from 2026.
Key changes:
- Adds
membership_expirytimestamp field to the User schema and generates corresponding database migration - Updates payment and admin flows to set membership expiry dates when users become members
- Modifies user-facing text to reflect "one year from now" instead of "31st Dec {year}"
- Adjusts cron job schedules for membership renewal reminders (from 15:59 to 03:00 UTC)
- Adds new path alias
@/*to tsconfig.json and updates imports across multiple files - Improves error handling in payment components with user-friendly toast notifications
Reviewed changes
Copilot reviewed 29 out of 32 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/server/db/schema.ts | Adds membership_expiry timestamp field to User table |
| src/server/db/migrations/0005_daffy_victor_mancha.sql | Migration script to add membership_expiry column |
| src/server/db/migrations/meta/_journal.json | Migration journal entry for the new migration |
| src/server/db/migrations/meta/0005_snapshot.json | Complete schema snapshot including the new membership_expiry field |
| src/server/api/routers/payments/pay.ts | Sets membership_expiry to one year from payment date when user pays |
| src/server/api/routers/admin/users/update-role.ts | Sets membership_expiry when admin assigns "member" role |
| src/app/dashboard/admin/@users/table.tsx | Displays membership expiry date in admin user table with visual indicator for expired memberships |
| src/components/email-template.tsx | Updates renewal reminder email with hardcoded 2025 year and constitutional amendment notice |
| src/app/profile/[id]/profile.tsx | Changes membership description from calendar-year to rolling year |
| src/app/create-account/page.tsx | Updates payment description text for new membership model |
| src/app/create-account/payment.tsx | Updates payment description text for new membership model |
| src/app/create-account/loading.tsx | Updates loading page payment description text |
| src/components/payment/online/index.tsx | Improves error handling with toast notifications and better type checking |
| src/components/payment/online/saved-cards.tsx | Fixes TypeScript type assertion for TokenResult |
| src/components/payment/online/card.tsx | Improves error checking with type guard for result.errors |
| src/components/payment/online/google-pay.tsx | Improves error checking with type guard for result.errors |
| src/components/payment/online/apple-pay.tsx | Improves error checking with type guard for result.errors |
| src/server/api/routers/users/update.ts | Removes completed TODO comment |
| vercel.json | Changes cron schedule timing from 15:59 to 03:00 UTC |
| tsconfig.json | Adds @/* path alias pointing to project root, removes baseUrl |
| src/app/projects/[id]/page.tsx | Updates import to use new @/ alias |
| src/app/projects/(default)/page.tsx | Updates import to use new @/ alias |
| src/app/hack-for-homes/sponsors.tsx | Updates import to use new @/ alias |
| src/app/hack-for-homes/participants/page.tsx | Updates import to use new @/ alias |
| src/app/hack-for-homes/agenda/page.tsx | Updates import to use new @/ alias |
| src/app/events/page.tsx | Updates import to use new @/ alias |
| src/app/about/sponsors.tsx | Updates import to use new @/ alias |
| src/app/about/committee.tsx | Updates import to use new @/ alias |
| src/app/about/clients.tsx | Updates import to use new @/ alias |
| declarations.d.ts | Adds module declaration for CSS files |
| README.md | Adds database migration commands documentation |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| await ctx.db.update(User).set({ role: "member" }).where(eq(User.id, currentUser.id)) | ||
|
|
||
| await ctx.db | ||
| .update(User) | ||
| .set({ membership_expiry: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }) |
There was a problem hiding this comment.
The two database update operations for the same user should be combined into a single update statement. This is more efficient and reduces the number of database round trips. Consider merging both updates into one:
await ctx.db.update(User).set({ role: "member", membership_expiry: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }).where(eq(User.id, currentUser.id))
| await ctx.db.update(User).set({ role: "member" }).where(eq(User.id, currentUser.id)) | |
| await ctx.db | |
| .update(User) | |
| .set({ membership_expiry: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }) | |
| await ctx.db | |
| .update(User) | |
| .set({ | |
| role: "member", | |
| membership_expiry: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000), | |
| }) |
| <Text style={text}>Hi {Firstname},</Text> | ||
| <Text style={text}> | ||
| {`Your membership of Coders for Causes ends on 31st Dec ${year}. To keep your membership active, please renew it by clicking the button below.`} | ||
| {`Your membership of Coders for Causes ends on 31st Dec 2025. To keep your membership active, please renew it by clicking the button below.`} |
There was a problem hiding this comment.
The hardcoded year "2025" in the email template will become outdated after December 31, 2025. Since this is a reminder email that will be sent annually, the year should be dynamic. Consider using a prop or computing it dynamically based on the user's membership expiry date to ensure the email remains accurate in future years.
|
|
||
| await ctx.db | ||
| .update(User) | ||
| .set({ membership_expiry: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }) |
There was a problem hiding this comment.
The membership expiry calculation using 365 * 24 * 60 * 60 * 1000 does not account for leap years, which will result in a membership expiring approximately one day earlier than expected every four years. Consider using a more accurate date calculation method such as using the date-fns library's addYears() function or accounting for the actual calendar year.
| if (input.role === "member") { | ||
| await ctx.db | ||
| .update(User) | ||
| .set({ membership_expiry: new Date(Date.now() + 365 * 24 * 60 * 60 * 1000) }) |
There was a problem hiding this comment.
The membership expiry calculation using 365 * 24 * 60 * 60 * 1000 does not account for leap years, which will result in a membership expiring approximately one day earlier than expected every four years. Consider using a more accurate date calculation method such as using the date-fns library's addYears() function or accounting for the actual calendar year.
src/app/create-account/payment.tsx
Outdated
| Become a paying member of Coders for Causes for just $5 a year (ends on 31st Dec{" "} | ||
| {new Date().getFullYear()} | ||
| ). There are many benefits to becoming a member which include: | ||
| Become a paying member of Coders for Causes for just $5 a year (ends one year from now ). There are many |
There was a problem hiding this comment.
The extra space before the closing parenthesis in "ends one year from now )" should be removed for consistency and proper formatting.
| Become a paying member of Coders for Causes for just $5 a year (ends one year from now ). There are many | |
| Become a paying member of Coders for Causes for just $5 a year (ends one year from now). There are many |
Change Summary
[Briefly summarise the changes that you made. Just high-level stuff]
Change Form
Fill this up (NA if not available). If a certain criteria is not met, can you please give a reason.
Other Information
[Is there anything in particular in the review that I should be aware of?]