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: participation streak templates #964

Merged
merged 5 commits into from
Feb 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
8 changes: 5 additions & 3 deletions common/achievement/bucket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ export const bucketCreatorDefs: BucketCreatorDefs = {
const subcourseBuckets = context.subcourse
.map((subcourse) => createLectureBuckets(subcourse, LectureBucketMessuringType.start))
.reduce((acc, val) => acc.concat(val), []);
return { bucketKind: 'time', buckets: [...matchBuckets, ...subcourseBuckets] };
const buckets = [...matchBuckets, ...subcourseBuckets].sort((a, b) => a.startTime.getTime() - b.startTime.getTime());
return { bucketKind: 'time', buckets: buckets };
},
},
by_lecture_participation: {
Expand All @@ -67,9 +68,10 @@ export const bucketCreatorDefs: BucketCreatorDefs = {
.map((match) => createLectureBuckets(match, LectureBucketMessuringType.participation))
.reduce((acc, val) => acc.concat(val), []);
const subcourseBuckets = context.subcourse
.map((subcourse) => createLectureBuckets(subcourse, LectureBucketMessuringType.participation))
.map((subcourse) => createLectureBuckets(subcourse, LectureBucketMessuringType.start))
.reduce((acc, val) => acc.concat(val), []);
return { bucketKind: 'time', buckets: [...matchBuckets, ...subcourseBuckets] };
const buckets = [...matchBuckets, ...subcourseBuckets].sort((a, b) => b.startTime.getTime() - a.startTime.getTime());
return { bucketKind: 'time', buckets: buckets };
},
},
by_weeks: {
Expand Down
25 changes: 15 additions & 10 deletions common/achievement/get.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const getFurtherAchievements = async (user: User): Promise<Achievement[]> => {
const dataAggr = template.conditionDataAggregations as Prisma.JsonObject;
const maxValue = Object.keys(dataAggr)
.map((key) => {
const val = dataAggr[key] as number;
const val = dataAggr[key]['valueToAchieve'] as number;
return Number(val);
})
.reduce((a, b) => a + b, 0);
Expand All @@ -90,7 +90,7 @@ const getFurtherAchievements = async (user: User): Promise<Achievement[]> => {
maxSteps: maxValue,
currentStep: 0,
isNewAchievement: null,
progressDescription: `Noch ${userAchievements.length - userAchievements.length} Schritte bis zum Abschluss`,
progressDescription: template.progressDescription,
actionName: template.actionName,
actionRedirectLink: template.actionRedirectLink,
};
Expand Down Expand Up @@ -152,10 +152,6 @@ const assembleAchievementData = async (userAchievements: achievements_with_templ
orderBy: { groupOrder: 'asc' },
});

const state: achievement_state = getAchievementState(userAchievements, currentAchievementIndex);

const isNewAchievement = state === achievement_state.COMPLETED && !userAchievements[currentAchievementIndex].isSeen;

const condition = userAchievements[currentAchievementIndex].recordValue
? userAchievements[currentAchievementIndex].template.condition.replace(
'recordValue',
Expand All @@ -181,8 +177,8 @@ const assembleAchievementData = async (userAchievements: achievements_with_templ
currentValue = dataAggregationKeys.map((key) => evaluationResult.resultObject[key]).reduce((a, b) => a + b, 0);
maxValue =
userAchievements[currentAchievementIndex].template.type === achievement_type_enum.STREAK
? userAchievements[currentAchievementIndex].recordValue !== null && userAchievements[currentAchievementIndex].recordValue! > currentValue
? userAchievements[currentAchievementIndex].recordValue!
? userAchievements[currentAchievementIndex].recordValue !== null && userAchievements[currentAchievementIndex].recordValue > currentValue
? userAchievements[currentAchievementIndex].recordValue
: currentValue
: dataAggregationKeys
.map((key) => {
Expand All @@ -192,22 +188,31 @@ const assembleAchievementData = async (userAchievements: achievements_with_templ
);
})
.reduce((a, b) => a + b, 0);
if (currentValue < maxValue && userAchievements[currentAchievementIndex].achievedAt) {
await prisma.user_achievement.update({
where: { id: userAchievements[currentAchievementIndex].id },
data: { achievedAt: null, isSeen: false },
});
Comment on lines +192 to +195
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think that this belongs here.
It would mean that we have an invalid state for some reason, which shouldn't be fixed while assembling data.

When does it happen?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Imagine you have a streak of 25 consecutive meetings joined.
Now you do not join any more meetings. You do not fire any more events "match_meeting_joined" or what ever the action name is.
The streak would never be resolved into being 0 because we never reevaluate. We offered a cronjob, that was already implemented, but that was not wanted either. So we have to update streaks here.

}
}
} else {
currentValue = currentAchievementIndex;
maxValue = achievementTemplates.length - 1;
}

const state: achievement_state = getAchievementState(userAchievements, currentAchievementIndex);
const isNewAchievement = state === achievement_state.COMPLETED && !userAchievements[currentAchievementIndex].isSeen;

const achievementContext = transformPrismaJson(
user,
userAchievements[currentAchievementIndex].relation,
userAchievements[currentAchievementIndex].context as Prisma.JsonObject
);
const leftProgress = maxValue - currentValue;
const leftProgress = maxValue - currentValue + 1;
LucasFalkowsky marked this conversation as resolved.
Show resolved Hide resolved
const currentAchievementTemplate = renderAchievementWithContext(userAchievements[currentAchievementIndex], achievementContext, {
remainingProgress: leftProgress.toString(),
progress: currentValue.toString(),
recordValue: maxValue.toString(),
maxValue: maxValue.toString(),
});

return {
Expand Down
4 changes: 2 additions & 2 deletions graphql/types/achievement.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ class Achievement {
@Field()
name: string;

@Field()
subtitle: string;
@Field({ nullable: true })
subtitle?: string;

@Field()
description: string;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
-- AlterTable
ALTER TABLE "achievement_template" ALTER COLUMN "subtitle" DROP NOT NULL,
ALTER COLUMN "achievedImage" DROP NOT NULL;
4 changes: 2 additions & 2 deletions prisma/schema.prisma
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ model achievement_template {
stepName String @db.VarChar
// what type of achievement is it
type achievement_type_enum
subtitle String @db.VarChar
subtitle String? @db.VarChar
description String @db.VarChar
image String @db.VarChar
achievedImage String @db.VarChar
achievedImage String? @db.VarChar
// some achievements show actions that a user can/must perform next.
// therefore we need the action name, type (for the icon) and a redirect link
actionName String? @db.VarChar
Expand Down
Loading
Loading