-
Notifications
You must be signed in to change notification settings - Fork 3
Feature/membership final refactor #287
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
Open
DarinHajou
wants to merge
62
commits into
dev
Choose a base branch
from
feature/membership-final-refactor
base: dev
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 60 commits
Commits
Show all changes
62 commits
Select commit
Hold shift + click to select a range
ffa6047
Implement final membership model (aligned with Haycoder’s schema)
DarinHajou ed0e258
Add IMembership to type definitions
DarinHajou 68d7a31
Move membership model file to models directory
DarinHajou 563057b
Add MembershipClassType enum for membership level
DarinHajou a85ebbd
Add membership controller and mark manageMembership as legacy
DarinHajou 9ca1bd4
Set up membership.service.ts with core logic, schema updates, and mar…
DarinHajou 32da7d5
Refactor: Rename MembershipType to MembershipClassType in membership …
DarinHajou 981ac39
Add membership.routes.ts with legacy and current endpoints + Swagger …
DarinHajou 98fe436
Add membership routes to app entry
DarinHajou 766e9b0
Create isMembershipFound middleware to check active membership by Pi UID
DarinHajou 491a0a7
Change name for membership class enum in types
DarinHajou 9a5053b
Add membership API schema definitions
DarinHajou 8235549
Add pi-backend.d.ts to resolve TS type errors
DarinHajou 124d2b4
Comment out payment logic to avoid temp errors in membership service
DarinHajou ecd7f91
Fix pi import from platformApiCLient
DarinHajou cd92a0e
Refactor platformAPIclient to export axios instance and piNetwork sep…
DarinHajou 9cc1b3e
Update tsconfig with custom typeRoots
DarinHajou fba7d48
Change file name to start with uppercase MembershipSchema.yml
DarinHajou bf8bed9
Remove exclamation marks from legacy note in swagger summary
DarinHajou 023925d
Add missing user_id and pi_uid fields to new membership creation
DarinHajou 59837c2
Add missing user_id and pi_uid fields to new membership creation
DarinHajou 587faf0
Merge branch 'feature/membership-final-refactor' of https://github.co…
DarinHajou 1754133
Refactor populate script to avoid duplicate memberships
DarinHajou d9af287
Add unique index to pi_uid in Membership schema
DarinHajou 6f84adb
Use findById instead of findOne for membership by ID
DarinHajou 523938c
Move manage membership to separate file membershipLegacy.controller.t…
DarinHajou 4fc92e5
Move manageMembership function to separate file membershipLegacy.cont…
DarinHajou b4b2033
Merge branch 'feature/membership-final-refactor' of https://github.co…
DarinHajou 9a691fb
Refactor route /manage to legacy membership controller for non-paymen…
DarinHajou 51310e7
Move addOrUpdateMembership to separate file membershipLegacy.service.ts
DarinHajou 2252e65
Rename addOrUpdateMembership to addOrUpdateMembershipLegacy for legac…
DarinHajou bf45e74
Update populateMemberships script connection logic
DarinHajou a1d8fb0
Add tierRank helper to support membership upgrade/downgrade logic
DarinHajou 7101e0c
Add edge case logic to updateOrRenewMembership using tierRank
DarinHajou 6355569
Delete redundant membership.ts helper file
DarinHajou 2a83910
Add full membership tier handling logic (upgrade, downgrade, renewal)
DarinHajou 214398f
Enforce max membership duration per class in updateOrRenewMembership()
DarinHajou 2aa20a1
Finalize membership tier logic with pi_uid (pre-user_id switch)
DarinHajou 9d1fe9b
Declare currentUser on Express Request interface for type safety
DarinHajou 968a133
Update updateOrRenewMembership controller to use req.currentUser inst…
DarinHajou 5429530
Swap legacy manageMembership route with updateOrRenewMembership
DarinHajou 7d36ee5
Refactor membership service to use user object instead of pi_uid
DarinHajou bc63516
Update category switching and required mappi value
DarinHajou 385ffee
Finalize membership logic with full tier/category handling, renewal r…
DarinHajou 97613c4
Integrate membership processing in payment flow
DarinHajou 9a96abf
Add membership metadata field to IPayment model
DarinHajou c025d1d
Include metadata in Payment schema
DarinHajou 0a08730
Implement updateOrRenewMembershipAfterPayment to handle Pi U2A member…
DarinHajou 1c95314
Add _id field to IUser to support ObjectId access in services
DarinHajou b1d9248
Add metadata to NewPayment interface for Order and Membership payment…
DarinHajou 545300c
Make pi_payment_id optional and sparse to support Pi U2A pre-approval…
DarinHajou 0f0b9b5
Remove redundant import from membership routes
DarinHajou 9c42fc0
Refactor Express.Request typing to use global namespace
DarinHajou 86d907c
Fix ObjectId to string conversion for payment and order creation
DarinHajou fbe9f50
Feat: Add payment initiation handler and refactor payment controller …
DarinHajou 2466c0d
Feat: Add createU2APayment service for Pi U2A flow and fix metadata h…
DarinHajou 4327ea2
Add createU2APayment service for Pi U2A flow and fix metadata handlin…
DarinHajou 085e93e
Merge branch 'feature/membership-final-refactor' of https://github.co…
DarinHajou 6198182
Add /payments/initiate route for Pi U2A payment initiation
DarinHajou b3c5cb5
Prevent duplicate pending membership payments in createU2APayment
DarinHajou 2d27c02
Merge remote-tracking branch 'origin/dev' into feature/membership-fin…
swoocn 1709adf
Misc PR adjustment; mod unit test; WIP.
swoocn File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
components: | ||
schemas: | ||
GetSingleMembershipRs: | ||
type: object | ||
properties: | ||
pi_uid: | ||
type: string | ||
description: The Pi Network user ID (used as membership identifier) | ||
example: pi_f392cb3b73913bcb2d1e5b69 | ||
membership_class: | ||
$ref: '/api/docs/enum/MembershipClassType.yml#/components/schemas/MembershipClassType' | ||
membership_expiration: | ||
type: string | ||
format: date-time | ||
example: 2024-12-21T00:00:00.000Z | ||
mappi_balance: | ||
type: number | ||
example: 100 | ||
mappi_used_to_date: | ||
type: number | ||
example: 25 | ||
_id: | ||
type: string | ||
example: 66741c62b175e7d059a2639e | ||
__v: | ||
type: number | ||
example: 0 | ||
|
||
ManageMembershipRq: | ||
type: object | ||
properties: | ||
membership_class: | ||
$ref: '/api/docs/enum/MembershipClassType.yml#/components/schemas/MembershipClassType' | ||
membership_duration: | ||
type: number | ||
example: 4 | ||
mappi_allowance: | ||
type: number | ||
example: 100 | ||
required: | ||
- membership_class | ||
- membership_duration | ||
- mappi_allowance | ||
|
||
ManageMembershipRs: | ||
type: object | ||
properties: | ||
pi_uid: | ||
type: string | ||
example: pi_f392cb3b73913bcb2d1e5b69 | ||
membership_class: | ||
$ref: '/api/docs/enum/MembershipClassType.yml#/components/schemas/MembershipClassType' | ||
membership_expiration: | ||
type: string | ||
format: date-time | ||
example: 2024-12-21T00:00:00.000Z | ||
mappi_balance: | ||
type: number | ||
example: 200 | ||
mappi_used_to_date: | ||
type: number | ||
example: 0 | ||
_id: | ||
type: string | ||
example: 66741c62b175e7d059a2639e | ||
__v: | ||
type: number | ||
example: 0 |
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nice! 😎👍 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import { Request, Response } from "express"; | ||
import * as membershipService from "../services/membership.service"; | ||
import logger from "../config/loggingConfig"; | ||
|
||
// Controller to fetch a single membership by its ID | ||
export const getSingleMembership = async (req: Request, res: Response) => { | ||
const { membership_id } = req.params; | ||
|
||
try { | ||
const currentMembership = await membershipService.getSingleMembershipById(membership_id); | ||
|
||
if (!currentMembership) { | ||
logger.warn(`Membership with ID ${membership_id} not found.`); | ||
return res.status(404).json({ message: "Membership not found" }); | ||
} | ||
|
||
logger.info(`Fetched membership with ID ${membership_id}`); | ||
return res.status(200).json(currentMembership); | ||
} catch (error) { | ||
logger.error(`Error getting membership ID ${membership_id}:`, error); | ||
return res.status(500).json({ message: 'An error occurred while getting single membership; please try again later' }); | ||
} | ||
}; | ||
|
||
export const updateOrRenewMembership = async (req: Request, res: Response) => { | ||
if (!req.currentUser) { | ||
return res.status(401).json({ error: "Unauthorized - user not authenticated "}); | ||
} | ||
|
||
try { | ||
const { membership_class, membership_duration, mappi_allowance } = req.body; | ||
|
||
const updated = await membershipService.updateOrRenewMembership({ | ||
user: req.currentUser, | ||
membership_class, | ||
membership_duration, | ||
mappi_allowance, | ||
}); | ||
|
||
return res.status(200).json(updated); | ||
} catch (error: any) { | ||
logger.error("Failed to update or renew membership:", error); | ||
return res.status(400).json({ error: error.message }); | ||
} | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Request, Response } from "express"; | ||
import * as membershipLegacyService from "../services/membershipLegacy.service"; | ||
import logger from "../config/loggingConfig"; | ||
import { MembershipClassType } from "../models/enums/membershipClassType"; | ||
|
||
// Controller to add or update a user's membership | ||
// !!! Legacy controller — used only for manual upgrades and testing. | ||
// Membership upgrades should now go through Pi (U2A) payment flow. | ||
export const manageMembership = async (req: Request, res: Response) => { | ||
const authUser = req.currentUser; | ||
|
||
// Early return if request is not authenticated | ||
if (!authUser) { | ||
logger.warn('Unauthorized attempt to manage membership.'); | ||
return res.status(401).json({ error: 'Unauthorized' }); | ||
} | ||
|
||
const { membership_class, membership_duration, mappi_allowance } = req.body; | ||
|
||
// Basic input validation | ||
if ( | ||
!membership_class || | ||
!Object.values(MembershipClassType).includes(membership_class) || // Ensure membership_class is valid | ||
typeof membership_duration !== 'number' || | ||
typeof mappi_allowance !== 'number' | ||
) { | ||
return res.status(400).json({ error: 'Invalid request payload' }); | ||
} | ||
|
||
try { | ||
// Add or update membership in the service layer | ||
const updatedMembership = await membershipLegacyService.addOrUpdateMembershipLegacy( | ||
authUser, | ||
membership_class, | ||
membership_duration, | ||
mappi_allowance | ||
); | ||
|
||
logger.info(`Membership managed successfully for user ${authUser.pi_uid}`); | ||
return res.status(200).json(updatedMembership); | ||
} catch (error) { | ||
logger.error(`Failed to manage membership for user ${authUser.pi_uid}:`, error); | ||
return res.status(500).json({ | ||
message: 'An error occurred while getting single membership; please try again later', | ||
}); | ||
} | ||
}; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file was deleted.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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.
Hi @DarinHajou - I noticed that package-lock.json was committed in the PR, but package.json wasn't modified.
Just checking—was committing the lock file intentional on your end?
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.
Hi @swoocn. Sry for the late reply, but - no that wasn't intentional on my part.