You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
1.4 KiB
TypeScript

//
// Common
//
export type MetadataProps = 'id' | 'createdAt' | 'deleted'
export type Opaque<T, K, L extends string = 'opaque'> = T & { _: K; __: L }
export type Id<T> = Opaque<string, T, 'id'>
//
// Users
//
export type AdministratorRole = 'admin' | 'moderator'
export type StudentRole = 'student'
export type UserRole = AdministratorRole | StudentRole
export type UserId = Id<User>
export type User = {
id: UserId
fullName: string
role: UserRole
}
export function isAdministrator(role: UserRole): role is AdministratorRole {
return role !== 'student'
}
export function isStudent(role: UserRole): role is StudentRole {
return role === 'student'
}
//
// Problems
//
export type ProblemId = Id<Problem>
export type Problem = {
id: ProblemId
createdAt: string
deleted: boolean
title: string
content: string
createdBy: UserId
}
//
// Solutions
//
export type SolutionStatus = 'pending' | 'correct' | 'wrong'
export type SolutionId = Id<Solution>
export type SolutionStatMap = Record<string, SolutionStat | undefined>
export type SolutionStat = {
sentSolutionsCount: number
correctSolutionsCount: number
}
export type Solution = {
id: SolutionId
createdAt: string
deleted: boolean
sentBy: UserId
forProblem: ProblemId
content: string
status: SolutionStatus
/**
* The _visibility status_ only applies when `status` is not "pending"
*/
visible: boolean
}