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: technique creation #628

Merged
merged 53 commits into from
Jul 1, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
9801309
New page creation
deepaksftc Jun 5, 2024
2dbe3de
Add techniques patch
simonfernandes Jun 5, 2024
1791c95
Add GraphQL groundwork
simonfernandes Jun 5, 2024
90cc6c5
Frontend grapghql changes
deepaksftc Jun 6, 2024
3920af1
Get Technique flow
deepaksftc Jun 6, 2024
aa4dcde
Add mutations
simonfernandes Jun 7, 2024
29999af
Fix naming
simonfernandes Jun 7, 2024
7cd6580
Get techniques flow
deepaksftc Jun 7, 2024
3c845ce
Correction in get instruments flow
deepaksftc Jun 7, 2024
f62005c
Corrections to get techniques flow
deepaksftc Jun 7, 2024
3e3ca40
Fix schema generation
simonfernandes Jun 7, 2024
4ff4319
Assign instruments flow
deepaksftc Jun 10, 2024
17b8353
Add technique creation
simonfernandes Jun 10, 2024
6d3f8f6
Add initial backend testing
simonfernandes Jun 10, 2024
c41da92
Fix file
simonfernandes Jun 10, 2024
3eae8a5
Fix technique delete flow
simonfernandes Jun 10, 2024
86bc220
Minor corrections
deepaksftc Jun 10, 2024
e36a003
Add mutations backend tests
simonfernandes Jun 11, 2024
6f8b8c3
Query unit test cases
deepaksftc Jun 11, 2024
f1dfe21
Validation schema for mutations
deepaksftc Jun 12, 2024
a339874
Add technique e2e base
simonfernandes Jun 12, 2024
53e299b
Add technique e2e cypress commands
simonfernandes Jun 12, 2024
3721725
Basic test cases
deepaksftc Jun 12, 2024
0b301ed
Basic tests
deepaksftc Jun 12, 2024
e14612f
Add technique instrument assignment test
simonfernandes Jun 12, 2024
a7850f2
Remove e2e restriction
simonfernandes Jun 12, 2024
e40c73c
Move validation to user-office-lib
simonfernandes Jun 12, 2024
332fc61
Revert "Move validation to user-office-lib"
simonfernandes Jun 12, 2024
ba52ecc
Move validation to user-office-lib
simonfernandes Jun 13, 2024
83d0733
Fix typos
simonfernandes Jun 13, 2024
6bb5cfd
Fix technique deletion
simonfernandes Jun 13, 2024
e25bfda
Fix instrument deletion
simonfernandes Jun 13, 2024
db05a9a
Review comment fixes
deepaksftc Jun 21, 2024
65bc025
Link technique setting commands
simonfernandes Jun 21, 2024
a7623c2
Revert changing id to techniqueId
simonfernandes Jun 21, 2024
5819163
Add backend tests
simonfernandes Jun 21, 2024
e288da1
Review comment fixes
deepaksftc Jun 25, 2024
ff01ff8
Validation version upgrade
deepaksftc Jun 26, 2024
141fce3
delete and update flow fix
deepaksftc Jun 26, 2024
f141a6c
Improve error handling
simonfernandes Jun 26, 2024
4ddd65e
Simplify condition
simonfernandes Jun 26, 2024
ddd1355
Simplify values
simonfernandes Jun 26, 2024
0abac72
Change return value
simonfernandes Jun 26, 2024
1bc25c5
Simplify params
simonfernandes Jun 26, 2024
e7395f5
Merge branch 'develop' into 1095
simonfernandes Jun 26, 2024
c98b997
Remove multiple instruments in single call
simonfernandes Jun 27, 2024
78e3fdd
Merge branch 'develop' into 1095
simonfernandes Jun 27, 2024
54353d9
Fix tests
simonfernandes Jun 27, 2024
d794ced
Events handling
deepaksftc Jun 27, 2024
57cc0a2
Passing technique id for events
deepaksftc Jun 27, 2024
24be98e
Change assign/remove inst icon
simonfernandes Jun 28, 2024
faf3561
Use translation for technique
simonfernandes Jun 28, 2024
ba2cbd6
Remove redundant else statement
simonfernandes Jul 1, 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
Prev Previous commit
Next Next commit
Add GraphQL groundwork
  • Loading branch information
