Skip to content

Commit

Permalink
Merge pull request #606 from unchainedshop/user-filter
Browse files Browse the repository at this point in the history
Add extended user filters
  • Loading branch information
pozylon authored Nov 26, 2024
2 parents 8d49c04 + 11f2fbf commit de46ac5
Show file tree
Hide file tree
Showing 16 changed files with 210 additions and 71 deletions.
8 changes: 8 additions & 0 deletions changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# Next
## Minor
- API: Extend `Query.users` to accept additional filter options `emailVerified` & `lastLogin`

## Breaking
- Change argument format of `Query.workStatistics`, `Query.eventStatistics` & `Query.orderStatistics` from previous
`from` & `to` to `dateRange` of type `DateFilterInput` for consistency.

# Unchained Engine v2.14

## Minor
Expand Down
107 changes: 98 additions & 9 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 4 additions & 2 deletions packages/api/src/resolvers/queries/events/eventStatistics.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { log } from '@unchainedshop/logger';
import { Root, Context } from '@unchainedshop/types/api.js';
import { DateFilterInput } from '@unchainedshop/types/common.js';

export default async function eventStatistics(
root: Root,
params: { types?: string[]; from?: Date; to?: Date },
params: { types?: string[]; dateRange?: DateFilterInput },
{ userId, modules }: Context,
) {
log(`query eventStatistics ${params.types || ''} ${params.from || ''} ${params.to || ''}`, {
log(`query eventStatistics ${(params?.types || []).join(', ')}`, {
userId,
...(params?.dateRange || {}),
});

return modules.events.getReport(params);
Expand Down
6 changes: 4 additions & 2 deletions packages/api/src/resolvers/queries/orders/orderStatistics.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { log } from '@unchainedshop/logger';
import { Root, Context } from '@unchainedshop/types/api.js';
import { DateFilterInput } from '@unchainedshop/types/common.js';

export default async function orderStatistics(
root: Root,
params: { from?: Date; to?: Date },
params: { dateRange?: DateFilterInput },
{ modules, userId }: Context,
) {
log(`query orderStatistics ${params.from || ''} ${params.to || ''}`, {
log(`query orderStatistics `, {
userId,
...(params?.dateRange || {}),
});

return modules.orders.getReport(params);
Expand Down
5 changes: 5 additions & 0 deletions packages/api/src/resolvers/queries/users/users.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { log } from '@unchainedshop/logger';
import { Context, Root, SortOption } from '@unchainedshop/types/api.js';
import { DateFilterInput } from '@unchainedshop/types/common.js';
import { UserQuery } from '@unchainedshop/types/user.js';

export default async function users(
Expand All @@ -8,6 +9,9 @@ export default async function users(
limit?: number;
offset?: number;
sort?: Array<SortOption>;
includeGuests?: boolean;
emailVerified?: boolean;
lastLogin?: DateFilterInput;
},
{ modules, userId }: Context,
) {
Expand All @@ -17,6 +21,7 @@ export default async function users(
}`,
{
userId,
...(params || {}),
},
);

Expand Down
6 changes: 4 additions & 2 deletions packages/api/src/resolvers/queries/worker/workStatistics.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
import { log } from '@unchainedshop/logger';
import { Root, Context } from '@unchainedshop/types/api.js';
import { DateFilterInput } from '@unchainedshop/types/common.js';

export default async function workStatistics(
root: Root,
params: { types?: string[]; from?: Date; to?: Date },
params: { types?: string[]; dateRange?: DateFilterInput },
{ modules, userId }: Context,
) {
log(`query workStatistics ${params.from || ''} ${params.to || ''}`, {
log(`query workStatistics ${(params?.types || []).join(', ')}`, {
userId,
...(params.dateRange || {}),
});

return modules.worker.getReport(params);
Expand Down
15 changes: 11 additions & 4 deletions packages/api/src/schema/query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,19 @@ export default [
includeGuests: Boolean = false
queryString: String
sort: [SortOptionInput!]
emailVerified: Boolean
lastLogin: DateFilterInput
): [User!]!
"""
Get total number of users in the system that match query
"""
usersCount(includeGuests: Boolean = false, queryString: String): Int!
usersCount(
includeGuests: Boolean = false
queryString: String
emailVerified: Boolean
lastLogin: DateFilterInput
): Int!
"""
Specific user data if userId provided, else returns currently logged in
Expand Down Expand Up @@ -479,15 +486,15 @@ export default [
"""
Returns aggregated report of all the events that occurred in the system
"""
eventStatistics(types: [String!], from: Timestamp, to: Timestamp): [EventStatistics!]!
eventStatistics(types: [String!], dateRange: DateFilterInput): [EventStatistics!]!
"""
Returns aggregated report of all the orders that occurred in the system
"""
orderStatistics(from: Timestamp, to: Timestamp): OrderStatistics!
orderStatistics(dateRange: DateFilterInput): OrderStatistics!
"""
Returns aggregated report of all the worker jobs that occurred in the system
"""
workStatistics(types: [String!], from: Timestamp, to: Timestamp): [WorkStatistics!]!
workStatistics(types: [String!], dateRange: DateFilterInput): [WorkStatistics!]!
}
`,
];
39 changes: 8 additions & 31 deletions packages/core-events/src/module/configureEventsModule.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
import type { mongodb } from '@unchainedshop/mongodb';

import { generateDbFilterById, generateDbMutations, buildSortOptions } from '@unchainedshop/mongodb';
import { getRegisteredEvents } from '@unchainedshop/events';
import { SortDirection, SortOption } from '@unchainedshop/types/api.js';
import { ModuleCreateMutation, ModuleInput, ModuleMutations } from '@unchainedshop/types/core.js';
import { ModuleInput, ModuleMutations } from '@unchainedshop/types/core.js';
import { EventsCollection, Event } from '../db/EventsCollection.js';
import { EventsSchema } from '../db/EventsSchema.js';
import { configureEventHistoryAdapter } from './configureEventHistoryAdapter.js';
import { EventReport } from '@unchainedshop/types/events.js';
import { EventReport, EventsModule } from '@unchainedshop/types/events.js';

export type EventQuery = {
types?: Array<string>;
Expand All @@ -24,27 +22,6 @@ export const buildFindSelector = ({ types, queryString, created }: EventQuery) =
return selector;
};

export interface EventsModule extends ModuleCreateMutation<Event> {
findEvent: (
params: mongodb.Filter<Event> & { eventId: string },
options?: mongodb.FindOptions,
) => Promise<Event>;

findEvents: (
params: EventQuery & {
limit?: number;
offset?: number;
sort?: Array<SortOption>;
},
options?: mongodb.FindOptions,
) => Promise<Array<Event>>;

type: (event: Event) => string;

count: (query: EventQuery) => Promise<number>;
getReport: (params?: { from?: Date; to?: Date; types?: string[] }) => Promise<EventReport[]>;
}

export const configureEventsModule = async ({
db,
}: ModuleInput<Record<string, never>>): Promise<EventsModule> => {
Expand Down Expand Up @@ -84,22 +61,22 @@ export const configureEventsModule = async ({
return count;
},

getReport: async ({ from, to, types } = { from: null, to: null, types: null }) => {
getReport: async ({ dateRange, types } = { dateRange: {}, types: null }) => {
const pipeline = [];
const matchConditions = [];
// build date filter based on provided values it can be a range if both to and from is supplied
// a upper or lowe limit if either from or to is provided
// or all if none is provided
if (from || to) {
if (dateRange?.start || dateRange?.end) {
const dateConditions = [];
if (from) {
const fromDate = new Date(from);
if (dateRange?.start) {
const fromDate = new Date(dateRange?.start);
dateConditions.push({
$or: [{ created: { $gte: fromDate } }, { updated: { $gte: fromDate } }],
});
}
if (to) {
const toDate = new Date(to);
if (dateRange?.end) {
const toDate = new Date(dateRange?.end);
dateConditions.push({
$or: [{ created: { $lte: toDate } }, { updated: { $lte: toDate } }],
});
Expand Down
12 changes: 6 additions & 6 deletions packages/core-orders/src/module/configureOrdersModule-queries.ts
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ export const configureOrdersModuleQueries = ({
return Orders.find(selector, findOptions).toArray();
},

getReport: async ({ from, to } = { from: null, to: null }) => {
getReport: async ({ dateRange } = { dateRange: {} }) => {
const selector: any = { $exists: true };
if (from || to) {
if (from) {
const fromDate = new Date(from);
if (dateRange?.end || dateRange?.start) {
if (dateRange?.start) {
const fromDate = new Date(dateRange?.start);
selector.$gte = fromDate;
}
if (to) {
const toDate = new Date(to);
if (dateRange?.end) {
const toDate = new Date(dateRange?.end);
selector.$lte = toDate;
}
}
Expand Down
Loading

0 comments on commit de46ac5

Please sign in to comment.