Fetch additional projects data and implement resolver for deployments query (#22)

* Add resolver function for fetching all deployments for a project

* Fetch project members while fetching organization data

* Map db project member and deployment entity to graphql type

* Fetch environment variables data while fetching organizations

* Add domain field in deployment

---------

Co-authored-by: neeraj <neeraj.rtly@gmail.com>
This commit is contained in:
prathamesh0 2024-01-18 14:06:49 +05:30 committed by Ashwin Phatak
parent 9f1306f9cd
commit 62c969d1ff
6 changed files with 145 additions and 20 deletions

View File

@ -7,6 +7,9 @@ import { User } from './entity/User';
import { Organization } from './entity/Organization';
import { UserOrganization } from './entity/UserOrganization';
import { Project } from './entity/Project';
import { Deployment } from './entity/Deployment';
import { ProjectMember } from './entity/ProjectMember';
import { EnvironmentVariable } from './entity/EnvironmentVariable';
const log = debug('snowball:database');
@ -37,16 +40,16 @@ export class Database {
return user;
}
async getOrganizationsbyUserId (userId: number) : Promise<Organization[]> {
async getOrganizationsByUserId (userId: number) : Promise<Organization[]> {
const userOrganizationRepository = this.dataSource.getRepository(UserOrganization);
const userOrgs = await userOrganizationRepository.find({
relations: {
user: true,
member: true,
organization: true
},
where: {
user: {
member: {
id: userId
}
}
@ -56,7 +59,7 @@ export class Database {
return organizations;
}
async getProjectsbyOrganizationId (organizationId: number): Promise<Project[]> {
async getProjectsByOrganizationId (organizationId: number): Promise<Project[]> {
const projectRepository = this.dataSource.getRepository(Project);
const projects = await projectRepository.find({
@ -73,4 +76,57 @@ export class Database {
return projects;
}
async getDeploymentsByProjectId (projectId: string): Promise<Deployment[]> {
const deploymentRepository = this.dataSource.getRepository(Deployment);
const deployments = await deploymentRepository.find({
relations: {
project: true,
domain: true
},
where: {
project: {
id: projectId
}
}
});
return deployments;
}
async getProjectMembers (projectId: string): Promise<ProjectMember[]> {
const projectMemberRepository = this.dataSource.getRepository(ProjectMember);
const projectMembers = await projectMemberRepository.find({
relations: {
project: true,
member: true
},
where: {
project: {
id: projectId
}
}
});
return projectMembers;
}
async getEnvironmentVariablesByProjectId (projectId: string): Promise<EnvironmentVariable[]> {
const environmentVariableRepository = this.dataSource.getRepository(EnvironmentVariable);
const environmentVariables = await environmentVariableRepository.find({
relations: {
project: true
},
where: {
project: {
id: projectId
}
}
});
return environmentVariables;
}
}

View File

@ -10,6 +10,12 @@ import {
import { Project } from './Project';
enum Environment {
Production = 'Production',
Preview = 'Preview',
Development = 'Development',
}
@Entity()
export class EnvironmentVariable {
@PrimaryGeneratedColumn()
@ -22,7 +28,7 @@ export class EnvironmentVariable {
@Column({
type: 'simple-array'
})
environments!: string[];
environments!: Environment[];
@Column('varchar')
key!: string;

View File

@ -12,9 +12,8 @@ import { Project } from './Project';
import { User } from './User';
enum Permissions {
Owner = 'Owner',
Maintainer = 'Maintainer',
Reader = 'Reader',
View = 'View',
Edit = 'Edit'
}
@Entity()
@ -24,16 +23,16 @@ export class ProjectMember {
@ManyToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
user!: User;
member!: User;
@ManyToOne(() => Project, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'projectId' })
project!: Project;
@Column({
enum: Permissions
type: 'simple-array'
})
role!: Permissions;
permissions!: Permissions[];
@CreateDateColumn()
createdAt!: Date;

View File

@ -24,7 +24,7 @@ export class UserOrganization {
@ManyToOne(() => User, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'userId' })
user!: User;
member!: User;
@ManyToOne(() => Organization, { onDelete: 'CASCADE' })
@JoinColumn({ name: 'organizationId' })

View File

@ -1,5 +1,5 @@
import { Database } from './database';
import { projectToGqlType } from './utils';
import { deploymentToGqlType, projectMemberToGqlType, projectToGqlType, environmentVariableToGqlType } from './utils';
export const createResolvers = async (db: Database): Promise<any> => {
return {
@ -10,25 +10,47 @@ export const createResolvers = async (db: Database): Promise<any> => {
},
organizations: async (_:any, __: any, context: any) => {
const organizations = await db.getOrganizationsbyUserId(context.userId);
const organizations = await db.getOrganizationsByUserId(context.userId);
const orgsWithProjectsPromises = organizations.map(async (org) => {
const dbProjects = await db.getProjectsbyOrganizationId(org.id);
const dbProjects = await db.getProjectsByOrganizationId(org.id);
const projects = dbProjects.map(dbProject => {
return projectToGqlType(dbProject);
const projectsWithPromises = dbProjects.map(async (dbProject) => {
const dbProjectMembers = await db.getProjectMembers(dbProject.id);
const dbEnvironmentVariables = await db.getEnvironmentVariablesByProjectId(dbProject.id);
const projectMembers = dbProjectMembers.map(dbProjectMember => {
return projectMemberToGqlType(dbProjectMember);
});
const environmentVariables = dbEnvironmentVariables.map(dbEnvironmentVariable => {
return environmentVariableToGqlType(dbEnvironmentVariable);
});
return projectToGqlType(dbProject, projectMembers, environmentVariables);
});
const projects = await Promise.all(projectsWithPromises);
return {
...org,
projects
};
});
// TODO: Add organizationMembers field when / if required
const orgsWithProjects = await Promise.all(orgsWithProjectsPromises);
// TODO: Populate members field when / if required
return orgsWithProjects;
},
deployments: async (_: any, { projectId }: { projectId: string }) => {
const dbDeployments = await db.getDeploymentsByProjectId(projectId);
const deployments = dbDeployments.map(dbDeployment => {
return deploymentToGqlType(dbDeployment);
});
return deployments;
}
}
};

View File

@ -4,6 +4,9 @@ import toml from 'toml';
import debug from 'debug';
import { Project } from './entity/Project';
import { ProjectMember } from './entity/ProjectMember';
import { Deployment } from './entity/Deployment';
import { EnvironmentVariable } from './entity/EnvironmentVariable';
const log = debug('snowball:utils');
@ -22,7 +25,7 @@ export const getConfig = async <ConfigType>(
return config;
};
export const projectToGqlType = (dbProject: Project): any => {
export const projectToGqlType = (dbProject: Project, projectMembers: ProjectMember[], environmentVariables: EnvironmentVariable[]): any => {
return {
id: dbProject.id,
owner: dbProject.owner,
@ -33,7 +36,46 @@ export const projectToGqlType = (dbProject: Project): any => {
template: dbProject.template,
framework: dbProject.framework,
webhooks: dbProject.webhooks,
members: projectMembers,
environmentVariables: environmentVariables,
createdAt: dbProject.createdAt,
updatedAt: dbProject.updatedAt
};
};
// TODO: Add domain field to deployment
export const deploymentToGqlType = (dbDeployment: Deployment): any => {
return {
id: dbDeployment.id,
domain: dbDeployment.domain,
branch: dbDeployment.branch,
commitHash: dbDeployment.commitHash,
title: dbDeployment.title,
environment: dbDeployment.environment,
isCurrent: dbDeployment.isCurrent,
status: dbDeployment.status,
createdAt: dbDeployment.createdAt,
updatedAt: dbDeployment.updatedAt
};
};
export const projectMemberToGqlType = (dbProjectMember: ProjectMember): any => {
return {
id: dbProjectMember.id,
member: dbProjectMember.member,
permissions: dbProjectMember.permissions,
createdAt: dbProjectMember.createdAt,
updatedAt: dbProjectMember.updatedAt
};
};
export const environmentVariableToGqlType = (dbEnvironmentVariable: EnvironmentVariable): any => {
return {
id: dbEnvironmentVariable.id,
environments: dbEnvironmentVariable.environments,
key: dbEnvironmentVariable.key,
value: dbEnvironmentVariable.value,
createdAt: dbEnvironmentVariable.createdAt,
updatedAt: dbEnvironmentVariable.updatedAt
};
};