Skip to content
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

feat: added cache revalidation API integration #1996

Merged
merged 3 commits into from
Dec 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,9 @@ ADMIN_LOGIN_USERNAME=
# For local development, use: admin
ADMIN_LOGIN_PASSWORD=


# Revalidate cache API token
# For local development, use: random string
REVALIDATE_API_TOKEN=

# Optional for local development

Expand Down
3 changes: 1 addition & 2 deletions apps/web-api/src/auth/auth.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,11 @@ import { AuthController } from './auth.controller';
import { AuthService } from './auth.service';
import { HttpModule } from '@nestjs/axios';
import { PrismaService } from '../shared/prisma.service';
import { RedisService } from '../utils/redis/redis.service';
import { OtpModule } from '../otp/otp.module';
@Module({
imports: [HttpModule, OtpModule],
controllers: [AuthController],
providers: [AuthService, PrismaService, RedisService],
providers: [AuthService, PrismaService],
exports: [AuthService]
})
export class AuthModule {}
13 changes: 6 additions & 7 deletions apps/web-api/src/members/members.service.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
/* eslint-disable prettier/prettier */
import {
BadRequestException,
CACHE_MANAGER,
ConflictException,
NotFoundException,
Inject,
Expand All @@ -11,7 +10,6 @@ import {
import { z } from 'zod';
import axios from 'axios';
import * as path from 'path';
import { Cache } from 'cache-manager';
import { Prisma, Member, ParticipantsRequest } from '@prisma/client';
import { PrismaService } from '../shared/prisma.service';
import { ParticipantsRequestService } from '../participants-request/participants-request.service';
Expand All @@ -26,6 +24,7 @@ import { LogService } from '../shared/log.service';
import { DEFAULT_MEMBER_ROLES } from '../utils/constants';
import { hashFileName } from '../utils/hashing';
import { copyObj, buildMultiRelationMapping } from '../utils/helper/helper';
import { CacheService } from '../utils/cache/cache.service';

@Injectable()
export class MembersService {
Expand All @@ -41,8 +40,8 @@ export class MembersService {
private participantsRequestService: ParticipantsRequestService,
@Inject(forwardRef(() => NotificationService))
private notificationService: NotificationService,
@Inject(CACHE_MANAGER) private cacheService: Cache
) { }
private cacheService: CacheService
) {}

/**
* Creates a new member in the database within a transaction.
Expand Down Expand Up @@ -427,7 +426,7 @@ export class MembersService {
newTokens = await this.authService.updateEmailInAuth(newEmail, oldEmail, memberInfo.externalId)
});
this.logger.info(`Email has been successfully updated from ${oldEmail} to ${newEmail}`)
await this.cacheService.reset();
await this.cacheService.reset({ service: 'members'});
return {
refreshToken: newTokens.refresh_token,
idToken: newTokens.id_token,
Expand Down Expand Up @@ -1166,7 +1165,7 @@ export class MembersService {
*/
async updatePreference(id: string, preferences: any): Promise<Member> {
const updatedMember = await this.updateMemberByUid(id, { preferences });
await this.cacheService.reset();
await this.cacheService.reset({ service: 'members'});
return updatedMember;
}

Expand All @@ -1175,7 +1174,7 @@ export class MembersService {
* This ensures that the system is up-to-date with the latest changes.
*/
private async postUpdateActions(): Promise<void> {
await this.cacheService.reset();
await this.cacheService.reset({ service: 'members'});
await this.forestadminService.triggerAirtableSync();
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
/* eslint-disable prettier/prettier */
import {
BadRequestException,
ConflictException,
import {
BadRequestException,
ConflictException,
NotFoundException,
Inject,
Injectable,
CACHE_MANAGER,
forwardRef
forwardRef,
Inject
} from '@nestjs/common';
import { ApprovalStatus, ParticipantType } from '@prisma/client';
import { Cache } from 'cache-manager';
import { Prisma, ParticipantsRequest, PrismaClient } from '@prisma/client';
import { generateProfileURL } from '../utils/helper/helper';
import { LogService } from '../shared/log.service';
Expand All @@ -19,6 +17,7 @@ import { TeamsService } from '../teams/teams.service';
import { NotificationService } from '../utils/notification/notification.service';
import { LocationTransferService } from '../utils/location-transfer/location-transfer.service';
import { ForestAdminService } from '../utils/forest-admin/forest-admin.service';
import { CacheService } from '../utils/cache/cache.service';

@Injectable()
export class ParticipantsRequestService {
Expand All @@ -28,8 +27,7 @@ export class ParticipantsRequestService {
private locationTransferService: LocationTransferService,
private forestAdminService: ForestAdminService,
private notificationService: NotificationService,
@Inject(CACHE_MANAGER)
private cacheService: Cache,
private cacheService: CacheService,
@Inject(forwardRef(() => MembersService))
private membersService: MembersService,
@Inject(forwardRef(() => TeamsService))
Expand Down Expand Up @@ -166,7 +164,7 @@ export class ParticipantsRequestService {
where: { uid },
data: formattedData,
});
await this.cacheService.reset();
await this.cacheService.reset({ service: "participants-requests" });
return result;
} catch (err) {
return this.handleErrors(err)
Expand All @@ -187,7 +185,7 @@ export class ParticipantsRequestService {
where: { uid: uidToReject },
data: { status: ApprovalStatus.REJECTED }
});
await this.cacheService.reset();
await this.cacheService.reset({ service: "participants-requests" });
return result;
} catch (err) {
return this.handleErrors(err)
Expand Down Expand Up @@ -250,7 +248,7 @@ export class ParticipantsRequestService {
participantsRequest.requesterEmailId
);
}
await this.cacheService.reset();
await this.cacheService.reset({ service: "participants-requests" });
await this.forestAdminService.triggerAirtableSync();
return result;
}
Expand Down Expand Up @@ -296,7 +294,7 @@ export class ParticipantsRequestService {
if (!disableNotification) {
this.notifyForCreate(result);
}
await this.cacheService.reset();
await this.cacheService.reset({ service: "participants-requests" });
return result;
}

Expand Down
10 changes: 5 additions & 5 deletions apps/web-api/src/pl-events/pl-event-guests.service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import { Injectable, NotFoundException, ConflictException, BadRequestException, Inject, CACHE_MANAGER } from '@nestjs/common';
import { Injectable, NotFoundException, ConflictException, BadRequestException } from '@nestjs/common';
import { LogService } from '../shared/log.service';
import { PrismaService } from '../shared/prisma.service';
import { Prisma, Member } from '@prisma/client';
import { MembersService } from '../members/members.service';
import { Cache } from 'cache-manager';
import { PLEventLocationsService } from './pl-event-locations.service';
import {
CreatePLEventGuestSchemaDto,
Expand All @@ -13,6 +12,7 @@ import {
FormattedLocationWithEvents,
PLEvent
} from './pl-event-locations.types';
import { CacheService } from '../utils/cache/cache.service';

@Injectable()
export class PLEventGuestsService {
Expand All @@ -21,7 +21,7 @@ export class PLEventGuestsService {
private logger: LogService,
private memberService: MembersService,
private eventLocationsService: PLEventLocationsService,
@Inject(CACHE_MANAGER) private cacheService: Cache
private cacheService: CacheService
) {}

/**
Expand All @@ -43,7 +43,7 @@ export class PLEventGuestsService {
data.memberUid = isAdmin ? data.memberUid : member.uid;
const guests = this.formatInputToEventGuests(data);
const result = await (tx || this.prisma).pLEventGuest.createMany({ data: guests });
this.cacheService.reset();
this.cacheService.reset({ service: 'PLEventGuest' });
return result;
} catch(err) {
this.handleErrors(err);
Expand Down Expand Up @@ -100,7 +100,7 @@ export class PLEventGuestsService {
OR: deleteConditions
}
});
await this.cacheService.reset();
await this.cacheService.reset({ service: 'PLEventGuest' });
return result;
} catch (err) {
this.handleErrors(err);
Expand Down
12 changes: 6 additions & 6 deletions apps/web-api/src/projects/projects.service.ts
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
import { Inject, CACHE_MANAGER, BadRequestException, ConflictException, ForbiddenException, Injectable, NotFoundException, HttpException } from '@nestjs/common';
import { BadRequestException, ConflictException, ForbiddenException, Injectable, NotFoundException } from '@nestjs/common';
import { LogService } from '../shared/log.service';
import { PrismaService } from '../shared/prisma.service';
import { Prisma } from '@prisma/client';
import { MembersService } from '../members/members.service';
import { Cache } from 'cache-manager';
import { CacheService } from '../utils/cache/cache.service';

@Injectable()
export class ProjectsService {
constructor(
private prisma: PrismaService,
private memberService: MembersService,
private logger: LogService,
@Inject(CACHE_MANAGER) private cacheService: Cache
private cacheService: CacheService
) { }

async createProject(project: Prisma.ProjectUncheckedCreateInput, userEmail: string) {
Expand All @@ -34,7 +34,7 @@ export class ProjectsService {
}
}
});
await this.cacheService.reset();
await this.cacheService.reset({ service: 'projects'});
return result;
} catch (err) {
this.handleErrors(err);
Expand Down Expand Up @@ -81,7 +81,7 @@ export class ProjectsService {
}
}
});
await this.cacheService.reset();
await this.cacheService.reset({ service: 'projects'});
return result;
});
} catch (err) {
Expand Down Expand Up @@ -169,7 +169,7 @@ export class ProjectsService {
where: { uid },
data: { isDeleted: true }
});
await this.cacheService.reset();
await this.cacheService.reset({ service: 'projects'});
return result;
} catch (err) {
this.handleErrors(err, `${uid}`);
Expand Down
3 changes: 3 additions & 0 deletions apps/web-api/src/shared/shared.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { ImagesController } from '../images/images.controller';
import { ImagesService } from '../images/images.service';
import { FileUploadService } from '../utils/file-upload/file-upload.service';
import { FileEncryptionService } from '../utils/file-encryption/file-encryption.service';
import { CacheService } from '../utils/cache/cache.service';

@Global()
@Module({
Expand All @@ -26,6 +27,7 @@ import { FileEncryptionService } from '../utils/file-encryption/file-encryption.
ImagesService,
FileUploadService,
FileEncryptionService,
CacheService
],
exports: [
PrismaService,
Expand All @@ -39,6 +41,7 @@ import { FileEncryptionService } from '../utils/file-encryption/file-encryption.
ImagesService,
FileUploadService,
FileEncryptionService,
CacheService
],
})
export class SharedModule {}
9 changes: 4 additions & 5 deletions apps/web-api/src/teams/teams.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ import {
ForbiddenException,
BadRequestException,
NotFoundException,
Inject,
forwardRef,
CACHE_MANAGER
Inject
} from '@nestjs/common';
import * as path from 'path';
import { z } from 'zod';
Expand All @@ -20,8 +19,8 @@ import { hashFileName } from '../utils/hashing';
import { ForestAdminService } from '../utils/forest-admin/forest-admin.service';
import { MembersService } from '../members/members.service';
import { LogService } from '../shared/log.service';
import { Cache } from 'cache-manager';
import { copyObj, buildMultiRelationMapping, buildRelationMapping } from '../utils/helper/helper';
import { CacheService } from '../utils/cache/cache.service';

@Injectable()
export class TeamsService {
Expand All @@ -35,7 +34,7 @@ export class TeamsService {
private logger: LogService,
private forestadminService: ForestAdminService,
private notificationService: NotificationService,
@Inject(CACHE_MANAGER) private cacheService: Cache
private cacheService: CacheService
) { }

/**
Expand Down Expand Up @@ -321,7 +320,7 @@ export class TeamsService {
* This ensures that the system is up-to-date with the latest changes.
*/
private async postUpdateActions(): Promise<void> {
await this.cacheService.reset();
await this.cacheService.reset({ service: "teams" });
await this.forestadminService.triggerAirtableSync();
}

Expand Down
59 changes: 59 additions & 0 deletions apps/web-api/src/utils/cache/cache.service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { Injectable, Inject, CACHE_MANAGER } from '@nestjs/common';
import { Cache } from 'cache-manager';
import axios from 'axios';
import { LogService } from '../../shared/log.service';

@Injectable()
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'],
projects: ['project-list', 'focus-areas'],
teams: ['team-filters', 'team-list', 'focus-areas'],
'participants-requests': ['member-filters', 'member-list','team-filters', 'team-list', 'focus-areas']
};

// Reset cache and call API based on service
async reset(data) {
const { service } = data;
await this.cache.reset(); // Reset the cache
const tags = this.serviceTagsMap[service];
if (tags) {
await this.revalidateCache(tags);
}
}

// Function to call the revalidate API
private async revalidateCache(tags: string[]) {
const baseUrl = process.env.WEB_UI_BASE_URL;
const token = process.env.REVALIDATE_API_TOKEN; // Assuming token is stored in env variable
if (!baseUrl) {
this.logService.error('WEB_UI_BASE_URL is not defined in the environment variables.');
return;
}
if (!token) {
this.logService.error('REVALIDATE_API_TOKEN is not defined in the environment variables.');
return;
}
const url = `${baseUrl}/api/revalidate`;
try {
const response = await axios.post(
url,
{ tags },
{
headers: {
Authorization: `Bearer ${token}`, // Adding Bearer token to headers
},
},
);
this.logService.info(`Revalidation API called successfully with tags: ${tags.join(', ')}`);
} catch (error) {
this.logService.error('Error calling revalidate API:', error.message);
}
}
}
Loading
Loading