Skip to content

Commit

Permalink
Temp
Browse files Browse the repository at this point in the history
  • Loading branch information
manelcecs committed Dec 11, 2023
1 parent a914675 commit 9bd4739
Show file tree
Hide file tree
Showing 14 changed files with 598 additions and 200 deletions.
32 changes: 20 additions & 12 deletions src/domain-services/categories/category-service.ts
Original file line number Diff line number Diff line change
@@ -1,34 +1,26 @@
import { type Database } from '@unocha/hpc-api-core/src/db';
import { FlowId } from '@unocha/hpc-api-core/src/db/models/flow';

Check failure on line 2 in src/domain-services/categories/category-service.ts

View workflow job for this annotation

GitHub Actions / Code Checks

All imports in the declaration are only used as types. Use `import type`
import { Op } from '@unocha/hpc-api-core/src/db/util/conditions';
import { type InstanceDataOfModel } from '@unocha/hpc-api-core/src/db/util/raw-model';
import { createBrandedValue } from '@unocha/hpc-api-core/src/util/types';
import { Service } from 'typedi';
import { type Category } from './graphql/types';

@Service()
export class CategoryService {
async getCategoriesForFlows(
flowLinks: Map<number, Array<InstanceDataOfModel<Database['flowLink']>>>,
flowIDs: FlowId[],
models: Database
): Promise<Map<number, Category[]>> {
const flowLinksBrandedIds = [];
for (const flowLink of flowLinks.keys()) {
flowLinksBrandedIds.push(createBrandedValue(flowLink));
}

// Group categories by flow ID for easy mapping
const categoriesMap = new Map<number, Category[]>();

if (flowLinksBrandedIds.length === 0) {
return categoriesMap;
}

const categoriesRef: Array<InstanceDataOfModel<Database['categoryRef']>> =
await models.categoryRef.find({
where: {
objectID: {
[Op.IN]: flowLinksBrandedIds,
[Op.IN]: flowIDs,
},
objectType: 'flow',
},
});

Expand Down Expand Up @@ -89,4 +81,20 @@ export class CategoryService {
},
};
}

async findCategories(models: Database, where: any) {
const category = await models.category.find({
where,
});

return category;
}

