Skip to content

Commit

Permalink
- add new graphQL query myActivityStatistics
Browse files Browse the repository at this point in the history
  • Loading branch information
zoranmesec committed Jul 17, 2023
1 parent 831c01d commit 9ea5d70
Show file tree
Hide file tree
Showing 5 changed files with 80 additions and 3 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ $ docker-compose up -d
# Use the precreated database dump from the server
$ mkdir db
$ curl https://plezanje.net/storage/db.sql --output ./db/db.sql
$ docker exec -it api_postgres_1 bash -c "psql -U plezanjenet -f /etc/db/db.sql"
$ docker exec -it api-postgres-1 bash -c "psql -U plezanjenet -f /etc/db/db.sql"
```

Copy the `.env.example` file to `.env` and set configuration parameters.
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "plezanje-graphql",
"version": "0.0.1",
"version": "0.0.2",
"description": "",
"author": "",
"private": true,
Expand Down
17 changes: 17 additions & 0 deletions src/activities/resolvers/activity-routes.resolver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import { Activity } from '../entities/activity.entity';
import { ActivityLoader } from '../loaders/activity.loader';
import { ActivityRoutesService } from '../services/activity-routes.service';
import { PaginatedActivityRoutes } from '../utils/paginated-activity-routes.class';
import { StatsActivities } from '../utils/stats-activities.class';
import { GraphQLResolveInfo } from 'graphql';
import { CacheScope } from 'apollo-server-types';
import { CreateActivityRouteInput } from '../dtos/create-activity-route.input';
Expand Down Expand Up @@ -115,6 +116,22 @@ export class ActivityRoutesResolver {
return this.activityRoutesService.paginate(input, currentUser);
}

@UseGuards(UserAuthGuard)
@Query(() => [StatsActivities])
myActivityStatistics(
@CurrentUser() currentUser: User,
@Args('input', { nullable: true }) input: FindActivityRoutesInput = {},
@Info() info: GraphQLResolveInfo,
) {
info.cacheControl.setCacheHint({ scope: CacheScope.Private });

// TODO: currentUser should serve as authorization filter (what is allowed to be returned)
// userId in input should be renamed to forUserId, and be used as a result filter (what is the client asking for)
input.userId = currentUser.id;
return this.activityRoutesService.getStats(input, currentUser);
}


@UseGuards(UserAuthGuard)
@Query(() => [ActivityRoute])
myCragSummary(
Expand Down
45 changes: 44 additions & 1 deletion src/activities/services/activity-routes.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ import {
calculateScore,
recalculateActivityRoutesScores,
} from '../../crags/utils/calculate-scores';
import { StatsActivities } from '../utils/stats-activities.class';

@Injectable()
export class ActivityRoutesService {
Expand Down Expand Up @@ -488,7 +489,6 @@ export class ActivityRoutesService {
currentUser: User = null,
): Promise<PaginatedActivityRoutes> {
const query = this.buildQuery(params, currentUser);

const itemCount = await query.getCount();

const pagination = new PaginationMeta(
Expand All @@ -507,6 +507,49 @@ export class ActivityRoutesService {
});
}

async getStats(
params: FindActivityRoutesInput = {},
currentUser: User = null,
): Promise<StatsActivities[]> {

const builder = this.activityRoutesRepository
.createQueryBuilder('ar')
.select('EXTRACT(YEAR FROM ar.date)', 'year')
.addSelect('r.difficulty', 'difficulty')
.addSelect('ar.ascent_type', 'ascent_type')
.addSelect('count(ar.id)', 'nr_ascents')
.addSelect('count(r.id)', 'nr_routes')
.addSelect('count(p.id)', 'nr_pitches')
.innerJoin('route', 'r', 'r.id = ar.route_id')
.leftJoin('pitch', 'p', 'p.id = ar.pitch_id')
.where('ar.user_id = :userId', {
userId: currentUser.id,
})
.andWhere('ar.ascent_type IN (:...ascentType)', {
ascentType: ['onsight', 'redpoint', 'flash'],
})
.andWhere(
"(r.publish_status IN ('published', 'in_review') OR (r.publish_status = 'draft' AND ar.user_id = :userId))",
{ userId: currentUser.id },
)
.groupBy("r.difficulty").addGroupBy("EXTRACT(YEAR FROM ar.date)").addGroupBy("ar.ascent_type")
.orderBy('r.difficulty', 'ASC')
.addOrderBy('year', 'ASC');

setBuilderCache(builder, 'getRawAndEntities');

const raw = await builder.getRawMany()
const myStats = raw.map((element, index) => {
return {
year: element.year,
difficulty: element.difficulty,
ascent_type: element.ascent_type,
nr_routes: element.nr_routes,
};
});
return myStats;
}

async find(
params: FindActivityRoutesInput = {},
currentUser: User = null,
Expand Down
17 changes: 17 additions & 0 deletions src/activities/utils/stats-activities.class.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { Field, Float, Int, ObjectType } from '@nestjs/graphql';

@ObjectType()
export class StatsActivities {
@Field(() => Int)
year: number;

@Field(() => Float)
difficulty: number;

@Field(() => String)
ascent_type: string;

@Field(() => Int)
nr_routes: number;

}

0 comments on commit 9ea5d70

Please sign in to comment.