simonfernandes authored and deepaksftc committed Jun 25, 2024
commit 1791c9577ee274d919810dde9811434be85a2703
1 change: 1 addition & 0 deletions apps/backend/src/config/Tokens.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export const Tokens = {
FileDataSource: Symbol('FileDataSource'),
GenericTemplateDataSource: Symbol('GenericTemplateDataSource'),
InstrumentDataSource: Symbol('InstrumentDataSource'),
TechniqueDataSource: Symbol('TechniqueDataSource'),
ListenToMessageQueue: Symbol('ListenToMessageQueue'),
MailService: Symbol('MailService'),
PdfTemplateDataSource: Symbol('PdfTemplateDataSource'),
Expand Down
2 changes: 2 additions & 0 deletions apps/backend/src/context/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ import SampleQueries from '../queries/SampleQueries';
import ScheduledEventQueries from '../queries/ScheduledEventQueries';
import ShipmentQueries from '../queries/ShipmentQueries';
import SystemQueries from '../queries/SystemQueries';
import TechniqueQueries from '../queries/TechniqueQueries';
import TemplateQueries from '../queries/TemplateQueries';
import UnitQueries from '../queries/UnitQueries';
import UserQueries from '../queries/UserQueries';
Expand All @@ -59,6 +60,7 @@ interface ResolverContextQueries {
file: FileQueries;
genericTemplate: GenericTemplateQueries;
instrument: InstrumentQueries;
technique: TechniqueQueries;
pdfTemplate: PdfTemplateQueries;
proposal: ProposalQueries;
proposalEsi: ProposalEsiQueries;
Expand Down
14 changes: 14 additions & 0 deletions apps/backend/src/datasources/TechniqueDataSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { Instrument } from '../models/Instrument';
import { Technique } from '../models/Technique';

export interface TechniqueDataSource {
// create(args: CreateTechniqueArgs): Promise<Technique>;
getTechnique(instrumentId: number): Promise<Technique | null>;
getTechniques(
first?: number,
offset?: number
): Promise<{ totalCount: number; techniques: Technique[] }>;
getInstrumentsByTechniqueId(techniqueId: number): Promise<Instrument[]>;
update(technique: Technique): Promise<Technique>;
delete(technique: number): Promise<Technique>;
}
33 changes: 33 additions & 0 deletions apps/backend/src/datasources/postgres/TechniqueDataSource.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import { injectable } from 'tsyringe';

import { Instrument } from '../../models/Instrument';
import { Technique } from '../../models/Technique';
import { TechniqueDataSource } from '../TechniqueDataSource';

@injectable()
export default class PostgresTechniqueDataSource
implements TechniqueDataSource
{
getTechnique(instrumentId: number): Promise<Technique | null> {
throw new Error('Method not implemented.');
}

getTechniques(
first?: number | undefined,
offset?: number | undefined
): Promise<{ totalCount: number; techniques: Technique[] }> {
throw new Error('Method not implemented.');
}

getInstrumentsByTechniqueId(techniqueId: number): Promise<Instrument[]> {
throw new Error('Method not implemented.');
}

update(technique: Technique): Promise<Technique> {
throw new Error('Method not implemented.');
}

delete(technique: number): Promise<Technique> {
throw new Error('Method not implemented.');
}
}
16 changes: 16 additions & 0 deletions apps/backend/src/models/Technique.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
export class Technique {
constructor(
public id: number,
public name: string,
public shortCode: string,
public description: string
) {}
}

export class TechniqueHasInstruments {
constructor(
public techniqueHasInstrumentIds: number[],
public techniqueIds: number[],
public instrumentIds: number[]
) {}
}
74 changes: 74 additions & 0 deletions apps/backend/src/mutations/TechniqueMutations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { inject, injectable } from 'tsyringe';

import { UserAuthorization } from '../auth/UserAuthorization';
import { Tokens } from '../config/Tokens';
import { Authorized } from '../decorators';
import { Rejection } from '../models/Rejection';
import { Roles } from '../models/Role';
import { Technique } from '../models/Technique';
import { UserWithRole } from '../models/User';
import { TechniqueDataSource } from './../datasources/TechniqueDataSource';

@injectable()
export default class TechniqueMutations {
constructor(
@inject(Tokens.TechniqueDataSource)
private dataSource: TechniqueDataSource,
@inject(Tokens.UserAuthorization) private userAuth: UserAuthorization
) {}

// @EventBus(Event.TECHNIQUE_CREATED)
@Authorized([Roles.USER_OFFICER])
async create(
agent: UserWithRole | null
// args: CreateTechniqueArgs
): Promise<Technique | Rejection> {
return new Rejection('not implemented');
// return this.dataSource.create(args).catch((error) => {
// return rejection(
// 'Could not create technique',
// { agent, shortCode: args.shortCode },
// error
// );
// });
}

// @EventBus(Event.TECHNIQUE_UPDATED)
// @ValidateArgs(updateTechniqueValidationSchema)
@Authorized([Roles.USER_OFFICER])
async update(
agent: UserWithRole | null
// args: UpdateInstrumentArgs
): Promise<Technique | Rejection> {
return new Rejection('not implemented');

// return this.dataSource.update(args).catch((error) => {
// return rejection(
// 'Could not update technique',
// { agent, techniqueId: args.id },
// error
// );
// });
}

// @EventBus(Event.TECHNIQUE_DELETED)
// @ValidateArgs(deleteTechniqueValidationSchema)
@Authorized([Roles.USER_OFFICER])
async delete(
agent: UserWithRole | null,
args: { id: number }
): Promise<Technique | Rejection> {
return new Rejection('not implemented');

// return this.dataSource.delete(args.id).catch((error) => {
// return rejection(
// 'Could not delete technique',
// { agent, techniqueId: args.id },
// error
// );
// });
}

// async assignInstrumentsToTechnique()
// async removeInstrumentsFromTechnique()
}
56 changes: 56 additions & 0 deletions apps/backend/src/queries/TechniqueQueries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { inject, injectable } from 'tsyringe';

import { UserAuthorization } from '../auth/UserAuthorization';
import { Tokens } from '../config/Tokens';
import { TechniqueDataSource } from '../datasources/TechniqueDataSource';
import { Authorized } from '../decorators';
import { Roles } from '../models/Role';
import { UserWithRole } from '../models/User';

@injectable()
export default class TechniqueQueries {
constructor(
@inject(Tokens.TechniqueDataSource)
public dataSource: TechniqueDataSource,
@inject(Tokens.UserAuthorization)
private userAuth: UserAuthorization
) {}

private isUserOfficer(agent: UserWithRole | null) {
if (agent == null) {
return false;
}

return agent?.currentRole?.shortCode === Roles.USER_OFFICER;
}

@Authorized()
async get(agent: UserWithRole | null, techniqueId: number) {
const technique = await this.dataSource.getTechnique(techniqueId);

return technique;
}

@Authorized()
async getInstrumentsByTechniqueId(
agent: UserWithRole | null,
techniqueId: number
) {
return await this.dataSource.getInstrumentsByTechniqueId(techniqueId);
}

@Authorized([
Roles.USER_OFFICER,
Roles.FAP_REVIEWER,
Roles.FAP_CHAIR,
Roles.FAP_SECRETARY,
])
async getAll(agent: UserWithRole | null) {
return await this.dataSource.getTechniques();
}

@Authorized()
async byRef(agent: UserWithRole | null, id: number) {
return this.dataSource.getTechnique(id);
}
}
50 changes: 50 additions & 0 deletions apps/backend/src/resolvers/types/Technique.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import {
ObjectType,
Field,
Int,
Resolver,
FieldResolver,
Root,
Ctx,
Directive,
} from 'type-graphql';

import { ResolverContext } from '../../context';
import { isRejection } from '../../models/Rejection';
import { Technique as TechniqueOrigin } from '../../models/Technique';
import { Instrument } from './Instrument';

@ObjectType()
@Directive('@key(fields: "id")')
export class Technique implements Partial<TechniqueOrigin> {
@Field(() => Int)
public id: number;

@Field()
public name: string;

@Field()
public shortCode: string;

@Field()
public description: string;

@Field(() => Int)
public managerUserId: number;
}

@Resolver(() => Technique)
export class TechniqueResolver {
@FieldResolver(() => [Instrument])
async instruments(
@Root() technique: Technique,
@Ctx() context: ResolverContext
): Promise<Instrument[] | null> {
const instruments =
context.queries.technique.dataSource.getInstrumentsByTechniqueId(
technique.id
);

return isRejection(instruments) ? [] : instruments;
}
}