async findCategoryRefs(models: Database, where: any) {
const categoryRef = await models.categoryRef.find({
where,
});

return categoryRef;
}
}
27 changes: 27 additions & 0 deletions src/domain-services/categories/model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
export type CategoryGroup =
| 'beneficiaryGroup'
| 'contributionStatus'
| 'contributionType'
| 'customLocation'
| 'earmarkingType'
| 'emergencyType'
| 'flowStatus'
| 'flowType'
| 'genderMarker'
| 'inactiveReason'
| 'keywords'
| 'method'
| 'organizationLevel'
| 'organizationType'
| 'pendingStatus'
| 'planCosting'
| 'planIndicated'
| 'planType'
| 'projectGrouping1'
| 'projectGrouping2'
| 'projectPriority'
| 'regions'
| 'reportChannel'
| 'responseType'
| 'sectorIASC'
| 'subsetOfPlan';
98 changes: 58 additions & 40 deletions src/domain-services/flows/flow-search-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import { ReportDetailService } from '../report-details/report-detail-service';
import { type UsageYear } from '../usage-years/grpahql/types';
import { UsageYearService } from '../usage-years/usage-year-service';
import {
type FlowCategoryFilters,
type FlowObjectFilters,
type SearchFlowsArgs,
type SearchFlowsArgsNonPaginated,
Expand All @@ -33,8 +34,8 @@ import {
} from './graphql/types';
import { type FlowEntity } from './model';
import { type FlowSearchStrategy } from './strategy/flow-search-strategy';
import { FlowObjectFiltersStrategy } from './strategy/impl/flow-object-conditions-strategy';
import { OnlyFlowFiltersStrategy } from './strategy/impl/only-flow-conditions-strategy';
import { FlowObjectFiltersStrategy } from './strategy/impl/flow-object-conditions-strategy-impl';
import { OnlyFlowFiltersStrategy } from './strategy/impl/only-flow-conditions-strategy-impl';

@Service()
export class FlowSearchService {
Expand All @@ -56,7 +57,8 @@ export class FlowSearchService {
models: Database,
filters: SearchFlowsArgs
): Promise<FlowSearchResult> {
const { limit, afterCursor, beforeCursor, sortField, sortOrder } = filters;
const { limit, nextPageCursor, prevPageCursor, sortField, sortOrder } =
filters;

const orderBy:
| { column: FlowSortField; order: 'asc' | 'desc' }
Expand All @@ -65,18 +67,19 @@ export class FlowSearchService {
order: sortOrder ?? 'desc',
};

const { flowFilters, flowObjectFilters } = filters;
const { flowFilters, flowObjectFilters, flowCategoryFilters } = filters;

const cursorCondition = this.buildCursorCondition(
beforeCursor,
afterCursor,
prevPageCursor,
nextPageCursor,
orderBy
);

// Determine strategy of how to search for flows
const { strategy, conditions } = this.determineStrategy(
flowFilters,
flowObjectFilters
flowObjectFilters,
flowCategoryFilters
);

// Fetch one more item to check for hasNextPage
Expand Down Expand Up @@ -137,7 +140,7 @@ export class FlowSearchService {
usageYearsMap,
reportDetailsMap,
] = await Promise.all([
this.categoryService.getCategoriesForFlows(flowLinksMap, models),
this.categoryService.getCategoriesForFlows(flowIds, models),
this.organizationService.getOrganizationsForFlows(
organizationsFO,
models
Expand Down Expand Up @@ -210,9 +213,9 @@ export class FlowSearchService {
return {
flows: items,
hasNextPage: limit <= flows.length,
hasPreviousPage: afterCursor !== undefined,
startCursor: flows.length ? items[0].cursor : '',
endCursor: flows.length ? items.at(-1)?.cursor ?? '' : '',
hasPreviousPage: nextPageCursor !== undefined,
prevPageCursor: flows.length ? items[0].cursor : '',
nextPageCursor: flows.length ? items.at(-1)?.cursor ?? '' : '',
pageSize: flows.length,
sortField: sortField ?? 'updatedAt',
sortOrder: sortOrder ?? 'desc',
Expand Down Expand Up @@ -274,49 +277,62 @@ export class FlowSearchService {

determineStrategy(
flowFilters: SearchFlowsFilters,
flowObjectFilters: FlowObjectFilters[]
flowObjectFilters: FlowObjectFilters[],
flowCategoryFilters: FlowCategoryFilters
): { strategy: FlowSearchStrategy; conditions: any } {
let conditions = {};

const isFlowFilterDefined = flowFilters !== undefined;
const isFlowObjectFilterDefined = flowObjectFilters !== undefined;
const isFlowObjectFiltersNotEmpty =
isFlowObjectFilterDefined && flowObjectFilters.length !== 0;

const isFlowCategoryFilterDefined = flowCategoryFilters !== undefined;

if (
(!isFlowFilterDefined &&
(!isFlowObjectFilterDefined || !isFlowObjectFiltersNotEmpty)) ||
(!isFlowObjectFilterDefined || !isFlowObjectFiltersNotEmpty) &&
!isFlowCategoryFilterDefined) ||
(isFlowFilterDefined &&
(!isFlowObjectFilterDefined || !isFlowObjectFiltersNotEmpty))
(!isFlowObjectFilterDefined || !isFlowObjectFiltersNotEmpty) &&
!isFlowCategoryFilterDefined)
) {
const flowConditions = this.prepareFlowConditions(flowFilters);
conditions = { ...conditions, ...flowConditions };
return { strategy: this.onlyFlowFiltersStrategy, conditions };
} else if (!isFlowFilterDefined && isFlowObjectFiltersNotEmpty) {
return {
strategy: this.onlyFlowFiltersStrategy,
conditions: flowConditions,
};
} else if (
!isFlowFilterDefined &&
isFlowObjectFiltersNotEmpty &&
isFlowCategoryFilterDefined
) {
const flowObjectConditions =
this.prepareFlowObjectConditions(flowObjectFilters);
conditions = { ...conditions, ...flowObjectConditions };

return {
strategy: this.flowObjectFiltersStrategy,
conditions: this.buildConditionsMap(undefined, flowObjectConditions),
conditions: {
conditionsMap: this.buildConditionsMap({}, flowObjectConditions),
flowCategoryFilters,
},
};
} else if (isFlowFilterDefined && isFlowObjectFiltersNotEmpty) {
} else if (
isFlowFilterDefined &&
isFlowObjectFiltersNotEmpty &&
isFlowCategoryFilterDefined
) {
const flowConditions = this.prepareFlowConditions(flowFilters);
const flowObjectConditions =
this.prepareFlowObjectConditions(flowObjectFilters);
conditions = {
...conditions,
...flowConditions,
...flowObjectConditions,
};

return {
strategy: this.flowObjectFiltersStrategy,
conditions: this.buildConditionsMap(
flowConditions,
flowObjectConditions
),
conditions: {
conditionsMap: this.buildConditionsMap(
flowConditions,
flowObjectConditions
),
flowCategoryFilters,
},
};
}

Expand Down Expand Up @@ -469,14 +485,15 @@ export class FlowSearchService {
parkedParentSource: FlowParkedParentSource[],
sortColumn?: FlowSortField
): FlowPaged {
let cursor: string | number | Date = sortColumn
? flow.id.valueOf()
: flow[sortColumn ?? 'updatedAt'];
let cursor = sortColumn ? flow[sortColumn] : flow.updatedAt;

if (cursor instanceof Date) {
cursor = cursor.toISOString();
} else if (typeof cursor === 'number') {
cursor = cursor.toString();
} else if (typeof cursor === 'boolean' || cursor === null) {
// cases such as 'boolean'
cursor = flow.id.toString();
}

return {
Expand Down Expand Up @@ -510,11 +527,12 @@ export class FlowSearchService {
models: Database,
args: SearchFlowsArgsNonPaginated
): Promise<FlowSearchTotalAmountResult> {
const { flowFilters, flowObjectFilters } = args;
const { flowFilters, flowObjectFilters, flowCategoryFilters } = args;

const { strategy, conditions } = this.determineStrategy(
flowFilters,
flowObjectFilters
flowObjectFilters,
flowCategoryFilters
);

const { flows, count } = await strategy.search(conditions, models);
Expand Down Expand Up @@ -544,8 +562,8 @@ export class FlowSearchService {

let hasNextPage = flowSearchResponse.hasNextPage;

let cursor = flowSearchResponse.endCursor;
let nextArgs: SearchFlowsArgs = { ...args, afterCursor: cursor };
let cursor = flowSearchResponse.nextPageCursor;
let nextArgs: SearchFlowsArgs = { ...args, nextPageCursor: cursor };

let nextFlowSearchResponse: FlowSearchResult;
while (hasNextPage) {
Expand All @@ -554,10 +572,10 @@ export class FlowSearchService {
flows.push(...nextFlowSearchResponse.flows);

hasNextPage = nextFlowSearchResponse.hasNextPage;
cursor = nextFlowSearchResponse.endCursor;
cursor = nextFlowSearchResponse.nextPageCursor;

// Update the cursor for the next iteration
nextArgs = { ...args, afterCursor: cursor };
nextArgs = { ...args, nextPageCursor: cursor };
}

return { flows, flowsCount: flows.length };
Expand Down
28 changes: 20 additions & 8 deletions src/domain-services/flows/graphql/args.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,15 @@ export class SearchFlowsFilters {
legacyId: number;
}

@InputType()
export class FlowCategoryFilters {
@Field({ nullable: true })
pending: boolean;

@Field(() => [FlowCategory], { nullable: true })
categoryFilters: FlowCategory[];
}

@InputType()
export class FlowObjectFilters {
@Field({ nullable: false })
Expand All @@ -51,11 +60,14 @@ export class FlowObjectFilters {

@InputType()
export class FlowCategory {
@Field({ nullable: false })
@Field({ nullable: true })
id: number;

@Field({ nullable: false })
@Field({ nullable: true })
group: string;

@Field({ nullable: true })
name: string;
}

@ArgsType()
Expand All @@ -66,11 +78,11 @@ export class SearchFlowsArgs extends PaginationArgs<FlowSortField> {
@Field(() => [FlowObjectFilters], { nullable: true })
flowObjectFilters: FlowObjectFilters[];

@Field(() => [FlowCategory], { nullable: true })
categoryFilters: FlowCategory[];

@Field({ nullable: true })
includeChildrenOfParkedFlows: boolean;

@Field({ nullable: true })
flowCategoryFilters: FlowCategoryFilters;
}

@ArgsType()
Expand All @@ -81,9 +93,9 @@ export class SearchFlowsArgsNonPaginated {
@Field(() => [FlowObjectFilters], { nullable: true })
flowObjectFilters: FlowObjectFilters[];

@Field(() => [FlowCategory], { nullable: true })
categoryFilters: FlowCategory[];

@Field({ nullable: true })
includeChildrenOfParkedFlows: boolean;

@Field({ nullable: true })
flowCategoryFilters: FlowCategoryFilters;
}
4 changes: 3 additions & 1 deletion src/domain-services/flows/strategy/flow-search-strategy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ export interface FlowSearchStrategyResponse {

export interface FlowSearchStrategy {
search(
flowConditions: Map<string, any>,
flowConditions:
| Map<string, any>
| { conditionsMap: Map<string, any>; flowCategoryFilters: any },
models: Database,
orderBy?: any,
limit?: number,
Expand Down
17 changes: 17 additions & 0 deletions src/domain-services/flows/strategy/flowID-search-strategy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { type Database } from '@unocha/hpc-api-core/src/db';
import { type FlowId } from '@unocha/hpc-api-core/src/db/models/flow';
import { type FlowCategoryFilters } from '../graphql/args';

export interface FlowIdSearchStrategyResponse {
flowIDs: FlowId[];
}

export interface FlowIDSearchStrategy {
search(
models: Database,
flowObjectsConditions: Map<string, Map<string, number[]>>,
flowCategoryConditions: FlowCategoryFilters
): Promise<FlowIdSearchStrategyResponse>;

generateWhereClause(flowIds: FlowId[], conditions: any): any;
}
Loading

0 comments on commit 9bd4739

Please sign in to comment.