Skip to content

Commit

Permalink
some type fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
mipyykko committed Aug 11, 2022
1 parent 1fd5986 commit 8147f01
Show file tree
Hide file tree
Showing 54 changed files with 359 additions and 277 deletions.
1 change: 1 addition & 0 deletions backend/api/completions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,7 @@ export class CompletionController {
const { user } = getUserResult.value
const { slug } = req.params

// TODO: typing
let tierData: any = []

const course = (
Expand Down
3 changes: 2 additions & 1 deletion backend/bin/kafkaConsumer/common/createKafkaConsumer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import { KafkaError } from "../../lib/errors"
import checkConnectionInInterval from "./connectedChecker"

const logCommit =
(logger: winston.Logger) => (err: any, topicPartitions: any) => {
(logger: winston.Logger) =>
(err: any, topicPartitions: Kafka.TopicPartition[]) => {
if (err) {
logger.error(new KafkaError("Error in commit", err))
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ export interface Message {
user_id: number
course_id: string
service_id: string
progress: [PointsByGroup]
progress: PointsByGroup[]
message_format_version: Number
}

Expand Down
12 changes: 7 additions & 5 deletions backend/bin/kafkaConsumer/common/userCourseProgress/validate.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import { Message as KafkaMessage } from "node-rdkafka"
import * as yup from "yup"

import { Message } from "./interfaces"

const CURRENT_MESSAGE_FORMAT_VERSION = 1

const PointsByGroupYupSchema = yup.object().shape({
Expand Down Expand Up @@ -32,14 +34,14 @@ export const MessageYupSchema = yup.object().shape({
.required(),
})

const handleNullProgressImpl = (value: any) => ({
const handleNullProgressImpl = (value: Message) => ({
...value,
progress: value?.progress?.map((progress: any) => ({
...progress,
progress: value?.progress?.map((pointsByGroup) => ({
...pointsByGroup,
progress:
progress.progress === null || isNaN(progress.progress)
pointsByGroup.progress === null || isNaN(pointsByGroup.progress)
? 0
: progress.progress,
: pointsByGroup.progress,
})),
})

Expand Down
69 changes: 37 additions & 32 deletions backend/bin/kafkaConsumer/common/userFunctions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,20 @@ import {
ServiceProgressType,
} from "./userCourseProgress/interfaces"

interface WithKafkaContext {
context: KafkaContext
}

interface GetCombinedUserCourseProgressArgs extends WithKafkaContext {
user: User
course: Course
}

export const getCombinedUserCourseProgress = async ({
user,
course,
context: { prisma },
}: {
user: User
course: Course
context: KafkaContext
}): Promise<CombinedUserCourseProgress> => {
}: GetCombinedUserCourseProgressArgs): Promise<CombinedUserCourseProgress> => {
const userCourseServiceProgresses = await prisma.user
.findUnique({ where: { id: user.id } })
.user_course_service_progresses({
Expand Down Expand Up @@ -61,15 +66,16 @@ export const getCombinedUserCourseProgress = async ({
return combined
}

interface CheckRequiredExerciseCompletionsArgs extends WithKafkaContext {
user: User
course: Course
}

export const checkRequiredExerciseCompletions = async ({
user,
course,
context: { knex },
}: {
user: User
course: Course
context: KafkaContext
}): Promise<boolean> => {
}: CheckRequiredExerciseCompletionsArgs): Promise<boolean> => {
if (course.exercise_completions_needed) {
const exercise_completions = await knex("exercise_completion")
.countDistinct("exercise_completion.exercise_id")
Expand All @@ -85,15 +91,16 @@ export const checkRequiredExerciseCompletions = async ({
return true
}

interface GetExerciseCompletionsForCoursesArgs extends WithKafkaContext {
user: User
courseIds: string[]
}

export const getExerciseCompletionsForCourses = async ({
user,
courseIds,
context: { knex },
}: {
user: User
courseIds: string[]
context: KafkaContext
}) => {
}: GetExerciseCompletionsForCoursesArgs) => {
// picks only one exercise completion per exercise/user:
// the one with the latest timestamp and latest updated_at
const exercise_completions: ExerciseCompletionPart[] = await knex(
Expand All @@ -118,15 +125,16 @@ export const getExerciseCompletionsForCourses = async ({
return exercise_completions // ?.rows ?? []
}

interface PruneDuplicateExerciseCompletionsArgs extends WithKafkaContext {
user_id: string
course_id: string
}

export const pruneDuplicateExerciseCompletions = async ({
user_id,
course_id,
context: { knex },
}: {
user_id: string
course_id: string
context: KafkaContext
}) => {
}: PruneDuplicateExerciseCompletionsArgs) => {
// variation: only prune those with the latest timestamp but older updated_at
/*const deleted: Array<Pick<ExerciseCompletion, "id">> = await knex(
"exercise_completion",
Expand Down Expand Up @@ -198,9 +206,7 @@ export const pruneDuplicateExerciseCompletions = async ({

export const pruneOrphanedExerciseCompletionRequiredActions = async ({
context: { knex },
}: {
context: KafkaContext
}) => {
}: WithKafkaContext) => {
const deleted: Array<Pick<ExerciseCompletionRequiredAction, "id">> =
await knex("exercise_completion_required_actions")
.whereNull("exercise_completion_id")
Expand All @@ -210,15 +216,16 @@ export const pruneOrphanedExerciseCompletionRequiredActions = async ({
return deleted
}

interface GetUserCourseSettingsArgs extends WithKafkaContext {
user_id: string
course_id: string
}

export const getUserCourseSettings = async ({
user_id,
course_id,
context: { prisma },
}: {
user_id: string
course_id: string
context: KafkaContext
}): Promise<UserCourseSetting | null> => {
}: GetUserCourseSettingsArgs): Promise<UserCourseSetting | null> => {
// - if the course inherits user course settings from some course, get settings from that one
// - if not, get from the course itself or null if none exists
const result = await prisma.course.findUnique({
Expand Down Expand Up @@ -256,12 +263,11 @@ export const getUserCourseSettings = async ({
)
}

interface CheckCompletionArgs {
interface CheckCompletionArgs extends WithKafkaContext {
user: User
course: Course
handler?: Course | null
combinedProgress?: CombinedUserCourseProgress
context: KafkaContext
}

export const checkCompletion = async ({
Expand Down Expand Up @@ -301,12 +307,11 @@ export const checkCompletion = async ({
}
}

interface CreateCompletionArgs {
interface CreateCompletionArgs extends WithKafkaContext {
user: User
course: Course
handler?: Course | null
tier?: number
context: KafkaContext
}

export const createCompletion = async ({
Expand Down
2 changes: 1 addition & 1 deletion backend/bin/kafkaConsumer/exerciseConsumer/interfaces.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ export interface Message {
timestamp: string
course_id: string
service_id: string
data: ExerciseData[] //[ExerciseData]
data: ExerciseData[]
message_format_version: number
}

Expand Down
49 changes: 27 additions & 22 deletions backend/bin/seedPoints.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,20 @@ import { Prisma } from "@prisma/client"
import prisma from "../prisma"

//Generate integer id which is not already taken
function generateUniqueUpstreamId({ ExistingIds }: { ExistingIds: number[] }) {
function generateUniqueUpstreamId(existingIds: number[]) {
//take the largest possible integer
const LargestPossibleUpstreamId = 2147483647
let UniqueIntId = 0
const MAX_INTEGER = 2147483647
let uniqueIntId = 0
//Go down from the largest possible integer
//until value not already in use is found
let i: number
for (i = LargestPossibleUpstreamId; i > 0; i--) {
if (ExistingIds.indexOf(i) === -1) {
UniqueIntId = i
return UniqueIntId
for (let i = MAX_INTEGER; i > 0; i--) {
if (existingIds.indexOf(i) === -1) {
uniqueIntId = i
return uniqueIntId
}
}

return UniqueIntId
return uniqueIntId
}

function generateRandomString() {
Expand All @@ -30,10 +29,12 @@ function generateRandomString() {
}

const addUsers = async () => {
//get existing users from database
const UsersInDatabase = await prisma.user.findMany()
//create a list of upstream ids already in use
let UpstreamIdsInUse = UsersInDatabase.map((user) => user.upstream_id)
//get existing upstream_ids
const upstreamIdsInUse = (
await prisma.user.findMany({
select: { upstream_id: true },
})
).map((user) => user.upstream_id)
//Generate random data for 100 users
//and add them to the database
let i = 0
Expand All @@ -42,7 +43,7 @@ const addUsers = async () => {
const last_name = faker.name.lastName()

const newUser = {
upstream_id: generateUniqueUpstreamId({ ExistingIds: UpstreamIdsInUse }),
upstream_id: generateUniqueUpstreamId(upstreamIdsInUse),
first_name,
last_name,
username: faker.internet.userName(first_name, last_name),
Expand All @@ -52,7 +53,7 @@ const addUsers = async () => {
real_student_number: generateRandomString(),
}
//add new upstreamId to ids already in use
UpstreamIdsInUse = UpstreamIdsInUse.concat(newUser.upstream_id)
upstreamIdsInUse.push(newUser.upstream_id)

await prisma.user.create({ data: newUser })
i += 1
Expand All @@ -71,10 +72,11 @@ const addServices = async () => {
}
}

const addUserCourseProgressess = async ({ courseId }: { courseId: string }) => {
const UsersInDb = await prisma.user.findMany({ take: 100 })
const addUserCourseProgressess = async (courseId: string) => {
const usersInDb = await prisma.user.findMany({ take: 100 })

return await Promise.all(
UsersInDb.map(async (user) => {
usersInDb.map(async (user) => {
const progress = [
{
group: "week1",
Expand Down Expand Up @@ -129,7 +131,7 @@ const addUserCourseProgressess = async ({ courseId }: { courseId: string }) => {
)
}

const addUserCourseSettingses = async ({ courseId }: { courseId: string }) => {
const addUserCourseSettingses = async (courseId: string) => {
const UsersInDb = await prisma.user.findMany({ take: 100 })
return await Promise.all(
UsersInDb.map(async (user) => {
Expand Down Expand Up @@ -160,11 +162,14 @@ const seedPointsData = async () => {
const course = await prisma.course.findUnique({
where: { slug: "elements-of-ai" },
})
console.log("course", course)

await addUsers()
await addServices()
course && (await addUserCourseProgressess({ courseId: course.id }))
course && (await addUserCourseSettingses({ courseId: course.id }))

if (course) {
await addUserCourseProgressess(course.id)
await addUserCourseSettingses(course.id)
}
}

seedPointsData().finally(() => process.exit(0))
20 changes: 16 additions & 4 deletions backend/graphql/CompletionRegistered.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,15 @@
import { ForbiddenError } from "apollo-server-express"
import { chunk } from "lodash"
import { arg, extendType, intArg, list, objectType, stringArg } from "nexus"
import {
arg,
extendType,
intArg,
list,
nonNull,
objectType,
stringArg,
} from "nexus"
import { type NexusGenInputs } from "nexus-typegen"

import { Prisma } from "@prisma/client"

Expand Down Expand Up @@ -109,11 +118,11 @@ export const CompletionRegisteredMutations = extendType({
t.field("registerCompletion", {
type: "String",
args: {
completions: list(arg({ type: "CompletionArg" })),
completions: nonNull(list(nonNull(arg({ type: "CompletionArg" })))),
},
authorize: isOrganization,
resolve: async (_, args, ctx: Context) => {
let queue = chunk(args.completions, 500)
const queue = chunk(args.completions, 500)

for (let i = 0; i < queue.length; i++) {
const promises = buildPromises(queue[i], ctx)
Expand All @@ -125,7 +134,10 @@ export const CompletionRegisteredMutations = extendType({
},
})

const buildPromises = (array: any[], ctx: Context) => {
const buildPromises = (
array: Array<NexusGenInputs["CompletionArg"]>,
ctx: Context,
) => {
return array.map(async (entry) => {
const { user_id, course_id } =
(await ctx.prisma.completion.findUnique({
Expand Down
Loading

0 comments on commit 8147f01

Please sign in to comment.