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: drop calendar repository #5824

Merged
merged 37 commits into from
Jun 22, 2024
Merged
Show file tree
Hide file tree
Changes from 36 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
291e84d
feat: wip refactor message queue module
magrinj May 29, 2024
9299944
feat: refactor all jobs
magrinj Jun 5, 2024
085e471
fix: rebase issues
magrinj Jun 6, 2024
6e36379
fix: drop ScheduleModule
magrinj Jun 6, 2024
6b85fbe
fix: small issues and test
magrinj Jun 6, 2024
f7790fc
fix: miss job names
magrinj Jun 6, 2024
51a13b9
fix: use enum instead of magic string
magrinj Jun 7, 2024
c09d3a4
fix: track job errors in Sentry
magrinj Jun 7, 2024
84f4826
fix: warn if driver type is not correct
magrinj Jun 11, 2024
2f3556c
Merge branch 'main' into feat/refactor-message-queue
Weiko Jun 12, 2024
f7abf53
fix contact creation queue
Weiko Jun 12, 2024
36f568e
use job.data as job class payload
Weiko Jun 12, 2024
a7e0f23
Merge branch 'main' into feat/refactor-message-queue
Weiko Jun 13, 2024
1d03883
feat: wip fix multiple worker created for one queue
magrinj Jun 13, 2024
38f11ba
fix: multiple job class for a given queue overriding worker
magrinj Jun 14, 2024
aa68057
Merge remote-tracking branch 'origin/main' into feat/refactor-message…
magrinj Jun 14, 2024
2150f9a
feat: wip drop calendar repositories
magrinj Jun 11, 2024
04d5bae
fix: missing file
magrinj Jun 12, 2024
12d22f1
fix: calendar participant service
magrinj Jun 14, 2024
d85ed82
fix: wip debug
magrinj Jun 17, 2024
d599738
fix: typing issues
magrinj Jun 18, 2024
d7e25ad
fix: TwentyORM imports
magrinj Jun 18, 2024
031f77c
fix: login issue
magrinj Jun 18, 2024
67bd4d7
feat: cleaner way to call workspace service with context manually
magrinj Jun 19, 2024
0b9d518
merge main into feat/drop-calendar-repository
magrinj Jun 19, 2024
d9886ec
fix: missing scopes
magrinj Jun 19, 2024
b66b20d
fix errors due to auth context being missing in the auth controller
bosiraphael Jun 20, 2024
5a99b06
pass userId inside transientToken
bosiraphael Jun 20, 2024
7b9f8ee
remove repository
bosiraphael Jun 20, 2024
286a6e5
fix save on calendar event
bosiraphael Jun 21, 2024
132fdde
trying to fix timelineActivity event not working on calendarEventPart…
bosiraphael Jun 21, 2024
fcd7cf4
Merge branch 'main' into feat/drop-calendar-repository
bosiraphael Jun 21, 2024
cd599b3
fix errors introduced by merge
bosiraphael Jun 21, 2024
434333d
add accountOwnerId to connectedAccount entity
bosiraphael Jun 21, 2024
6b31619
Disable non-migrated pre-hooks on calendarEvents
charlesBochet Jun 22, 2024
5d58733
Fix issues
charlesBochet Jun 22, 2024
dba5b4b
Fix pg-boss implementation
charlesBochet Jun 22, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ export class AnalyticsService {

async create(
createEventInput: CreateEventInput,
userId: string | undefined,
workspaceId: string | undefined,
userId: string | null | undefined,
workspaceId: string | null | undefined,
workspaceDisplayName: string | undefined,
workspaceDomainName: string | undefined,
hostName: string | undefined,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ import { ConnectedAccountWorkspaceEntity } from 'src/modules/connected-account/s
import { CalendarChannelWorkspaceEntity } from 'src/modules/calendar/standard-objects/calendar-channel.workspace-entity';
import { MessageChannelWorkspaceEntity } from 'src/modules/messaging/common/standard-objects/message-channel.workspace-entity';
import { OnboardingModule } from 'src/engine/core-modules/onboarding/onboarding.module';
import { TwentyORMModule } from 'src/engine/twenty-orm/twenty-orm.module';
import { WorkspaceDataSourceModule } from 'src/engine/workspace-datasource/workspace-datasource.module';

import { AuthResolver } from './auth.resolver';

Expand Down Expand Up @@ -60,11 +62,12 @@ const jwtModule = JwtModule.registerAsync({
ObjectMetadataRepositoryModule.forFeature([
ConnectedAccountWorkspaceEntity,
MessageChannelWorkspaceEntity,
CalendarChannelWorkspaceEntity,
]),
HttpModule,
UserWorkspaceModule,
OnboardingModule,
TwentyORMModule.forFeature([CalendarChannelWorkspaceEntity]),
WorkspaceDataSourceModule,
],
controllers: [
GoogleAuthController,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,7 @@ export class AuthResolver {
}
const transientToken = await this.tokenService.generateTransientToken(
workspaceMember.id,
user.id,
user.defaultWorkspace.id,
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ import { GoogleAPIsService } from 'src/engine/core-modules/auth/services/google-
import { TokenService } from 'src/engine/core-modules/auth/services/token.service';
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
import { OnboardingService } from 'src/engine/core-modules/onboarding/onboarding.service';
import { WorkspaceMemberRepository } from 'src/modules/workspace-member/repositories/workspace-member.repository';
import { WorkspaceMemberWorkspaceEntity } from 'src/modules/workspace-member/standard-objects/workspace-member.workspace-entity';
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
import { LoadServiceWithWorkspaceContext } from 'src/engine/twenty-orm/context/load-service-with-workspace.context';

@Controller('auth/google-apis')
export class GoogleAPIsAuthController {
Expand All @@ -27,8 +25,7 @@ export class GoogleAPIsAuthController {
private readonly tokenService: TokenService,
private readonly environmentService: EnvironmentService,
private readonly onboardingService: OnboardingService,
@InjectObjectMetadataRepository(WorkspaceMemberWorkspaceEntity)
private readonly workspaceMemberService: WorkspaceMemberRepository,
private readonly loadServiceWithWorkspaceContext: LoadServiceWithWorkspaceContext,
) {}

@Get()
Expand Down Expand Up @@ -56,7 +53,7 @@ export class GoogleAPIsAuthController {
messageVisibility,
} = user;

const { workspaceMemberId, workspaceId } =
const { workspaceMemberId, userId, workspaceId } =
await this.tokenService.verifyTransientToken(transientToken);

const demoWorkspaceIds = this.environmentService.get('DEMO_WORKSPACE_IDS');
Expand All @@ -71,7 +68,13 @@ export class GoogleAPIsAuthController {
throw new Error('Workspace not found');
}

await this.googleAPIsService.refreshGoogleRefreshToken({
const googleAPIsServiceInstance =
await this.loadServiceWithWorkspaceContext.load(
this.googleAPIsService,
workspaceId,
);

await googleAPIsServiceInstance.refreshGoogleRefreshToken({
handle: email,
workspaceMemberId: workspaceMemberId,
workspaceId: workspaceId,
Expand All @@ -81,12 +84,14 @@ export class GoogleAPIsAuthController {
messageVisibility,
});

const userId = (
await this.workspaceMemberService.find(workspaceMemberId, workspaceId)
)?.userId;

if (userId) {
await this.onboardingService.skipSyncEmailOnboardingStep(
const onboardingServiceInstance =
await this.loadServiceWithWorkspaceContext.load(
this.onboardingService,
workspaceId,
);

await onboardingServiceInstance.skipSyncEmailOnboardingStep(
userId,
workspaceId,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@ import { Injectable } from '@nestjs/common';
import { EntityManager } from 'typeorm';
import { v4 } from 'uuid';

import { TypeORMService } from 'src/database/typeorm/typeorm.service';
import { EnvironmentService } from 'src/engine/integrations/environment/environment.service';
import { MessageQueue } from 'src/engine/integrations/message-queue/message-queue.constants';
import { MessageQueueService } from 'src/engine/integrations/message-queue/services/message-queue.service';
import { DataSourceService } from 'src/engine/metadata-modules/data-source/data-source.service';
import { InjectObjectMetadataRepository } from 'src/engine/object-metadata-repository/object-metadata-repository.decorator';
import {
GoogleCalendarSyncJobData,
GoogleCalendarSyncJob,
} from 'src/modules/calendar/jobs/google-calendar-sync.job';
import { CalendarChannelRepository } from 'src/modules/calendar/repositories/calendar-channel.repository';
import {
CalendarChannelWorkspaceEntity,
CalendarChannelVisibility,
Expand All @@ -35,12 +32,16 @@ import {
MessagingMessageListFetchJobData,
} from 'src/modules/messaging/message-import-manager/jobs/messaging-message-list-fetch.job';
import { InjectMessageQueue } from 'src/engine/integrations/message-queue/decorators/message-queue.decorator';
import { InjectWorkspaceRepository } from 'src/engine/twenty-orm/decorators/inject-workspace-repository.decorator';
import { WorkspaceRepository } from 'src/engine/twenty-orm/repository/workspace.repository';
import { WorkspaceDataSource } from 'src/engine/twenty-orm/datasource/workspace.datasource';
import { InjectWorkspaceDatasource } from 'src/engine/twenty-orm/decorators/inject-workspace-datasource.decorator';

@Injectable()
export class GoogleAPIsService {
constructor(
private readonly dataSourceService: DataSourceService,
private readonly typeORMService: TypeORMService,
@InjectWorkspaceDatasource()
private readonly workspaceDataSource: WorkspaceDataSource,
@InjectMessageQueue(MessageQueue.messagingQueue)
private readonly messageQueueService: MessageQueueService,
@InjectMessageQueue(MessageQueue.calendarQueue)
Expand All @@ -50,8 +51,8 @@ export class GoogleAPIsService {
private readonly connectedAccountRepository: ConnectedAccountRepository,
@InjectObjectMetadataRepository(MessageChannelWorkspaceEntity)
private readonly messageChannelRepository: MessageChannelRepository,
@InjectObjectMetadataRepository(CalendarChannelWorkspaceEntity)
private readonly calendarChannelRepository: CalendarChannelRepository,
@InjectWorkspaceRepository(CalendarChannelWorkspaceEntity)
private readonly calendarChannelRepository: WorkspaceRepository<CalendarChannelWorkspaceEntity>,
) {}

async refreshGoogleRefreshToken(input: {
Expand All @@ -71,14 +72,6 @@ export class GoogleAPIsService {
messageVisibility,
} = input;

const dataSourceMetadata =
await this.dataSourceService.getLastDataSourceMetadataFromWorkspaceIdOrFail(
workspaceId,
);

const workspaceDataSource =
await this.typeORMService.connectToDataSource(dataSourceMetadata);

const isCalendarEnabled = this.environmentService.get(
'CALENDAR_PROVIDER_GOOGLE_ENABLED',
);
Expand All @@ -93,65 +86,67 @@ export class GoogleAPIsService {
const existingAccountId = connectedAccounts?.[0]?.id;
const newOrExistingConnectedAccountId = existingAccountId ?? v4();

await workspaceDataSource?.transaction(async (manager: EntityManager) => {
if (!existingAccountId) {
await this.connectedAccountRepository.create(
{
id: newOrExistingConnectedAccountId,
handle,
provider: ConnectedAccountProvider.GOOGLE,
accessToken: input.accessToken,
refreshToken: input.refreshToken,
accountOwnerId: workspaceMemberId,
},
workspaceId,
manager,
);

await this.messageChannelRepository.create(
{
id: v4(),
connectedAccountId: newOrExistingConnectedAccountId,
type: MessageChannelType.EMAIL,
handle,
visibility:
messageVisibility || MessageChannelVisibility.SHARE_EVERYTHING,
syncStatus: MessageChannelSyncStatus.ONGOING,
},
workspaceId,
manager,
);
await this.workspaceDataSource.transaction(
async (manager: EntityManager) => {
if (!existingAccountId) {
await this.connectedAccountRepository.create(
{
id: newOrExistingConnectedAccountId,
handle,
provider: ConnectedAccountProvider.GOOGLE,
accessToken: input.accessToken,
refreshToken: input.refreshToken,
accountOwnerId: workspaceMemberId,
},
workspaceId,
manager,
);

if (isCalendarEnabled) {
await this.calendarChannelRepository.create(
await this.messageChannelRepository.create(
{
id: v4(),
connectedAccountId: newOrExistingConnectedAccountId,
type: MessageChannelType.EMAIL,
handle,
visibility:
calendarVisibility ||
CalendarChannelVisibility.SHARE_EVERYTHING,
messageVisibility || MessageChannelVisibility.SHARE_EVERYTHING,
syncStatus: MessageChannelSyncStatus.ONGOING,
},
workspaceId,
manager,
);
}
} else {
await this.connectedAccountRepository.updateAccessTokenAndRefreshToken(
input.accessToken,
input.refreshToken,
newOrExistingConnectedAccountId,
workspaceId,
manager,
);

await this.messageChannelRepository.resetSync(
newOrExistingConnectedAccountId,
workspaceId,
manager,
);
}
});
if (isCalendarEnabled) {
await this.calendarChannelRepository.save(
{
id: v4(),
connectedAccountId: newOrExistingConnectedAccountId,
handle,
visibility:
calendarVisibility ||
CalendarChannelVisibility.SHARE_EVERYTHING,
},
{},
manager,
);
}
} else {
await this.connectedAccountRepository.updateAccessTokenAndRefreshToken(
input.accessToken,
input.refreshToken,
newOrExistingConnectedAccountId,
workspaceId,
manager,
);

await this.messageChannelRepository.resetSync(
newOrExistingConnectedAccountId,
workspaceId,
manager,
);
}
},
);

if (this.environmentService.get('MESSAGING_PROVIDER_GMAIL_ENABLED')) {
const messageChannels =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,7 @@ export class TokenService {

async generateTransientToken(
workspaceMemberId: string,
userId: string,
workspaceId: string,
): Promise<AuthToken> {
const secret = this.environmentService.get('LOGIN_TOKEN_SECRET');
Expand All @@ -158,6 +159,7 @@ export class TokenService {
const expiresAt = addMilliseconds(new Date().getTime(), ms(expiresIn));
const jwtPayload = {
sub: workspaceMemberId,
userId,
workspaceId,
};

Expand Down Expand Up @@ -234,6 +236,7 @@ export class TokenService {

async verifyTransientToken(transientToken: string): Promise<{
workspaceMemberId: string;
userId: string;
workspaceId: string;
}> {
const transientTokenSecret =
Expand All @@ -243,6 +246,7 @@ export class TokenService {

return {
workspaceMemberId: payload.sub,
userId: payload.userId,
workspaceId: payload.workspaceId,
};
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -203,9 +203,7 @@ export class BillingService {
: frontBaseUrl;

const quantity =
(await this.userWorkspaceService.getWorkspaceMemberCount(
user.defaultWorkspaceId,
)) || 1;
(await this.userWorkspaceService.getWorkspaceMemberCount()) || 1;

const stripeCustomerId = (
await this.billingSubscriptionRepository.findOneBy({
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { Logger } from '@nestjs/common';
import { Logger, Scope } from '@nestjs/common';

import { BillingService } from 'src/engine/core-modules/billing/billing.service';
import { UserWorkspaceService } from 'src/engine/core-modules/user-workspace/user-workspace.service';
Expand All @@ -8,7 +8,10 @@ import { MessageQueue } from 'src/engine/integrations/message-queue/message-queu
import { Process } from 'src/engine/integrations/message-queue/decorators/process.decorator';
export type UpdateSubscriptionJobData = { workspaceId: string };

@Processor(MessageQueue.billingQueue)
@Processor({
queueName: MessageQueue.billingQueue,
scope: Scope.REQUEST,
})
export class UpdateSubscriptionJob {
protected readonly logger = new Logger(UpdateSubscriptionJob.name);

Expand All @@ -21,7 +24,7 @@ export class UpdateSubscriptionJob {
@Process(UpdateSubscriptionJob.name)
async handle(data: UpdateSubscriptionJobData): Promise<void> {
const workspaceMembersCount =
await this.userWorkspaceService.getWorkspaceMemberCount(data.workspaceId);
await this.userWorkspaceService.getWorkspaceMemberCount();

if (!workspaceMembersCount || workspaceMembersCount <= 0) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import { UUIDScalarType } from 'src/engine/api/graphql/workspace-schema-builder/
@ObjectType('TimelineCalendarEventParticipant')
export class TimelineCalendarEventParticipant {
@Field(() => UUIDScalarType, { nullable: true })
personId: string;
personId: string | null;

@Field(() => UUIDScalarType, { nullable: true })
workspaceMemberId: string;
workspaceMemberId: string | null;

@Field()
firstName: string;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,19 +81,19 @@ export class TimelineCalendarEventService {
const participants = event.calendarEventParticipants.map(
(participant) => ({
calendarEventId: event.id,
personId: participant.person?.id,
workspaceMemberId: participant.workspaceMember?.id,
personId: participant.person?.id ?? null,
workspaceMemberId: participant.workspaceMember?.id ?? null,
firstName:
participant.person?.name.firstName ||
participant.person?.name?.firstName ||
participant.workspaceMember?.name.firstName ||
'',
lastName:
participant.person?.name.lastName ||
participant.person?.name?.lastName ||
participant.workspaceMember?.name.lastName ||
'',
displayName:
participant.person?.name.firstName ||
participant.person?.name.lastName ||
participant.person?.name?.firstName ||
participant.person?.name?.lastName ||
participant.workspaceMember?.name.firstName ||
participant.workspaceMember?.name.lastName ||
'',
Expand Down
Loading
Loading