Skip to content

Commit

Permalink
Develop (#2047)
Browse files Browse the repository at this point in the history
  • Loading branch information
madan-ideas2it authored Jan 3, 2025
2 parents a4bdb08 + c912ccd commit a286a12
Show file tree
Hide file tree
Showing 12 changed files with 108 additions and 14 deletions.
1 change: 1 addition & 0 deletions apps/web-api/prisma/fixtures/members.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const membersFactory = Factory.define<Omit<Member, 'id'>>(
twitterHandler: faker.internet.userName(name),
linkedinHandler: faker.internet.userName(name),
telegramHandler: faker.internet.userName(name),
telegramUid: faker.helpers.slugify(`uid-tele-${name.toLowerCase()}`),
officeHours: faker.helpers.arrayElement([null, faker.internet.url()]),
moreDetails: faker.helpers.arrayElement([null, faker.lorem.paragraph()]),
plnFriend: faker.datatype.boolean(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
Warnings:
- A unique constraint covering the columns `[telegramHandler]` on the table `Member` will be added. If there are existing duplicate values, this will fail.
- A unique constraint covering the columns `[telegramUid]` on the table `Member` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE "Member" ADD COLUMN "telegramUid" TEXT;

-- CreateIndex
CREATE UNIQUE INDEX "Member_telegramHandler_key" ON "Member"("telegramHandler");

-- CreateIndex
CREATE UNIQUE INDEX "Member_telegramUid_key" ON "Member"("telegramUid");
3 changes: 2 additions & 1 deletion apps/web-api/prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,8 @@ model Member {
discordHandler String?
twitterHandler String?
linkedinHandler String?
telegramHandler String?
telegramHandler String? @unique
telegramUid String? @unique
officeHours String?
moreDetails String?
bio String?
Expand Down
6 changes: 4 additions & 2 deletions apps/web-api/src/internals/internals.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@ import { Module } from '@nestjs/common';
import { PLEventsModule } from '../pl-events/pl-events.module';
import { PLEventsInternalController } from './pl-events.controller';
import { AuthModule } from '../auth/auth.module'
import { MembersController } from './members.controller';
import { MembersModule } from '../members/members.module';

@Module({
controllers: [PLEventsInternalController],
controllers: [PLEventsInternalController, MembersController],
providers: [],
exports: [],
imports:[PLEventsModule, AuthModule]
imports:[PLEventsModule, AuthModule, MembersModule]
})
export class InternalsModule {}
35 changes: 35 additions & 0 deletions apps/web-api/src/internals/members.controller.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { Controller, UseGuards, Body, BadRequestException, NotFoundException } from '@nestjs/common';
import { Api, initNestServer, ApiDecorator } from '@ts-rest/nest';
import { apiInternals } from 'libs/contracts/src/lib/contract-internals';
import { InternalUpdateMemberDto, ResponseMemberSchema } from 'libs/contracts/src/schema';
import { ApiOkResponseFromZod } from '../decorators/api-response-from-zod';
import { InternalAuthGuard } from '../guards/auth.guard';
import { MembersService } from '../members/members.service';

const server = initNestServer(apiInternals);
type RouteShape = typeof server.routeShapes;

@Controller("")
@UseGuards(InternalAuthGuard)
export class MembersController {
constructor(
private readonly membersService: MembersService
) {}

@Api(server.route.updateTelagramUid)
@ApiOkResponseFromZod(ResponseMemberSchema)
async updateTelegramUid(
@Body() updateRequestDto: InternalUpdateMemberDto
) {
if(updateRequestDto.telegramHandler) {
const member = await this.membersService.findUnique({telegramHandler: {equals: updateRequestDto.telegramHandler, mode: 'insensitive'}});
if(member) {
return await this.membersService.updateMemberByUid(member.uid, {telegramUid: updateRequestDto.telegramUid});
}
throw new NotFoundException(`Member with telegram handle ${updateRequestDto.telegramHandler} not found`);

} else {
throw new BadRequestException('Telegram handle cannot be empty');
}
}
}
8 changes: 8 additions & 0 deletions apps/web-api/src/members/members.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,14 @@ export class MemberController {
this.membersService.buildParticipationTypeFilter(queryParams)
],
};
// Check for the office hours blank when OH not null is passed
if (request.query['officeHours__not'] === 'null') {
builtQuery.where.AND.push({
officeHours: {
not: '',
},
});
}
return await this.membersService.findAll(builtQuery);
}

Expand Down
15 changes: 13 additions & 2 deletions apps/web-api/src/members/members.service.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable prettier/prettier */
import {
BadRequestException,
ConflictException,
Expand Down Expand Up @@ -85,6 +84,16 @@ export class MembersService {
}
}

/**
* Retrieves a member based on unique query options
* @param queryOptions - Object containing unique field value pairs
* @returns A promise resolving to member if found else null
*/
async findUnique(queryOptions: Prisma.MemberWhereInput): Promise<Member | null> {
//Ideally this should be findUnique but to handle case insensitive we have done this, we should habdle this with lower case handles when saving
return await this.prisma.member.findFirst({ where: queryOptions });
}

/**
* This method retrieves the default(Founder, CEO, CTO and COO) and user selected(memberRoles) role's count
* @param defaultAndUserSelectedRoles An array of role name(default & user selected roles)
Expand Down Expand Up @@ -204,10 +213,12 @@ export class MembersService {
tx: Prisma.TransactionClient = this.prisma,
): Promise<Member> {
try {
return await tx.member.update({
const result = await tx.member.update({
where: { uid },
data: member,
});
await this.cacheService.reset({ service: 'members' });
return result;
} catch (error) {
return this.handleErrors(error);
}
Expand Down
10 changes: 9 additions & 1 deletion apps/web-api/src/teams/teams.controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,15 @@ export class TeamsController {
this.teamsService.buildFocusAreaFilters(focusAreas),
this.teamsService.buildRecentTeamsFilter(request.query),
this.teamsService.buildParticipationTypeFilter(request.query)
]
],
};
// Check for the office hours blank when OH not null is passed
if (request.query['officeHours__not'] === 'null') {
builtQuery.where.AND.push({
officeHours: {
not: '',
},
});
}
return this.teamsService.findAll(builtQuery);
}
Expand Down
11 changes: 6 additions & 5 deletions apps/web-api/src/utils/cache/cache.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ export class CacheService {
constructor(
@Inject(CACHE_MANAGER) private cache: Cache,
private logService: LogService
) {}
) { }

// Mapping service names to tags
private serviceTagsMap = {
members: ['member-filters', 'member-list', 'members-roles'],
projects: ['project-list', 'focus-areas'],
teams: ['team-filters', 'team-list', 'focus-areas'],
'participants-requests': ['member-filters', 'member-list','team-filters', 'team-list', 'focus-areas']
members: ['member-filters', 'member-list', 'members-roles', "featured", "member-airtable", "member-repositories", "member-detail","team-list"],
projects: ['project-list', 'focus-areas', "project-detail", "team-detail", "featured", "project-oso"],
teams: ['team-filters', 'team-list', 'focus-areas', "team-detail", "featured", "team-airtable"],
'participants-requests': ['member-filters', 'member-list', 'team-filters', 'team-list', 'focus-areas'],
PLEventGuest: ["irl-locations", "irl-guests", "irl-locations-topic", "irl-guest-events"]
};

// Reset cache and call API based on service
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
/* eslint-disable prettier/prettier */
import { Injectable } from '@nestjs/common';
import { AwsService } from '../aws/aws.service';
import { SlackService } from '../slack/slack.service';
Expand Down
11 changes: 11 additions & 0 deletions libs/contracts/src/lib/contract-internals.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { initContract } from '@ts-rest/core';
import {
InternalUpdateMemberDto,
PLEventGuestQueryParams,
ResponseMemberSchema,
ResponsePLEventGuestSchemaWithRelationsSchema
} from '../schema';
import { getAPIVersionAsPath } from '../utils/versioned-path';
Expand All @@ -17,4 +19,13 @@ export const apiInternals = contract.router({
},
summary: 'Get a pl event with guests by location',
},
updateTelagramUid: {
method: 'PATCH',
path: `${getAPIVersionAsPath('1')}/internals/members`,
body: InternalUpdateMemberDto,
responses: {
200: ResponseMemberSchema
},
summary: 'Update the telegram uid for a member'
}
});
6 changes: 4 additions & 2 deletions libs/contracts/src/schema/member.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ export const MemberSchema = z.object({
discordHandler: z.string().nullish(),
twitterHandler: z.string().nullish(),
telegramHandler: z.string().nullish(),
telegramUid: z.string().nullable(),
officeHours: z.string().nullish(),
airtableRecId: z.string().nullish(),
plnFriend: z.boolean().nullish(),
Expand All @@ -61,7 +62,7 @@ export const MemberSchema = z.object({



export const ResponseMemberSchema = MemberSchema.omit({ id: true }).strict();
export const ResponseMemberSchema = MemberSchema.omit({ id: true, telegramUid: true }).strict();

export const ResponseMemberWithRelationsSchema = ResponseMemberSchema.extend({
image: ResponseImageWithRelationsSchema.optional(),
Expand Down Expand Up @@ -115,7 +116,8 @@ export const MemberDetailQueryParams = MemberQueryParams.unwrap()
.pick(RETRIEVAL_QUERY_FILTERS)
.optional();

export class MemberDto extends createZodDto(MemberSchema) {}
export class MemberDto extends createZodDto(MemberSchema.omit({telegramUid: true})) {}
export class InternalUpdateMemberDto extends createZodDto(MemberSchema.pick({telegramUid: true, telegramHandler: true})) {}

export class CreateMemberSchemaDto extends createZodDto(CreateMemberSchema) {}

Expand Down

0 comments on commit a286a12

Please sign in to comment.