Tomi Cvetic 5 жил өмнө
parent
commit
26a63b5c78

+ 5 - 0
.vscode/settings.json

@@ -0,0 +1,5 @@
+{
+    "prettier.semi": false,
+    "standard.autoFixOnSave": true,
+    "editor.formatOnSave": true
+}

+ 372 - 47
backend/database/generated/prisma-client/index.d.ts

@@ -23,6 +23,7 @@ export interface Exists {
   rating: (where?: RatingWhereInput) => Promise<boolean>;
   track: (where?: TrackWhereInput) => Promise<boolean>;
   training: (where?: TrainingWhereInput) => Promise<boolean>;
+  trainingType: (where?: TrainingTypeWhereInput) => Promise<boolean>;
   user: (where?: UserWhereInput) => Promise<boolean>;
 }
 
@@ -178,6 +179,27 @@ export interface Prisma {
     first?: Int;
     last?: Int;
   }) => TrainingConnectionPromise;
+  trainingType: (
+    where: TrainingTypeWhereUniqueInput
+  ) => TrainingTypeNullablePromise;
+  trainingTypes: (args?: {
+    where?: TrainingTypeWhereInput;
+    orderBy?: TrainingTypeOrderByInput;
+    skip?: Int;
+    after?: String;
+    before?: String;
+    first?: Int;
+    last?: Int;
+  }) => FragmentableArray<TrainingType>;
+  trainingTypesConnection: (args?: {
+    where?: TrainingTypeWhereInput;
+    orderBy?: TrainingTypeOrderByInput;
+    skip?: Int;
+    after?: String;
+    before?: String;
+    first?: Int;
+    last?: Int;
+  }) => TrainingTypeConnectionPromise;
   user: (where: UserWhereUniqueInput) => UserNullablePromise;
   users: (args?: {
     where?: UserWhereInput;
@@ -315,6 +337,26 @@ export interface Prisma {
   }) => TrainingPromise;
   deleteTraining: (where: TrainingWhereUniqueInput) => TrainingPromise;
   deleteManyTrainings: (where?: TrainingWhereInput) => BatchPayloadPromise;
+  createTrainingType: (data: TrainingTypeCreateInput) => TrainingTypePromise;
+  updateTrainingType: (args: {
+    data: TrainingTypeUpdateInput;
+    where: TrainingTypeWhereUniqueInput;
+  }) => TrainingTypePromise;
+  updateManyTrainingTypes: (args: {
+    data: TrainingTypeUpdateManyMutationInput;
+    where?: TrainingTypeWhereInput;
+  }) => BatchPayloadPromise;
+  upsertTrainingType: (args: {
+    where: TrainingTypeWhereUniqueInput;
+    create: TrainingTypeCreateInput;
+    update: TrainingTypeUpdateInput;
+  }) => TrainingTypePromise;
+  deleteTrainingType: (
+    where: TrainingTypeWhereUniqueInput
+  ) => TrainingTypePromise;
+  deleteManyTrainingTypes: (
+    where?: TrainingTypeWhereInput
+  ) => BatchPayloadPromise;
   createUser: (data: UserCreateInput) => UserPromise;
   updateUser: (args: {
     data: UserUpdateInput;
@@ -361,6 +403,9 @@ export interface Subscription {
   training: (
     where?: TrainingSubscriptionWhereInput
   ) => TrainingSubscriptionPayloadSubscription;
+  trainingType: (
+    where?: TrainingTypeSubscriptionWhereInput
+  ) => TrainingTypeSubscriptionPayloadSubscription;
   user: (
     where?: UserSubscriptionWhereInput
   ) => UserSubscriptionPayloadSubscription;
@@ -426,6 +471,8 @@ export type RatingOrderByInput =
   | "createdAt_ASC"
   | "createdAt_DESC";
 
+export type Permission = "ADMIN" | "INSTRUCTOR" | "USER";
+
 export type FormatOrderByInput =
   | "id_ASC"
   | "id_DESC"
@@ -441,8 +488,6 @@ export type UserOrderByInput =
   | "email_DESC"
   | "name_ASC"
   | "name_DESC"
-  | "abbreviation_ASC"
-  | "abbreviation_DESC"
   | "password_ASC"
   | "password_DESC"
   | "createdAt_ASC"
@@ -456,7 +501,17 @@ export type TrainingOrderByInput =
   | "createdAt_ASC"
   | "createdAt_DESC"
   | "trainingDate_ASC"
-  | "trainingDate_DESC";
+  | "trainingDate_DESC"
+  | "published_ASC"
+  | "published_DESC";
+
+export type TrainingTypeOrderByInput =
+  | "id_ASC"
+  | "id_DESC"
+  | "name_ASC"
+  | "name_DESC"
+  | "description_ASC"
+  | "description_DESC";
 
 export type MutationType = "CREATED" | "UPDATED" | "DELETED";
 
@@ -805,20 +860,6 @@ export interface UserWhereInput {
   name_not_starts_with?: Maybe<String>;
   name_ends_with?: Maybe<String>;
   name_not_ends_with?: Maybe<String>;
-  abbreviation?: Maybe<String>;
-  abbreviation_not?: Maybe<String>;
-  abbreviation_in?: Maybe<String[] | String>;
-  abbreviation_not_in?: Maybe<String[] | String>;
-  abbreviation_lt?: Maybe<String>;
-  abbreviation_lte?: Maybe<String>;
-  abbreviation_gt?: Maybe<String>;
-  abbreviation_gte?: Maybe<String>;
-  abbreviation_contains?: Maybe<String>;
-  abbreviation_not_contains?: Maybe<String>;
-  abbreviation_starts_with?: Maybe<String>;
-  abbreviation_not_starts_with?: Maybe<String>;
-  abbreviation_ends_with?: Maybe<String>;
-  abbreviation_not_ends_with?: Maybe<String>;
   password?: Maybe<String>;
   password_not?: Maybe<String>;
   password_in?: Maybe<String[] | String>;
@@ -952,6 +993,7 @@ export interface TrainingWhereInput {
   title_not_starts_with?: Maybe<String>;
   title_ends_with?: Maybe<String>;
   title_not_ends_with?: Maybe<String>;
+  type?: Maybe<TrainingTypeWhereInput>;
   content_every?: Maybe<BlockWhereInput>;
   content_some?: Maybe<BlockWhereInput>;
   content_none?: Maybe<BlockWhereInput>;
@@ -977,11 +1019,65 @@ export interface TrainingWhereInput {
   ratings_every?: Maybe<RatingWhereInput>;
   ratings_some?: Maybe<RatingWhereInput>;
   ratings_none?: Maybe<RatingWhereInput>;
+  published?: Maybe<Boolean>;
+  published_not?: Maybe<Boolean>;
   AND?: Maybe<TrainingWhereInput[] | TrainingWhereInput>;
   OR?: Maybe<TrainingWhereInput[] | TrainingWhereInput>;
   NOT?: Maybe<TrainingWhereInput[] | TrainingWhereInput>;
 }
 
+export interface TrainingTypeWhereInput {
+  id?: Maybe<ID_Input>;
+  id_not?: Maybe<ID_Input>;
+  id_in?: Maybe<ID_Input[] | ID_Input>;
+  id_not_in?: Maybe<ID_Input[] | ID_Input>;
+  id_lt?: Maybe<ID_Input>;
+  id_lte?: Maybe<ID_Input>;
+  id_gt?: Maybe<ID_Input>;
+  id_gte?: Maybe<ID_Input>;
+  id_contains?: Maybe<ID_Input>;
+  id_not_contains?: Maybe<ID_Input>;
+  id_starts_with?: Maybe<ID_Input>;
+  id_not_starts_with?: Maybe<ID_Input>;
+  id_ends_with?: Maybe<ID_Input>;
+  id_not_ends_with?: Maybe<ID_Input>;
+  name?: Maybe<String>;
+  name_not?: Maybe<String>;
+  name_in?: Maybe<String[] | String>;
+  name_not_in?: Maybe<String[] | String>;
+  name_lt?: Maybe<String>;
+  name_lte?: Maybe<String>;
+  name_gt?: Maybe<String>;
+  name_gte?: Maybe<String>;
+  name_contains?: Maybe<String>;
+  name_not_contains?: Maybe<String>;
+  name_starts_with?: Maybe<String>;
+  name_not_starts_with?: Maybe<String>;
+  name_ends_with?: Maybe<String>;
+  name_not_ends_with?: Maybe<String>;
+  description?: Maybe<String>;
+  description_not?: Maybe<String>;
+  description_in?: Maybe<String[] | String>;
+  description_not_in?: Maybe<String[] | String>;
+  description_lt?: Maybe<String>;
+  description_lte?: Maybe<String>;
+  description_gt?: Maybe<String>;
+  description_gte?: Maybe<String>;
+  description_contains?: Maybe<String>;
+  description_not_contains?: Maybe<String>;
+  description_starts_with?: Maybe<String>;
+  description_not_starts_with?: Maybe<String>;
+  description_ends_with?: Maybe<String>;
+  description_not_ends_with?: Maybe<String>;
+  AND?: Maybe<TrainingTypeWhereInput[] | TrainingTypeWhereInput>;
+  OR?: Maybe<TrainingTypeWhereInput[] | TrainingTypeWhereInput>;
+  NOT?: Maybe<TrainingTypeWhereInput[] | TrainingTypeWhereInput>;
+}
+
+export type TrainingTypeWhereUniqueInput = AtLeastOne<{
+  id: Maybe<ID_Input>;
+}>;
+
 export type UserWhereUniqueInput = AtLeastOne<{
   id: Maybe<ID_Input>;
   email?: Maybe<String>;
@@ -1327,9 +1423,10 @@ export interface UserCreateWithoutCommentsInput {
   id?: Maybe<ID_Input>;
   email: String;
   name: String;
-  abbreviation: String;
   password: String;
   ratings?: Maybe<RatingCreateManyWithoutUserInput>;
+  permissions?: Maybe<UserCreatepermissionsInput>;
+  interests?: Maybe<UserCreateinterestsInput>;
 }
 
 export interface RatingCreateManyWithoutUserInput {
@@ -1343,6 +1440,14 @@ export interface RatingCreateWithoutUserInput {
   comment: String;
 }
 
+export interface UserCreatepermissionsInput {
+  set?: Maybe<Permission[] | Permission>;
+}
+
+export interface UserCreateinterestsInput {
+  set?: Maybe<String[] | String>;
+}
+
 export interface CommentUpdateInput {
   text?: Maybe<String>;
   author?: Maybe<UserUpdateOneRequiredWithoutCommentsInput>;
@@ -1358,9 +1463,10 @@ export interface UserUpdateOneRequiredWithoutCommentsInput {
 export interface UserUpdateWithoutCommentsDataInput {
   email?: Maybe<String>;
   name?: Maybe<String>;
-  abbreviation?: Maybe<String>;
   password?: Maybe<String>;
   ratings?: Maybe<RatingUpdateManyWithoutUserInput>;
+  permissions?: Maybe<UserUpdatepermissionsInput>;
+  interests?: Maybe<UserUpdateinterestsInput>;
 }
 
 export interface RatingUpdateManyWithoutUserInput {
@@ -1460,6 +1566,14 @@ export interface RatingUpdateManyDataInput {
   comment?: Maybe<String>;
 }
 
+export interface UserUpdatepermissionsInput {
+  set?: Maybe<Permission[] | Permission>;
+}
+
+export interface UserUpdateinterestsInput {
+  set?: Maybe<String[] | String>;
+}
+
 export interface UserUpsertWithoutCommentsInput {
   update: UserUpdateWithoutCommentsDataInput;
   create: UserCreateWithoutCommentsInput;
@@ -1509,9 +1623,10 @@ export interface UserCreateWithoutRatingsInput {
   id?: Maybe<ID_Input>;
   email: String;
   name: String;
-  abbreviation: String;
   password: String;
   comments?: Maybe<CommentCreateManyWithoutAuthorInput>;
+  permissions?: Maybe<UserCreatepermissionsInput>;
+  interests?: Maybe<UserCreateinterestsInput>;
 }
 
 export interface CommentCreateManyWithoutAuthorInput {
@@ -1542,9 +1657,10 @@ export interface UserUpdateOneRequiredWithoutRatingsInput {
 export interface UserUpdateWithoutRatingsDataInput {
   email?: Maybe<String>;
   name?: Maybe<String>;
-  abbreviation?: Maybe<String>;
   password?: Maybe<String>;
   comments?: Maybe<CommentUpdateManyWithoutAuthorInput>;
+  permissions?: Maybe<UserUpdatepermissionsInput>;
+  interests?: Maybe<UserUpdateinterestsInput>;
 }
 
 export interface CommentUpdateManyWithoutAuthorInput {
@@ -1663,10 +1779,23 @@ export interface TrackUpdateManyMutationInput {
 export interface TrainingCreateInput {
   id?: Maybe<ID_Input>;
   title: String;
+  type: TrainingTypeCreateOneInput;
   content?: Maybe<BlockCreateManyInput>;
   trainingDate: DateTimeInput;
   participants?: Maybe<UserCreateManyInput>;
   ratings?: Maybe<RatingCreateManyInput>;
+  published: Boolean;
+}
+
+export interface TrainingTypeCreateOneInput {
+  create?: Maybe<TrainingTypeCreateInput>;
+  connect?: Maybe<TrainingTypeWhereUniqueInput>;
+}
+
+export interface TrainingTypeCreateInput {
+  id?: Maybe<ID_Input>;
+  name: String;
+  description: String;
 }
 
 export interface BlockCreateManyInput {
@@ -1683,10 +1812,11 @@ export interface UserCreateInput {
   id?: Maybe<ID_Input>;
   email: String;
   name: String;
-  abbreviation: String;
   password: String;
   comments?: Maybe<CommentCreateManyWithoutAuthorInput>;
   ratings?: Maybe<RatingCreateManyWithoutUserInput>;
+  permissions?: Maybe<UserCreatepermissionsInput>;
+  interests?: Maybe<UserCreateinterestsInput>;
 }
 
 export interface RatingCreateManyInput {
@@ -1696,10 +1826,29 @@ export interface RatingCreateManyInput {
 
 export interface TrainingUpdateInput {
   title?: Maybe<String>;
+  type?: Maybe<TrainingTypeUpdateOneRequiredInput>;
   content?: Maybe<BlockUpdateManyInput>;
   trainingDate?: Maybe<DateTimeInput>;
   participants?: Maybe<UserUpdateManyInput>;
   ratings?: Maybe<RatingUpdateManyInput>;
+  published?: Maybe<Boolean>;
+}
+
+export interface TrainingTypeUpdateOneRequiredInput {
+  create?: Maybe<TrainingTypeCreateInput>;
+  update?: Maybe<TrainingTypeUpdateDataInput>;
+  upsert?: Maybe<TrainingTypeUpsertNestedInput>;
+  connect?: Maybe<TrainingTypeWhereUniqueInput>;
+}
+
+export interface TrainingTypeUpdateDataInput {
+  name?: Maybe<String>;
+  description?: Maybe<String>;
+}
+
+export interface TrainingTypeUpsertNestedInput {
+  update: TrainingTypeUpdateDataInput;
+  create: TrainingTypeCreateInput;
 }
 
 export interface BlockUpdateManyInput {
@@ -1847,10 +1996,11 @@ export interface UserUpdateWithWhereUniqueNestedInput {
 export interface UserUpdateDataInput {
   email?: Maybe<String>;
   name?: Maybe<String>;
-  abbreviation?: Maybe<String>;
   password?: Maybe<String>;
   comments?: Maybe<CommentUpdateManyWithoutAuthorInput>;
   ratings?: Maybe<RatingUpdateManyWithoutUserInput>;
+  permissions?: Maybe<UserUpdatepermissionsInput>;
+  interests?: Maybe<UserUpdateinterestsInput>;
 }
 
 export interface UserUpsertWithWhereUniqueNestedInput {
@@ -1902,20 +2052,6 @@ export interface UserScalarWhereInput {
   name_not_starts_with?: Maybe<String>;
   name_ends_with?: Maybe<String>;
   name_not_ends_with?: Maybe<String>;
-  abbreviation?: Maybe<String>;
-  abbreviation_not?: Maybe<String>;
-  abbreviation_in?: Maybe<String[] | String>;
-  abbreviation_not_in?: Maybe<String[] | String>;
-  abbreviation_lt?: Maybe<String>;
-  abbreviation_lte?: Maybe<String>;
-  abbreviation_gt?: Maybe<String>;
-  abbreviation_gte?: Maybe<String>;
-  abbreviation_contains?: Maybe<String>;
-  abbreviation_not_contains?: Maybe<String>;
-  abbreviation_starts_with?: Maybe<String>;
-  abbreviation_not_starts_with?: Maybe<String>;
-  abbreviation_ends_with?: Maybe<String>;
-  abbreviation_not_ends_with?: Maybe<String>;
   password?: Maybe<String>;
   password_not?: Maybe<String>;
   password_in?: Maybe<String[] | String>;
@@ -1951,8 +2087,9 @@ export interface UserUpdateManyWithWhereNestedInput {
 export interface UserUpdateManyDataInput {
   email?: Maybe<String>;
   name?: Maybe<String>;
-  abbreviation?: Maybe<String>;
   password?: Maybe<String>;
+  permissions?: Maybe<UserUpdatepermissionsInput>;
+  interests?: Maybe<UserUpdateinterestsInput>;
 }
 
 export interface RatingUpdateManyInput {
@@ -1996,22 +2133,35 @@ export interface RatingUpsertWithWhereUniqueNestedInput {
 export interface TrainingUpdateManyMutationInput {
   title?: Maybe<String>;
   trainingDate?: Maybe<DateTimeInput>;
+  published?: Maybe<Boolean>;
+}
+
+export interface TrainingTypeUpdateInput {
+  name?: Maybe<String>;
+  description?: Maybe<String>;
+}
+
+export interface TrainingTypeUpdateManyMutationInput {
+  name?: Maybe<String>;
+  description?: Maybe<String>;
 }
 
 export interface UserUpdateInput {
   email?: Maybe<String>;
   name?: Maybe<String>;
-  abbreviation?: Maybe<String>;
   password?: Maybe<String>;
   comments?: Maybe<CommentUpdateManyWithoutAuthorInput>;
   ratings?: Maybe<RatingUpdateManyWithoutUserInput>;
+  permissions?: Maybe<UserUpdatepermissionsInput>;
+  interests?: Maybe<UserUpdateinterestsInput>;
 }
 
 export interface UserUpdateManyMutationInput {
   email?: Maybe<String>;
   name?: Maybe<String>;
-  abbreviation?: Maybe<String>;
   password?: Maybe<String>;
+  permissions?: Maybe<UserUpdatepermissionsInput>;
+  interests?: Maybe<UserUpdateinterestsInput>;
 }
 
 export interface BlockSubscriptionWhereInput {
@@ -2101,6 +2251,23 @@ export interface TrainingSubscriptionWhereInput {
   >;
 }
 
+export interface TrainingTypeSubscriptionWhereInput {
+  mutation_in?: Maybe<MutationType[] | MutationType>;
+  updatedFields_contains?: Maybe<String>;
+  updatedFields_contains_every?: Maybe<String[] | String>;
+  updatedFields_contains_some?: Maybe<String[] | String>;
+  node?: Maybe<TrainingTypeWhereInput>;
+  AND?: Maybe<
+    TrainingTypeSubscriptionWhereInput[] | TrainingTypeSubscriptionWhereInput
+  >;
+  OR?: Maybe<
+    TrainingTypeSubscriptionWhereInput[] | TrainingTypeSubscriptionWhereInput
+  >;
+  NOT?: Maybe<
+    TrainingTypeSubscriptionWhereInput[] | TrainingTypeSubscriptionWhereInput
+  >;
+}
+
 export interface UserSubscriptionWhereInput {
   mutation_in?: Maybe<MutationType[] | MutationType>;
   updatedFields_contains?: Maybe<String>;
@@ -2421,16 +2588,16 @@ export interface User {
   id: ID_Output;
   email: String;
   name: String;
-  abbreviation: String;
   password: String;
   createdAt: DateTimeOutput;
+  permissions: Permission[];
+  interests: String[];
 }
 
 export interface UserPromise extends Promise<User>, Fragmentable {
   id: () => Promise<ID_Output>;
   email: () => Promise<String>;
   name: () => Promise<String>;
-  abbreviation: () => Promise<String>;
   password: () => Promise<String>;
   createdAt: () => Promise<DateTimeOutput>;
   comments: <T = FragmentableArray<Comment>>(args?: {
@@ -2451,6 +2618,8 @@ export interface UserPromise extends Promise<User>, Fragmentable {
     first?: Int;
     last?: Int;
   }) => T;
+  permissions: () => Promise<Permission[]>;
+  interests: () => Promise<String[]>;
 }
 
 export interface UserSubscription
@@ -2459,7 +2628,6 @@ export interface UserSubscription
   id: () => Promise<AsyncIterator<ID_Output>>;
   email: () => Promise<AsyncIterator<String>>;
   name: () => Promise<AsyncIterator<String>>;
-  abbreviation: () => Promise<AsyncIterator<String>>;
   password: () => Promise<AsyncIterator<String>>;
   createdAt: () => Promise<AsyncIterator<DateTimeOutput>>;
   comments: <T = Promise<AsyncIterator<CommentSubscription>>>(args?: {
@@ -2480,6 +2648,8 @@ export interface UserSubscription
     first?: Int;
     last?: Int;
   }) => T;
+  permissions: () => Promise<AsyncIterator<Permission[]>>;
+  interests: () => Promise<AsyncIterator<String[]>>;
 }
 
 export interface UserNullablePromise
@@ -2488,7 +2658,6 @@ export interface UserNullablePromise
   id: () => Promise<ID_Output>;
   email: () => Promise<String>;
   name: () => Promise<String>;
-  abbreviation: () => Promise<String>;
   password: () => Promise<String>;
   createdAt: () => Promise<DateTimeOutput>;
   comments: <T = FragmentableArray<Comment>>(args?: {
@@ -2509,6 +2678,8 @@ export interface UserNullablePromise
     first?: Int;
     last?: Int;
   }) => T;
+  permissions: () => Promise<Permission[]>;
+  interests: () => Promise<String[]>;
 }
 
 export interface Rating {
@@ -2823,11 +2994,13 @@ export interface Training {
   title: String;
   createdAt: DateTimeOutput;
   trainingDate: DateTimeOutput;
+  published: Boolean;
 }
 
 export interface TrainingPromise extends Promise<Training>, Fragmentable {
   id: () => Promise<ID_Output>;
   title: () => Promise<String>;
+  type: <T = TrainingTypePromise>() => T;
   content: <T = FragmentableArray<Block>>(args?: {
     where?: BlockWhereInput;
     orderBy?: BlockOrderByInput;
@@ -2857,6 +3030,7 @@ export interface TrainingPromise extends Promise<Training>, Fragmentable {
     first?: Int;
     last?: Int;
   }) => T;
+  published: () => Promise<Boolean>;
 }
 
 export interface TrainingSubscription
@@ -2864,6 +3038,7 @@ export interface TrainingSubscription
     Fragmentable {
   id: () => Promise<AsyncIterator<ID_Output>>;
   title: () => Promise<AsyncIterator<String>>;
+  type: <T = TrainingTypeSubscription>() => T;
   content: <T = Promise<AsyncIterator<BlockSubscription>>>(args?: {
     where?: BlockWhereInput;
     orderBy?: BlockOrderByInput;
@@ -2893,6 +3068,7 @@ export interface TrainingSubscription
     first?: Int;
     last?: Int;
   }) => T;
+  published: () => Promise<AsyncIterator<Boolean>>;
 }
 
 export interface TrainingNullablePromise
@@ -2900,6 +3076,7 @@ export interface TrainingNullablePromise
     Fragmentable {
   id: () => Promise<ID_Output>;
   title: () => Promise<String>;
+  type: <T = TrainingTypePromise>() => T;
   content: <T = FragmentableArray<Block>>(args?: {
     where?: BlockWhereInput;
     orderBy?: BlockOrderByInput;
@@ -2929,6 +3106,37 @@ export interface TrainingNullablePromise
     first?: Int;
     last?: Int;
   }) => T;
+  published: () => Promise<Boolean>;
+}
+
+export interface TrainingType {
+  id: ID_Output;
+  name: String;
+  description: String;
+}
+
+export interface TrainingTypePromise
+  extends Promise<TrainingType>,
+    Fragmentable {
+  id: () => Promise<ID_Output>;
+  name: () => Promise<String>;
+  description: () => Promise<String>;
+}
+
+export interface TrainingTypeSubscription
+  extends Promise<AsyncIterator<TrainingType>>,
+    Fragmentable {
+  id: () => Promise<AsyncIterator<ID_Output>>;
+  name: () => Promise<AsyncIterator<String>>;
+  description: () => Promise<AsyncIterator<String>>;
+}
+
+export interface TrainingTypeNullablePromise
+  extends Promise<TrainingType | null>,
+    Fragmentable {
+  id: () => Promise<ID_Output>;
+  name: () => Promise<String>;
+  description: () => Promise<String>;
 }
 
 export interface TrainingConnection {
@@ -2987,6 +3195,62 @@ export interface AggregateTrainingSubscription
   count: () => Promise<AsyncIterator<Int>>;
 }
 
+export interface TrainingTypeConnection {
+  pageInfo: PageInfo;
+  edges: TrainingTypeEdge[];
+}
+
+export interface TrainingTypeConnectionPromise
+  extends Promise<TrainingTypeConnection>,
+    Fragmentable {
+  pageInfo: <T = PageInfoPromise>() => T;
+  edges: <T = FragmentableArray<TrainingTypeEdge>>() => T;
+  aggregate: <T = AggregateTrainingTypePromise>() => T;
+}
+
+export interface TrainingTypeConnectionSubscription
+  extends Promise<AsyncIterator<TrainingTypeConnection>>,
+    Fragmentable {
+  pageInfo: <T = PageInfoSubscription>() => T;
+  edges: <T = Promise<AsyncIterator<TrainingTypeEdgeSubscription>>>() => T;
+  aggregate: <T = AggregateTrainingTypeSubscription>() => T;
+}
+
+export interface TrainingTypeEdge {
+  node: TrainingType;
+  cursor: String;
+}
+
+export interface TrainingTypeEdgePromise
+  extends Promise<TrainingTypeEdge>,
+    Fragmentable {
+  node: <T = TrainingTypePromise>() => T;
+  cursor: () => Promise<String>;
+}
+
+export interface TrainingTypeEdgeSubscription
+  extends Promise<AsyncIterator<TrainingTypeEdge>>,
+    Fragmentable {
+  node: <T = TrainingTypeSubscription>() => T;
+  cursor: () => Promise<AsyncIterator<String>>;
+}
+
+export interface AggregateTrainingType {
+  count: Int;
+}
+
+export interface AggregateTrainingTypePromise
+  extends Promise<AggregateTrainingType>,
+    Fragmentable {
+  count: () => Promise<Int>;
+}
+
+export interface AggregateTrainingTypeSubscription
+  extends Promise<AsyncIterator<AggregateTrainingType>>,
+    Fragmentable {
+  count: () => Promise<AsyncIterator<Int>>;
+}
+
 export interface UserConnection {
   pageInfo: PageInfo;
   edges: UserEdge[];
@@ -3390,6 +3654,7 @@ export interface TrainingPreviousValues {
   title: String;
   createdAt: DateTimeOutput;
   trainingDate: DateTimeOutput;
+  published: Boolean;
 }
 
 export interface TrainingPreviousValuesPromise
@@ -3399,6 +3664,7 @@ export interface TrainingPreviousValuesPromise
   title: () => Promise<String>;
   createdAt: () => Promise<DateTimeOutput>;
   trainingDate: () => Promise<DateTimeOutput>;
+  published: () => Promise<Boolean>;
 }
 
 export interface TrainingPreviousValuesSubscription
@@ -3408,6 +3674,54 @@ export interface TrainingPreviousValuesSubscription
   title: () => Promise<AsyncIterator<String>>;
   createdAt: () => Promise<AsyncIterator<DateTimeOutput>>;
   trainingDate: () => Promise<AsyncIterator<DateTimeOutput>>;
+  published: () => Promise<AsyncIterator<Boolean>>;
+}
+
+export interface TrainingTypeSubscriptionPayload {
+  mutation: MutationType;
+  node: TrainingType;
+  updatedFields: String[];
+  previousValues: TrainingTypePreviousValues;
+}
+
+export interface TrainingTypeSubscriptionPayloadPromise
+  extends Promise<TrainingTypeSubscriptionPayload>,
+    Fragmentable {
+  mutation: () => Promise<MutationType>;
+  node: <T = TrainingTypePromise>() => T;
+  updatedFields: () => Promise<String[]>;
+  previousValues: <T = TrainingTypePreviousValuesPromise>() => T;
+}
+
+export interface TrainingTypeSubscriptionPayloadSubscription
+  extends Promise<AsyncIterator<TrainingTypeSubscriptionPayload>>,
+    Fragmentable {
+  mutation: () => Promise<AsyncIterator<MutationType>>;
+  node: <T = TrainingTypeSubscription>() => T;
+  updatedFields: () => Promise<AsyncIterator<String[]>>;
+  previousValues: <T = TrainingTypePreviousValuesSubscription>() => T;
+}
+
+export interface TrainingTypePreviousValues {
+  id: ID_Output;
+  name: String;
+  description: String;
+}
+
+export interface TrainingTypePreviousValuesPromise
+  extends Promise<TrainingTypePreviousValues>,
+    Fragmentable {
+  id: () => Promise<ID_Output>;
+  name: () => Promise<String>;
+  description: () => Promise<String>;
+}
+
+export interface TrainingTypePreviousValuesSubscription
+  extends Promise<AsyncIterator<TrainingTypePreviousValues>>,
+    Fragmentable {
+  id: () => Promise<AsyncIterator<ID_Output>>;
+  name: () => Promise<AsyncIterator<String>>;
+  description: () => Promise<AsyncIterator<String>>;
 }
 
 export interface UserSubscriptionPayload {
@@ -3439,9 +3753,10 @@ export interface UserPreviousValues {
   id: ID_Output;
   email: String;
   name: String;
-  abbreviation: String;
   password: String;
   createdAt: DateTimeOutput;
+  permissions: Permission[];
+  interests: String[];
 }
 
 export interface UserPreviousValuesPromise
@@ -3450,9 +3765,10 @@ export interface UserPreviousValuesPromise
   id: () => Promise<ID_Output>;
   email: () => Promise<String>;
   name: () => Promise<String>;
-  abbreviation: () => Promise<String>;
   password: () => Promise<String>;
   createdAt: () => Promise<DateTimeOutput>;
+  permissions: () => Promise<Permission[]>;
+  interests: () => Promise<String[]>;
 }
 
 export interface UserPreviousValuesSubscription
@@ -3461,9 +3777,10 @@ export interface UserPreviousValuesSubscription
   id: () => Promise<AsyncIterator<ID_Output>>;
   email: () => Promise<AsyncIterator<String>>;
   name: () => Promise<AsyncIterator<String>>;
-  abbreviation: () => Promise<AsyncIterator<String>>;
   password: () => Promise<AsyncIterator<String>>;
   createdAt: () => Promise<AsyncIterator<DateTimeOutput>>;
+  permissions: () => Promise<AsyncIterator<Permission[]>>;
+  interests: () => Promise<AsyncIterator<String[]>>;
 }
 
 /*
@@ -3508,10 +3825,18 @@ export const models: Model[] = [
     name: "User",
     embedded: false
   },
+  {
+    name: "Permission",
+    embedded: false
+  },
   {
     name: "Training",
     embedded: false
   },
+  {
+    name: "TrainingType",
+    embedded: false
+  },
   {
     name: "Block",
     embedded: false

+ 10 - 1
backend/database/generated/prisma-client/index.js

@@ -8,10 +8,18 @@ var models = [
     name: "User",
     embedded: false
   },
+  {
+    name: "Permission",
+    embedded: false
+  },
   {
     name: "Training",
     embedded: false
   },
+  {
+    name: "TrainingType",
+    embedded: false
+  },
   {
     name: "Block",
     embedded: false
@@ -40,6 +48,7 @@ var models = [
 exports.Prisma = prisma_lib_1.makePrismaClientClass({
   typeDefs,
   models,
-  endpoint: `http://localhost:8846`
+  endpoint: `http://prisma:4466`,
+  secret: `PrismaSecret`
 });
 exports.prisma = new exports.Prisma();

+ 211 - 41
backend/database/generated/prisma-client/prisma-schema.js

@@ -31,6 +31,10 @@ type AggregateTraining {
   count: Int!
 }
 
+type AggregateTrainingType {
+  count: Int!
+}
+
 type AggregateUser {
   count: Int!
 }
@@ -968,6 +972,12 @@ type Mutation {
   upsertTraining(where: TrainingWhereUniqueInput!, create: TrainingCreateInput!, update: TrainingUpdateInput!): Training!
   deleteTraining(where: TrainingWhereUniqueInput!): Training
   deleteManyTrainings(where: TrainingWhereInput): BatchPayload!
+  createTrainingType(data: TrainingTypeCreateInput!): TrainingType!
+  updateTrainingType(data: TrainingTypeUpdateInput!, where: TrainingTypeWhereUniqueInput!): TrainingType
+  updateManyTrainingTypes(data: TrainingTypeUpdateManyMutationInput!, where: TrainingTypeWhereInput): BatchPayload!
+  upsertTrainingType(where: TrainingTypeWhereUniqueInput!, create: TrainingTypeCreateInput!, update: TrainingTypeUpdateInput!): TrainingType!
+  deleteTrainingType(where: TrainingTypeWhereUniqueInput!): TrainingType
+  deleteManyTrainingTypes(where: TrainingTypeWhereInput): BatchPayload!
   createUser(data: UserCreateInput!): User!
   updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User
   updateManyUsers(data: UserUpdateManyMutationInput!, where: UserWhereInput): BatchPayload!
@@ -993,6 +1003,12 @@ type PageInfo {
   endCursor: String
 }
 
+enum Permission {
+  ADMIN
+  INSTRUCTOR
+  USER
+}
+
 type Query {
   block(where: BlockWhereUniqueInput!): Block
   blocks(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block]!
@@ -1015,6 +1031,9 @@ type Query {
   training(where: TrainingWhereUniqueInput!): Training
   trainings(where: TrainingWhereInput, orderBy: TrainingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Training]!
   trainingsConnection(where: TrainingWhereInput, orderBy: TrainingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): TrainingConnection!
+  trainingType(where: TrainingTypeWhereUniqueInput!): TrainingType
+  trainingTypes(where: TrainingTypeWhereInput, orderBy: TrainingTypeOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [TrainingType]!
+  trainingTypesConnection(where: TrainingTypeWhereInput, orderBy: TrainingTypeOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): TrainingTypeConnection!
   user(where: UserWhereUniqueInput!): User
   users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]!
   usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection!
@@ -1290,6 +1309,7 @@ type Subscription {
   rating(where: RatingSubscriptionWhereInput): RatingSubscriptionPayload
   track(where: TrackSubscriptionWhereInput): TrackSubscriptionPayload
   training(where: TrainingSubscriptionWhereInput): TrainingSubscriptionPayload
+  trainingType(where: TrainingTypeSubscriptionWhereInput): TrainingTypeSubscriptionPayload
   user(where: UserSubscriptionWhereInput): UserSubscriptionPayload
 }
 
@@ -1567,11 +1587,13 @@ input TrackWhereUniqueInput {
 type Training {
   id: ID!
   title: String!
+  type: TrainingType!
   content(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block!]
   createdAt: DateTime!
   trainingDate: DateTime!
   participants(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User!]
   ratings(where: RatingWhereInput, orderBy: RatingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Rating!]
+  published: Boolean!
 }
 
 type TrainingConnection {
@@ -1583,10 +1605,12 @@ type TrainingConnection {
 input TrainingCreateInput {
   id: ID
   title: String!
+  type: TrainingTypeCreateOneInput!
   content: BlockCreateManyInput
   trainingDate: DateTime!
   participants: UserCreateManyInput
   ratings: RatingCreateManyInput
+  published: Boolean!
 }
 
 type TrainingEdge {
@@ -1603,6 +1627,8 @@ enum TrainingOrderByInput {
   createdAt_DESC
   trainingDate_ASC
   trainingDate_DESC
+  published_ASC
+  published_DESC
 }
 
 type TrainingPreviousValues {
@@ -1610,6 +1636,7 @@ type TrainingPreviousValues {
   title: String!
   createdAt: DateTime!
   trainingDate: DateTime!
+  published: Boolean!
 }
 
 type TrainingSubscriptionPayload {
@@ -1630,17 +1657,160 @@ input TrainingSubscriptionWhereInput {
   NOT: [TrainingSubscriptionWhereInput!]
 }
 
+type TrainingType {
+  id: ID!
+  name: String!
+  description: String!
+}
+
+type TrainingTypeConnection {
+  pageInfo: PageInfo!
+  edges: [TrainingTypeEdge]!
+  aggregate: AggregateTrainingType!
+}
+
+input TrainingTypeCreateInput {
+  id: ID
+  name: String!
+  description: String!
+}
+
+input TrainingTypeCreateOneInput {
+  create: TrainingTypeCreateInput
+  connect: TrainingTypeWhereUniqueInput
+}
+
+type TrainingTypeEdge {
+  node: TrainingType!
+  cursor: String!
+}
+
+enum TrainingTypeOrderByInput {
+  id_ASC
+  id_DESC
+  name_ASC
+  name_DESC
+  description_ASC
+  description_DESC
+}
+
+type TrainingTypePreviousValues {
+  id: ID!
+  name: String!
+  description: String!
+}
+
+type TrainingTypeSubscriptionPayload {
+  mutation: MutationType!
+  node: TrainingType
+  updatedFields: [String!]
+  previousValues: TrainingTypePreviousValues
+}
+
+input TrainingTypeSubscriptionWhereInput {
+  mutation_in: [MutationType!]
+  updatedFields_contains: String
+  updatedFields_contains_every: [String!]
+  updatedFields_contains_some: [String!]
+  node: TrainingTypeWhereInput
+  AND: [TrainingTypeSubscriptionWhereInput!]
+  OR: [TrainingTypeSubscriptionWhereInput!]
+  NOT: [TrainingTypeSubscriptionWhereInput!]
+}
+
+input TrainingTypeUpdateDataInput {
+  name: String
+  description: String
+}
+
+input TrainingTypeUpdateInput {
+  name: String
+  description: String
+}
+
+input TrainingTypeUpdateManyMutationInput {
+  name: String
+  description: String
+}
+
+input TrainingTypeUpdateOneRequiredInput {
+  create: TrainingTypeCreateInput
+  update: TrainingTypeUpdateDataInput
+  upsert: TrainingTypeUpsertNestedInput
+  connect: TrainingTypeWhereUniqueInput
+}
+
+input TrainingTypeUpsertNestedInput {
+  update: TrainingTypeUpdateDataInput!
+  create: TrainingTypeCreateInput!
+}
+
+input TrainingTypeWhereInput {
+  id: ID
+  id_not: ID
+  id_in: [ID!]
+  id_not_in: [ID!]
+  id_lt: ID
+  id_lte: ID
+  id_gt: ID
+  id_gte: ID
+  id_contains: ID
+  id_not_contains: ID
+  id_starts_with: ID
+  id_not_starts_with: ID
+  id_ends_with: ID
+  id_not_ends_with: ID
+  name: String
+  name_not: String
+  name_in: [String!]
+  name_not_in: [String!]
+  name_lt: String
+  name_lte: String
+  name_gt: String
+  name_gte: String
+  name_contains: String
+  name_not_contains: String
+  name_starts_with: String
+  name_not_starts_with: String
+  name_ends_with: String
+  name_not_ends_with: String
+  description: String
+  description_not: String
+  description_in: [String!]
+  description_not_in: [String!]
+  description_lt: String
+  description_lte: String
+  description_gt: String
+  description_gte: String
+  description_contains: String
+  description_not_contains: String
+  description_starts_with: String
+  description_not_starts_with: String
+  description_ends_with: String
+  description_not_ends_with: String
+  AND: [TrainingTypeWhereInput!]
+  OR: [TrainingTypeWhereInput!]
+  NOT: [TrainingTypeWhereInput!]
+}
+
+input TrainingTypeWhereUniqueInput {
+  id: ID
+}
+
 input TrainingUpdateInput {
   title: String
+  type: TrainingTypeUpdateOneRequiredInput
   content: BlockUpdateManyInput
   trainingDate: DateTime
   participants: UserUpdateManyInput
   ratings: RatingUpdateManyInput
+  published: Boolean
 }
 
 input TrainingUpdateManyMutationInput {
   title: String
   trainingDate: DateTime
+  published: Boolean
 }
 
 input TrainingWhereInput {
@@ -1672,6 +1842,7 @@ input TrainingWhereInput {
   title_not_starts_with: String
   title_ends_with: String
   title_not_ends_with: String
+  type: TrainingTypeWhereInput
   content_every: BlockWhereInput
   content_some: BlockWhereInput
   content_none: BlockWhereInput
@@ -1697,6 +1868,8 @@ input TrainingWhereInput {
   ratings_every: RatingWhereInput
   ratings_some: RatingWhereInput
   ratings_none: RatingWhereInput
+  published: Boolean
+  published_not: Boolean
   AND: [TrainingWhereInput!]
   OR: [TrainingWhereInput!]
   NOT: [TrainingWhereInput!]
@@ -1710,11 +1883,12 @@ type User {
   id: ID!
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   createdAt: DateTime!
   comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment!]
   ratings(where: RatingWhereInput, orderBy: RatingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Rating!]
+  permissions: [Permission!]!
+  interests: [String!]!
 }
 
 type UserConnection {
@@ -1727,10 +1901,15 @@ input UserCreateInput {
   id: ID
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   comments: CommentCreateManyWithoutAuthorInput
   ratings: RatingCreateManyWithoutUserInput
+  permissions: UserCreatepermissionsInput
+  interests: UserCreateinterestsInput
+}
+
+input UserCreateinterestsInput {
+  set: [String!]
 }
 
 input UserCreateManyInput {
@@ -1748,22 +1927,28 @@ input UserCreateOneWithoutRatingsInput {
   connect: UserWhereUniqueInput
 }
 
+input UserCreatepermissionsInput {
+  set: [Permission!]
+}
+
 input UserCreateWithoutCommentsInput {
   id: ID
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   ratings: RatingCreateManyWithoutUserInput
+  permissions: UserCreatepermissionsInput
+  interests: UserCreateinterestsInput
 }
 
 input UserCreateWithoutRatingsInput {
   id: ID
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   comments: CommentCreateManyWithoutAuthorInput
+  permissions: UserCreatepermissionsInput
+  interests: UserCreateinterestsInput
 }
 
 type UserEdge {
@@ -1778,8 +1963,6 @@ enum UserOrderByInput {
   email_DESC
   name_ASC
   name_DESC
-  abbreviation_ASC
-  abbreviation_DESC
   password_ASC
   password_DESC
   createdAt_ASC
@@ -1790,9 +1973,10 @@ type UserPreviousValues {
   id: ID!
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   createdAt: DateTime!
+  permissions: [Permission!]!
+  interests: [String!]!
 }
 
 input UserScalarWhereInput {
@@ -1838,20 +2022,6 @@ input UserScalarWhereInput {
   name_not_starts_with: String
   name_ends_with: String
   name_not_ends_with: String
-  abbreviation: String
-  abbreviation_not: String
-  abbreviation_in: [String!]
-  abbreviation_not_in: [String!]
-  abbreviation_lt: String
-  abbreviation_lte: String
-  abbreviation_gt: String
-  abbreviation_gte: String
-  abbreviation_contains: String
-  abbreviation_not_contains: String
-  abbreviation_starts_with: String
-  abbreviation_not_starts_with: String
-  abbreviation_ends_with: String
-  abbreviation_not_ends_with: String
   password: String
   password_not: String
   password_in: [String!]
@@ -1900,26 +2070,33 @@ input UserSubscriptionWhereInput {
 input UserUpdateDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
   comments: CommentUpdateManyWithoutAuthorInput
   ratings: RatingUpdateManyWithoutUserInput
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateInput {
   email: String
   name: String
-  abbreviation: String
   password: String
   comments: CommentUpdateManyWithoutAuthorInput
   ratings: RatingUpdateManyWithoutUserInput
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
+}
+
+input UserUpdateinterestsInput {
+  set: [String!]
 }
 
 input UserUpdateManyDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateManyInput {
@@ -1937,8 +2114,9 @@ input UserUpdateManyInput {
 input UserUpdateManyMutationInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateManyWithWhereNestedInput {
@@ -1960,20 +2138,26 @@ input UserUpdateOneRequiredWithoutRatingsInput {
   connect: UserWhereUniqueInput
 }
 
+input UserUpdatepermissionsInput {
+  set: [Permission!]
+}
+
 input UserUpdateWithoutCommentsDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
   ratings: RatingUpdateManyWithoutUserInput
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateWithoutRatingsDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
   comments: CommentUpdateManyWithoutAuthorInput
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateWithWhereUniqueNestedInput {
@@ -2040,20 +2224,6 @@ input UserWhereInput {
   name_not_starts_with: String
   name_ends_with: String
   name_not_ends_with: String
-  abbreviation: String
-  abbreviation_not: String
-  abbreviation_in: [String!]
-  abbreviation_not_in: [String!]
-  abbreviation_lt: String
-  abbreviation_lte: String
-  abbreviation_gt: String
-  abbreviation_gte: String
-  abbreviation_contains: String
-  abbreviation_not_contains: String
-  abbreviation_starts_with: String
-  abbreviation_not_starts_with: String
-  abbreviation_ends_with: String
-  abbreviation_not_ends_with: String
   password: String
   password_not: String
   password_in: [String!]

+ 325 - 95
backend/database/generated/prisma.graphql

@@ -1,5 +1,5 @@
-# source: http://localhost:8846
-# timestamp: Tue Nov 05 2019 20:22:41 GMT+0100 (Central European Standard Time)
+# source: http://prisma:4466
+# timestamp: Thu Nov 07 2019 16:25:57 GMT+0000 (Coordinated Universal Time)
 
 type AggregateBlock {
   count: Int!
@@ -29,6 +29,10 @@ type AggregateTraining {
   count: Int!
 }
 
+type AggregateTrainingType {
+  count: Int!
+}
+
 type AggregateUser {
   count: Int!
 }
@@ -1705,6 +1709,7 @@ type Mutation {
   createTraining(data: TrainingCreateInput!): Training!
   createComment(data: CommentCreateInput!): Comment!
   createUser(data: UserCreateInput!): User!
+  createTrainingType(data: TrainingTypeCreateInput!): TrainingType!
   createTrack(data: TrackCreateInput!): Track!
   createExcersise(data: ExcersiseCreateInput!): Excersise!
   createBlock(data: BlockCreateInput!): Block!
@@ -1713,6 +1718,7 @@ type Mutation {
   updateTraining(data: TrainingUpdateInput!, where: TrainingWhereUniqueInput!): Training
   updateComment(data: CommentUpdateInput!, where: CommentWhereUniqueInput!): Comment
   updateUser(data: UserUpdateInput!, where: UserWhereUniqueInput!): User
+  updateTrainingType(data: TrainingTypeUpdateInput!, where: TrainingTypeWhereUniqueInput!): TrainingType
   updateTrack(data: TrackUpdateInput!, where: TrackWhereUniqueInput!): Track
   updateExcersise(data: ExcersiseUpdateInput!, where: ExcersiseWhereUniqueInput!): Excersise
   updateBlock(data: BlockUpdateInput!, where: BlockWhereUniqueInput!): Block
@@ -1721,6 +1727,7 @@ type Mutation {
   deleteTraining(where: TrainingWhereUniqueInput!): Training
   deleteComment(where: CommentWhereUniqueInput!): Comment
   deleteUser(where: UserWhereUniqueInput!): User
+  deleteTrainingType(where: TrainingTypeWhereUniqueInput!): TrainingType
   deleteTrack(where: TrackWhereUniqueInput!): Track
   deleteExcersise(where: ExcersiseWhereUniqueInput!): Excersise
   deleteBlock(where: BlockWhereUniqueInput!): Block
@@ -1729,6 +1736,7 @@ type Mutation {
   upsertTraining(where: TrainingWhereUniqueInput!, create: TrainingCreateInput!, update: TrainingUpdateInput!): Training!
   upsertComment(where: CommentWhereUniqueInput!, create: CommentCreateInput!, update: CommentUpdateInput!): Comment!
   upsertUser(where: UserWhereUniqueInput!, create: UserCreateInput!, update: UserUpdateInput!): User!
+  upsertTrainingType(where: TrainingTypeWhereUniqueInput!, create: TrainingTypeCreateInput!, update: TrainingTypeUpdateInput!): TrainingType!
   upsertTrack(where: TrackWhereUniqueInput!, create: TrackCreateInput!, update: TrackUpdateInput!): Track!
   upsertExcersise(where: ExcersiseWhereUniqueInput!, create: ExcersiseCreateInput!, update: ExcersiseUpdateInput!): Excersise!
   upsertBlock(where: BlockWhereUniqueInput!, create: BlockCreateInput!, update: BlockUpdateInput!): Block!
@@ -1737,6 +1745,7 @@ type Mutation {
   updateManyTrainings(data: TrainingUpdateManyMutationInput!, where: TrainingWhereInput): BatchPayload!
   updateManyComments(data: CommentUpdateManyMutationInput!, where: CommentWhereInput): BatchPayload!
   updateManyUsers(data: UserUpdateManyMutationInput!, where: UserWhereInput): BatchPayload!
+  updateManyTrainingTypes(data: TrainingTypeUpdateManyMutationInput!, where: TrainingTypeWhereInput): BatchPayload!
   updateManyTracks(data: TrackUpdateManyMutationInput!, where: TrackWhereInput): BatchPayload!
   updateManyExcersises(data: ExcersiseUpdateManyMutationInput!, where: ExcersiseWhereInput): BatchPayload!
   updateManyBlocks(data: BlockUpdateManyMutationInput!, where: BlockWhereInput): BatchPayload!
@@ -1745,6 +1754,7 @@ type Mutation {
   deleteManyTrainings(where: TrainingWhereInput): BatchPayload!
   deleteManyComments(where: CommentWhereInput): BatchPayload!
   deleteManyUsers(where: UserWhereInput): BatchPayload!
+  deleteManyTrainingTypes(where: TrainingTypeWhereInput): BatchPayload!
   deleteManyTracks(where: TrackWhereInput): BatchPayload!
   deleteManyExcersises(where: ExcersiseWhereInput): BatchPayload!
   deleteManyBlocks(where: BlockWhereInput): BatchPayload!
@@ -1779,10 +1789,17 @@ type PageInfo {
   endCursor: String
 }
 
+enum Permission {
+  ADMIN
+  INSTRUCTOR
+  USER
+}
+
 type Query {
   trainings(where: TrainingWhereInput, orderBy: TrainingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Training]!
   comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment]!
   users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]!
+  trainingTypes(where: TrainingTypeWhereInput, orderBy: TrainingTypeOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [TrainingType]!
   tracks(where: TrackWhereInput, orderBy: TrackOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Track]!
   excersises(where: ExcersiseWhereInput, orderBy: ExcersiseOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Excersise]!
   blocks(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block]!
@@ -1791,6 +1808,7 @@ type Query {
   training(where: TrainingWhereUniqueInput!): Training
   comment(where: CommentWhereUniqueInput!): Comment
   user(where: UserWhereUniqueInput!): User
+  trainingType(where: TrainingTypeWhereUniqueInput!): TrainingType
   track(where: TrackWhereUniqueInput!): Track
   excersise(where: ExcersiseWhereUniqueInput!): Excersise
   block(where: BlockWhereUniqueInput!): Block
@@ -1799,6 +1817,7 @@ type Query {
   trainingsConnection(where: TrainingWhereInput, orderBy: TrainingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): TrainingConnection!
   commentsConnection(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): CommentConnection!
   usersConnection(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): UserConnection!
+  trainingTypesConnection(where: TrainingTypeWhereInput, orderBy: TrainingTypeOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): TrainingTypeConnection!
   tracksConnection(where: TrackWhereInput, orderBy: TrackOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): TrackConnection!
   excersisesConnection(where: ExcersiseWhereInput, orderBy: ExcersiseOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): ExcersiseConnection!
   blocksConnection(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): BlockConnection!
@@ -2274,6 +2293,7 @@ type Subscription {
   training(where: TrainingSubscriptionWhereInput): TrainingSubscriptionPayload
   comment(where: CommentSubscriptionWhereInput): CommentSubscriptionPayload
   user(where: UserSubscriptionWhereInput): UserSubscriptionPayload
+  trainingType(where: TrainingTypeSubscriptionWhereInput): TrainingTypeSubscriptionPayload
   track(where: TrackSubscriptionWhereInput): TrackSubscriptionPayload
   excersise(where: ExcersiseSubscriptionWhereInput): ExcersiseSubscriptionPayload
   block(where: BlockSubscriptionWhereInput): BlockSubscriptionPayload
@@ -2828,11 +2848,13 @@ input TrackWhereUniqueInput {
 type Training implements Node {
   id: ID!
   title: String!
+  type: TrainingType!
   content(where: BlockWhereInput, orderBy: BlockOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Block!]
   createdAt: DateTime!
   trainingDate: DateTime!
   participants(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User!]
   ratings(where: RatingWhereInput, orderBy: RatingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Rating!]
+  published: Boolean!
 }
 
 """A connection to a list of items."""
@@ -2849,6 +2871,8 @@ input TrainingCreateInput {
   id: ID
   title: String!
   trainingDate: DateTime!
+  published: Boolean!
+  type: TrainingTypeCreateOneInput!
   content: BlockCreateManyInput
   participants: UserCreateManyInput
   ratings: RatingCreateManyInput
@@ -2872,6 +2896,8 @@ enum TrainingOrderByInput {
   createdAt_DESC
   trainingDate_ASC
   trainingDate_DESC
+  published_ASC
+  published_DESC
 }
 
 type TrainingPreviousValues {
@@ -2879,6 +2905,7 @@ type TrainingPreviousValues {
   title: String!
   createdAt: DateTime!
   trainingDate: DateTime!
+  published: Boolean!
 }
 
 type TrainingSubscriptionPayload {
@@ -2918,9 +2945,261 @@ input TrainingSubscriptionWhereInput {
   node: TrainingWhereInput
 }
 
+type TrainingType implements Node {
+  id: ID!
+  name: String!
+  description: String!
+}
+
+"""A connection to a list of items."""
+type TrainingTypeConnection {
+  """Information to aid in pagination."""
+  pageInfo: PageInfo!
+
+  """A list of edges."""
+  edges: [TrainingTypeEdge]!
+  aggregate: AggregateTrainingType!
+}
+
+input TrainingTypeCreateInput {
+  id: ID
+  name: String!
+  description: String!
+}
+
+input TrainingTypeCreateOneInput {
+  create: TrainingTypeCreateInput
+  connect: TrainingTypeWhereUniqueInput
+}
+
+"""An edge in a connection."""
+type TrainingTypeEdge {
+  """The item at the end of the edge."""
+  node: TrainingType!
+
+  """A cursor for use in pagination."""
+  cursor: String!
+}
+
+enum TrainingTypeOrderByInput {
+  id_ASC
+  id_DESC
+  name_ASC
+  name_DESC
+  description_ASC
+  description_DESC
+}
+
+type TrainingTypePreviousValues {
+  id: ID!
+  name: String!
+  description: String!
+}
+
+type TrainingTypeSubscriptionPayload {
+  mutation: MutationType!
+  node: TrainingType
+  updatedFields: [String!]
+  previousValues: TrainingTypePreviousValues
+}
+
+input TrainingTypeSubscriptionWhereInput {
+  """Logical AND on all given filters."""
+  AND: [TrainingTypeSubscriptionWhereInput!]
+
+  """Logical OR on all given filters."""
+  OR: [TrainingTypeSubscriptionWhereInput!]
+
+  """Logical NOT on all given filters combined by AND."""
+  NOT: [TrainingTypeSubscriptionWhereInput!]
+
+  """The subscription event gets dispatched when it's listed in mutation_in"""
+  mutation_in: [MutationType!]
+
+  """
+  The subscription event gets only dispatched when one of the updated fields names is included in this list
+  """
+  updatedFields_contains: String
+
+  """
+  The subscription event gets only dispatched when all of the field names included in this list have been updated
+  """
+  updatedFields_contains_every: [String!]
+
+  """
+  The subscription event gets only dispatched when some of the field names included in this list have been updated
+  """
+  updatedFields_contains_some: [String!]
+  node: TrainingTypeWhereInput
+}
+
+input TrainingTypeUpdateDataInput {
+  name: String
+  description: String
+}
+
+input TrainingTypeUpdateInput {
+  name: String
+  description: String
+}
+
+input TrainingTypeUpdateManyMutationInput {
+  name: String
+  description: String
+}
+
+input TrainingTypeUpdateOneRequiredInput {
+  create: TrainingTypeCreateInput
+  connect: TrainingTypeWhereUniqueInput
+  update: TrainingTypeUpdateDataInput
+  upsert: TrainingTypeUpsertNestedInput
+}
+
+input TrainingTypeUpsertNestedInput {
+  update: TrainingTypeUpdateDataInput!
+  create: TrainingTypeCreateInput!
+}
+
+input TrainingTypeWhereInput {
+  """Logical AND on all given filters."""
+  AND: [TrainingTypeWhereInput!]
+
+  """Logical OR on all given filters."""
+  OR: [TrainingTypeWhereInput!]
+
+  """Logical NOT on all given filters combined by AND."""
+  NOT: [TrainingTypeWhereInput!]
+  id: ID
+
+  """All values that are not equal to given value."""
+  id_not: ID
+
+  """All values that are contained in given list."""
+  id_in: [ID!]
+
+  """All values that are not contained in given list."""
+  id_not_in: [ID!]
+
+  """All values less than the given value."""
+  id_lt: ID
+
+  """All values less than or equal the given value."""
+  id_lte: ID
+
+  """All values greater than the given value."""
+  id_gt: ID
+
+  """All values greater than or equal the given value."""
+  id_gte: ID
+
+  """All values containing the given string."""
+  id_contains: ID
+
+  """All values not containing the given string."""
+  id_not_contains: ID
+
+  """All values starting with the given string."""
+  id_starts_with: ID
+
+  """All values not starting with the given string."""
+  id_not_starts_with: ID
+
+  """All values ending with the given string."""
+  id_ends_with: ID
+
+  """All values not ending with the given string."""
+  id_not_ends_with: ID
+  name: String
+
+  """All values that are not equal to given value."""
+  name_not: String
+
+  """All values that are contained in given list."""
+  name_in: [String!]
+
+  """All values that are not contained in given list."""
+  name_not_in: [String!]
+
+  """All values less than the given value."""
+  name_lt: String
+
+  """All values less than or equal the given value."""
+  name_lte: String
+
+  """All values greater than the given value."""
+  name_gt: String
+
+  """All values greater than or equal the given value."""
+  name_gte: String
+
+  """All values containing the given string."""
+  name_contains: String
+
+  """All values not containing the given string."""
+  name_not_contains: String
+
+  """All values starting with the given string."""
+  name_starts_with: String
+
+  """All values not starting with the given string."""
+  name_not_starts_with: String
+
+  """All values ending with the given string."""
+  name_ends_with: String
+
+  """All values not ending with the given string."""
+  name_not_ends_with: String
+  description: String
+
+  """All values that are not equal to given value."""
+  description_not: String
+
+  """All values that are contained in given list."""
+  description_in: [String!]
+
+  """All values that are not contained in given list."""
+  description_not_in: [String!]
+
+  """All values less than the given value."""
+  description_lt: String
+
+  """All values less than or equal the given value."""
+  description_lte: String
+
+  """All values greater than the given value."""
+  description_gt: String
+
+  """All values greater than or equal the given value."""
+  description_gte: String
+
+  """All values containing the given string."""
+  description_contains: String
+
+  """All values not containing the given string."""
+  description_not_contains: String
+
+  """All values starting with the given string."""
+  description_starts_with: String
+
+  """All values not starting with the given string."""
+  description_not_starts_with: String
+
+  """All values ending with the given string."""
+  description_ends_with: String
+
+  """All values not ending with the given string."""
+  description_not_ends_with: String
+}
+
+input TrainingTypeWhereUniqueInput {
+  id: ID
+}
+
 input TrainingUpdateInput {
   title: String
   trainingDate: DateTime
+  published: Boolean
+  type: TrainingTypeUpdateOneRequiredInput
   content: BlockUpdateManyInput
   participants: UserUpdateManyInput
   ratings: RatingUpdateManyInput
@@ -2929,6 +3208,7 @@ input TrainingUpdateInput {
 input TrainingUpdateManyMutationInput {
   title: String
   trainingDate: DateTime
+  published: Boolean
 }
 
 input TrainingWhereInput {
@@ -3064,6 +3344,11 @@ input TrainingWhereInput {
 
   """All values greater than or equal the given value."""
   trainingDate_gte: DateTime
+  published: Boolean
+
+  """All values that are not equal to given value."""
+  published_not: Boolean
+  type: TrainingTypeWhereInput
   content_every: BlockWhereInput
   content_some: BlockWhereInput
   content_none: BlockWhereInput
@@ -3083,11 +3368,12 @@ type User implements Node {
   id: ID!
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   createdAt: DateTime!
   comments(where: CommentWhereInput, orderBy: CommentOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Comment!]
   ratings(where: RatingWhereInput, orderBy: RatingOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [Rating!]
+  permissions: [Permission!]!
+  interests: [String!]!
 }
 
 """A connection to a list of items."""
@@ -3104,12 +3390,17 @@ input UserCreateInput {
   id: ID
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
+  permissions: UserCreatepermissionsInput
+  interests: UserCreateinterestsInput
   comments: CommentCreateManyWithoutAuthorInput
   ratings: RatingCreateManyWithoutUserInput
 }
 
+input UserCreateinterestsInput {
+  set: [String!]
+}
+
 input UserCreateManyInput {
   create: [UserCreateInput!]
   connect: [UserWhereUniqueInput!]
@@ -3125,12 +3416,17 @@ input UserCreateOneWithoutRatingsInput {
   connect: UserWhereUniqueInput
 }
 
+input UserCreatepermissionsInput {
+  set: [Permission!]
+}
+
 input UserCreateWithoutCommentsInput {
   id: ID
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
+  permissions: UserCreatepermissionsInput
+  interests: UserCreateinterestsInput
   ratings: RatingCreateManyWithoutUserInput
 }
 
@@ -3138,8 +3434,9 @@ input UserCreateWithoutRatingsInput {
   id: ID
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
+  permissions: UserCreatepermissionsInput
+  interests: UserCreateinterestsInput
   comments: CommentCreateManyWithoutAuthorInput
 }
 
@@ -3159,8 +3456,6 @@ enum UserOrderByInput {
   email_DESC
   name_ASC
   name_DESC
-  abbreviation_ASC
-  abbreviation_DESC
   password_ASC
   password_DESC
   createdAt_ASC
@@ -3171,9 +3466,10 @@ type UserPreviousValues {
   id: ID!
   email: String!
   name: String!
-  abbreviation: String!
   password: String!
   createdAt: DateTime!
+  permissions: [Permission!]!
+  interests: [String!]!
 }
 
 input UserScalarWhereInput {
@@ -3305,46 +3601,6 @@ input UserScalarWhereInput {
 
   """All values not ending with the given string."""
   name_not_ends_with: String
-  abbreviation: String
-
-  """All values that are not equal to given value."""
-  abbreviation_not: String
-
-  """All values that are contained in given list."""
-  abbreviation_in: [String!]
-
-  """All values that are not contained in given list."""
-  abbreviation_not_in: [String!]
-
-  """All values less than the given value."""
-  abbreviation_lt: String
-
-  """All values less than or equal the given value."""
-  abbreviation_lte: String
-
-  """All values greater than the given value."""
-  abbreviation_gt: String
-
-  """All values greater than or equal the given value."""
-  abbreviation_gte: String
-
-  """All values containing the given string."""
-  abbreviation_contains: String
-
-  """All values not containing the given string."""
-  abbreviation_not_contains: String
-
-  """All values starting with the given string."""
-  abbreviation_starts_with: String
-
-  """All values not starting with the given string."""
-  abbreviation_not_starts_with: String
-
-  """All values ending with the given string."""
-  abbreviation_ends_with: String
-
-  """All values not ending with the given string."""
-  abbreviation_not_ends_with: String
   password: String
 
   """All values that are not equal to given value."""
@@ -3449,8 +3705,9 @@ input UserSubscriptionWhereInput {
 input UserUpdateDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
   comments: CommentUpdateManyWithoutAuthorInput
   ratings: RatingUpdateManyWithoutUserInput
 }
@@ -3458,17 +3715,23 @@ input UserUpdateDataInput {
 input UserUpdateInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
   comments: CommentUpdateManyWithoutAuthorInput
   ratings: RatingUpdateManyWithoutUserInput
 }
 
+input UserUpdateinterestsInput {
+  set: [String!]
+}
+
 input UserUpdateManyDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateManyInput {
@@ -3486,8 +3749,9 @@ input UserUpdateManyInput {
 input UserUpdateManyMutationInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
 }
 
 input UserUpdateManyWithWhereNestedInput {
@@ -3509,19 +3773,25 @@ input UserUpdateOneRequiredWithoutRatingsInput {
   upsert: UserUpsertWithoutRatingsInput
 }
 
+input UserUpdatepermissionsInput {
+  set: [Permission!]
+}
+
 input UserUpdateWithoutCommentsDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
   ratings: RatingUpdateManyWithoutUserInput
 }
 
 input UserUpdateWithoutRatingsDataInput {
   email: String
   name: String
-  abbreviation: String
   password: String
+  permissions: UserUpdatepermissionsInput
+  interests: UserUpdateinterestsInput
   comments: CommentUpdateManyWithoutAuthorInput
 }
 
@@ -3675,46 +3945,6 @@ input UserWhereInput {
 
   """All values not ending with the given string."""
   name_not_ends_with: String
-  abbreviation: String
-
-  """All values that are not equal to given value."""
-  abbreviation_not: String
-
-  """All values that are contained in given list."""
-  abbreviation_in: [String!]
-
-  """All values that are not contained in given list."""
-  abbreviation_not_in: [String!]
-
-  """All values less than the given value."""
-  abbreviation_lt: String
-
-  """All values less than or equal the given value."""
-  abbreviation_lte: String
-
-  """All values greater than the given value."""
-  abbreviation_gt: String
-
-  """All values greater than or equal the given value."""
-  abbreviation_gte: String
-
-  """All values containing the given string."""
-  abbreviation_contains: String
-
-  """All values not containing the given string."""
-  abbreviation_not_contains: String
-
-  """All values starting with the given string."""
-  abbreviation_starts_with: String
-
-  """All values not starting with the given string."""
-  abbreviation_not_starts_with: String
-
-  """All values ending with the given string."""
-  abbreviation_ends_with: String
-
-  """All values not ending with the given string."""
-  abbreviation_not_ends_with: String
   password: String
 
   """All values that are not equal to given value."""

+ 17 - 2
backend/datamodel.prisma

@@ -2,21 +2,36 @@ type User {
     id: ID! @id
     email: String! @unique
     name: String!
-    abbreviation: String!
     password: String!
     createdAt: DateTime! @createdAt
-    comments: [Comment]!
+    comments: [Comment]! 
     ratings: [Rating]!
+    permissions: [Permission]!  @scalarList(strategy: RELATION)
+    interests: [String]!  @scalarList(strategy: RELATION)
+}
+
+enum Permission {
+    ADMIN
+    INSTRUCTOR
+    USER
 }
 
 type Training {
     id: ID! @id
     title: String!
+    type: TrainingType!
     content: [Block]!
     createdAt: DateTime! @createdAt
     trainingDate: DateTime!
     participants: [User]!
     ratings: [Rating]!
+    published: Boolean!
+}
+
+type TrainingType {
+    id: ID! @id
+    name: String!
+    description: String!
 }
 
 type Block {

+ 9 - 16
backend/index.js

@@ -9,21 +9,14 @@ require('dotenv').config()
 const { GraphQLServer } = require('graphql-yoga')
 const cookieParser = require('cookie-parser')
 const bodyParser = require('body-parser')
-const cors = require('cors')
-const express = require('express')
+// const cors = require("cors");
 const { merge } = require('lodash')
 const { db, populateUser } = require('./src/db')
 // const { authenticate } = require('./src/authenticate')
 
 const prismaResolvers = require('./src/resolvers')
 
-// const typeDefs = ['./schema.graphql', system.typeDefs, interfaces.typeDefs]
-
-const resolvers = merge(
-  // system.resolvers,
-  // interfaces.resolvers,
-  prismaResolvers.resolvers
-)
+const resolvers = merge(prismaResolvers.resolvers)
 const typeDefs = ['./schema.graphql']
 
 const server = new GraphQLServer({
@@ -41,17 +34,17 @@ server.express.use(bodyParser.json())
 // server.express.use(quickMiddleware)
 // server.express.use(authenticate)
 server.express.use(populateUser)
-server.express.use(
-  cors({ origin: process.env.FRONTEND_URL, credentials: true })
-)
-server.express.use('/static', express.static('static'))
+/* server.express.use(
+  cors({ origin: process.env.FRONTEND_URL, credentials: false })
+); */
+// server.express.use("/static", express.static("static"));
 
 server.start(
-  {
+  /* {
     cors: {
-      credentials: true,
+      credentials: false,
       origin: process.env.FRONTEND_URL
     }
-  },
+  }, */
   server => console.log(`Server is running on http://localhost:${server.port}`)
 )

+ 3 - 3
backend/package-lock.json

@@ -7193,9 +7193,9 @@
       },
       "dependencies": {
         "@types/node": {
-          "version": "10.17.3",
-          "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.3.tgz",
-          "integrity": "sha512-QZ9CjUB3QoA3f2afw3utKlfRPhpmufB7jC2+oDhLWnXqoyx333fhKSQDLQu2EK7OE0a15X67eYiRAaJsHXrpMA=="
+          "version": "10.17.4",
+          "resolved": "https://registry.npmjs.org/@types/node/-/node-10.17.4.tgz",
+          "integrity": "sha512-F2pgg+LcIr/elguz+x+fdBX5KeZXGUOp7TV8M0TVIrDezYLFRNt8oMTyps0VQ1kj5WGGoR18RdxnRDHXrIFHMQ=="
         },
         "debug": {
           "version": "4.1.1",

+ 1 - 1
backend/package.json

@@ -20,7 +20,7 @@
     "graphql": "14.5.8",
     "graphql-yoga": "1.18.3",
     "jsonwebtoken": "8.5.1",
-    "prisma": "1.34.10",
+    "prisma": "^1.34.10",
     "prisma-binding": "2.3.16",
     "standard": "14.3.1"
   },

+ 2 - 1
backend/prisma.yml

@@ -1,5 +1,6 @@
-endpoint: http://localhost:8846
+endpoint: http://prisma:4466
 datamodel: datamodel.prisma
+secret: "PrismaSecret"
 hooks:
   post-deploy:
     - prisma generate

+ 35 - 7
backend/schema.graphql

@@ -1,12 +1,40 @@
-# import * from '../database/generated/prisma.graphql'
+# import * from './database/generated/prisma.graphql'
 
 type Query {
-    users(where: UserWhereInput, orderBy: UserOrderByInput, skip: Int, after: String, before: String, first: Int, last: Int): [User]!
-    me: User!
+  users(
+    where: UserWhereInput
+    orderBy: UserOrderByInput
+    skip: Int
+    after: String
+    before: String
+    first: Int
+    last: Int
+  ): [User]!
+  trainings(
+    where: TrainingWhereInput
+    orderBy: TrainingOrderByInput
+    skip: Int
+    after: String
+    before: String
+    first: Int
+    last: Int
+  ): [Training]!
+  me: User!
 }
 
 type Mutation {
-    createUser(name: String!, email: String!, abbreviation: String!, password: String!): User!
-    userLogin(email: String!, password: String!): User!
-    userLogout: String!
-}
+  createUser(name: String!, email: String!, password: String!): User!
+  createTraining(
+    title: String!
+    type: TrainingType!
+    content: [Input]!
+    createdAt: DateTime!
+    trainingDate: DateTime!
+    participants: [Input]!
+    ratings: [Input]!
+    published: Boolean!
+  ): Training!
+  login(email: String!, password: String!): User!
+  signup(name: String!, email: String!, password: String!): User!
+  logout: String!
+}

+ 12 - 0
backend/src/authenticate.js

@@ -0,0 +1,12 @@
+const jwt = require('jsonwebtoken')
+
+const authenticate = (req, res, next) => {
+  const { token } = req.cookies
+  if (token) {
+    const { userId } = jwt.verify(token, process.env.APP_SECRET)
+    req.userId = userId
+  }
+  next()
+}
+
+module.exports = { authenticate }

+ 4 - 2
backend/src/db.js

@@ -2,16 +2,18 @@
  * Using prisma-binding from
  * https://github.com/prisma/prisma-binding
  */
-
 const { Prisma } = require('prisma-binding')
 const {
   typeDefs
 } = require('../database/generated/prisma-client/prisma-schema')
 
+console.log('Prisma', process.env.PRISMA_ENDPOINT, process.env.PRISMA_SECRET)
+
 const db = new Prisma({
   typeDefs,
   endpoint: process.env.PRISMA_ENDPOINT,
-  secret: process.env.PRISMA_SECRET
+  secret: process.env.PRISMA_SECRET,
+  debug: true
 })
 
 const populateUser = async (req, res, next) => {

+ 36 - 2
backend/src/resolvers.js

@@ -2,8 +2,11 @@ const { forwardTo } = require('prisma-binding')
 const bcrypt = require('bcryptjs')
 const jwt = require('jsonwebtoken')
 
+const LoginError = new Error('You must be logged in.')
+
 const Query = {
   users: forwardTo('db'),
+  trainings: forwardTo('db'),
   me: (parent, args, context, info) => {
     if (!context.request.userId) throw new Error('Not logged in.')
     return context.db.query.user(
@@ -35,7 +38,27 @@ const Mutation = {
     })
     return user
   },
-  userLogin: async (parent, args, context, info) => {
+  signup: async (parent, args, ctx, info) => {
+    args.email = args.email.toLowerCase()
+    const password = await bcrypt.hash(args.password, 10)
+    const user = await ctx.db.mutation.createUser(
+      {
+        data: {
+          ...args,
+          password,
+          permissions: { set: ['USER'] }
+        }
+      },
+      info
+    )
+    const token = jwt.sign({ userId: user.id }, process.env.APP_SECRET)
+    ctx.response.cookie('token', token, {
+      httpOnly: true,
+      maxAge: 24 * 60 * 60 * 1000
+    })
+    return user
+  },
+  login: async (parent, args, context, info) => {
     const { email, password } = args
     const user = await context.db.query.user({ where: { email } })
     if (!user) throw new Error('User not found')
@@ -53,9 +76,20 @@ const Mutation = {
     )
     return user
   },
-  userLogout: async (parent, args, context, info) => {
+  logout: async (parent, args, context, info) => {
     context.response.clearCookie('token')
     return 'Logged out.'
+  },
+  createTraining: async (parent, args, context, info) => {
+    const { userId } = context.request
+    // if (!userId) throw LoginError
+    const training = await context.db.mutation.createTraining(
+      {
+        data: args
+      },
+      info
+    )
+    return training
   }
 }
 

+ 7 - 0
docker-compose.yml

@@ -9,10 +9,13 @@ services:
       - "./frontend:/app"
       - "./backend/database:/database"
       - "/app/node_modules"
+      - "/app/.next"
     ports:
       - "127.0.0.1:8800:3000"
     environment:
       - NODE_ENV=development
+    depends_on:
+      - backend
 
   backend:
     container_name: backend
@@ -25,6 +28,8 @@ services:
       - "127.0.0.1:8801:4000"
     environment:
       - NODE_ENV=development
+    depends_on:
+      - prisma
 
   prisma:
     image: prismagraphql/prisma:1.34.10
@@ -34,6 +39,7 @@ services:
     environment:
       PRISMA_CONFIG: |
         port: 4466
+        #managementApiSecret: "PrismaSecret"
         databases:
           default:
             connector: mysql
@@ -42,6 +48,7 @@ services:
             user: root
             password: prisma
             migrations: true
+
   mysql:
     image: mysql:5.7
     restart: always

+ 51 - 0
frontend/components/login.js

@@ -0,0 +1,51 @@
+import { Mutation } from 'react-apollo'
+import gql from 'graphql-tag'
+//import { CURRENT_USER_QUERY } from './User'
+
+const LOGIN_MUTATION = gql`
+    mutation LOGIN_MUTATION($email: String!, $password: String!) {
+        login(email: $email, password: $password) { 
+            id
+            email
+            name 
+        }
+    }
+`
+
+class Login extends React.Component {
+    state = {
+        email: "",
+        password: ""
+    }
+
+    saveToState = (ev) => {
+        this.setState({ [ev.target.name]: ev.target.value })
+    }
+
+    render() {
+        return <Mutation mutation={LOGIN_MUTATION} variables={this.state} refetchQueries={[{ query: CURRENT_USER_QUERY }]}>
+            {(signin, { error, loading }) => {
+                return <form method="post" onSubmit={async ev => {
+                    ev.preventDefault()
+                    const res = await signin()
+                    console.log(res)
+                    this.setState({ name: '', email: '', password: '' })
+                }}>
+                    <fieldset disabled={loading} aria-busy={loading}>
+                        <h2>Sign in.</h2>
+                        <Error error={error} />
+                        <label htmlFor="email">email
+                            <input type="email" name="email" placeholder="email" value={this.state.email} onChange={this.saveToState} />
+                        </label>
+                        <label htmlFor="password">password
+                            <input type="password" name="password" placeholder="password" value={this.state.password} onChange={this.saveToState} />
+                        </label>
+                        <button type="submit">Sign In!</button>
+                    </fieldset>
+                </form>
+            }}
+        </Mutation>
+    }
+}
+
+export default Login

+ 14 - 14
frontend/pages/_app.js

@@ -1,7 +1,7 @@
-import App, { Container } from 'next/app'
-import Page from '../components/page'
-import { ApolloProvider } from 'react-apollo'
-import withApollo from '../lib/withApollo'
+import App from "next/app";
+import Page from "../components/page";
+import { ApolloProvider } from "react-apollo";
+import withApollo from "../lib/withApollo";
 
 /**
  * Next.js uses the `App` component to initialize pages. See:
@@ -20,22 +20,22 @@ import withApollo from '../lib/withApollo'
  */
 
 class MyApp extends App {
-  static async getInitialProps ({ Component, ctx }) {
-    let pageProps = {}
+  static async getInitialProps({ Component, ctx }) {
+    let pageProps = {};
 
     if (Component.getInitialProps) {
-      pageProps = await Component.getInitialProps(ctx)
+      pageProps = await Component.getInitialProps(ctx);
     }
 
     // Add the query object to the pageProps
     // https://github.com/wesbos/Advanced-React/blob/master/finished-application/frontend/pages/_app.js
-    pageProps.query = ctx.query
+    pageProps.query = ctx.query;
 
-    return { pageProps }
+    return { pageProps };
   }
 
-  render () {
-    const { Component, apollo, pageProps } = this.props
+  render() {
+    const { Component, apollo, pageProps } = this.props;
 
     return (
       <ApolloProvider client={apollo}>
@@ -43,8 +43,8 @@ class MyApp extends App {
           <Component {...pageProps} />
         </Page>
       </ApolloProvider>
-    )
+    );
   }
 }
-console.log('read _app.js')
-export default withApollo(MyApp)
+
+export default withApollo(MyApp);

+ 18 - 18
frontend/pages/index.js

@@ -1,23 +1,23 @@
-import React from 'react'
-import Head from 'next/head'
-import Header from '../components/header'
-import Nav from '../components/nav'
-import Sidebar from '../components/sidebar'
-import Footer from '../components/footer'
-import Poll from '../components/poll'
-import Training from '../components/training'
-import { TrainingArchive } from '../components/training'
-import Exercise from '../components/exercise'
-import { ExerciseList } from '../components/exercise'
-import { PeopleList } from '../components/people'
-import data from '../initial-data.js'
-console.log('home done.')
+import React from "react";
+import Head from "next/head";
+import Header from "../components/header";
+import Nav from "../components/nav"
+import Sidebar from "../components/sidebar";
+import Footer from "../components/footer";
+import Poll from "../components/poll";
+import Training from "../components/training";
+import { TrainingArchive } from "../components/training";
+import Exercise from "../components/exercise";
+import { ExerciseList } from "../components/exercise";
+import { PeopleList } from "../components/people";
+import data from "../initial-data.js";
+console.log("home done.");
 
 const Home = () => (
-  <div id='app'>
+  <div id="app">
     <Head>
       <title>Home</title>
-      <link rel='icon' href='/favicon.ico' />
+      <link rel="icon" href="/favicon.ico" />
     </Head>
 
     <Header />
@@ -31,6 +31,6 @@ const Home = () => (
     </main>
     <Footer />
   </div>
-)
+);
 
-export default Home
+export default Home;