| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202 |
- const Schmervice = require('@hapipal/schmervice')
-
- module.exports = class MembershipService extends Schmervice.Service {
- constructor(...args) {
- super(...args)
- }
-
- /**
- * Internal method to get list of grouping_ids for this user
- * @param {number} userId
- * @returns {Array} List of all grouping_ids for user
- */
- async _getGroupIdsForUserId(userId) {
- const { Membership } = this.server.models()
-
- /** Grab every Membership associated with this id */
- const allMemberships = await Membership.query().where('user_id', userId)
-
- /** Copy a list of the just the Groupings */
- const groupingIdsToGrab = allMemberships.map(
- membership => membership.grouping_id,
- )
-
- /** Uncomment to dedupe the list just in case */
- return [...new Set(groupingIdsToGrab)]
- }
-
- /**
- * Internal method to create a new grouping
- * @param {*} groupingToTry
- * @param {*} txn
- * @returns
- */
- async _createGrouping(groupingToTry, txn) {
- const { Grouping } = this.server.models()
- const groupingInfo = {
- grouping_name: groupingToTry.grouping_name,
- grouping_type: groupingToTry.grouping_type,
- }
- return await Grouping.query(txn).insert(groupingInfo)
- }
-
- async findOrCreateGrouping(groupingToTry) {
- let idToReturn = groupingToTry.grouping_id
- if (!idToReturn) {
- /** ?: For some reason this returns the key id */
- const grouping = await this._createGrouping(groupingToTry)
- idToReturn = grouping.id
- }
- return idToReturn
- }
-
- /**
- * Get a list of groupings for user
- * @param {number} userId
- * @returns {Array}
- */
- async findGroupingsById(userId) {
- const { Grouping } = this.server.models()
-
- const dedupedGroupings = await this._getGroupIdsForUserId(userId)
-
- /** Grab just the Groupings this id has a Membership for */
- return await Grouping.query()
- .throwIfNotFound()
- .whereIn('grouping_id', dedupedGroupings)
- }
-
- async _groupingIdsInCommon(userId, targetId) {
- const dedupedUserGroupingIds = await this._getGroupIdsForUserId(userId)
- const dedupedTargetGroupingIds = await this._getGroupIdsForUserId(
- targetId,
- )
-
- /** Return true if both people have a group in common */
- return dedupedUserGroupingIds.filter(groupingId =>
- dedupedTargetGroupingIds.includes(groupingId),
- )
- }
- async _patchMembership(memberships, userId, patch) {
- const { Membership } = this.server.models()
-
- /** Set membership as active only if the user initiates it */
- for (let membershipInfo of memberships) {
- await Membership.query()
- .where('membership_id', membershipInfo.membership_id)
- .where('user_id', userId)
- .patch(patch)
- }
- }
-
- async attemptMatch(userId, targetId) {
- const { Membership } = this.server.models()
-
- /** If both people have groups in common */
- const matchingGroupingIds = await this._groupingIdsInCommon(
- userId,
- targetId,
- )
-
- if (matchingGroupingIds.length) {
- /** Grab all memberships associated with groupingIds */
- const memberships = await Membership.query().whereIn(
- 'grouping_id',
- matchingGroupingIds,
- )
-
- /** Set membership as active only if the user initiates it */
- await this._patchMembership(memberships, userId, {
- is_active: true,
- })
-
- /** Make a new query to get updated information */
- return await Membership.query().whereIn(
- 'grouping_id',
- matchingGroupingIds,
- )
- }
- }
-
- /**
- * Check for grouping membership then add membership record and set to active
- * or create a new grouping and add membership record for user and membership record for target
- * @param {number} userId
- * @param {number} targetId
- * @param {object} groupingToWrite
- * @param {string} role
- * @returns
- */
- async joinGrouping(userId, targetId, groupingToWrite, role, txn) {
- const { Membership } = this.server.models()
-
- /** If both people have groups in common */
- const matchingGroupingIds = await this._groupingIdsInCommon(
- userId,
- targetId,
- )
-
- if (matchingGroupingIds.length) {
- /** Grab all memberships associated with groupingIds */
- const memberships = await Membership.query().whereIn(
- 'grouping_id',
- matchingGroupingIds,
- )
-
- /** Set membership as active only if the user initiates it */
- await this._patchMembership(memberships, userId, {
- is_active: true,
- })
-
- /** Make a new query to get updated information */
- return await Membership.query().whereIn(
- 'grouping_id',
- matchingGroupingIds,
- )
- } else {
- /**
- * If both have NO grouping in common create a membership
- * for both to new group but set membership as inactive for target
- * */
- /** Check if the grouping exists and if NOT creat it */
- const groupingId = await this.findOrCreateGrouping(groupingToWrite)
-
- const userMembership = await Membership.query(txn).insert({
- user_id: userId,
- grouping_id: groupingId,
- membership_type: role,
- can_edit: false,
- is_active: true,
- })
-
- const targetMembership = await Membership.query(txn).insert({
- user_id: targetId,
- grouping_id: groupingId,
- membership_type: role,
- can_edit: false,
- is_active: false,
- })
-
- return [userMembership, targetMembership]
- }
- }
-
- /**
- * Remove membership record based on grouping_id
- * @param {number} userId
- * @param {number} groupingId
- * @returns
- */
- async leaveGrouping(userId, groupingId) {
- const { Membership } = this.server.models()
-
- const dedupedGroupings = await this._getGroupIdsForUserId(userId)
-
- /** Do NOTHING if NOT in Grouping */
- if (!dedupedGroupings.includes(groupingId)) return
-
- return await Membership.query()
- .delete()
- .where('grouping_id', groupingId)
- }
- }
|