Compare commits

...

179 Commits

Author SHA1 Message Date
Levin Faber 11738e8ba5 Merge branch 'develop' into 'f/raum-übersicht' 7 years ago
Levin Faber deefa9102e Merge branch 'f/frontend-login' into 'develop' 7 years ago
Tobi 6ef357574a
📚 Pflichtenheft mit Seitenumbrüchen in PDF 7 years ago
Tobi db8a41721a
📚 Pflichtenheft formales 7 years ago
K.A.J 1ec0709190 Zeitplan aktualisieren und alte Version entfernen 7 years ago
K.A.J b07b8094f2 Update LS Musikschule. PROJEKTSTRUKTURPLAN.xlsx 7 years ago
Tobi b13ff7be25
📚 Protokolle formatiert 7 years ago
K.A.J ad8530381f Zeitplan: althernative Ansichten hinzugefügt 7 years ago
K.A.J ec7a4c35b7 Zeitplan aktualisiert 7 years ago
Tobi 65d37cd383
🔥 Nicht verwendete Dateien aus EVABackend entfernt 7 years ago
Tobi d9cdd77df4 Merge branch 'f/4-erstellung-der-zu-verwendenden-datenbankstrukturen-2' into 'develop' 7 years ago
Tobi 4020b1464a
🚧 Models für Aufnahmeantrag und Rooms 7 years ago
Levin Faber 44d9ff017b Update Endpoints.md 7 years ago
Tobi d04978fdae
🚧 CookieAuth implementiert 7 years ago
Levin Faber 8898a0ca0c Update Endpoints.md 7 years ago
Levin Faber 2837158a51 Update Endpoints.md 7 years ago
Levin Faber 6380190882
Neue View: Raumübersicht. Braucht Datenquelle 7 years ago
Kai Senkowski 521d0cab0e removed unused import 7 years ago
Kai Senkowski 472455d976 passwort placeholder changed 7 years ago
Kai Senkowski 2ed2003190 added login page 7 years ago
Tobi 87a870a7a0
Merge branch 'develop' into f/4-erstellung-der-zu-verwendenden-datenbankstrukturen-2 7 years ago
Tobi f032b6abe2
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Tobi ceb78a2c55
📚 Protokolle 2019-06-19 7 years ago
Levin Faber 645d9b751b Merge branch 'f/formular-aufnahmeantrag' into 'develop' 7 years ago
Tobi 2caef34ed5
📚 Protokoll 2019-06-12 7 years ago
Levin Faber 687c3be906
Export Pflichtenheft 7 years ago
Levin Faber 383e89c26b
📖 Entwicklungsumgebung 7 years ago
Levin Faber 592c3071f2
Merge Dev 7 years ago
Levin Faber ac16036d6c
📖 Pflichtenheft erweitert 7 years ago
Tobi 66a275974a
🚧 IdentityFramework hinzugefügt und initialisiert; Controller vorbereitet 7 years ago
Kai Senkowski b60f09b101 Merge branch 'f/formular-aufnahmeantrag' of gitlab.com:fia72-dev/eva_lernsituation into f/formular-aufnahmeantrag 7 years ago
Kai Senkowski 410d292264 theme colors added 7 years ago
Tobi 448e66fc2a
Merge branch 'develop' into f/4-erstellung-der-zu-verwendenden-datenbankstrukturen-2 7 years ago
K.A.J e784d9de21 Merge branch 'develop' of https://gitlab.com/fia72-dev/eva_lernsituation into develop 7 years ago
Levin Faber 6d96073ee5 Merge branch 'f/formular-aufnahmeantrag' into 'develop' 7 years ago
K.A.J 2e83797af0 Update PROJEKTSTRUKTURPLAN 7 years ago
Levin Faber 5616e84854
Merge dev 7 years ago
Levin Faber 517e31a638 💚 Update .gitlab-ci.yml 7 years ago
Tobi e0ea0bdce1
📚 Protokoll und Endpoints überarbeitet 7 years ago
Levin Faber 5aca92512f
Fixed ci 7 years ago
Levin Faber a8b6fdba05
Restart host 7 years ago
Levin Faber 9a8e8adafd
change restart host 7 years ago
Levin Faber 7311176cef
gpMerge branch 'f/formular-aufnahmeantrag' of gitlab.com:fia72-dev/eva_lernsituation into f/formular-aufnahmeantrag 7 years ago
Levin Faber 1aa54c18f2
Changed nginx to serve 7 years ago
Kai Senkowski 536dd4b7a7 Update Endpoints.md 7 years ago
Kai Senkowski e4c359fab5 Added Aufnahmeantrag Endpoints.md 7 years ago
Kai Senkowski 6c2e4612eb Merge branch 'f/formular-aufnahmeantrag' of gitlab.com:fia72-dev/eva_lernsituation into f/formular-aufnahmeantrag 7 years ago
Kai Senkowski eef0c6cc02 removed unused imports 7 years ago
K.A.J 14da357f8b Update PROJEKTSTRUKTURPLAN 7 years ago
Levin Faber a86ca40f60
Merge remote-tracking branch 'origin/develop' into f/formular-aufnahmeantrag 7 years ago
Tobi ba5e6dafcb
📚 Protokoll 2019-06-12 7 years ago
Levin Faber a19b0d05a0
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Levin Faber 4f93a72bea
Cleanup, created PDF 7 years ago
K.A.J 7ecba69ac5 Update PROJEKTSTRUKTURPLAN 7 years ago
Tobi 0f331055e6
🚧 Datenmodels erweitert 7 years ago
K.A.J aff67bb600 Projektstrukturplan hinzufügen 7 years ago
Levin Faber e4f6c38736 :green_hearth: Update .gitlab-ci.yml 7 years ago
Levin Faber 7a3d966022 Merge branch 'develop' into 'f/formular-aufnahmeantrag' 7 years ago
Kai Senkowski 30a174af35 📦 Update package.json version update material UI 7 years ago
Levin Faber 0f644ab9fb 📖 Update Pflichtenheft.md 7 years ago
Levin Faber 3c1969a54e 📝 Update Pflichtenheft.md 7 years ago
Tobi bf985ed0a0
📚 Dokumente 2019-05-06 7 years ago
Levin Faber 3fdc722df7
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Levin Faber db8305a8e2
Added functions and kais work 7 years ago
Tobi 044ebda7df Merge branch 'patch-2' into 'develop' 7 years ago
Levin Faber 9b613c23a9
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Tobi 4daebcf1d5
📚 Dokumente 2019-05-29 7 years ago
Levin Faber 91597f7de4
Pflichtenheft 7 years ago
Tobi 138dda4374
📚 MindMap hinzugefügt 7 years ago
Tobi 0beb7c57ca
📚 Use Case Diagramm aktualisiert 7 years ago
Levin Faber d480a85c82
Pflichtenheft 7 years ago
Tobi fc4f037891
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Tobi 6f904c3e38
🚧 Use Case Diagramm hinzugefügt 7 years ago
K.A.J 2b8de44519 Update Fragenkatalog.md 7 years ago
K.A.J db978f9e90 Create Zeitplan.md 7 years ago
Kai Senkowski df559f1b8d border color changed 7 years ago
Kai Senkowski 39f6fb1b18 instrument checkbox fixed 7 years ago
Kai Senkowski bcbd943dd6 instrument checkbox added 7 years ago
K.A.J cd8005ef79 Merge branch 'develop' of https://gitlab.com/fia72-dev/eva_lernsituation into develop 7 years ago
K.A.J 112447b2dc Create Fragenkatalog.md 7 years ago
Tobi 248b680fe6
📝 Ergebnisse zu Laufzettel ergänzt (2019-05-22) 7 years ago
Kai Senkowski 46f35ff7eb added box shadow to form 7 years ago
Tobi 3abdc43589
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Tobi b1fbad9eab
📚 ER-Diagram aktualisiert 7 years ago
Tobi 093cc62e35
🚧 Datenmodels erweitert 7 years ago
Levin Faber 5409726f67 Update _Dokumente/Ausgearbeitete Dokumente/Endpoints.md 7 years ago
Kai Senkowski 74c2ee475b laufzeit und typ zu selects 7 years ago
Tobi 645eafeb0d
📚 Protokolle 2019-05-22 7 years ago
Tobi e947e20f93
📚 ER-Diagram aktualisiert 7 years ago
Tobi 3edee380b7
📚 ER-Diagram aktualisiert 7 years ago
Tobi ac8ea43d25
📚 ER-Diagram aktualisiert 7 years ago
Kai Senkowski 63e55b8b1f Aufnahmeantrag fromular ergänzt 7 years ago
Levin Faber 0c0d3a3be0 Update _Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md, README.md files 7 years ago
Levin Faber afa43826b4 Update .gitlab-ci.yml 7 years ago
Levin Faber 17d441ddb1 Merge branch 'f/gitlab-ci-pipelines-einrichten' into 'develop' 7 years ago
Levin Faber bafd52afb2 Update .gitlab-ci.yml 7 years ago
Levin Faber 7f5724a95f Update .gitlab-ci.yml 7 years ago
Kai Senkowski 3baeff8b0a Merge remote-tracking branch 'origin/f/react-grundstruktur' into f/formular-aufnahmeantrag 7 years ago
Kai Senkowski 09f9687dd5 added component Aufnahmeantrag 7 years ago
Levin Faber 0248913e81
WIP 7 years ago
Levin Faber 96bce4fc39
Added Router 7 years ago
Levin Faber 1d2d00d8f8
WIP 7 years ago
Tobi 939dfaafb4
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Tobi e957901597
🚧 EVA ERD Dateien hinzugefügt 7 years ago
Tobi 035415dcaa
:constuction: ERD mit Code-First Implementation begonnen 7 years ago
Levin Faber 6fb075ecc0
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Levin Faber 60a1c01eb9
Added Paperprot 7 years ago
Tobi 7e23a93410
📝 Protokolle für 2019-05-15 7 years ago
Tobi 337b2f9e7a
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Tobi 18232ee6b3
📝 Protokolle für 2019-05-15 7 years ago
Kai Senkowski 1744b47a86 📝 Update README.md 7 years ago
Levin Faber a890331609 Update .gitlab-ci.yml 7 years ago
Levin Faber 8d9e9e7a44 Merge branch 'f/1-frontend-react-initialisieren' into 'develop' 7 years ago
Kai Senkowski 6dc3854226 🔧 React app name changed 7 years ago
Levin Faber d121318f75
Renamed Dockerfile 7 years ago
Tobi 4536a4ef40 Merge branch 'f/2-backend-asp-net-core-initialisieren' into 'develop' 7 years ago
Tobi b94e0a3de7
🎉 EVABackend .NET Core Projekt initialisiert 7 years ago
Levin Faber b79e566d18 Merge branch 'f/gitlab-ci-pipelines-einrichten' into 'develop' 7 years ago
Levin Faber 02a5e125a2 Update .gitlab-ci.yml 7 years ago
Levin Faber ad6a2404d7 Update .gitlab-ci.yml 7 years ago
Levin Faber 233aa04817 Update .gitlab-ci.yml 7 years ago
Levin Faber 6e63b48163 Update .gitlab-ci.yml 7 years ago
Levin Faber 0b14603366 Update .gitlab-ci.yml 7 years ago
Levin Faber cd887b4fb6 Update .gitlab-ci.yml 7 years ago
Levin Faber 7d439075b6 Update .gitlab-ci.yml 7 years ago
Levin Faber 895a6376b7 Update .gitlab-ci.yml 7 years ago
Levin Faber cd5d32af4d Update .gitlab-ci.yml 7 years ago
Levin Faber 743e32885b Update .gitlab-ci.yml 7 years ago
Levin Faber e6aa36948f Update .gitlab-ci.yml 7 years ago
Levin Faber 786af31d9f
🚚 File permissions 7 years ago
Levin Faber 0eeaeb077d Update .gitlab-ci.yml, Docker/config/restart-host.sh files 7 years ago
Levin Faber b515e5a7a7 Update .gitlab-ci.yml 7 years ago
Levin Faber 93fd8d871e Update .gitlab-ci.yml, Docker/Dockerfile_FE_Host files 7 years ago
Levin Faber 1fde640178 Update .gitlab-ci.yml 7 years ago
Levin Faber f985a69de9 Update .gitlab-ci.yml 7 years ago
Levin Faber ba0ed4a900 Update .gitlab-ci.yml 7 years ago
Levin Faber 4d3422b39d Update .gitlab-ci.yml 7 years ago
Levin Faber 4ccc812f35 Update .gitlab-ci.yml 7 years ago
Levin Faber 3509439dfb Update .gitlab-ci.yml 7 years ago
Levin Faber 6fa231ac3c Update .gitlab-ci.yml 7 years ago
Levin Faber a6f323c8eb Update .gitlab-ci.yml 7 years ago
Levin Faber 479a4d2d81 Update .gitlab-ci.yml 7 years ago
Levin Faber 92bb8351dc Update .gitlab-ci.yml 7 years ago
Levin Faber ac1c31beb7 Update .gitlab-ci.yml 7 years ago
Levin Faber f777c10353 Update .gitlab-ci.yml 7 years ago
Levin Faber abcd2e95fd Update .gitlab-ci.yml 7 years ago
Levin Faber 3e34d3cf1a Update .gitlab-ci.yml 7 years ago
Levin Faber d0a85eb60c Update .gitlab-ci.yml 7 years ago
Levin Faber 2625465071 Update .gitlab-ci.yml 7 years ago
Levin Faber ff38e43576 Update .gitlab-ci.yml 7 years ago
Levin Faber bc4629ea67 Update .gitlab-ci.yml 7 years ago
Levin Faber ff4d67bfe1 Update .gitlab-ci.yml 7 years ago
Levin Faber 849140bd54 Update .gitlab-ci.yml 7 years ago
Levin Faber 1535bb0e21 Update .gitlab-ci.yml 7 years ago
Levin Faber 95ea0e935a Update .gitlab-ci.yml 7 years ago
Levin Faber 30929c60f7 Update .gitlab-ci.yml 7 years ago
Levin Faber f0014a083d 👷 Add new file 7 years ago
Levin Faber 23fb24972e Merge branch 'develop' into 'f/gitlab-ci-pipelines-einrichten' 7 years ago
Levin Faber 819eda375b Merge branch 'f/docker-fe' into 'develop' 7 years ago
Levin Faber e878d571ea
🐳 Added Dockerfile for Build 7 years ago
Levin Faber 63acad363a Merge branch 'f/1-frontend-react-initialisieren' into 'develop' 7 years ago
u14461 3d70291fa9 🎉 React App initialisiert 7 years ago
Levin Faber 6c3fc58051 📝 Update README.md 7 years ago
Levin Faber 49f8e987f7 📝 Update README.md 7 years ago
Tobi e9a84f69a4 Merge branch 'f/docker-fe' into 'develop' 7 years ago
Levin Faber 9f7ba498f5
🐳 Added Dockerfiles, FE Placeholder 7 years ago
Levin Faber 80f04bad40 📝 Update README.md 7 years ago
Levin Faber a60f4338ab 📝 Update README.md 7 years ago
Levin Faber bfe064c04a
Merge branch 'develop' of gitlab.com:fia72-dev/eva_lernsituation into develop 7 years ago
Levin Faber 64666e06eb
🚚 Moved Dokuments, added Frontend and Backend Folder 7 years ago
Tobi 7c66efedae
📝 Vorlage Protokoll angepasst 7 years ago
Tobi 99c0ad580f 📝 Rollenverteilung angepasst 7 years ago
Tobi bdb63ed920 📝 Namen der Teilnehmer korrigiert 7 years ago
Levin Faber 661be5e9b5
📝 Protocol and Roles 7 years ago
Levin Faber e06404fc30
📝 Protokoll Template 7 years ago
Levin Faber b54b4bf845
🚚 Added Folder 7 years ago
Levin Faber b59b103236
📝 Updated Folder structure 7 years ago
Levin Faber 3faa816ab5
📝 Updated Folder structure 7 years ago
Levin Faber 8422cd200f Update README.md 7 years ago
  1. 23
      .gitignore
  2. 74
      .gitlab-ci.yml
  3. 0
      Backend/.gitkeep
  4. 9
      Backend/EVABackend/.dockerignore
  5. 348
      Backend/EVABackend/.gitignore
  6. 25
      Backend/EVABackend/EVABackend.sln
  7. 27
      Backend/EVABackend/EVABackend/Areas/Identity/Data/EVABackendIdentityContext.cs
  8. 13
      Backend/EVABackend/EVABackend/Areas/Identity/Data/EVABackendUser.cs
  9. 36
      Backend/EVABackend/EVABackend/Areas/Identity/IdentityHostingStartup.cs
  10. 194
      Backend/EVABackend/EVABackend/Controllers/EVAController.cs
  11. 20
      Backend/EVABackend/EVABackend/Dockerfile
  12. 21
      Backend/EVABackend/EVABackend/EVABackend.csproj
  13. 229
      Backend/EVABackend/EVABackend/Migrations/20190612100741_CreateIdentitySchema.Designer.cs
  14. 217
      Backend/EVABackend/EVABackend/Migrations/20190612100741_CreateIdentitySchema.cs
  15. 388
      Backend/EVABackend/EVABackend/Migrations/EVA/20190612101730_InitialCreate.Designer.cs
  16. 403
      Backend/EVABackend/EVABackend/Migrations/EVA/20190612101730_InitialCreate.cs
  17. 386
      Backend/EVABackend/EVABackend/Migrations/EVA/EVAContextModelSnapshot.cs
  18. 227
      Backend/EVABackend/EVABackend/Migrations/EVABackendIdentityContextModelSnapshot.cs
  19. 42
      Backend/EVABackend/EVABackend/Models/Aufnahmeantrag.cs
  20. 13
      Backend/EVABackend/EVABackend/Models/CreateRooms.cs
  21. 227
      Backend/EVABackend/EVABackend/Models/EVAContext.cs
  22. 24
      Backend/EVABackend/EVABackend/Program.cs
  23. 38
      Backend/EVABackend/EVABackend/Properties/launchSettings.json
  24. 26
      Backend/EVABackend/EVABackend/ScaffoldingReadme.txt
  25. 44
      Backend/EVABackend/EVABackend/Startup.cs
  26. 9
      Backend/EVABackend/EVABackend/appsettings.Development.json
  27. 11
      Backend/EVABackend/EVABackend/appsettings.json
  28. BIN
      Backend/EVABackend/EVABackend/eva_ls.db
  29. BIN
      Backend/EVABackend/EVABackend/eva_users.db
  30. 15
      Docker/Dockerfile_FE_Builder.dockerfile
  31. 14
      Docker/Dockerfile_FE_Host.dockerfile
  32. 14
      Docker/config/nginx.conf
  33. 7
      Docker/config/restart-host.sh
  34. 23
      Frontend/.gitignore
  35. 0
      Frontend/.gitkeep
  36. 7
      Frontend/README.md
  37. 12
      Frontend/dist/index.html
  38. 13129
      Frontend/package-lock.json
  39. 34
      Frontend/package.json
  40. BIN
      Frontend/public/favicon.ico
  41. 18
      Frontend/public/index.html
  42. 15
      Frontend/public/manifest.json
  43. 38
      Frontend/src/components/App.js
  44. 376
      Frontend/src/components/Aufnahmeantrag.js
  45. 80
      Frontend/src/components/Login.js
  46. 89
      Frontend/src/components/RoomOverview.js
  47. 6
      Frontend/src/index.js
  48. 19
      Frontend/src/style/index.css
  49. 250
      Pflichtenheft.diff
  50. 34
      README.md
  51. 0
      _Dokumente/Ausgangsmaterial/LS _MS_Ausgangslage.docx
  52. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Aktivitaeten_und_Dokumente.pdf
  53. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Ausgangslage.pdf
  54. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Beispiel_Lastenheft.pdf
  55. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Laufzettel_v2.pdf
  56. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Material_Kundengespräch_01.docx
  57. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Material_Kundengespräch_01.pdf
  58. 0
      _Dokumente/Ausgangsmaterial/LS_MS_PaperPrototyping.pdf
  59. 0
      _Dokumente/Ausgangsmaterial/LS_MS_Pflichtenheft.pdf
  60. 0
      _Dokumente/Ausgangsmaterial/LS_MS__Beispiel_Pflichtenheft.pdf
  61. 0
      _Dokumente/Ausgangsmaterial/P01_Lernsituation_MS_1.0_FIA7x.ppt
  62. 0
      _Dokumente/Ausgangsmaterial/Pflichtenheftvorlage.doc
  63. 0
      _Dokumente/Ausgangsmaterial/Pflichtenheftvorlage.pdf
  64. 0
      _Dokumente/Ausgangsmaterial/Projektmanagement Kompendium.pdf
  65. BIN
      _Dokumente/Ausgearbeitete Dokumente/EVA ERD Umletino.png
  66. 57
      _Dokumente/Ausgearbeitete Dokumente/EVA ERD Umletino.uxf
  67. BIN
      _Dokumente/Ausgearbeitete Dokumente/EVA Use Case Umletino.png
  68. 24
      _Dokumente/Ausgearbeitete Dokumente/EVA Use Case Umletino.uxf
  69. 199
      _Dokumente/Ausgearbeitete Dokumente/Endpoints.md
  70. 9
      _Dokumente/Ausgearbeitete Dokumente/Fragenkatalog.md
  71. BIN
      _Dokumente/Ausgearbeitete Dokumente/LS Musikschule. PROJEKTSTRUKTURPLAN.pdf
  72. BIN
      _Dokumente/Ausgearbeitete Dokumente/LS Musikschule. PROJEKTSTRUKTURPLAN.xlsx
  73. BIN
      _Dokumente/Ausgearbeitete Dokumente/MindMap.pdf
  74. BIN
      _Dokumente/Ausgearbeitete Dokumente/Papierprototyp_1.pdf
  75. BIN
      _Dokumente/Ausgearbeitete Dokumente/Papierprototyp_2.pdf
  76. 843
      _Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.html
  77. 345
      _Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md
  78. BIN
      _Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.pdf
  79. 11
      _Dokumente/Ausgearbeitete Dokumente/Rollenverteilung.md
  80. 15
      _Dokumente/Ausgearbeitete Dokumente/Wasserfalldiagramm.md
  81. BIN
      _Dokumente/Ausgearbeitete Dokumente/Zeitplan.jpg
  82. BIN
      _Dokumente/Ausgearbeitete Dokumente/img/Hauptseite.png
  83. BIN
      _Dokumente/Ausgearbeitete Dokumente/img/Hauptseite_Dozent.png
  84. BIN
      _Dokumente/Ausgearbeitete Dokumente/img/Hauptseite_Verwaltung.png
  85. 21
      _Dokumente/Protokolle/2019-05-08_Protokoll.md
  86. 44
      _Dokumente/Protokolle/2019-05-15_Protokoll.md
  87. 18
      _Dokumente/Protokolle/2019-05-22_Protokoll.md
  88. 21
      _Dokumente/Protokolle/2019-05-29_Protokoll.md
  89. 24
      _Dokumente/Protokolle/2019-06-05_Protokoll.md
  90. 28
      _Dokumente/Protokolle/2019-06-12_Protokoll.md
  91. 17
      _Dokumente/Protokolle/2019-06-19_Protokoll.md
  92. 15
      _Dokumente/Protokolle/Protokoll_Template.md
  93. 3
      package-lock.json

23
.gitignore vendored

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

74
.gitlab-ci.yml

@ -0,0 +1,74 @@
stages:
- build_docker
- build_frontend
build_frontend:
stage: build_frontend
tags:
- docker
image: registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-build
before_script:
- eval $(ssh-agent -s)
- ssh-add <(echo "${DEPLOY_ENV_KEY}")
- mkdir -p ~/.ssh
- '[[ -f /.dockerenv ]] && echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config'
- cp -r Frontend/src/ /workdir/src/
- cp -r Frontend/public/ /workdir/public/
script:
- pwd
- ls -la
- cd /workdir
- npm run build
- ls -la /workdir/build
- ssh $DEPLOY_ENV_USER@$DEPLOY_ENV_TARGET "mkdir -p /home/$DEPLOY_ENV_USER/serve"
- ssh $DEPLOY_ENV_USER@$DEPLOY_ENV_TARGET "rm -rf /home/$DEPLOY_ENV_USER/serve/*"
- ssh $DEPLOY_ENV_USER@$DEPLOY_ENV_TARGET "mkdir -p /home/$DEPLOY_ENV_USER/serve/$CI_COMMIT_REF_NAME"
- rsync --progress -av -e ssh /workdir/build/* $DEPLOY_ENV_USER@$DEPLOY_ENV_TARGET:/home/$DEPLOY_ENV_USER/serve/
only:
changes:
- Frontend/*
environment:
name: deploy
url: https://$DEPLOY_ENV_TARGET
build_docker_host:
stage: build_docker
tags:
- docker-builder
before_script:
- eval $(ssh-agent -s)
- ssh-add <(echo "${DEPLOY_ENV_KEY}")
- mkdir -p ~/.ssh
- echo -e "Host *\n\tStrictHostKeyChecking no\n\n" > ~/.ssh/config
- docker info
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -f Docker/Dockerfile_FE_Host.dockerfile -t registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-serve .
- docker push registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-serve
- ls -la Docker/config/restart-host.sh
- rsync --progress -av -e ssh Docker/config/restart-host.sh $DEPLOY_ENV_USER@$DEPLOY_ENV_TARGET:/home/$DEPLOY_ENV_USER/restart-host.sh
- ssh $DEPLOY_ENV_USER@$DEPLOY_ENV_TARGET "./restart-host.sh"
only:
changes:
- Docker/Dockerfile_FE_Host.dockerfile
- Docker/config/*
build_docker_builder:
stage: build_docker
tags:
- docker-builder
before_script:
- docker info
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
script:
- docker build -f Docker/Dockerfile_FE_Builder.dockerfile -t registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-build .
- docker push registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-build
only:
changes:
- Docker/Dockerfile_FE_Builder.dockerfile
- Docker/config/*
- Frontend/package.json
- Frontend/package-lock.json
- .gitlab-ci.yml

0
Backend/.gitkeep

9
Backend/EVABackend/.dockerignore

@ -0,0 +1,9 @@
.dockerignore
.env
.git
.gitignore
.vs
.vscode
*/bin
*/obj
**/.toolstarget

348
Backend/EVABackend/.gitignore vendored

@ -0,0 +1,348 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.rsuser
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Mono auto generated files
mono_crash.*
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
[Aa][Rr][Mm]/
[Aa][Rr][Mm]64/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015/2017 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# Visual Studio 2017 auto generated files
Generated\ Files/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# Benchmark Results
BenchmarkDotNet.Artifacts/
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
# StyleCop
StyleCopReport.xml
# Files built by Visual Studio
*_i.c
*_p.c
*_h.h
*.ilk
*.meta
*.obj
*.iobj
*.pch
*.pdb
*.ipdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*_wpftmp.csproj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# Visual Studio Trace Files
*.e2e
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# AxoCover is a Code Coverage Tool
.axoCover/*
!.axoCover/settings.json
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# Note: Comment the next line if you want to checkin your web deploy settings,
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# NuGet Symbol Packages
*.snupkg
# The packages folder can be ignored because of Package Restore
**/[Pp]ackages/*
# except build/, which is used as an MSBuild target.
!**/[Pp]ackages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/[Pp]ackages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
*.appx
*.appxbundle
*.appxupload
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!?*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Including strong name files can present a security risk
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
#*.snk
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
ServiceFabricBackup/
*.rptproj.bak
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
*.rptproj.rsuser
*- [Bb]ackup.rdl
*- [Bb]ackup ([0-9]).rdl
*- [Bb]ackup ([0-9][0-9]).rdl
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# CodeRush personal settings
.cr/personal
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Tabs Studio
*.tss
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs
# OpenCover UI analysis results
OpenCover/
# Azure Stream Analytics local run output
ASALocalRun/
# MSBuild Binary and Structured Log
*.binlog
# NVidia Nsight GPU debugger configuration file
*.nvuser
# MFractors (Xamarin productivity tool) working folder
.mfractor/
# Local History for Visual Studio
.localhistory/
# BeatPulse healthcheck temp database
healthchecksdb
# Backup folder for Package Reference Convert tool in Visual Studio 2017
MigrationBackup/

25
Backend/EVABackend/EVABackend.sln

@ -0,0 +1,25 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.28803.156
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "EVABackend", "EVABackend\EVABackend.csproj", "{35629A48-394C-4EE6-B853-1B92641B9FED}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{35629A48-394C-4EE6-B853-1B92641B9FED}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{35629A48-394C-4EE6-B853-1B92641B9FED}.Debug|Any CPU.Build.0 = Debug|Any CPU
{35629A48-394C-4EE6-B853-1B92641B9FED}.Release|Any CPU.ActiveCfg = Release|Any CPU
{35629A48-394C-4EE6-B853-1B92641B9FED}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {9D649B10-EA35-49B9-BCB5-A989D21D6832}
EndGlobalSection
EndGlobal

27
Backend/EVABackend/EVABackend/Areas/Identity/Data/EVABackendIdentityContext.cs

@ -0,0 +1,27 @@
using EVABackend.Areas.Identity.Data;
using Microsoft.AspNetCore.Identity.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore;
namespace EVABackend.Models
{
public class EVABackendIdentityContext : IdentityDbContext<EVABackendUser>
{
public EVABackendIdentityContext(DbContextOptions<EVABackendIdentityContext> options)
: base(options)
{
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=eva_users.db");
}
protected override void OnModelCreating(ModelBuilder builder)
{
base.OnModelCreating(builder);
// Customize the ASP.NET Identity model and override the defaults if needed.
// For example, you can rename the ASP.NET Identity table names and more.
// Add your customizations after calling base.OnModelCreating(builder);
}
}
}

13
Backend/EVABackend/EVABackend/Areas/Identity/Data/EVABackendUser.cs

@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Identity;
namespace EVABackend.Areas.Identity.Data
{
// Add profile data for application users by adding properties to the EVABackendUser class
public class EVABackendUser : IdentityUser
{
}
}

36
Backend/EVABackend/EVABackend/Areas/Identity/IdentityHostingStartup.cs

@ -0,0 +1,36 @@
using EVABackend.Areas.Identity.Data;
using EVABackend.Models;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;
[assembly: HostingStartup(typeof(EVABackend.Areas.Identity.IdentityHostingStartup))]
namespace EVABackend.Areas.Identity
{
public class IdentityHostingStartup : IHostingStartup
{
public void Configure(IWebHostBuilder builder)
{
builder.ConfigureServices((context, services) =>
{
services.AddDbContext<EVABackendIdentityContext>(options =>
options.UseSqlite(
context.Configuration.GetConnectionString("EVABackendIdentityContextConnection")));
services.AddDefaultIdentity<EVABackendUser>()
.AddRoles<IdentityRole>()
.AddEntityFrameworkStores<EVABackendIdentityContext>()
.AddDefaultTokenProviders();
services.ConfigureApplicationCookie(options =>
{
options.Cookie.Name = "EVABackend_Token";
});
});
}
}
}

194
Backend/EVABackend/EVABackend/Controllers/EVAController.cs

@ -0,0 +1,194 @@
using EVABackend.Areas.Identity.Data;
using EVABackend.Models;
using Microsoft.AspNetCore.Authentication;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using System.Linq;
using System.Threading.Tasks;
namespace EVABackend.Controllers
{
[ApiController]
public class EVAController : ControllerBase
{
private readonly EVAContext _context;
private readonly UserManager<EVABackendUser> _userManager;
private readonly RoleManager<IdentityRole> _roleManager;
private readonly SignInManager<EVABackendUser> _signInManager;
public EVAController(UserManager<EVABackendUser> userManager, RoleManager<IdentityRole> roleManager, SignInManager<EVABackendUser> signInManager)
{
_userManager = userManager;
_roleManager = roleManager;
_signInManager = signInManager;
_context = new EVAContext();
}
[HttpGet]
[Route("login")]
[AllowAnonymous]
public ActionResult Login()
{
return Ok(new { status = "Nicht unterstützt" });
}
[HttpGet]
[Route("create_dummy_data")]
[Authorize]
public async Task<ActionResult> CreateDummyData()
{
if (_userManager.FindByNameAsync("Test") == null)
{
var user = new EVABackendUser
{
UserName = "Test",
Email = "info@test.de"
};
await _userManager.CreateAsync(user, "123Abc!&");
}
var roleNames = new string[] { "Schueler", "Verwaltung", "Admin" };
foreach (var roleName in roleNames)
{
if (!(await _roleManager.RoleExistsAsync(roleName)))
{
await _roleManager.CreateAsync(new IdentityRole(roleName));
}
}
await _userManager.AddToRolesAsync((await _userManager.FindByNameAsync("Test")), roleNames);
return Ok();
}
[HttpPost]
[Route("login")]
[AllowAnonymous]
public async Task<ActionResult> Login([FromForm] string username, [FromForm] string password)
{
var result = await _signInManager.PasswordSignInAsync(username, password, false, false);
if (result.Succeeded)
{
return Ok();
}
return Unauthorized();
}
[HttpPost]
[Route("logout")]
[Authorize]
public async Task<ActionResult> Logout()
{
await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
return Ok();
}
[HttpPost]
[Route("aufnahmeantrag")]
[AllowAnonymous]
public async Task<ActionResult> Aufnahmeantrag(Aufnahmeantrag model)
{
var schueler = new Schueler
{
Name = model.Name,
Vorname = model.Vonname,
IstErmaessigt = model.IstErmaessigt,
Ort = model.Ort,
Bankname = model.Bankname,
BLZ = model.BLZ,
Geburtsdatum = model.Geburtsdatum,
Geburtsort = model.Geburtsort,
Telefon = model.Telefon,
EMail = model.EMail,
PLZ = model.PLZ,
KontoNr = model.KontoNr,
Strasse = model.StrasseHNR
};
await _context.Schueler.AddAsync(schueler);
await _context.SaveChangesAsync();
var instrumente = _context.Instrumente.Where(i => model.Instrumente.Contains(i.Id)).ToList();
var kurs = new Kurs
{
Bestaetigt = false,
Name = model.Name,
Kuendigungsfrist = 2,
UnterrichtsTyp = model.Typ,
Laufzeit = 6
};
await _context.Kurse.AddAsync(kurs);
await _context.SaveChangesAsync();
kurs.Instrumente = instrumente.Select(i => new KursInstrument { InstrumentId = i.Id, KursId = kurs.Id }).ToList();
await _context.KursSchueler.AddAsync(new KursSchueler { KursId = kurs.Id, SchuelerId = schueler.Id });
await _context.SaveChangesAsync();
var antrag = new Antrag
{
UnterrichtTyp = model.Typ,
Schueler = schueler,
KursId = kurs.Id
};
await _context.Antraege.AddAsync(antrag);
await _context.SaveChangesAsync();
antrag.Instrumente = instrumente.Select(i => new AntragInstrument { AntragId = antrag.Id, InstrumentId = i.Id }).ToList();
await _context.SaveChangesAsync();
return Ok();
}
[HttpGet]
[Route("instruments")]
[Authorize]
public ActionResult Instruments()
{
var instruments = _context.Instrumente.ToList();
return Ok(instruments.ToArray());
}
[HttpGet]
[Route("rooms")]
[Authorize(Roles = "Verwaltung")]
public ActionResult Rooms()
{
var rooms = _context.Raeume.ToList();
var model = rooms.Select(r => new
{
RaumID = r.Id,
RaumName= r.Name,
Instrumente = r.Instrumente.Select(i => new
{
InstrumentID = i.InstrumentId,
InstrumentName = i.Instrument.Name
})
});
return Ok(model.ToArray());
}
[HttpPut]
[Route("create_rooms")]
[Authorize(Roles = "Verwaltung")]
public async Task<ActionResult> CreateRooms(CreateRooms model)
{
}
}
}

20
Backend/EVABackend/EVABackend/Dockerfile

@ -0,0 +1,20 @@
FROM mcr.microsoft.com/dotnet/core/aspnet:2.1-stretch-slim AS base
WORKDIR /app
EXPOSE 80
EXPOSE 443
FROM mcr.microsoft.com/dotnet/core/sdk:2.1-stretch AS build
WORKDIR /src
COPY ["EVABackend.csproj", "EVABackend/"]
RUN dotnet restore "EVABackend/EVABackend.csproj"
COPY . .
WORKDIR "/src/EVABackend"
RUN dotnet build "EVABackend.csproj" -c Release -o /app
FROM build AS publish
RUN dotnet publish "EVABackend.csproj" -c Release -o /app
FROM base AS final
WORKDIR /app
COPY --from=publish /app .
ENTRYPOINT ["dotnet", "EVABackend.dll"]

21
Backend/EVABackend/EVABackend/EVABackend.csproj

@ -0,0 +1,21 @@
<Project Sdk="Microsoft.NET.Sdk.Web">
<PropertyGroup>
<TargetFramework>netcoreapp2.1</TargetFramework>
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
<UserSecretsId>81a3ba40-5295-4382-9a09-5339b5d22d08</UserSecretsId>
</PropertyGroup>
<ItemGroup>
<Folder Include="Areas\Identity\Services\" />
</ItemGroup>
<ItemGroup>
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.1.1" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.8" />
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.7.8" />
<PackageReference Include="Microsoft.VisualStudio.Web.CodeGeneration.Design" Version="2.1.9" />
</ItemGroup>
</Project>

229
Backend/EVABackend/EVABackend/Migrations/20190612100741_CreateIdentitySchema.Designer.cs generated

@ -0,0 +1,229 @@
// <auto-generated />
using System;
using EVABackend.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace EVABackend.Migrations
{
[DbContext(typeof(EVABackendIdentityContext))]
[Migration("20190612100741_CreateIdentitySchema")]
partial class CreateIdentitySchema
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.8-servicing-32085");
modelBuilder.Entity("EVABackend.Areas.Identity.Data.EVABackendUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("Name")
.HasMaxLength(128);
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

217
Backend/EVABackend/EVABackend/Migrations/20190612100741_CreateIdentitySchema.cs

@ -0,0 +1,217 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EVABackend.Migrations
{
public partial class CreateIdentitySchema : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "AspNetRoles",
columns: table => new
{
Id = table.Column<string>(nullable: false),
Name = table.Column<string>(maxLength: 256, nullable: true),
NormalizedName = table.Column<string>(maxLength: 256, nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoles", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetUsers",
columns: table => new
{
Id = table.Column<string>(nullable: false),
UserName = table.Column<string>(maxLength: 256, nullable: true),
NormalizedUserName = table.Column<string>(maxLength: 256, nullable: true),
Email = table.Column<string>(maxLength: 256, nullable: true),
NormalizedEmail = table.Column<string>(maxLength: 256, nullable: true),
EmailConfirmed = table.Column<bool>(nullable: false),
PasswordHash = table.Column<string>(nullable: true),
SecurityStamp = table.Column<string>(nullable: true),
ConcurrencyStamp = table.Column<string>(nullable: true),
PhoneNumber = table.Column<string>(nullable: true),
PhoneNumberConfirmed = table.Column<bool>(nullable: false),
TwoFactorEnabled = table.Column<bool>(nullable: false),
LockoutEnd = table.Column<DateTimeOffset>(nullable: true),
LockoutEnabled = table.Column<bool>(nullable: false),
AccessFailedCount = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUsers", x => x.Id);
});
migrationBuilder.CreateTable(
name: "AspNetRoleClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
RoleId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetRoleClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetRoleClaims_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserClaims",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
UserId = table.Column<string>(nullable: false),
ClaimType = table.Column<string>(nullable: true),
ClaimValue = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserClaims", x => x.Id);
table.ForeignKey(
name: "FK_AspNetUserClaims_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserLogins",
columns: table => new
{
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
ProviderKey = table.Column<string>(maxLength: 128, nullable: false),
ProviderDisplayName = table.Column<string>(nullable: true),
UserId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserLogins", x => new { x.LoginProvider, x.ProviderKey });
table.ForeignKey(
name: "FK_AspNetUserLogins_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserRoles",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
RoleId = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserRoles", x => new { x.UserId, x.RoleId });
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetRoles_RoleId",
column: x => x.RoleId,
principalTable: "AspNetRoles",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AspNetUserRoles_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "AspNetUserTokens",
columns: table => new
{
UserId = table.Column<string>(nullable: false),
LoginProvider = table.Column<string>(maxLength: 128, nullable: false),
Name = table.Column<string>(maxLength: 128, nullable: false),
Value = table.Column<string>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_AspNetUserTokens", x => new { x.UserId, x.LoginProvider, x.Name });
table.ForeignKey(
name: "FK_AspNetUserTokens_AspNetUsers_UserId",
column: x => x.UserId,
principalTable: "AspNetUsers",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_AspNetRoleClaims_RoleId",
table: "AspNetRoleClaims",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "RoleNameIndex",
table: "AspNetRoles",
column: "NormalizedName",
unique: true);
migrationBuilder.CreateIndex(
name: "IX_AspNetUserClaims_UserId",
table: "AspNetUserClaims",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserLogins_UserId",
table: "AspNetUserLogins",
column: "UserId");
migrationBuilder.CreateIndex(
name: "IX_AspNetUserRoles_RoleId",
table: "AspNetUserRoles",
column: "RoleId");
migrationBuilder.CreateIndex(
name: "EmailIndex",
table: "AspNetUsers",
column: "NormalizedEmail");
migrationBuilder.CreateIndex(
name: "UserNameIndex",
table: "AspNetUsers",
column: "NormalizedUserName",
unique: true);
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AspNetRoleClaims");
migrationBuilder.DropTable(
name: "AspNetUserClaims");
migrationBuilder.DropTable(
name: "AspNetUserLogins");
migrationBuilder.DropTable(
name: "AspNetUserRoles");
migrationBuilder.DropTable(
name: "AspNetUserTokens");
migrationBuilder.DropTable(
name: "AspNetRoles");
migrationBuilder.DropTable(
name: "AspNetUsers");
}
}
}

388
Backend/EVABackend/EVABackend/Migrations/EVA/20190612101730_InitialCreate.Designer.cs generated

@ -0,0 +1,388 @@
// <auto-generated />
using System;
using EVABackend.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace EVABackend.Migrations.EVA
{
[DbContext(typeof(EVAContext))]
[Migration("20190612101730_InitialCreate")]
partial class InitialCreate
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.8-servicing-32085");
modelBuilder.Entity("EVABackend.Models.Antrag", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("KursId");
b.Property<int?>("SchuelerId");
b.Property<int?>("UnterrichtTypId");
b.HasKey("Id");
b.HasIndex("SchuelerId");
b.HasIndex("UnterrichtTypId");
b.ToTable("Antraege");
});
modelBuilder.Entity("EVABackend.Models.AntragInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("AntragId");
b.HasKey("InstrumentId", "AntragId");
b.HasIndex("AntragId");
b.ToTable("AntragInstrument");
});
modelBuilder.Entity("EVABackend.Models.Dozent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("BLZ")
.IsRequired();
b.Property<string>("Bankname")
.IsRequired();
b.Property<string>("EMail")
.IsRequired();
b.Property<DateTime>("Geburtsdatum");
b.Property<string>("Geburtsort")
.IsRequired();
b.Property<string>("KontoNr")
.IsRequired();
b.Property<string>("Name")
.IsRequired();
b.Property<string>("Ort")
.IsRequired();
b.Property<int>("PLZ");
b.Property<string>("Strasse")
.IsRequired();
b.Property<decimal>("Stundensatz");
b.Property<string>("Telefon")
.IsRequired();
b.Property<string>("Vorname")
.IsRequired();
b.HasKey("Id");
b.ToTable("Donzenten");
});
modelBuilder.Entity("EVABackend.Models.DozentInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("DozentId");
b.HasKey("InstrumentId", "DozentId");
b.HasIndex("DozentId");
b.ToTable("DozentInstrument");
});
modelBuilder.Entity("EVABackend.Models.Instrument", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired();
b.HasKey("Id");
b.ToTable("Instrumente");
});
modelBuilder.Entity("EVABackend.Models.Kurs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Bestaetigt");
b.Property<int>("Kuendigungsfrist");
b.Property<int>("Laufzeit");
b.Property<string>("Name")
.IsRequired();
b.Property<int?>("UnterrichtsTypId");
b.HasKey("Id");
b.HasIndex("UnterrichtsTypId");
b.ToTable("Kurse");
});
modelBuilder.Entity("EVABackend.Models.KursInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("KursId");
b.HasKey("InstrumentId", "KursId");
b.HasIndex("KursId");
b.ToTable("KursInstrument");
});
modelBuilder.Entity("EVABackend.Models.KursSchueler", b =>
{
b.Property<int>("SchuelerId");
b.Property<int>("KursId");
b.Property<int?>("DozentId");
b.HasKey("SchuelerId", "KursId");
b.HasIndex("DozentId");
b.HasIndex("KursId");
b.ToTable("KursSchueler");
});
modelBuilder.Entity("EVABackend.Models.Raum", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Belegt");
b.Property<string>("Name")
.IsRequired();
b.HasKey("Id");
b.ToTable("Raeume");
});
modelBuilder.Entity("EVABackend.Models.RaumInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("RaumId");
b.HasKey("InstrumentId", "RaumId");
b.HasIndex("RaumId");
b.ToTable("RaumInstrument");
});
modelBuilder.Entity("EVABackend.Models.Schueler", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("BLZ")
.IsRequired();
b.Property<string>("Bankname")
.IsRequired();
b.Property<string>("EMail")
.IsRequired();
b.Property<DateTime>("Geburtsdatum");
b.Property<string>("Geburtsort")
.IsRequired();
b.Property<bool>("IstErmaessigt");
b.Property<string>("KontoNr")
.IsRequired();
b.Property<string>("Name")
.IsRequired();
b.Property<string>("Ort")
.IsRequired();
b.Property<int>("PLZ");
b.Property<string>("Strasse")
.IsRequired();
b.Property<string>("Telefon")
.IsRequired();
b.Property<string>("Vorname")
.IsRequired();
b.HasKey("Id");
b.ToTable("Schueler");
});
modelBuilder.Entity("EVABackend.Models.Unterricht", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("KursId");
b.Property<string>("Notiz");
b.Property<int?>("RaumId");
b.Property<DateTime>("Startzeit");
b.HasKey("Id");
b.HasIndex("KursId");
b.HasIndex("RaumId");
b.ToTable("Unterrichte");
});
modelBuilder.Entity("EVABackend.Models.UnterrichtTyp", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired();
b.HasKey("Id");
b.ToTable("UnterrichtTypen");
});
modelBuilder.Entity("EVABackend.Models.Antrag", b =>
{
b.HasOne("EVABackend.Models.Schueler", "Schueler")
.WithMany()
.HasForeignKey("SchuelerId");
b.HasOne("EVABackend.Models.UnterrichtTyp", "UnterrichtTyp")
.WithMany()
.HasForeignKey("UnterrichtTypId");
});
modelBuilder.Entity("EVABackend.Models.AntragInstrument", b =>
{
b.HasOne("EVABackend.Models.Antrag", "Antrag")
.WithMany("Instrumente")
.HasForeignKey("AntragId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.DozentInstrument", b =>
{
b.HasOne("EVABackend.Models.Dozent", "Dozent")
.WithMany("Instrumente")
.HasForeignKey("DozentId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.Kurs", b =>
{
b.HasOne("EVABackend.Models.UnterrichtTyp", "UnterrichtsTyp")
.WithMany()
.HasForeignKey("UnterrichtsTypId");
});
modelBuilder.Entity("EVABackend.Models.KursInstrument", b =>
{
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Kurs", "Kurs")
.WithMany("Instrumente")
.HasForeignKey("KursId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.KursSchueler", b =>
{
b.HasOne("EVABackend.Models.Dozent")
.WithMany("KursSchueler")
.HasForeignKey("DozentId");
b.HasOne("EVABackend.Models.Kurs", "Kurs")
.WithMany("KursSchueler")
.HasForeignKey("KursId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Schueler", "Schueler")
.WithMany("KursSchueler")
.HasForeignKey("SchuelerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.RaumInstrument", b =>
{
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Raum", "Raum")
.WithMany("Instrumente")
.HasForeignKey("RaumId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.Unterricht", b =>
{
b.HasOne("EVABackend.Models.Kurs")
.WithMany("Unterrichte")
.HasForeignKey("KursId");
b.HasOne("EVABackend.Models.Raum", "Raum")
.WithMany()
.HasForeignKey("RaumId");
});
#pragma warning restore 612, 618
}
}
}

403
Backend/EVABackend/EVABackend/Migrations/EVA/20190612101730_InitialCreate.cs

@ -0,0 +1,403 @@
using System;
using Microsoft.EntityFrameworkCore.Migrations;
namespace EVABackend.Migrations.EVA
{
public partial class InitialCreate : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Donzenten",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: false),
Vorname = table.Column<string>(nullable: false),
Geburtsdatum = table.Column<DateTime>(nullable: false),
Geburtsort = table.Column<string>(nullable: false),
PLZ = table.Column<int>(nullable: false),
Ort = table.Column<string>(nullable: false),
Strasse = table.Column<string>(nullable: false),
Telefon = table.Column<string>(nullable: false),
EMail = table.Column<string>(nullable: false),
Bankname = table.Column<string>(nullable: false),
BLZ = table.Column<string>(nullable: false),
KontoNr = table.Column<string>(nullable: false),
Stundensatz = table.Column<decimal>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Donzenten", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Instrumente",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Instrumente", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Raeume",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: false),
Belegt = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Raeume", x => x.Id);
});
migrationBuilder.CreateTable(
name: "Schueler",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: false),
Vorname = table.Column<string>(nullable: false),
Geburtsdatum = table.Column<DateTime>(nullable: false),
Geburtsort = table.Column<string>(nullable: false),
PLZ = table.Column<int>(nullable: false),
Ort = table.Column<string>(nullable: false),
Strasse = table.Column<string>(nullable: false),
Telefon = table.Column<string>(nullable: false),
EMail = table.Column<string>(nullable: false),
Bankname = table.Column<string>(nullable: false),
BLZ = table.Column<string>(nullable: false),
KontoNr = table.Column<string>(nullable: false),
IstErmaessigt = table.Column<bool>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Schueler", x => x.Id);
});
migrationBuilder.CreateTable(
name: "UnterrichtTypen",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_UnterrichtTypen", x => x.Id);
});
migrationBuilder.CreateTable(
name: "DozentInstrument",
columns: table => new
{
InstrumentId = table.Column<int>(nullable: false),
DozentId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_DozentInstrument", x => new { x.InstrumentId, x.DozentId });
table.ForeignKey(
name: "FK_DozentInstrument_Donzenten_DozentId",
column: x => x.DozentId,
principalTable: "Donzenten",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_DozentInstrument_Instrumente_InstrumentId",
column: x => x.InstrumentId,
principalTable: "Instrumente",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "RaumInstrument",
columns: table => new
{
InstrumentId = table.Column<int>(nullable: false),
RaumId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_RaumInstrument", x => new { x.InstrumentId, x.RaumId });
table.ForeignKey(
name: "FK_RaumInstrument_Instrumente_InstrumentId",
column: x => x.InstrumentId,
principalTable: "Instrumente",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_RaumInstrument_Raeume_RaumId",
column: x => x.RaumId,
principalTable: "Raeume",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Antraege",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
SchuelerId = table.Column<int>(nullable: true),
UnterrichtTypId = table.Column<int>(nullable: true),
KursId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Antraege", x => x.Id);
table.ForeignKey(
name: "FK_Antraege_Schueler_SchuelerId",
column: x => x.SchuelerId,
principalTable: "Schueler",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Antraege_UnterrichtTypen_UnterrichtTypId",
column: x => x.UnterrichtTypId,
principalTable: "UnterrichtTypen",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "Kurse",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Name = table.Column<string>(nullable: false),
Laufzeit = table.Column<int>(nullable: false),
Kuendigungsfrist = table.Column<int>(nullable: false),
Bestaetigt = table.Column<bool>(nullable: false),
UnterrichtsTypId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Kurse", x => x.Id);
table.ForeignKey(
name: "FK_Kurse_UnterrichtTypen_UnterrichtsTypId",
column: x => x.UnterrichtsTypId,
principalTable: "UnterrichtTypen",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateTable(
name: "AntragInstrument",
columns: table => new
{
InstrumentId = table.Column<int>(nullable: false),
AntragId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_AntragInstrument", x => new { x.InstrumentId, x.AntragId });
table.ForeignKey(
name: "FK_AntragInstrument_Antraege_AntragId",
column: x => x.AntragId,
principalTable: "Antraege",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_AntragInstrument_Instrumente_InstrumentId",
column: x => x.InstrumentId,
principalTable: "Instrumente",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "KursInstrument",
columns: table => new
{
InstrumentId = table.Column<int>(nullable: false),
KursId = table.Column<int>(nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_KursInstrument", x => new { x.InstrumentId, x.KursId });
table.ForeignKey(
name: "FK_KursInstrument_Instrumente_InstrumentId",
column: x => x.InstrumentId,
principalTable: "Instrumente",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_KursInstrument_Kurse_KursId",
column: x => x.KursId,
principalTable: "Kurse",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "KursSchueler",
columns: table => new
{
SchuelerId = table.Column<int>(nullable: false),
KursId = table.Column<int>(nullable: false),
DozentId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_KursSchueler", x => new { x.SchuelerId, x.KursId });
table.ForeignKey(
name: "FK_KursSchueler_Donzenten_DozentId",
column: x => x.DozentId,
principalTable: "Donzenten",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_KursSchueler_Kurse_KursId",
column: x => x.KursId,
principalTable: "Kurse",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
table.ForeignKey(
name: "FK_KursSchueler_Schueler_SchuelerId",
column: x => x.SchuelerId,
principalTable: "Schueler",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateTable(
name: "Unterrichte",
columns: table => new
{
Id = table.Column<int>(nullable: false)
.Annotation("Sqlite:Autoincrement", true),
Startzeit = table.Column<DateTime>(nullable: false),
Notiz = table.Column<string>(nullable: true),
RaumId = table.Column<int>(nullable: true),
KursId = table.Column<int>(nullable: true)
},
constraints: table =>
{
table.PrimaryKey("PK_Unterrichte", x => x.Id);
table.ForeignKey(
name: "FK_Unterrichte_Kurse_KursId",
column: x => x.KursId,
principalTable: "Kurse",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
table.ForeignKey(
name: "FK_Unterrichte_Raeume_RaumId",
column: x => x.RaumId,
principalTable: "Raeume",
principalColumn: "Id",
onDelete: ReferentialAction.Restrict);
});
migrationBuilder.CreateIndex(
name: "IX_Antraege_SchuelerId",
table: "Antraege",
column: "SchuelerId");
migrationBuilder.CreateIndex(
name: "IX_Antraege_UnterrichtTypId",
table: "Antraege",
column: "UnterrichtTypId");
migrationBuilder.CreateIndex(
name: "IX_AntragInstrument_AntragId",
table: "AntragInstrument",
column: "AntragId");
migrationBuilder.CreateIndex(
name: "IX_DozentInstrument_DozentId",
table: "DozentInstrument",
column: "DozentId");
migrationBuilder.CreateIndex(
name: "IX_Kurse_UnterrichtsTypId",
table: "Kurse",
column: "UnterrichtsTypId");
migrationBuilder.CreateIndex(
name: "IX_KursInstrument_KursId",
table: "KursInstrument",
column: "KursId");
migrationBuilder.CreateIndex(
name: "IX_KursSchueler_DozentId",
table: "KursSchueler",
column: "DozentId");
migrationBuilder.CreateIndex(
name: "IX_KursSchueler_KursId",
table: "KursSchueler",
column: "KursId");
migrationBuilder.CreateIndex(
name: "IX_RaumInstrument_RaumId",
table: "RaumInstrument",
column: "RaumId");
migrationBuilder.CreateIndex(
name: "IX_Unterrichte_KursId",
table: "Unterrichte",
column: "KursId");
migrationBuilder.CreateIndex(
name: "IX_Unterrichte_RaumId",
table: "Unterrichte",
column: "RaumId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "AntragInstrument");
migrationBuilder.DropTable(
name: "DozentInstrument");
migrationBuilder.DropTable(
name: "KursInstrument");
migrationBuilder.DropTable(
name: "KursSchueler");
migrationBuilder.DropTable(
name: "RaumInstrument");
migrationBuilder.DropTable(
name: "Unterrichte");
migrationBuilder.DropTable(
name: "Antraege");
migrationBuilder.DropTable(
name: "Donzenten");
migrationBuilder.DropTable(
name: "Instrumente");
migrationBuilder.DropTable(
name: "Kurse");
migrationBuilder.DropTable(
name: "Raeume");
migrationBuilder.DropTable(
name: "Schueler");
migrationBuilder.DropTable(
name: "UnterrichtTypen");
}
}
}

386
Backend/EVABackend/EVABackend/Migrations/EVA/EVAContextModelSnapshot.cs

@ -0,0 +1,386 @@
// <auto-generated />
using System;
using EVABackend.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace EVABackend.Migrations.EVA
{
[DbContext(typeof(EVAContext))]
partial class EVAContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.8-servicing-32085");
modelBuilder.Entity("EVABackend.Models.Antrag", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("KursId");
b.Property<int?>("SchuelerId");
b.Property<int?>("UnterrichtTypId");
b.HasKey("Id");
b.HasIndex("SchuelerId");
b.HasIndex("UnterrichtTypId");
b.ToTable("Antraege");
});
modelBuilder.Entity("EVABackend.Models.AntragInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("AntragId");
b.HasKey("InstrumentId", "AntragId");
b.HasIndex("AntragId");
b.ToTable("AntragInstrument");
});
modelBuilder.Entity("EVABackend.Models.Dozent", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("BLZ")
.IsRequired();
b.Property<string>("Bankname")
.IsRequired();
b.Property<string>("EMail")
.IsRequired();
b.Property<DateTime>("Geburtsdatum");
b.Property<string>("Geburtsort")
.IsRequired();
b.Property<string>("KontoNr")
.IsRequired();
b.Property<string>("Name")
.IsRequired();
b.Property<string>("Ort")
.IsRequired();
b.Property<int>("PLZ");
b.Property<string>("Strasse")
.IsRequired();
b.Property<decimal>("Stundensatz");
b.Property<string>("Telefon")
.IsRequired();
b.Property<string>("Vorname")
.IsRequired();
b.HasKey("Id");
b.ToTable("Donzenten");
});
modelBuilder.Entity("EVABackend.Models.DozentInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("DozentId");
b.HasKey("InstrumentId", "DozentId");
b.HasIndex("DozentId");
b.ToTable("DozentInstrument");
});
modelBuilder.Entity("EVABackend.Models.Instrument", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired();
b.HasKey("Id");
b.ToTable("Instrumente");
});
modelBuilder.Entity("EVABackend.Models.Kurs", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Bestaetigt");
b.Property<int>("Kuendigungsfrist");
b.Property<int>("Laufzeit");
b.Property<string>("Name")
.IsRequired();
b.Property<int?>("UnterrichtsTypId");
b.HasKey("Id");
b.HasIndex("UnterrichtsTypId");
b.ToTable("Kurse");
});
modelBuilder.Entity("EVABackend.Models.KursInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("KursId");
b.HasKey("InstrumentId", "KursId");
b.HasIndex("KursId");
b.ToTable("KursInstrument");
});
modelBuilder.Entity("EVABackend.Models.KursSchueler", b =>
{
b.Property<int>("SchuelerId");
b.Property<int>("KursId");
b.Property<int?>("DozentId");
b.HasKey("SchuelerId", "KursId");
b.HasIndex("DozentId");
b.HasIndex("KursId");
b.ToTable("KursSchueler");
});
modelBuilder.Entity("EVABackend.Models.Raum", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<bool>("Belegt");
b.Property<string>("Name")
.IsRequired();
b.HasKey("Id");
b.ToTable("Raeume");
});
modelBuilder.Entity("EVABackend.Models.RaumInstrument", b =>
{
b.Property<int?>("InstrumentId");
b.Property<int?>("RaumId");
b.HasKey("InstrumentId", "RaumId");
b.HasIndex("RaumId");
b.ToTable("RaumInstrument");
});
modelBuilder.Entity("EVABackend.Models.Schueler", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("BLZ")
.IsRequired();
b.Property<string>("Bankname")
.IsRequired();
b.Property<string>("EMail")
.IsRequired();
b.Property<DateTime>("Geburtsdatum");
b.Property<string>("Geburtsort")
.IsRequired();
b.Property<bool>("IstErmaessigt");
b.Property<string>("KontoNr")
.IsRequired();
b.Property<string>("Name")
.IsRequired();
b.Property<string>("Ort")
.IsRequired();
b.Property<int>("PLZ");
b.Property<string>("Strasse")
.IsRequired();
b.Property<string>("Telefon")
.IsRequired();
b.Property<string>("Vorname")
.IsRequired();
b.HasKey("Id");
b.ToTable("Schueler");
});
modelBuilder.Entity("EVABackend.Models.Unterricht", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<int?>("KursId");
b.Property<string>("Notiz");
b.Property<int?>("RaumId");
b.Property<DateTime>("Startzeit");
b.HasKey("Id");
b.HasIndex("KursId");
b.HasIndex("RaumId");
b.ToTable("Unterrichte");
});
modelBuilder.Entity("EVABackend.Models.UnterrichtTyp", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("Name")
.IsRequired();
b.HasKey("Id");
b.ToTable("UnterrichtTypen");
});
modelBuilder.Entity("EVABackend.Models.Antrag", b =>
{
b.HasOne("EVABackend.Models.Schueler", "Schueler")
.WithMany()
.HasForeignKey("SchuelerId");
b.HasOne("EVABackend.Models.UnterrichtTyp", "UnterrichtTyp")
.WithMany()
.HasForeignKey("UnterrichtTypId");
});
modelBuilder.Entity("EVABackend.Models.AntragInstrument", b =>
{
b.HasOne("EVABackend.Models.Antrag", "Antrag")
.WithMany("Instrumente")
.HasForeignKey("AntragId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.DozentInstrument", b =>
{
b.HasOne("EVABackend.Models.Dozent", "Dozent")
.WithMany("Instrumente")
.HasForeignKey("DozentId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.Kurs", b =>
{
b.HasOne("EVABackend.Models.UnterrichtTyp", "UnterrichtsTyp")
.WithMany()
.HasForeignKey("UnterrichtsTypId");
});
modelBuilder.Entity("EVABackend.Models.KursInstrument", b =>
{
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Kurs", "Kurs")
.WithMany("Instrumente")
.HasForeignKey("KursId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.KursSchueler", b =>
{
b.HasOne("EVABackend.Models.Dozent")
.WithMany("KursSchueler")
.HasForeignKey("DozentId");
b.HasOne("EVABackend.Models.Kurs", "Kurs")
.WithMany("KursSchueler")
.HasForeignKey("KursId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Schueler", "Schueler")
.WithMany("KursSchueler")
.HasForeignKey("SchuelerId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.RaumInstrument", b =>
{
b.HasOne("EVABackend.Models.Instrument", "Instrument")
.WithMany()
.HasForeignKey("InstrumentId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Models.Raum", "Raum")
.WithMany("Instrumente")
.HasForeignKey("RaumId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("EVABackend.Models.Unterricht", b =>
{
b.HasOne("EVABackend.Models.Kurs")
.WithMany("Unterrichte")
.HasForeignKey("KursId");
b.HasOne("EVABackend.Models.Raum", "Raum")
.WithMany()
.HasForeignKey("RaumId");
});
#pragma warning restore 612, 618
}
}
}

227
Backend/EVABackend/EVABackend/Migrations/EVABackendIdentityContextModelSnapshot.cs

@ -0,0 +1,227 @@
// <auto-generated />
using System;
using EVABackend.Models;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
namespace EVABackend.Migrations
{
[DbContext(typeof(EVABackendIdentityContext))]
partial class EVABackendIdentityContextModelSnapshot : ModelSnapshot
{
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "2.1.8-servicing-32085");
modelBuilder.Entity("EVABackend.Areas.Identity.Data.EVABackendUser", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<int>("AccessFailedCount");
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Email")
.HasMaxLength(256);
b.Property<bool>("EmailConfirmed");
b.Property<bool>("LockoutEnabled");
b.Property<DateTimeOffset?>("LockoutEnd");
b.Property<string>("NormalizedEmail")
.HasMaxLength(256);
b.Property<string>("NormalizedUserName")
.HasMaxLength(256);
b.Property<string>("PasswordHash");
b.Property<string>("PhoneNumber");
b.Property<bool>("PhoneNumberConfirmed");
b.Property<string>("SecurityStamp");
b.Property<bool>("TwoFactorEnabled");
b.Property<string>("UserName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedEmail")
.HasName("EmailIndex");
b.HasIndex("NormalizedUserName")
.IsUnique()
.HasName("UserNameIndex");
b.ToTable("AspNetUsers");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRole", b =>
{
b.Property<string>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ConcurrencyStamp")
.IsConcurrencyToken();
b.Property<string>("Name")
.HasMaxLength(256);
b.Property<string>("NormalizedName")
.HasMaxLength(256);
b.HasKey("Id");
b.HasIndex("NormalizedName")
.IsUnique()
.HasName("RoleNameIndex");
b.ToTable("AspNetRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("RoleId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("RoleId");
b.ToTable("AspNetRoleClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd();
b.Property<string>("ClaimType");
b.Property<string>("ClaimValue");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("AspNetUserClaims");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("ProviderKey")
.HasMaxLength(128);
b.Property<string>("ProviderDisplayName");
b.Property<string>("UserId")
.IsRequired();
b.HasKey("LoginProvider", "ProviderKey");
b.HasIndex("UserId");
b.ToTable("AspNetUserLogins");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("RoleId");
b.HasKey("UserId", "RoleId");
b.HasIndex("RoleId");
b.ToTable("AspNetUserRoles");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.Property<string>("UserId");
b.Property<string>("LoginProvider")
.HasMaxLength(128);
b.Property<string>("Name")
.HasMaxLength(128);
b.Property<string>("Value");
b.HasKey("UserId", "LoginProvider", "Name");
b.ToTable("AspNetUserTokens");
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityRoleClaim<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserClaim<string>", b =>
{
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserLogin<string>", b =>
{
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserRole<string>", b =>
{
b.HasOne("Microsoft.AspNetCore.Identity.IdentityRole")
.WithMany()
.HasForeignKey("RoleId")
.OnDelete(DeleteBehavior.Cascade);
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
modelBuilder.Entity("Microsoft.AspNetCore.Identity.IdentityUserToken<string>", b =>
{
b.HasOne("EVABackend.Areas.Identity.Data.EVABackendUser")
.WithMany()
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade);
});
#pragma warning restore 612, 618
}
}
}

42
Backend/EVABackend/EVABackend/Models/Aufnahmeantrag.cs

@ -0,0 +1,42 @@
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace EVABackend.Models
{
public class Aufnahmeantrag
{
[Required]
public string Name { get; set; }
[Required]
public string Vonname { get; set; }
public bool IstErmaessigt { get; set; }
public DateTime Geburtsdatum { get; set; }
[Required]
public string Geburtsort { get; set; }
[Range(1, 100000)]
public int PLZ { get; set; }
[Required]
public string Ort { get; set; }
[Required]
public string StrasseHNR { get; set; }
[Required]
public string Bankname { get; set; }
[Required]
public string BLZ { get; set; }
[Required]
public string KontoNr { get; set; }
[Required]
public UnterrichtTyp Typ { get; set; }
[Required]
public List<int> Instrumente { get; set; }
[Required]
public string Laufzeit { get; set; }
[Required]
public string KursId { get; set; }
[Required]
public string Telefon { get; set; }
[Required]
public string EMail { get; set; }
}
}

13
Backend/EVABackend/EVABackend/Models/CreateRooms.cs

@ -0,0 +1,13 @@
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
namespace EVABackend.Models
{
public class CreateRooms
{
[Required]
public string Name { get; set; }
[Required]
public List<string> InstrumentIDs { get; set; }
}
}

227
Backend/EVABackend/EVABackend/Models/EVAContext.cs

@ -0,0 +1,227 @@
using System.Reflection.Emit;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
namespace EVABackend.Models
{
public class EVAContext : DbContext
{
public DbSet<Schueler> Schueler { get; set; }
public DbSet<Dozent> Donzenten { get; set; }
public DbSet<Kurs> Kurse { get; set; }
public DbSet<KursSchueler> KursSchueler { get; set; }
public DbSet<Unterricht> Unterrichte { get; set; }
public DbSet<Instrument> Instrumente { get; set; }
public DbSet<Raum> Raeume { get; set; }
public DbSet<Antrag> Antraege { get; set; }
public DbSet<UnterrichtTyp> UnterrichtTypen { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlite("Data Source=eva_ls.db");
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<KursSchueler>()
.HasKey(c => new { c.SchuelerId, c.KursId });
modelBuilder.Entity<RaumInstrument>()
.HasKey(c => new { c.InstrumentId, c.RaumId });
modelBuilder.Entity<KursInstrument>()
.HasKey(c => new { c.InstrumentId, c.KursId });
modelBuilder.Entity<DozentInstrument>()
.HasKey(c => new { c.InstrumentId, c.DozentId });
modelBuilder.Entity<AntragInstrument>()
.HasKey(c => new { c.InstrumentId, c.AntragId });
modelBuilder.Entity<KursSchueler>()
.HasOne(c => c.Schueler)
.WithMany(c => c.KursSchueler)
.HasForeignKey(c => c.SchuelerId);
modelBuilder.Entity<KursSchueler>()
.HasOne(c => c.Kurs)
.WithMany(c => c.KursSchueler)
.HasForeignKey(c => c.KursId);
modelBuilder.Entity<Kurs>()
.HasMany(c => c.Instrumente)
.WithOne(c => c.Kurs)
.HasForeignKey(c => c.KursId);
modelBuilder.Entity<Dozent>()
.HasMany(c => c.Instrumente)
.WithOne(c => c.Dozent)
.HasForeignKey(c => c.DozentId);
modelBuilder.Entity<Raum>()
.HasMany(c => c.Instrumente)
.WithOne(c => c.Raum)
.HasForeignKey(c => c.RaumId);
modelBuilder.Entity<Antrag>()
.HasMany(c => c.Instrumente)
.WithOne(c => c.Antrag)
.HasForeignKey(c => c.AntragId);
}
}
public abstract class Person
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
[Required]
public string Vorname { get; set; }
public DateTime Geburtsdatum { get; set; }
[Required]
public string Geburtsort { get; set; }
public int PLZ { get; set; }
[Required]
public string Ort { get; set; }
[Required]
public string Strasse { get; set; }
[Required]
public string Telefon { get; set; }
[Required]
public string EMail { get; set; }
[Required]
public string Bankname { get; set; }
[Required]
public string BLZ { get; set; }
[Required]
public string KontoNr { get; set; }
public virtual ICollection<KursSchueler> KursSchueler { get; set; }
}
public class Schueler : Person
{
public bool IstErmaessigt { get; set; }
}
public class Dozent : Person
{
public decimal Stundensatz { get; set; }
public virtual ICollection<DozentInstrument> Instrumente { get; set; }
}
public class Kurs
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public int Laufzeit { get; set; }
public int Kuendigungsfrist { get; set; }
public bool Bestaetigt { get; set; }
public UnterrichtTyp UnterrichtsTyp { get; set; }
public virtual ICollection<KursInstrument> Instrumente { get; set; }
public virtual ICollection<Unterricht> Unterrichte { get; set; }
public virtual ICollection<KursSchueler> KursSchueler { get; set; }
}
public class KursSchueler
{
public int SchuelerId { get; set; }
public int KursId { get; set; }
public virtual Schueler Schueler { get; set; }
public virtual Kurs Kurs { get; set; }
}
public class Unterricht
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public DateTime Startzeit { get; set; }
public string Notiz { get; set; }
public Raum Raum { get; set; }
}
public class Raum
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
public bool Belegt { get; set; }
public virtual ICollection<RaumInstrument> Instrumente { get; set; }
}
public class Antrag
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
public Schueler Schueler { get; set; }
public UnterrichtTyp UnterrichtTyp { get; set; }
public int KursId { get; set; }
public virtual ICollection<AntragInstrument> Instrumente { get; set; }
}
public class UnterrichtTyp
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
public class Instrument
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Required]
public string Name { get; set; }
}
public class KursInstrument
{
public int? InstrumentId { get; set; }
public Instrument Instrument { get; set; }
public int? KursId { get; set; }
public Kurs Kurs { get; set; }
}
public class RaumInstrument
{
public int? InstrumentId { get; set; }
public Instrument Instrument { get; set; }
public int? RaumId { get; set; }
public Raum Raum { get; set; }
}
public class DozentInstrument
{
public int? InstrumentId { get; set; }
public Instrument Instrument { get; set; }
public int? DozentId { get; set; }
public Dozent Dozent { get; set; }
}
public class AntragInstrument
{
public int? InstrumentId { get; set; }
public Instrument Instrument { get; set; }
public int? AntragId { get; set; }
public Antrag Antrag { get; set; }
}
//public enum InstrumentTyp
//{
// Klavier, Schlagzeug, Geige, Gitarre, Band
//}
}

24
Backend/EVABackend/EVABackend/Program.cs

@ -0,0 +1,24 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.Logging;
namespace EVABackend
{
public class Program
{
public static void Main(string[] args)
{
CreateWebHostBuilder(args).Build().Run();
}
public static IWebHostBuilder CreateWebHostBuilder(string[] args) =>
WebHost.CreateDefaultBuilder(args)
.UseStartup<Startup>();
}
}

38
Backend/EVABackend/EVABackend/Properties/launchSettings.json

@ -0,0 +1,38 @@
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
"iisExpress": {
"applicationUrl": "http://localhost:50570",
"sslPort": 44374
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
"launchBrowser": true,
"launchUrl": "login",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"EVABackend": {
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "login",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
},
"applicationUrl": "https://localhost:5001;http://localhost:5000"
},
"Docker": {
"commandName": "Docker",
"launchBrowser": true,
"launchUrl": "{Scheme}://{ServiceHost}:{ServicePort}/login",
"httpPort": 50571,
"useSSL": true,
"sslPort": 44375
}
}
}

26
Backend/EVABackend/EVABackend/ScaffoldingReadme.txt

@ -0,0 +1,26 @@
Support for ASP.NET Core Identity was added to your project
- The code for adding Identity to your project was generated under Areas/Identity.
Configuration of the Identity related services can be found in the Areas/Identity/IdentityHostingStartup.cs file.
If your app was previously configured to use Identity, then you should remove the call to the AddIdentity method from your ConfigureServices method.
The generated UI requires support for static files. To add static files to your app:
1. Call app.UseStaticFiles() from your Configure method
To use ASP.NET Core Identity you also need to enable authentication. To authentication to your app:
1. Call app.UseAuthentication() from your Configure method (after static files)
The generated UI requires MVC. To add MVC to your app:
1. Call services.AddMvc() from your ConfigureServices method
2. Call app.UseMvc() from your Configure method (after authentication)
The generated database code requires Entity Framework Core Migrations. Run the following commands:
1. dotnet ef migrations add CreateIdentitySchema
2. dotnet ef database update
Or from the Visual Studio Package Manager Console:
1. Add-Migration CreateIdentitySchema
2. Update-Database
Apps that use ASP.NET Core Identity should also use HTTPS. To enable HTTPS see https://go.microsoft.com/fwlink/?linkid=848054.

44
Backend/EVABackend/EVABackend/Startup.cs

@ -0,0 +1,44 @@
using EVABackend.Areas.Identity.Data;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
namespace EVABackend
{
public class Startup
{
public Startup(IConfiguration configuration)
{
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// This method gets called by the runtime. Use this method to add services to the container.
public void ConfigureServices(IServiceCollection services)
{
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
}
else
{
app.UseHsts();
}
app.UseStaticFiles();
app.UseAuthentication();
app.UseHttpsRedirection();
app.UseMvc();
}
}
}

9
Backend/EVABackend/EVABackend/appsettings.Development.json

@ -0,0 +1,9 @@
{
"Logging": {
"LogLevel": {
"Default": "Debug",
"System": "Information",
"Microsoft": "Information"
}
}
}

11
Backend/EVABackend/EVABackend/appsettings.json

@ -0,0 +1,11 @@
{
"Logging": {
"LogLevel": {
"Default": "Warning"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"EVABackendIdentityContextConnection": "DataSource=EVABackend.db"
}
}

BIN
Backend/EVABackend/EVABackend/eva_ls.db

Binary file not shown.

BIN
Backend/EVABackend/EVABackend/eva_users.db

Binary file not shown.

15
Docker/Dockerfile_FE_Builder.dockerfile

@ -0,0 +1,15 @@
# Tag: frontend-build
FROM node:10.8-stretch
RUN apt update
RUN apt install -y rsync
RUN mkdir -p /workdir
COPY Frontend/package.json /workdir/package.json
COPY Frontend/package-lock.json /workdir/package-lock.json
WORKDIR /workdir
RUN pwd && ls -la
run npm install

14
Docker/Dockerfile_FE_Host.dockerfile

@ -0,0 +1,14 @@
# Tag: frontend-serve
# FROM nginx
# COPY Docker/config/nginx.conf /etc/nginx/nginx.conf
FROM node:10.8-stretch
WORKDIR /opt/frontend
RUN pwd && ls -la
RUN npm install -g serve
CMD ["serve", "-s", "build"]

14
Docker/config/nginx.conf

@ -0,0 +1,14 @@
events {
worker_connections 1024;
}
http {
server {
listen 80;
root /usr/share/nginx/html;
location / {
autoindex on;
}
}
}

7
Docker/config/restart-host.sh

@ -0,0 +1,7 @@
#! /bin/bash
docker login -u gitlab+deploy-token-66068 -p vD23SzzitUn8y8xGknKz registry.gitlab.com
docker stop eva_frontend_serve
docker rm eva_frontend_serve
docker rmi registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-serve
docker run -d -p 8083:5000 -v /home/gitlab/serve:/opt/frontend/build:ro --name "eva_frontend_serve" registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-serve

23
Frontend/.gitignore vendored

@ -0,0 +1,23 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
# dependencies
/node_modules
/.pnp
.pnp.js
# testing
/coverage
# production
/build
# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local
npm-debug.log*
yarn-debug.log*
yarn-error.log*

0
Frontend/.gitkeep

7
Frontend/README.md

@ -0,0 +1,7 @@
# React App für die EVA_Lernsituatuin
# Pakages
- Material UI
- React Router
- Sentry

12
Frontend/dist/index.html vendored

@ -0,0 +1,12 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Temporäre Seite</title>
</head>
<body>
Hallo bitte geh weg.
</body>
</html>

13129
Frontend/package-lock.json generated

File diff suppressed because it is too large Load Diff

34
Frontend/package.json

@ -0,0 +1,34 @@
{
"name": "lernsituation",
"version": "0.1.0",
"private": true,
"dependencies": {
"@material-ui/core": "^4.0.2",
"@material-ui/icons": "^4.0.1",
"react": "^16.8.6",
"react-dom": "^16.8.6",
"react-router-dom": "^5.0.0",
"react-scripts": "3.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": {
"production": [
">0.2%",
"not dead",
"not op_mini all"
],
"development": [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version"
]
}
}

BIN
Frontend/public/favicon.ico

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.8 KiB

18
Frontend/public/index.html

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico" />
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width, shrink-to-fit=no"
/>
<meta name="theme-color" content="#000000" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<title>Lernsituation</title>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div>
</body>
</html>

15
Frontend/public/manifest.json

@ -0,0 +1,15 @@
{
"short_name": "Lernsituation",
"name": "EVA_Lernsituation",
"icons": [
{
"src": "favicon.ico",
"sizes": "64x64 32x32 24x24 16x16",
"type": "image/x-icon"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
}

38
Frontend/src/components/App.js

@ -0,0 +1,38 @@
import React, { Component } from "react";
import CssBaseline from "@material-ui/core/CssBaseline";
import { BrowserRouter as Router, Route } from "react-router-dom";
import Login from "./Login.js";
import { Box } from "@material-ui/core";
import Aufnahmeantrag from "./Aufnahmeantrag.js";
import {RoomOverview} from "./RoomOverview";
import { createMuiTheme, MuiThemeProvider } from "@material-ui/core";
const theme = createMuiTheme({
palette: {
primary: { main: "#2e294e" },
grey: { main: "#595959" },
danger: { main: "#d90368" },
secondary: { main: "#eadeda" },
text: { main: "#ffffff" }
}
});
class App extends Component {
state = {};
render() {
return (
<MuiThemeProvider theme={theme}>
<CssBaseline />
<Router>
<Box flexDirection="column" width="100%">
<Route path="/login" component={Login} />
<Route path="/aufnahmeantrag" component={Aufnahmeantrag} />
<Route path="/raumübersicht" component={RoomOverview} />
</Box>
</Router>
</MuiThemeProvider>
);
}
}
export default App;

376
Frontend/src/components/Aufnahmeantrag.js

@ -0,0 +1,376 @@
import React, { Component } from "react";
import {
FormControlLabel,
Checkbox,
TextField,
Typography,
Grid,
Fab,
Container,
FormControl,
InputLabel,
MenuItem,
Select,
OutlinedInput
} from "@material-ui/core";
import SendIcon from "@material-ui/icons/Send";
import { withStyles, createStyles } from "@material-ui/core/styles";
const useStyles = createStyles(theme => ({
textField: {
margingLeft: theme.spacing(1),
marginRight: theme.spacing(1)
},
fab: {
margin: theme.spacing(1)
},
form: {
backgroundColor: "rgba(255, 255, 255, 1)",
borderRadius: "5px",
margin: "20px",
padding: "20px",
boxShadow: "0px 0px 5px 0px lightgrey",
border: "1px solid lightgrey"
},
checkbox: {
display: "flex",
alignItems: "center",
height: "100%",
marginLeft: "7px"
},
instruments: {
border: "1px solid #bbb",
borderRadius: "5px",
display: "flex",
flexWrap: "wrap",
padding: "10px"
}
}));
class Aufnahmeantrag extends Component {
state = {
form: {
Name: "",
Vorname: "",
Geburtsdatum: "",
Geburtsort: "",
PLZ: "",
Ort: "",
Strasse: "",
Hausnummer: "",
Telefon: "",
EMail: "",
BLZ: "",
Bankname: "",
KontoNr: "",
Instrument: [],
Ermaessigt: null,
Laufzeit: "",
Typ: ""
},
instruments: [
{ name: "Gitarre", toggle: false },
{ name: "Schlagzeug", toggle: false },
{ name: "Flöte", toggle: false },
{ name: "Trompete", toggle: false },
{ name: "Banjo", toggle: false },
{ name: "Klavier", toggle: false },
{ name: "Orgel", toggle: false },
{ name: "Kazoo", toggle: false }
]
};
handleChange = name => event => {
this.setState({ form: { ...this.state.form, [name]: event.target.value } });
};
handleInstrument = instrument => {
var instruments = this.state.instruments;
var instrumentsArray = [];
instruments.forEach(obj => {
if (obj === instrument) obj.toggle = !obj.toggle;
if (obj.toggle === true) instrumentsArray.push(obj.name);
});
this.setState({
form: { ...this.state.form, Instrument: instrumentsArray }
});
this.setState({ instruments });
};
render() {
const classes = this.props.classes;
return (
<Container maxWidth="md">
<div className={classes.form}>
<Grid container direction="row" justify="center" alignItems="center">
<Grid container spacing={1}>
<Grid item xs={12}>
<Typography align="center" variant="h4">
Aufnahmeantrag
</Typography>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Name"
className={classes.textField}
value={this.state.form.Name}
onChange={this.handleChange("Name")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Vorname"
className={classes.textField}
value={this.state.form.Vorname}
onChange={this.handleChange("Vorname")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Geburtsdatum"
className={classes.textField}
value={this.state.form.Geburtsdatum}
onChange={this.handleChange("Geburtsdatum")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Geburtsort"
className={classes.textField}
value={this.state.form.Geburtsort}
onChange={this.handleChange("Geburtsort")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="PLZ"
className={classes.textField}
value={this.state.form.PLZ}
onChange={this.handleChange("PLZ")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Ort"
className={classes.textField}
value={this.state.form.Ort}
onChange={this.handleChange("Ort")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Strasse"
className={classes.textField}
value={this.state.form.Strasse}
onChange={this.handleChange("Strasse")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Hausnummer"
className={classes.textField}
value={this.state.form.Hausnummer}
onChange={this.handleChange("Hausnummer")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Telefon"
className={classes.textField}
value={this.state.form.Telefon}
onChange={this.handleChange("Telefon")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="EMail"
className={classes.textField}
value={this.state.form.EMail}
onChange={this.handleChange("EMail")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={12} xs={12}>
<Typography align="left" variant="h6">
Instrumente
</Typography>
<div className={classes.instruments}>
{this.state.instruments.map(instrument => (
<FormControlLabel
key={instrument.name}
control={
<Checkbox
checked={instrument.toggle}
onChange={() => this.handleInstrument(instrument)}
value={instrument.name}
color="primary"
/>
}
label={instrument.name}
/>
))}
</div>
</Grid>
<Grid item sm={6} xs={12}>
<FormControl
margin="normal"
fullWidth={true}
variant="outlined"
className={classes.textField}
>
<InputLabel htmlFor="outlined-laufzeit-simple">
Laufzeit
</InputLabel>
<Select
value={this.state.form.Laufzeit}
onChange={this.handleChange("Laufzeit")}
input={
<OutlinedInput
labelWidth={60}
name="laufzeit"
id="outlined-laufzeit-simple"
/>
}
>
<MenuItem value={6}>6 Monate</MenuItem>
<MenuItem value={12}>12 Monate</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item sm={6} xs={12}>
<FormControl
margin="normal"
fullWidth={true}
variant="outlined"
className={classes.textField}
>
<InputLabel htmlFor="outlined-laufzeit-simple">
Unterichtstyp
</InputLabel>
<Select
value={this.state.form.Typ}
onChange={this.handleChange("Typ")}
input={
<OutlinedInput
labelWidth={95}
name="laufzeit"
id="outlined-laufzeit-simple"
/>
}
>
<MenuItem value={"einzel"}>Einzelunterricht</MenuItem>
<MenuItem value={"band"}>Gruppenunterricht / Band</MenuItem>
</Select>
</FormControl>
</Grid>
<Grid item sm={12} xs={12}>
<div className={classes.checkbox}>
<FormControlLabel
control={
<Checkbox
checked={this.state.form.Ermaessigt}
onChange={() => this.handleChange("Ermaessigt")}
value="Ermaessigt"
color="primary"
/>
}
label="Schüler/Student/Azubi"
/>
</div>
</Grid>
</Grid>
<Grid container spacing={1}>
<Grid item xs={12}>
<Typography align="center" variant="h4">
Bankverbindung
</Typography>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="BLZ"
className={classes.textField}
value={this.state.form.BLZ}
onChange={this.handleChange("BLZ")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item sm={6} xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Bankname"
className={classes.textField}
value={this.state.form.Bankname}
onChange={this.handleChange("Bankname")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="KontoNr"
className={classes.textField}
value={this.state.form.KontoNr}
onChange={this.handleChange("KontoNr")}
margin="normal"
variant="outlined"
/>
</Grid>
</Grid>
<Fab color="primary" aria-label="Send" className={classes.fab}>
<SendIcon />
</Fab>
</Grid>
</div>
</Container>
);
}
}
export default withStyles(useStyles)(Aufnahmeantrag);

80
Frontend/src/components/Login.js

@ -0,0 +1,80 @@
import React, { Component } from "react";
import { TextField, Typography, Grid, Fab, Container } from "@material-ui/core";
import SendIcon from "@material-ui/icons/Send";
import { withStyles, createStyles } from "@material-ui/styles";
const useStyles = createStyles(theme => ({
textField: {
margingLeft: theme.spacing(1),
marginRight: theme.spacing(1)
},
fab: {
margin: theme.spacing(1)
},
form: {
backgroundColor: "#f5f5f5",
borderRadius: "5px",
margin: "20px",
padding: "20px",
boxShadow: "0px 0px 5px 0px lightgrey",
border: "1px solid lightgrey"
}
}));
class Login extends Component {
state = { username: "", password: "" };
handleChange = name => event => {
this.setState({ [name]: event.target.value });
};
render() {
const classes = this.props.classes;
return (
<Container maxWidth="md">
<div className={classes.form}>
<Grid container direction="row" justify="center" alignItems="center">
<Grid container spacing={1}>
<Grid item xs={12}>
<Typography align="center" variant="h4">
Login
</Typography>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Username"
className={classes.textField}
value={this.state.username}
onChange={this.handleChange("username")}
margin="normal"
variant="outlined"
/>
</Grid>
<Grid item xs={12}>
<TextField
fullWidth={true}
id="outlined-name"
label="Password"
className={classes.textField}
value={this.state.password}
onChange={this.handleChange("password")}
margin="normal"
variant="outlined"
type="password"
/>
</Grid>
</Grid>
<Fab color="primary" aria-label="Send" className={classes.fab}>
<SendIcon />
</Fab>
</Grid>
</div>
</Container>
);
}
}
export default withStyles(useStyles)(Login);

89
Frontend/src/components/RoomOverview.js

@ -0,0 +1,89 @@
import React, { Component } from "react";
import { Container, Table, TableBody, TableCell, TableHead, TableRow, Button, Typography } from "@material-ui/core";
import { Link } from "react-router-dom";
export class RoomOverview extends Component {
state = {
rooms: [
{
name: "DemoRoom",
id: "21433242",
instrumente: [
{id: "1", name: "Saxophone"}
]
},
{
name: "DemoRoom",
id: "214332342",
instrumente: [
{id: "1", name: "Saxophone"},
{id: "1", name: "Saxophone"},
{id: "1", name: "Klavir"}
]
},
{
name: "DemoRoom",
id: "000",
instrumente: [
{id: "1", name: "Saxophone"}
]
},
{
name: "DemoRoom",
id: "898989",
instrumente: [
{id: "1", name: "Saxophone"}
]
},
{
name: "DemoRoom",
id: "214899933242",
instrumente: [
{id: "1", name: "Saxophone"}
]
}
]
};
editItem(id) {
return () => {
}
}
render() {
return (
<Container maxWidth="md">
<Typography align="center" variant="h4">
Raumübersicht
</Typography>
<Table>
<TableHead>
<TableRow>
<TableCell>Raum Name</TableCell>
<TableCell>Instrumente</TableCell>
<TableCell></TableCell>
</TableRow>
</TableHead>
<TableBody>
{this.state.rooms.map(room => (
<TableRow key={room.id}>
<TableCell>{room.name}</TableCell>
<TableCell>{room.instrumente.reduce((accu, curr) => `${accu} ${curr.name}`, ``)}</TableCell>
<TableCell>
<Button
color="primary"
component={Link}
to={`/raum-bearbeiten#${room.id}`}
linkButton={true}
>
Bearbeiten
</Button>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
</Container>
);
}
};

6
Frontend/src/index.js

@ -0,0 +1,6 @@
import React from "react";
import ReactDOM from "react-dom";
import "./style/index.css";
import App from "./components/App";
ReactDOM.render(<App />, document.getElementById("root"));

19
Frontend/src/style/index.css

@ -0,0 +1,19 @@
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Roboto", "Oxygen",
"Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue",
sans-serif;
background-color: rgba(234, 222, 218, 1) !important;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
code {
font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New",
monospace;
}
html {
background-color: rgba(234, 222, 218, 1);
}

250
Pflichtenheft.diff

@ -0,0 +1,250 @@
diff --git a/_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md b/_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md
index 81225fe..4cebbf2 100644
--- a/_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md
+++ b/_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md
@@ -1,41 +1,61 @@
# Pflichtenheft
## Inhalt
-1. Zielbestimmung
- 1. Musskriterien
- 1. Abgrenzungskriterien
-1. Produkteinsatz
- 1. Anwendungsbereiche
- 1. Zielgruppen
- 1. Betriebsbedingungen
-1. Produktumgebung
- 1. Software
- 1. Hardware
-1. Produktfunktionen
- 1. Dozentenfunktionen
- 1. Wochenübersicht
- 2. Kursdetails
- 2. Verwaltungsfunktionen
- 1. Offene Anträge
- 2. Kurse erstellen
- 1. Kursübersicht
- 2. Schülerübersicht
- 3. Schüler eines Dozenten
- 4. Raumübersicht m. Raumplan
- 5. Raumdetails
- 6. Offene Anträge
- 7. Finanzübersichrt
- 1. Sonstige Funktionen
- 1. Login
- 2. Mitglied zu Kurs hinzufügen
- 1. Benutzeroberfläche
- 1. Dialogstruktur
- 2. Bildschirmlayout
-
-
-## Zielbestimmung
-
-> Das Ziel von Parsec Iron Puffin (*PIP*) ist es, eine Anwendung zu bieten welche die Organisation der Musikschule erlaubt. Hierzu werden für Dozenten und Verwaltung verschiedene administrative Funktionen bereitgestellt. Die aktuellen Betriebsprozesse sollen vereinfacht und beschleunigt werden.
+- [Pflichtenheft](#pflichtenheft)
+ - [Inhalt](#inhalt)
+ - [Zielbestimmungsss](#zielbestimmungsss)
+ - [Musskriterien](#musskriterien)
+ - [Wunschkriterien](#wunschkriterien)
+ - [Abgrenzungungskriterien](#abgrenzungungskriterien)
+ - [Produktübersicht](#produkt%C3%BCbersicht)
+ - [Produktdaten](#produktdaten)
+ - [Speichernutzung](#speichernutzung)
+ - [Produktleistungen](#produktleistungen)
+ - [Benutzeroberfläche **/L01/**](#benutzeroberfl%C3%A4che-l01)
+ - [Datenschutz **/L02/**](#datenschutz-l02)
+ - [Loggin und Nachvollziehbarkeit **/L03/**](#loggin-und-nachvollziehbarkeit-l03)
+ - [Produkteinsatz](#produkteinsatz)
+ - [Anwendungsbereiche](#anwendungsbereiche)
+ - [Zielgruppe](#zielgruppe)
+ - [Betriebsbedingungen](#betriebsbedingungen)
+ - [Produktumgebung](#produktumgebung)
+ - [Software](#software)
+ - [Hardware](#hardware)
+ - [Produktfunktionen](#produktfunktionen)
+ - [Annahmen und Definitionen zu Produktfunktionen](#annahmen-und-definitionen-zu-produktfunktionen)
+ - [Dozentenfunktionen](#dozentenfunktionen)
+ - [Wochenübersicht **/FD01/**](#wochen%C3%BCbersicht-fd01)
+ - [Kursdetails **/FD02/**](#kursdetails-fd02)
+ - [Verwaltungsfunktionen](#verwaltungsfunktionen)
+ - [Offene Anträge **/FV01/**](#offene-antr%C3%A4ge-fv01)
+ - [Kurs Erstellen **/FV02/**](#kurs-erstellen-fv02)
+ - [Kursübersicht **/FV03/**](#kurs%C3%BCbersicht-fv03)
+ - [Schülerübersicht **/FV04/**](#sch%C3%BCler%C3%BCbersicht-fv04)
+ - [Schüler eines Dozenten **/FV05/**](#sch%C3%BCler-eines-dozenten-fv05)
+ - [Raumübersicht **/FV06/**](#raum%C3%BCbersicht-fv06)
+ - [Raumdetails **/FV07/**](#raumdetails-fv07)
+ - [Finanzübersicht **/FV09/**](#finanz%C3%BCbersicht-fv09)
+ - [Sonstige Funktionen](#sonstige-funktionen)
+ - [Login **/F01/**](#login-f01)
+ - [Mitglied zu Kurs hinzufügen **/F02/**](#mitglied-zu-kurs-hinzuf%C3%BCgen-f02)
+ - [Antrag Stellen **/F03/**](#antrag-stellen-f03)
+ - [Benutzeroberfläche](#benutzeroberfl%C3%A4che)
+ - [Dialogstruktur](#dialogstruktur)
+ - [Startseite](#startseite)
+ - [Übersichtsseite Dozenten](#%C3%BCbersichtsseite-dozenten)
+ - [Übersichtsseite Verwaltung](#%C3%BCbersichtsseite-verwaltung)
+ - [Bildschirmlayout](#bildschirmlayout)
+ - [Testfälle](#testf%C3%A4lle)
+
+## Zielbestimmungsss
+
+> Das Ziel von Parsec Iron Puffin (*PIP*) ist es, eine Anwendung zu bieten welche die Organisation der Musikschule erlaubt. Hierzu werden für Dozenten und Verwaltung verschiedene administrative Funktionen bereitgestellt. Die aktuellen Betriebsprozesse sollen vereinfacht und beschleunigt werden.
+
+Die Anwendung bietet der Verwaltung Übersichten über die Schüler, Dozenten, Kurse und Finanzen. Es können Schüler der Kurse und Dozenten der Schüler angezeigt werden.
+
+Der Dozent erhält eine Übersicht über die Stunden, welche er in der Woch zu unterrichten hat. Außerdem kann er eine Detailansicht eines Kurses aufrufen, welche ihm Informationen über die Schüler in diesem Kurs und die Unterrichtsinhalte der vergangenen Stunden bietet.
+
+Nutzer können mithilfe der Anwendung Kurse beantragen und "Band"-Kursen beitreten.
### Musskriterien
* Es besteht ein Authentifizierung um den Zugriff auf alle Funktionen auf die jeweils berechtigten Personen zu beschränken.
@@ -56,12 +76,6 @@
* Der Administrative Nutzer
* Konfiguriert die Betriebsparameter des Systems
* Sichert die Datenbank
- * Ein Kurs hat
- * einen Dozenten
- * einen Typ (Einzel-, Bandunterricht, Früherziehung)
- * einen Raum
- * ein oder zwei Zeitpunkte
- * und eine Laufzeit
* Der Schüler
* kann einen Aufnahmeantrag über ein Webformular abschicken
* erhält, nachdem die Verwaltung einen Kurs aus dem Antrag erstellt hat, eine Bestätigung (Kursbestätigung) mit den Zeiten Seiner Unterrichtseinheiten
@@ -83,6 +97,33 @@
* Das *PIP*
* soll keine Abrechnung erstellen oder verschicken.
+## Produktübersicht
+ * Das System wird von den Rollen Verwaltung, Dozent und Anonym bedient.
+ * Die Rollen Verwaltung und Dozent werden über einen Login authentizifiert, ihnen stehen abhängig von ihrer Rolle verschiedene Funktionen zur verfügung, diese werden unter [Produktfunktionen](#produktfunktionen) spezifiziert. Sonstige Funktionen stehen _allen_ Rollen zur verfügung.
+
+## Produktdaten
+ * Datenstrukturen der Anwendung:
+ ![ERD](EVA&#32;ERD&#32;Umletino.png)
+ * Aus einem Antrag wird ein _Schüler_, eine von _Person_ erbende Klasse, erstellt, welche alle personenbezogene Daten erhält. (siehe Diagramm)
+ * Außerdem werden Angaben zu der Auswahl des Antragstellers zu _Instrument_ und _Unterrichtstyp_ gespeichert.
+ * Einem _Kurs_ wird stehts ein _Schüler_ zugewiesen, es sei denn es handelt sich um einen Kurs mit Typ "Band". In diesem Fall können beliebig viele _Schüler_ zugewiesen werden.
+ * Ein _Kurs_ hat _Unterrichtseinheiten_. Diese Stellen einzelne eindeutige Zeitpunkte dar, an welchen der _Kurs_ unterrichtet wird/wurde.
+ * Es wird der Startzeitpunkt gespeichert, "Wed Jun 12 2019 12:15:00 GMT+0200 (Central European Summer Time)" stellt die _Unterrichtseinheit_ von 12:15 bis 12:30 dar.
+ * Für jede Unterrichtseinheit kann der Dozent den Inhalt pflegen, um die Unterrichtsinhalte zu Dokumentieren.
+
+### Speichernutzung
+ * Ein Personendatensatz kann bis zu 5KB groß sein, typisch ~300 Byte.
+ * Ein Kursdatensatzen kann bis zu 55 Byte groß sein.
+ * Ein Unterrichtseinheitendatensatz kann bis zu 2056 Byte groß sein.
+
+## Produktleistungen
+### Benutzeroberfläche **/L01/**
+ * Die Anwendung bietet eine deutschsprachige Benutzeroberfläche
+### Datenschutz **/L02/**
+ * Daten werden in einer passwordgeschützten Datenbank abgelegt
+### Loggin und Nachvollziehbarkeit **/L03/**
+ * Zugriffe wie das Schreiben von Daten (anlegen und modifizieren von Datensätzen) werden in einem Log dokumentiert und können so nachvollzogen werden.
+
## Produkteinsatz
### Anwendungsbereiche
@@ -100,7 +141,7 @@ Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen D
## Produktumgebung
### Software
* Client
- * Chrome oder Chromium basierter Browser der Version 74
+ * Chrome oder Chromium basierter Browser der Version 74, Firefox 67
* Server
* Docker unter Linux (Version 18.09.5)
@@ -113,7 +154,16 @@ Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen D
## Produktfunktionen
-### **Dozentenfunktionen**
+#### Annahmen und Definitionen zu Produktfunktionen
+> Getroffene Annahmen und Definitionen zu unterliegenen Produktfunktionen und Geschäftsprozessen, mit denen die Nutzer nicht direkt in Kontakt kommen und daher nicht einer speziellen Funktion zugeordnet werden können.
+
+ * Aus einem eingegangenen Antrag wird wird von der Verwaltung mithilfe der gebotenen Funktion ein Kurs erstellt. Hierfür wählt diese einene passenden Dozenten, Raum, und Zeitpunkt(e) aus. Diese werden dem Antragsteller auf geeignetem Weg, zusammen mit einem ausgefertigtem Vertrag zustellt. Der Antragsteller hat bis zum ersten Unterrichtszeitpunkt Zeit, um diesen Vertrag unterschrieben vorzulegen, ansonsten verfällt der Kurs und Dozent und Raum werden zu dem Zeitpunkt(en) freigegeben.
+ * Im Falle eines "Band"-Kurses wird dem Antragsteller zusammen mit dem Vertrag ein Einzigartiger Link zugestellt. Über diesen Link können sich weiter Mitglieder durch angeben ihrer personenbezogenen Daten zu diesem bereits erstellten Kurs anmelden. Die Anmeldung ist bis zum ersten Unterrichtszeitpunkt möglich.
+ * Die Laufzeit des Vertrags startet zum ersten Unterrichtstermin.
+ * Unterrichtszeiten werden in 15min (1/4 Stunden) blöcken gegeben und geplant.
+
+
+### Dozentenfunktionen
#### Wochenübersicht **/FD01/**
* Der Nutzer sieht eine Übersicht mit von Ihm gegebenen Kursen in den kommenden 7 Tagen, gruppiert nach Wochentag
* Mit einem Klick auf einen Kurs gelangt man zu den entsprechenden Kursdetails
@@ -123,11 +173,11 @@ Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen D
* Er sieht alle Schüler, welche an dem Kurs teilnehmen
* Er sieht die Einträge zu den den Unterrichtsinhalten der vergangen Unterrichtseinheiten und kann den Inhalt des letzten Termins bearbeiten / erfassen.
-### **Verwaltungsfunktionen
+### Verwaltungsfunktionen
#### Offene Anträge **/FV01/**
* Es werden alle neu eingegangenen und nicht bestägtigten Anträge angzeigt.
-* Mit einem Klick auf einen eingegangen Antrag wird die [Kurs erstellen](#kurs-erstellen) Seite aufgerufen.
+* Mit einem Klick auf einen eingegangen Antrag wird die [Kurs erstellen](#kurs-erstellen-fv02) Seite aufgerufen.
#### Kurs Erstellen **/FV02/**
* Nach einem eingegegangen Antrag kann basierent auf diesem ein Kurs erstellt werden.
@@ -140,7 +190,7 @@ Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen D
#### Kursübersicht **/FV03/**
* In der Kursübersicht werden in Tabellenform alle Kurse zusammen mit ihren Dozenten angezeigt.
* Die Tabelle kann spaltenweise sortiert und nach Dozenten- und Kursname gefiltert werden.
-* Ein Klick auf einen Kurs führt zu [Kursdetails](#kursdetails-f02).
+* Ein Klick auf einen Kurs führt zu [Kursdetails](#kursdetails-fd02).
* Ein Klick auf einen Dozenten führt zu [Schüler eines Dozenten](#sch%C3%BCler-eines-dozenten-fv05)
#### Schülerübersicht **/FV04/**
@@ -168,7 +218,7 @@ Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen D
* Es werden die gesamten monatlichen Einnahmen der Musikschule angzeigt.
* Es werden die Zahlungen an die Dozenten, aufgeschlüsselt nacht Dozent angezeigt.
-### **Sonstige Funktionen**
+### Sonstige Funktionen
#### Login **/F01/**
* Der Nutzer kann sich mit Benutzername und Passwort anmelden.
@@ -180,6 +230,26 @@ Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen D
* Dafür müssen diese nur Ihre Personenbezogenen Daten angeben, Sie werden in der über den Link identifizierten Kurs eingeschrieben.
* Dies muss vor dem ersten Unterrichtstermin geschehen.
+#### Antrag Stellen **/F03/**
+* Der Nutzer gibt personenbezogene- und kursbezogenen Daten an, aus diesen wird beim Absenden ein Antrag in der Datenbank erstellt, welche von der Verwaltung mithilfe der Funktion [Offene Anträge](#offene-antr%C3%A4ge-fv01) eingesehen und weiter verarbeitet werden können.
+* Personenbezogene Daten:
+ * Vorname
+ * Nachname
+ * Geb. Datum
+ * Geb. Ort
+ * PLZ
+ * Ort
+ * Straße
+ * Hausnummer
+ * Telefon
+ * EMail
+ * BLZ
+ * Bankname
+ * Kontonummer
+* Kursbezogene Daten:
+ * Instrumente
+ * Laufzeit
+ * Unterrichtstyp
## Benutzeroberfläche
@@ -210,4 +280,12 @@ Die Übersichtsseite Verwaltung ist die Startseite der Verwaltung, die die Verwa
Das Frontend wird mithilfe der JavaScript Bibliothek React erstellt, das Design wird mithilfe der MIT-lizensierten Designbibliothek Material-UI realisiert. Die Anwendung ist für Mobilegeräte optimiert und wird nach den Prinzipien des Responsiven Desings entwickelt.
-> Ausnahme sind die Administrationsfunktionen
\ No newline at end of file
+> Ausnahme sind die Administrationsfunktionen
+
+## Testfälle
+
+1. Der Login funktioniert und erlaubt nur Zugriff auf authorisierte Bereiche / Ansichten.
+2. Anonyme Nutzer können Anträge stellen, diese gehen in der Datenbank ein.
+3. Die Verwaltung kann Anträge verarbeiten und daraus Kurse erstellen.
+ * Der Antragsteller wird über die Verarbeitung informiert.
+4. Die Übersichtsseiten zeigen korrekte Informationen an.
\ No newline at end of file

34
README.md

@ -1,14 +1,42 @@
# EVA Lernsituation
_Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
## Teilnehmer
* Levin Faber
* Alexej Komnik
* Tobias Schifffarth
* Tobias Schiffarth
* Kai Senkowski
## Organisation
* ALLE Dokumente werden im [Gitlab](https://gitlab.com/fia72-dev/eva_lernsituation) abgelegt
* Alle Dokumente werden im [Gitlab](https://gitlab.com/fia72-dev/eva_lernsituation) abgelegt
* Kommunikation erfolgt über [Slack](https://dullidivision.slack.com)
* Es wird nach dem Wasserfallmodell entwickelt
## Kommunikationsplan
* Alle Dokumente werden im [Gitlab](https://gitlab.com/fia72-dev/eva_lernsituation) abgelegt
* Kommunikation erfolgt über [Slack](https://dullidivision.slack.com) oder mündlich in Meetings (es werden Protokolle erstellt)
* Das Arbeiten erfolgt in der Schule und bei Bedarf nach Absprache Remote
* Es wird pro Arbeitstag ein Meeting gehalten, in welchem der aktuelle Status besprochen wird ("Jour fixe")
* Alle offiziellen Kommuniktionen werden von einem am Anfang des Meetings bestimmten Mitarbeiter dokumentiert _(Ordner /Dokumente/Protokolle. Hier liegt eine Vorlage)_
* Die Einhaltung der Kommunikationsrichtlinien wird vom Teamleiter überwacht
## Konzepte
### Infrastruktur
* Alles wird in Dockercontainern deployed
* Server können von Tobi und Levin bereitgestellt werden
* Auf beiden ist eine Docker Installation vorhanden
* Das gebaute FE wird von einem NGINX geserved (registry.gitlab.com/fia72-dev/eva_lernsituation/frontend-serve)
* // Todo backend @Tobi
### Deployment
* Deployed wird über GitLab Pipelines

0
Dokumente_LS_Musikschule/LS _MS_Ausgangslage.docx → _Dokumente/Ausgangsmaterial/LS _MS_Ausgangslage.docx

0
Dokumente_LS_Musikschule/LS_MS_Aktivitaeten_und_Dokumente.pdf → _Dokumente/Ausgangsmaterial/LS_MS_Aktivitaeten_und_Dokumente.pdf

0
Dokumente_LS_Musikschule/LS_MS_Ausgangslage.pdf → _Dokumente/Ausgangsmaterial/LS_MS_Ausgangslage.pdf

0
Dokumente_LS_Musikschule/LS_MS_Beispiel_Lastenheft.pdf → _Dokumente/Ausgangsmaterial/LS_MS_Beispiel_Lastenheft.pdf

0
Dokumente_LS_Musikschule/LS_MS_Laufzettel_v2.pdf → _Dokumente/Ausgangsmaterial/LS_MS_Laufzettel_v2.pdf

0
Dokumente_LS_Musikschule/LS_MS_Material_Kundengespräch_01.docx → _Dokumente/Ausgangsmaterial/LS_MS_Material_Kundengespräch_01.docx

0
Dokumente_LS_Musikschule/LS_MS_Material_Kundengespräch_01.pdf → _Dokumente/Ausgangsmaterial/LS_MS_Material_Kundengespräch_01.pdf

0
Dokumente_LS_Musikschule/LS_MS_PaperPrototyping.pdf → _Dokumente/Ausgangsmaterial/LS_MS_PaperPrototyping.pdf

0
Dokumente_LS_Musikschule/LS_MS_Pflichtenheft.pdf → _Dokumente/Ausgangsmaterial/LS_MS_Pflichtenheft.pdf

0
Dokumente_LS_Musikschule/LS_MS__Beispiel_Pflichtenheft.pdf → _Dokumente/Ausgangsmaterial/LS_MS__Beispiel_Pflichtenheft.pdf

0
Dokumente_LS_Musikschule/P01_Lernsituation_MS_1.0_FIA7x.ppt → _Dokumente/Ausgangsmaterial/P01_Lernsituation_MS_1.0_FIA7x.ppt

0
Dokumente_LS_Musikschule/Pflichtenheftvorlage.doc → _Dokumente/Ausgangsmaterial/Pflichtenheftvorlage.doc

0
Dokumente_LS_Musikschule/Pflichtenheftvorlage.pdf → _Dokumente/Ausgangsmaterial/Pflichtenheftvorlage.pdf

0
Dokumente_LS_Musikschule/Projektmanagement Kompendium.pdf → _Dokumente/Ausgangsmaterial/Projektmanagement Kompendium.pdf

BIN
_Dokumente/Ausgearbeitete Dokumente/EVA ERD Umletino.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 50 KiB

57
_Dokumente/Ausgearbeitete Dokumente/EVA ERD Umletino.uxf

@ -0,0 +1,57 @@
<diagram program="umletino" version="14.3.0"><zoom_level>10</zoom_level><help_text></help_text><element><id>UMLClass</id><coordinates><x>125</x><y>60</y><w>240</w><h>180</h></coordinates><panel_attributes>Person
&lt;&lt;abstract&gt;&gt;
--
_Id_
Name, Vorname
Geburtsdatum, Geburtsort
PLZ, Ort, Strasse
Telefon, EMail
Bankname
BLZ
KontoNr</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>125</x><y>290</y><w>100</w><h>50</h></coordinates><panel_attributes>Schueler
-
IstErmaessigt</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>265</x><y>290</y><w>100</w><h>50</h></coordinates><panel_attributes>Dozent
--
Stundensatz</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>304</x><y>230</y><w>30</w><h>80</h></coordinates><panel_attributes>lt=&lt;&lt;-</panel_attributes><additional_attributes>10;10;10;60</additional_attributes></element><element><id>Relation</id><coordinates><x>164</x><y>230</y><w>30</w><h>80</h></coordinates><panel_attributes>lt=&lt;&lt;-</panel_attributes><additional_attributes>10;10;10;60</additional_attributes></element><element><id>UMLClass</id><coordinates><x>184</x><y>451</y><w>120</w><h>100</h></coordinates><panel_attributes>Kurs
--
_Id_
Name
Laufzeit
Kuendigungsfrist
Bestaetigt</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>634</x><y>361</y><w>100</w><h>80</h></coordinates><panel_attributes>Raum
--
_Nr_
Name
Belegt</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLClass</id><coordinates><x>464</x><y>451</y><w>100</w><h>90</h></coordinates><panel_attributes>Unterricht
--
_Id_
Name
Anfangszeit
Notiz
</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>254</x><y>331</y><w>80</w><h>140</h></coordinates><panel_attributes>m1=1
m2=0..n</panel_attributes><additional_attributes>60;10;10;120</additional_attributes></element><element><id>Relation</id><coordinates><x>164</x><y>331</y><w>90</w><h>140</h></coordinates><panel_attributes>m1=0..n
m2=1..n</panel_attributes><additional_attributes>10;10;60;120</additional_attributes></element><element><id>Relation</id><coordinates><x>294</x><y>491</y><w>190</w><h>40</h></coordinates><panel_attributes>m1=1..n
m2=1</panel_attributes><additional_attributes>170;10;10;10</additional_attributes></element><element><id>Relation</id><coordinates><x>554</x><y>431</y><w>160</w><h>100</h></coordinates><panel_attributes>m1=1
m2=1..n</panel_attributes><additional_attributes>130;10;130;70;10;70</additional_attributes></element><element><id>UMLClass</id><coordinates><x>154</x><y>630</y><w>180</w><h>90</h></coordinates><panel_attributes>UnterrichtTyp
&lt;&lt;enum&gt;&gt;
--
Einzel
Gruppe
Musikalische Früherziehung</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>234</x><y>541</y><w>110</w><h>110</h></coordinates><panel_attributes>*UnterrichtTyp*
m1=1</panel_attributes><additional_attributes>10;90;10;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>464</x><y>271</y><w>100</w><h>120</h></coordinates><panel_attributes>Instrument
&lt;&lt;enum&gt;&gt;
--
Klavier
Schlagzeug
Geige
Gitarre
Band</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>554</x><y>321</y><w>160</w><h>60</h></coordinates><panel_attributes>m1=1..n
m2=1</panel_attributes><additional_attributes>10;10;130;10;130;40</additional_attributes></element><element><id>Relation</id><coordinates><x>354</x><y>311</y><w>130</w><h>40</h></coordinates><panel_attributes>m1=1..n
m2=0..n</panel_attributes><additional_attributes>110;10;10;10</additional_attributes></element><element><id>UMLClass</id><coordinates><x>840</x><y>60</y><w>110</w><h>110</h></coordinates><panel_attributes>Antrag
-
Laufzeit
KursId</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>54</x><y>21</y><w>870</w><h>330</h></coordinates><panel_attributes>m1=1
m2=1</panel_attributes><additional_attributes>70;300;10;300;10;10;840;10;840;40</additional_attributes></element><element><id>Relation</id><coordinates><x>324</x><y>161</y><w>590</w><h>550</h></coordinates><panel_attributes>*UnterrichtTyp*
m1=1</panel_attributes><additional_attributes>10;520;570;520;570;10</additional_attributes></element><element><id>Relation</id><coordinates><x>504</x><y>131</y><w>360</w><h>160</h></coordinates><panel_attributes>*Instrumente*
m1=1..n</panel_attributes><additional_attributes>10;140;10;20;340;19</additional_attributes></element><element><id>Relation</id><coordinates><x>294</x><y>351</y><w>190</w><h>150</h></coordinates><panel_attributes>*Instrumente*
m1=1..n</panel_attributes><additional_attributes>170;10;10;130</additional_attributes></element></diagram>

BIN
_Dokumente/Ausgearbeitete Dokumente/EVA Use Case Umletino.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

24
_Dokumente/Ausgearbeitete Dokumente/EVA Use Case Umletino.uxf

@ -0,0 +1,24 @@
<diagram program="umletino" version="14.3.0"><zoom_level>10</zoom_level><element><id>UMLActor</id><coordinates><x>10</x><y>145</y><w>80</w><h>110</h></coordinates><panel_attributes>Verwaltung</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLActor</id><coordinates><x>10</x><y>535</y><w>80</w><h>110</h></coordinates><panel_attributes>Teilnehmer</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLGeneric</id><coordinates><x>130</x><y>5</y><w>990</w><h>660</h></coordinates><panel_attributes>Online-Auftritt der Musikschule
--
halign=center</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>160</x><y>45</y><w>120</w><h>40</h></coordinates><panel_attributes>Dozenten anlegen</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>180</x><y>555</y><w>170</w><h>40</h></coordinates><panel_attributes>Aufnahmeantrag stellen</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLActor</id><coordinates><x>20</x><y>405</y><w>60</w><h>110</h></coordinates><panel_attributes>Dozent</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>170</x><y>385</y><w>170</w><h>50</h></coordinates><panel_attributes>Stundenplan pro Woche</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>940</x><y>45</y><w>120</w><h>40</h></coordinates><panel_attributes>Raumplanung</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>700</x><y>125</y><w>120</w><h>50</h></coordinates><panel_attributes>Kurse anlegen</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>370</x><y>445</y><w>200</w><h>50</h></coordinates><panel_attributes>Eintragung der Unterrichtsinhalte</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLActor</id><coordinates><x>0</x><y>695</y><w>100</w><h>110</h></coordinates><panel_attributes>Administrator</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLGeneric</id><coordinates><x>130</x><y>665</y><w>990</w><h>150</h></coordinates><panel_attributes>Backend-Administration
--
halign=center</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>950</x><y>185</y><w>120</w><h>40</h></coordinates><panel_attributes>Unterrichtsplanung</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>260</x><y>705</y><w>260</w><h>40</h></coordinates><panel_attributes>Zugriff und Verwaltung der Datenbank</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>270</x><y>765</y><w>230</w><h>40</h></coordinates><panel_attributes>Zugriff und Verwaltung des Hostings</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>810</x><y>55</y><w>150</w><h>100</h></coordinates><panel_attributes>lt=.&gt;
&lt;&lt;includes&gt;&gt;</panel_attributes><additional_attributes>10;80;130;10</additional_attributes></element><element><id>Relation</id><coordinates><x>810</x><y>145</y><w>160</w><h>80</h></coordinates><panel_attributes>lt=.&gt;
&lt;&lt;includes&gt;&gt;</panel_attributes><additional_attributes>10;17;140;60</additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>200</x><y>225</y><w>290</w><h>140</h></coordinates><panel_attributes>Dozentenübersicht
--
Welche Kurse aktuell
Welche Kurstypen möglich
Welche aktuellen Schüler (mit Anzahl)
Stundenplan pro Woche
Bezahlung (inkl. Stundensätze)</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>620</x><y>45</y><w>120</w><h>70</h></coordinates><panel_attributes>Schülerübersicht
--
Kurse zu Schüler
</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>550</x><y>195</y><w>150</w><h>70</h></coordinates><panel_attributes>Raumübersicht
--
Welche Instrumente
Belegunsplan</panel_attributes><additional_attributes></additional_attributes></element><element><id>UMLUseCase</id><coordinates><x>350</x><y>45</y><w>210</w><h>40</h></coordinates><panel_attributes>Übersicht monatliche Einnahmen</panel_attributes><additional_attributes></additional_attributes></element><element><id>Relation</id><coordinates><x>70</x><y>57</y><w>110</w><h>140</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;120;90;10</additional_attributes></element><element><id>Relation</id><coordinates><x>70</x><y>57</y><w>300</w><h>140</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;120;280;10</additional_attributes></element><element><id>Relation</id><coordinates><x>70</x><y>67</y><w>570</w><h>130</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;110;550;10</additional_attributes></element><element><id>Relation</id><coordinates><x>70</x><y>167</y><w>150</w><h>140</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;10;130;120</additional_attributes></element><element><id>Relation</id><coordinates><x>70</x><y>167</y><w>500</w><h>80</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;10;480;60</additional_attributes></element><element><id>Relation</id><coordinates><x>70</x><y>137</y><w>650</w><h>60</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;40;630;10</additional_attributes></element><element><id>Relation</id><coordinates><x>80</x><y>397</y><w>110</w><h>70</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;50;90;10</additional_attributes></element><element><id>Relation</id><coordinates><x>80</x><y>437</y><w>310</w><h>50</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;10;290;30</additional_attributes></element><element><id>Relation</id><coordinates><x>80</x><y>557</y><w>120</w><h>40</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;20;100;20</additional_attributes></element><element><id>Relation</id><coordinates><x>80</x><y>707</y><w>200</w><h>50</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;30;180;20</additional_attributes></element><element><id>Relation</id><coordinates><x>80</x><y>727</y><w>210</w><h>80</h></coordinates><panel_attributes></panel_attributes><additional_attributes>10;10;190;60</additional_attributes></element><element><id>Relation</id><coordinates><x>340</x><y>170</y><w>440</w><h>430</h></coordinates><panel_attributes>lt=.&gt;
&lt;&lt;includes&gt;&gt;</panel_attributes><additional_attributes>10;410;420;410;420;10</additional_attributes></element></diagram>

199
_Dokumente/Ausgearbeitete Dokumente/Endpoints.md

@ -0,0 +1,199 @@
# Endpoints
Im folgenden werden diverse Http-Schnittstellen zur Kommunikation zwischen Frontend und Backend beschrieben.
Zusäzlich ist angegeben, für welche Benutzerrollen die jeweiligen Funktionen zu Verfügung steht.
---
### Login
- POST login
- Parameter
- Username string
- Password string
- POST logout
### Übersichtsseite (Dozent und Verwaltung)
- GET screens
- Liefert alle erlaubten Ansichten für einen User zurück
- Liefert Array
- Screen string
### Wochenübersicht (Dozent)
- GET weekly_overview
- Liefert alle Unterrichtseinheiten für die nächsten 7 Tage
- Liefert Array
### Kursübericht [besser Kursdetails] (Dozent und Verwaltung)
- GET course_detail
- Liefert alle Informationen zu einem Kurs
- Paramter
- KursID string
- Liefert object
- KursID string
- DozentID string
- DozentName string
- Unterrichtseinheiten Array
- StartZeit DateTime
- Students Array
- StudentID string
- StudentName string
- GET course_contents
- Liefert alle eingetragenen Inhalten zum Kurs
- Parameter
- KursID string
- PUT new_course_content
- Inhalt der letzten UE wird gesetzt
- Parameter
- KursID string
- Content string
### Welcher Lehrer Welcher Kurs (Verwaltung)
- GET course_teacher_match
- Liefert Array
- KursID string
- KursName string
- DozentID string
- DozentName string
### Welche Schüler Welcher Kurs (Verwaltung)
- GET course_student_match
- Liefert Array
- KursID string
- KursName string
- DozentID string
- DozentName string
### Lehrerübersicht (Verwaltung)
- GET all_teachers
- Liefert alle Dozenten
- Liefert Array
- DozentID string
- DozentName string
### Schüler von Lehrer (Dozent und Verwaltung)
- GET students_of_teacher
- Parameter DozentID
- Liefert Array
- StundentID string
- StudentName string
### Raumübersicht (Verwaltung)
- GET rooms
- Liefert alle verfügbaren Räume, inkl. der vorhandenen Instrumente
- Liefert Array
- RaumID string
- RaumName string
- Belegt bool
- Instrumente Array
- InstrumentID string
- InstrumentName string
- PUT create_rooms
- Parameter
- RaumName string
- Instrumente Array
- InstrumentID string
### Raumdetails (Verwaltung)
- GET room_free
- Liefert alle aktuell freien Räumen
- Parameter
- RaumID string
- Liefert object
- Belegt bool
- GET room_details
- Liefert Daten zu einem Raum
- Paramter
- RaumID string
- Liefert
- RaumID string
- RaumName string
- Belegt true
- Instrumente Array
- InstrumentID string
- InstrumentName string
- Vorhanden bool
- GET lessons
- Liefert alle Unterrichtszeiten in einem Raum
- Parameter
- RaumID string
- Liefert Array
- KursName string
- StartZeit DateTime
### Kurs Erstellen [Person + Kurs] (Verwaltung)
- POST get_capable_teachers
- Liefert alle Dozenten, die einen bestimmten Kurs leiten können
- Parameter
- Typ string
- Instrumente Array
- InstrumentID string
- Liefert Array
- DozentID string
- DozentName string
- POST get_cross_referenced_rooms
- Parameter
- Typ string
- Instrumente Array
- InstrumentID string
- DozentID string
- Liefert Array
- RaumID string
- Zeiten Array
- Zeit DateTime
- POST create_person
- Erstellt eine Person
- Parameter
- Name string
- Vorname string
- IstErmaessigt bool
- Geburtsdatum DateTime
- Geburtsort string
- PLZ string
- Ort string
- StrasseHNR string
- Bankname string
- BLZ string
- KontoNr string
- Liefert object
- StudentID string
- POST create_course
- Erstellt einen Kurs
- Parameter
- Typ string
- Instrumente Array
- InstrumentID string
- DonzentID string
- Unterrichtseinheiten Array
- Zeit int
- POST enroll_student
- Ordnet einen Schueler einem Kurs zu
- Parameter
- KursID string
- StudentID string
### Aufnahmeantrag (Anonymous)
- POST aufnahmeantrag
- Parameter
- Name string
- Vorname string
- IstErmaessigt bool
- Geburtsdatum DateTime
- Geburtsort string
- PLZ string
- Ort string
- StrasseHNR string
- Bankname string
- BLZ string
- KontoNr string
- Typ string
- Instrumente Array
- InstrumentID string
- Laufzeit
- KursID string
### Instrumente (Anonymous)
- GET instruments
- Liefert Instrumente Array
- InstrumentID string
- InstrumentName string

9
_Dokumente/Ausgearbeitete Dokumente/Fragenkatalog.md

@ -0,0 +1,9 @@
### Fragenkatalog
|Frage|Antwort|
|-|-|
|Öffnungszeiten|10:00 - 21:00|
|Arbeitszeiten von Dozenten (vollzeit, teilzeit)|beliebig|
|Wer legt den Donzenten an?|Büro (Verwaltung) oder Admin|
|Wer legt die Kurse an?|Büro (Verwaltung) oder Admin|
|Benutzerrollen|Admin, Büro, Dozent, Schüler|

BIN
_Dokumente/Ausgearbeitete Dokumente/LS Musikschule. PROJEKTSTRUKTURPLAN.pdf

Binary file not shown.

BIN
_Dokumente/Ausgearbeitete Dokumente/LS Musikschule. PROJEKTSTRUKTURPLAN.xlsx

Binary file not shown.

BIN
_Dokumente/Ausgearbeitete Dokumente/MindMap.pdf

Binary file not shown.

BIN
_Dokumente/Ausgearbeitete Dokumente/Papierprototyp_1.pdf

Binary file not shown.

BIN
_Dokumente/Ausgearbeitete Dokumente/Papierprototyp_2.pdf

Binary file not shown.

843
_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.html

@ -0,0 +1,843 @@
<!DOCTYPE html>
<html>
<head>
<title>Pflichtenheft.md</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
<style>
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
body {
font-family: "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
font-size: 14px;
padding: 0 12px;
line-height: 22px;
word-wrap: break-word;
}
#code-csp-warning {
position: fixed;
top: 0;
right: 0;
color: white;
margin: 16px;
text-align: center;
font-size: 12px;
font-family: sans-serif;
background-color:#444444;
cursor: pointer;
padding: 6px;
box-shadow: 1px 1px 1px rgba(0,0,0,.25);
}
#code-csp-warning:hover {
text-decoration: none;
background-color:#007acc;
box-shadow: 2px 2px 2px rgba(0,0,0,.25);
}
body.scrollBeyondLastLine {
margin-bottom: calc(100vh - 22px);
}
body.showEditorSelection .code-line {
position: relative;
}
body.showEditorSelection .code-active-line:before,
body.showEditorSelection .code-line:hover:before {
content: "";
display: block;
position: absolute;
top: 0;
left: -12px;
height: 100%;
}
body.showEditorSelection li.code-active-line:before,
body.showEditorSelection li.code-line:hover:before {
left: -30px;
}
.vscode-light.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(0, 0, 0, 0.15);
}
.vscode-light.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(0, 0, 0, 0.40);
}
.vscode-dark.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 255, 255, 0.4);
}
.vscode-dark.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 255, 255, 0.60);
}
.vscode-high-contrast.showEditorSelection .code-active-line:before {
border-left: 3px solid rgba(255, 160, 0, 0.7);
}
.vscode-high-contrast.showEditorSelection .code-line:hover:before {
border-left: 3px solid rgba(255, 160, 0, 1);
}
img {
max-width: 100%;
max-height: 100%;
}
a {
color: #4080D0;
text-decoration: none;
}
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
h1 {
padding-bottom: 0.3em;
line-height: 1.2;
border-bottom-width: 1px;
border-bottom-style: solid;
}
h1, h2, h3 {
font-weight: normal;
}
h1 code,
h2 code,
h3 code,
h4 code,
h5 code,
h6 code {
font-size: inherit;
line-height: auto;
}
a:hover {
color: #4080D0;
text-decoration: underline;
}
table {
border-collapse: collapse;
}
table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
padding: 5px 10px;
}
table > tbody > tr + tr > td {
border-top: 1px solid;
}
blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left: 5px solid;
}
code {
font-family: Menlo, Monaco, Consolas, "Droid Sans Mono", "Courier New", monospace, "Droid Sans Fallback";
font-size: 14px;
line-height: 19px;
}
body.wordWrap pre {
white-space: pre-wrap;
}
.mac code {
font-size: 12px;
line-height: 18px;
}
pre:not(.hljs),
pre.hljs code > div {
padding: 16px;
border-radius: 3px;
overflow: auto;
}
/** Theming */
.vscode-light,
.vscode-light pre code {
color: rgb(30, 30, 30);
}
.vscode-dark,
.vscode-dark pre code {
color: #DDD;
}
.vscode-high-contrast,
.vscode-high-contrast pre code {
color: white;
}
.vscode-light code {
color: #A31515;
}
.vscode-dark code {
color: #D7BA7D;
}
.vscode-light pre:not(.hljs),
.vscode-light code > div {
background-color: rgba(220, 220, 220, 0.4);
}
.vscode-dark pre:not(.hljs),
.vscode-dark code > div {
background-color: rgba(10, 10, 10, 0.4);
}
.vscode-high-contrast pre:not(.hljs),
.vscode-high-contrast code > div {
background-color: rgb(0, 0, 0);
}
.vscode-high-contrast h1 {
border-color: rgb(0, 0, 0);
}
.vscode-light table > thead > tr > th {
border-color: rgba(0, 0, 0, 0.69);
}
.vscode-dark table > thead > tr > th {
border-color: rgba(255, 255, 255, 0.69);
}
.vscode-light h1,
.vscode-light hr,
.vscode-light table > tbody > tr + tr > td {
border-color: rgba(0, 0, 0, 0.18);
}
.vscode-dark h1,
.vscode-dark hr,
.vscode-dark table > tbody > tr + tr > td {
border-color: rgba(255, 255, 255, 0.18);
}
.vscode-light blockquote,
.vscode-dark blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.vscode-high-contrast blockquote {
background: transparent;
border-color: #fff;
}
</style>
<style>
/* Tomorrow Theme */
/* http://jmblog.github.com/color-themes-for-google-code-highlightjs */
/* Original theme - https://github.com/chriskempson/tomorrow-theme */
/* Tomorrow Comment */
.hljs-comment,
.hljs-quote {
color: #8e908c;
}
/* Tomorrow Red */
.hljs-variable,
.hljs-template-variable,
.hljs-tag,
.hljs-name,
.hljs-selector-id,
.hljs-selector-class,
.hljs-regexp,
.hljs-deletion {
color: #c82829;
}
/* Tomorrow Orange */
.hljs-number,
.hljs-built_in,
.hljs-builtin-name,
.hljs-literal,
.hljs-type,
.hljs-params,
.hljs-meta,
.hljs-link {
color: #f5871f;
}
/* Tomorrow Yellow */
.hljs-attribute {
color: #eab700;
}
/* Tomorrow Green */
.hljs-string,
.hljs-symbol,
.hljs-bullet,
.hljs-addition {
color: #718c00;
}
/* Tomorrow Blue */
.hljs-title,
.hljs-section {
color: #4271ae;
}
/* Tomorrow Purple */
.hljs-keyword,
.hljs-selector-tag {
color: #8959a8;
}
.hljs {
display: block;
overflow-x: auto;
color: #4d4d4c;
padding: 0.5em;
}
.hljs-emphasis {
font-style: italic;
}
.hljs-strong {
font-weight: bold;
}
</style>
<style>
/*
* Markdown PDF CSS
*/
body {
font-family: "Meiryo", "Segoe WPC", "Segoe UI", "SFUIText-Light", "HelveticaNeue-Light", sans-serif, "Droid Sans Fallback";
}
pre {
background-color: #f8f8f8;
border: 1px solid #cccccc;
border-radius: 3px;
overflow-x: auto;
white-space: pre-wrap;
overflow-wrap: break-word;
}
pre:not(.hljs) {
padding: 23px;
line-height: 19px;
}
blockquote {
background: rgba(127, 127, 127, 0.1);
border-color: rgba(0, 122, 204, 0.5);
}
.emoji {
height: 1.4em;
}
/* for inline code */
:not(pre):not(.hljs) > code {
color: #C9AE75; /* Change the old color so it seems less like an error */
font-size: inherit;
}
/* Page Break : use <div class="page"/> to insert page break
-------------------------------------------------------- */
.page {
page-break-after: always;
}
</style>
</head>
<body>
<h1 id="pflichtenheft">Pflichtenheft</h1>
<h2 id="inhalt">Inhalt</h2>
<ul>
<li><a href="#pflichtenheft">Pflichtenheft</a>
<ul>
<li><a href="#inhalt">Inhalt</a></li>
<li><a href="#zielbestimmungsss">Zielbestimmungsss</a>
<ul>
<li><a href="#musskriterien">Musskriterien</a></li>
<li><a href="#wunschkriterien">Wunschkriterien</a></li>
<li><a href="#abgrenzungungskriterien">Abgrenzungungskriterien</a></li>
</ul>
</li>
<li><a href="#produkt%C3%BCbersicht">Produktübersicht</a></li>
<li><a href="#produktdaten">Produktdaten</a>
<ul>
<li><a href="#speichernutzung">Speichernutzung</a></li>
</ul>
</li>
<li><a href="#produktleistungen">Produktleistungen</a>
<ul>
<li><a href="#benutzeroberfl%C3%A4che-l01">Benutzeroberfläche <strong>/L01/</strong></a></li>
<li><a href="#datenschutz-l02">Datenschutz <strong>/L02/</strong></a></li>
<li><a href="#loggin-und-nachvollziehbarkeit-l03">Loggin und Nachvollziehbarkeit <strong>/L03/</strong></a></li>
</ul>
</li>
<li><a href="#produkteinsatz">Produkteinsatz</a>
<ul>
<li><a href="#anwendungsbereiche">Anwendungsbereiche</a></li>
<li><a href="#zielgruppe">Zielgruppe</a></li>
<li><a href="#betriebsbedingungen">Betriebsbedingungen</a></li>
</ul>
</li>
<li><a href="#produktumgebung">Produktumgebung</a>
<ul>
<li><a href="#software">Software</a></li>
<li><a href="#hardware">Hardware</a></li>
</ul>
</li>
<li><a href="#entwicklungsumgebung">Entwicklungsumgebung</a>
<ul>
<li><a href="#software-1">Software</a>
<ul>
<li><a href="#backend">Backend</a></li>
<li><a href="#frontend">Frontend</a></li>
</ul>
</li>
<li><a href="#hardware-1">Hardware</a>
<ul>
<li><a href="#backend-und-frontend">Backend und Frontend</a></li>
</ul>
</li>
<li><a href="#orgware">Orgware</a>
<ul>
<li><a href="#backend-und-frontend-1">Backend und Frontend</a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#produktfunktionen">Produktfunktionen</a>
<ul>
<li><a href="#annahmen-und-definitionen-zu-produktfunktionen">Annahmen und Definitionen zu Produktfunktionen</a></li>
<li><a href="#dozentenfunktionen">Dozentenfunktionen</a>
<ul>
<li><a href="#wochen%C3%BCbersicht-fd01">Wochenübersicht <strong>/FD01/</strong></a></li>
<li><a href="#kursdetails-fd02">Kursdetails <strong>/FD02/</strong></a></li>
</ul>
</li>
<li><a href="#verwaltungsfunktionen">Verwaltungsfunktionen</a>
<ul>
<li><a href="#offene-antr%C3%A4ge-fv01">Offene Anträge <strong>/FV01/</strong></a></li>
<li><a href="#kurs-erstellen-fv02">Kurs Erstellen <strong>/FV02/</strong></a></li>
<li><a href="#kurs%C3%BCbersicht-fv03">Kursübersicht <strong>/FV03/</strong></a></li>
<li><a href="#sch%C3%BCler%C3%BCbersicht-fv04">Schülerübersicht <strong>/FV04/</strong></a></li>
<li><a href="#sch%C3%BCler-eines-dozenten-fv05">Schüler eines Dozenten <strong>/FV05/</strong></a></li>
<li><a href="#raum%C3%BCbersicht-fv06">Raumübersicht <strong>/FV06/</strong></a></li>
<li><a href="#raumdetails-fv07">Raumdetails <strong>/FV07/</strong></a></li>
<li><a href="#finanz%C3%BCbersicht-fv09">Finanzübersicht <strong>/FV09/</strong></a></li>
</ul>
</li>
<li><a href="#sonstige-funktionen">Sonstige Funktionen</a>
<ul>
<li><a href="#login-f01">Login <strong>/F01/</strong></a></li>
<li><a href="#mitglied-zu-kurs-hinzuf%C3%BCgen-f02">Mitglied zu Kurs hinzufügen <strong>/F02/</strong></a></li>
<li><a href="#antrag-stellen-f03">Antrag Stellen <strong>/F03/</strong></a></li>
</ul>
</li>
</ul>
</li>
<li><a href="#benutzeroberfl%C3%A4che">Benutzeroberfläche</a>
<ul>
<li><a href="#dialogstruktur">Dialogstruktur</a>
<ul>
<li><a href="#startseite">Startseite</a></li>
<li><a href="#%C3%BCbersichtsseite-dozenten">Übersichtsseite Dozenten</a></li>
<li><a href="#%C3%BCbersichtsseite-verwaltung">Übersichtsseite Verwaltung</a></li>
</ul>
</li>
<li><a href="#bildschirmlayout">Bildschirmlayout</a></li>
</ul>
</li>
<li><a href="#testf%C3%A4lle">Testfälle</a></li>
</ul>
</li>
</ul>
<h2 id="zielbestimmungsss">Zielbestimmungsss</h2>
<blockquote>
<p>Das Ziel von Parsec Iron Puffin (<em>PIP</em>) ist es, eine Anwendung zu bieten welche die Organisation der Musikschule erlaubt. Hierzu werden für Dozenten und Verwaltung verschiedene administrative Funktionen bereitgestellt. Die aktuellen Betriebsprozesse sollen vereinfacht und beschleunigt werden.</p>
</blockquote>
<p>Die Anwendung bietet der Verwaltung Übersichten über die Schüler, Dozenten, Kurse und Finanzen. Es können Schüler der Kurse und Dozenten der Schüler angezeigt werden.</p>
<p>Der Dozent erhält eine Übersicht über die Stunden, welche er in der Woch zu unterrichten hat. Außerdem kann er eine Detailansicht eines Kurses aufrufen, welche ihm Informationen über die Schüler in diesem Kurs und die Unterrichtsinhalte der vergangenen Stunden bietet.</p>
<p>Nutzer können mithilfe der Anwendung Kurse beantragen und &quot;Band&quot;-Kursen beitreten.</p>
<h3 id="musskriterien">Musskriterien</h3>
<ul>
<li>Es besteht ein Authentifizierung um den Zugriff auf alle Funktionen auf die jeweils berechtigten Personen zu beschränken.</li>
<li>Der Dozent
<ul>
<li>Kann seine Stunden in der kommenden Woche sehen können.</li>
<li>Kann den Inhalt seiner Kurs für jede Unterrichtseinheit (<em>UE</em>) pflegen.</li>
<li>Kann die Schüler eines Kurses sehen.</li>
</ul>
</li>
<li>Die Verwaltung
<ul>
<li>Kann sehen, welcher Lehrer welchen Kurs leitet.</li>
<li>Kann sehen, welcher Schüler an welchem Kurs teilnimmt.</li>
<li>Kann sehen, welche Schüler von einem gegebenen Lehrer unterrichtet werden.</li>
<li>Kann Räume anlegen.</li>
<li>Kann bearbeiten, welche Instrumente in einem Raum zu verfügung stehen.</li>
<li>Kann die aktuelle Verfügbarkeit und die nächsten Termine eines Raumes sehen.</li>
<li>Kann offene Anträge sehen.</li>
<li>Kann aus eingehenden Anträgen neue Kurs erstellen und UE planen.</li>
<li>Kann in einer Übersicht die Einnahmen der Musikschule und den Betrag, welcher an jeden Dozent gezahlt wird sehen.</li>
</ul>
</li>
<li>Der Administrative Nutzer
<ul>
<li>Konfiguriert die Betriebsparameter des Systems</li>
<li>Sichert die Datenbank</li>
</ul>
</li>
<li>Der Schüler
<ul>
<li>kann einen Aufnahmeantrag über ein Webformular abschicken</li>
<li>erhält, nachdem die Verwaltung einen Kurs aus dem Antrag erstellt hat, eine Bestätigung (Kursbestätigung) mit den Zeiten Seiner Unterrichtseinheiten</li>
<li>hat bis zum ersten Unterrichtstermin Zeit, um den Unterricht zu bestätigen</li>
</ul>
</li>
<li>Sonstiges
<ul>
<li>Deutsch ist Verkehrssprache</li>
<li>Alle Funktionen sind über das Internet erreichbar</li>
<li>Die Anwendung ist für Mobilgeräte optimiert</li>
</ul>
</li>
</ul>
<h3 id="wunschkriterien">Wunschkriterien</h3>
<ul>
<li>Der Administrative Nutzer
<ul>
<li>Möchte bei der Erstellung eines Kurses durch einen Vorschlag zu passendem Raum, Dozenten und Zeitpunkt unterstützt werden.</li>
</ul>
</li>
<li>Der Schüler
<ul>
<li>Möchte sich einloggen können um die eigenen Unterrichtszeiten und Inhalte einzusehen</li>
</ul>
</li>
<li>Sonstiges
<ul>
<li>Daten sollen soweit sinnvoll möglich auf dem Endgerät zwischengespeichert werden, damit auch ohne Internetverbindung Grundlegende funktionalität geleistet werden kann.</li>
</ul>
</li>
</ul>
<h3 id="abgrenzungungskriterien">Abgrenzungungskriterien</h3>
<ul>
<li>Das <em>PIP</em>
<ul>
<li>soll keine Abrechnung erstellen oder verschicken.</li>
</ul>
</li>
</ul>
<h2 id="produkt%C3%BCbersicht">Produktübersicht</h2>
<ul>
<li>Das System wird von den Rollen Verwaltung, Dozent und Anonym bedient.</li>
<li>Die Rollen Verwaltung und Dozent werden über einen Login authentizifiert, ihnen stehen abhängig von ihrer Rolle verschiedene Funktionen zur verfügung, diese werden unter <a href="#produktfunktionen">Produktfunktionen</a> spezifiziert. Sonstige Funktionen stehen <em>allen</em> Rollen zur verfügung.</li>
</ul>
<h2 id="produktdaten">Produktdaten</h2>
<ul>
<li>Datenstrukturen der Anwendung:
<img src="EVA ERD Umletino.png" alt="ERD"></li>
<li>Aus einem Antrag wird ein <em>Schüler</em>, eine von <em>Person</em> erbende Klasse, erstellt, welche alle personenbezogene Daten erhält. (siehe Diagramm)</li>
<li>Außerdem werden Angaben zu der Auswahl des Antragstellers zu <em>Instrument</em> und <em>Unterrichtstyp</em> gespeichert.</li>
<li>Einem <em>Kurs</em> wird stehts ein <em>Schüler</em> zugewiesen, es sei denn es handelt sich um einen Kurs mit Typ &quot;Band&quot;. In diesem Fall können beliebig viele <em>Schüler</em> zugewiesen werden.</li>
<li>Ein <em>Kurs</em> hat <em>Unterrichtseinheiten</em>. Diese Stellen einzelne eindeutige Zeitpunkte dar, an welchen der <em>Kurs</em> unterrichtet wird/wurde.
<ul>
<li>Es wird der Startzeitpunkt gespeichert, &quot;Wed Jun 12 2019 12:15:00 GMT+0200 (Central European Summer Time)&quot; stellt die <em>Unterrichtseinheit</em> von 12:15 bis 12:30 dar.</li>
<li>Für jede Unterrichtseinheit kann der Dozent den Inhalt pflegen, um die Unterrichtsinhalte zu Dokumentieren.</li>
</ul>
</li>
</ul>
<h3 id="speichernutzung">Speichernutzung</h3>
<ul>
<li>Ein Personendatensatz kann bis zu 5KB groß sein, typisch ~300 Byte.</li>
<li>Ein Kursdatensatzen kann bis zu 55 Byte groß sein.</li>
<li>Ein Unterrichtseinheitendatensatz kann bis zu 2056 Byte groß sein.</li>
</ul>
<h2 id="produktleistungen">Produktleistungen</h2>
<h3 id="benutzeroberfl%C3%A4che-l01">Benutzeroberfläche <strong>/L01/</strong></h3>
<ul>
<li>Die Anwendung bietet eine deutschsprachige Benutzeroberfläche</li>
</ul>
<h3 id="datenschutz-l02">Datenschutz <strong>/L02/</strong></h3>
<ul>
<li>Daten werden in einer passwordgeschützten Datenbank abgelegt</li>
</ul>
<h3 id="loggin-und-nachvollziehbarkeit-l03">Loggin und Nachvollziehbarkeit <strong>/L03/</strong></h3>
<ul>
<li>Zugriffe wie das Schreiben von Daten (anlegen und modifizieren von Datensätzen) werden in einem Log dokumentiert und können so nachvollzogen werden.</li>
</ul>
<h2 id="produkteinsatz">Produkteinsatz</h2>
<h3 id="anwendungsbereiche">Anwendungsbereiche</h3>
<p>Die Anwendung wird von den Dozenten und der Verwaltung zur Planung und Organisation der Musikschule genutzt.</p>
<h3 id="zielgruppe">Zielgruppe</h3>
<p>Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen Dozenten der Musikschule. Eventeuell wird die Zielgruppe um die Schüler der Musikschule erweitert.</p>
<h3 id="betriebsbedingungen">Betriebsbedingungen</h3>
<ul>
<li>Betriebsdauer: täglich, 24 Stunden</li>
<li>Die Anwendung und ihre Teile werden auf einem virtuellen privaten Server bei einem externen Anbieter bereitgestellt</li>
<li>Die Anwendung ist global über das Internet erreichbar</li>
<li>Der Betrieb wird vom Auftragnehmer überwacht</li>
</ul>
<h2 id="produktumgebung">Produktumgebung</h2>
<h3 id="software">Software</h3>
<ul>
<li>Client
<ul>
<li>Chrome oder Chromium basierter Browser der Version 74, Firefox 67</li>
</ul>
</li>
<li>Server
<ul>
<li>Docker unter Linux (Version 18.09.5)</li>
</ul>
</li>
</ul>
<h3 id="hardware">Hardware</h3>
<ul>
<li>Client
<ul>
<li>Internetfähiges Endgerät</li>
</ul>
</li>
<li>Server
<ul>
<li>Internetfähiger Server</li>
<li>Ausreichende Rechen- und Festplattenkapazität</li>
</ul>
</li>
</ul>
<h2 id="entwicklungsumgebung">Entwicklungsumgebung</h2>
<h3 id="software">Software</h3>
<h4 id="backend">Backend</h4>
<ul>
<li>Entwickler nutzen die IDE Visual Studio 2019 von Microsoft</li>
<li>Zum Untersuchen der Datenbank wird der DB Browser genutzt</li>
<li>Code wird mithilfe des .NET Komplierers kompiliert</li>
<li>Als Betriebssystem wird Microsoft Windows genutzt</li>
<li>Als Codeverwaltung wird Gitlab CE genutzt</li>
<li>Als CI/CD Tool wird Gitlab CI/CD genutzt</li>
</ul>
<h4 id="frontend">Frontend</h4>
<ul>
<li>Entwickler nutzen den Code Editor Visual Studio Code von Microsoft</li>
<li>Codequality Kontrolle wird von dem Codelinter &quot;ESLint&quot; unterstützt</li>
<li>Node JS</li>
<li>Verschiedene Node JS Tools werden zur Unterstützung genutzt (z.B. nodemon)</li>
<li>Als Betriebssystem wird Microsoft Windows oder Ubuntu 19.04 genutzt</li>
<li>Als Codeverwaltung wird Gitlab CE genutzt</li>
<li>Als CI/CD Tool wird Gitlab CI/CD genutzt</li>
</ul>
<h3 id="hardware">Hardware</h3>
<h4 id="backend-und-frontend">Backend und Frontend</h4>
<ul>
<li>Computer mit einem amd64 Mehrkernprozessor, mind. 8 GB RAM und mind. 1 GB freiem Festspeicher</li>
</ul>
<h3 id="orgware">Orgware</h3>
<h4 id="backend-und-frontend">Backend und Frontend</h4>
<ul>
<li>Das Team nutzt Slack zur Kommunikation</li>
<li>Als Codeverwaltung wird Gitlab CE genutzt</li>
<li>Als CI/CD Tool wird Gitlab CI/CD genutzt</li>
</ul>
<h2 id="produktfunktionen">Produktfunktionen</h2>
<h4 id="annahmen-und-definitionen-zu-produktfunktionen">Annahmen und Definitionen zu Produktfunktionen</h4>
<blockquote>
<p>Getroffene Annahmen und Definitionen zu unterliegenen Produktfunktionen und Geschäftsprozessen, mit denen die Nutzer nicht direkt in Kontakt kommen und daher nicht einer speziellen Funktion zugeordnet werden können.</p>
</blockquote>
<ul>
<li>Aus einem eingegangenen Antrag wird wird von der Verwaltung mithilfe der gebotenen Funktion ein Kurs erstellt. Hierfür wählt diese einene passenden Dozenten, Raum, und Zeitpunkt(e) aus. Diese werden dem Antragsteller auf geeignetem Weg, zusammen mit einem ausgefertigtem Vertrag zustellt. Der Antragsteller hat bis zum ersten Unterrichtszeitpunkt Zeit, um diesen Vertrag unterschrieben vorzulegen, ansonsten verfällt der Kurs und Dozent und Raum werden zu dem Zeitpunkt(en) freigegeben.</li>
<li>Im Falle eines &quot;Band&quot;-Kurses wird dem Antragsteller zusammen mit dem Vertrag ein Einzigartiger Link zugestellt. Über diesen Link können sich weiter Mitglieder durch angeben ihrer personenbezogenen Daten zu diesem bereits erstellten Kurs anmelden. Die Anmeldung ist bis zum ersten Unterrichtszeitpunkt möglich.</li>
<li>Die Laufzeit des Vertrags startet zum ersten Unterrichtstermin.</li>
<li>Unterrichtszeiten werden in 15min (1/4 Stunden) blöcken gegeben und geplant.</li>
</ul>
<h3 id="dozentenfunktionen">Dozentenfunktionen</h3>
<h4 id="wochen%C3%BCbersicht-fd01">Wochenübersicht <strong>/FD01/</strong></h4>
<ul>
<li>Der Nutzer sieht eine Übersicht mit von Ihm gegebenen Kursen in den kommenden 7 Tagen, gruppiert nach Wochentag</li>
<li>Mit einem Klick auf einen Kurs gelangt man zu den entsprechenden Kursdetails</li>
</ul>
<h4 id="kursdetails-fd02">Kursdetails <strong>/FD02/</strong></h4>
<ul>
<li>Der Nutzer sieht Details zu einem Kurs</li>
<li>Er sieht alle Schüler, welche an dem Kurs teilnehmen</li>
<li>Er sieht die Einträge zu den den Unterrichtsinhalten der vergangen Unterrichtseinheiten und kann den Inhalt des letzten Termins bearbeiten / erfassen.</li>
</ul>
<h3 id="verwaltungsfunktionen">Verwaltungsfunktionen</h3>
<h4 id="offene-antr%C3%A4ge-fv01">Offene Anträge <strong>/FV01/</strong></h4>
<ul>
<li>Es werden alle neu eingegangenen und nicht bestägtigten Anträge angzeigt.</li>
<li>Mit einem Klick auf einen eingegangen Antrag wird die <a href="#kurs-erstellen-fv02">Kurs erstellen</a> Seite aufgerufen.</li>
</ul>
<h4 id="kurs-erstellen-fv02">Kurs Erstellen <strong>/FV02/</strong></h4>
<ul>
<li>Nach einem eingegegangen Antrag kann basierent auf diesem ein Kurs erstellt werden.</li>
<li>Typ (Einzel, Gruppe, ), Instrument(e), Laufzeit und Personenbezogne Daten werden in der Kurserstllungs Mask vorausgefüllt</li>
<li>Es werden Dozenten angezeigt, welche zu den Instrumentenanforderungen passen</li>
<li>Es werden Räume angezeigt, welche zu den Instrumentenanforderungen passen</li>
<li>Nach Auswahl von Raum und Dozent wird/werden die Zeit(en) für die Unterrichtseinheiten gewählt werden; Die Möglichkeit der auswahl wird überprüft</li>
<li>Nach erfolgreicher Auswahl wird der Kurs in der Datenbank angelegt und der Schüler über den Kurs informiert. Dieser muss ihn vor der ersten Unterrichtseinheit bestätigen, ansonster verfällt der Kurs.</li>
</ul>
<h4 id="kurs%C3%BCbersicht-fv03">Kursübersicht <strong>/FV03/</strong></h4>
<ul>
<li>In der Kursübersicht werden in Tabellenform alle Kurse zusammen mit ihren Dozenten angezeigt.</li>
<li>Die Tabelle kann spaltenweise sortiert und nach Dozenten- und Kursname gefiltert werden.</li>
<li>Ein Klick auf einen Kurs führt zu <a href="#kursdetails-fd02">Kursdetails</a>.</li>
<li>Ein Klick auf einen Dozenten führt zu <a href="#sch%C3%BCler-eines-dozenten-fv05">Schüler eines Dozenten</a></li>
</ul>
<h4 id="sch%C3%BCler%C3%BCbersicht-fv04">Schülerübersicht <strong>/FV04/</strong></h4>
<ul>
<li>Es werden in Tabellenform alle Schüler mit Ihren Kursen angezeigt, ein Kurs pro Zeile
<ul>
<li>Ein Schüler kann also mehrere Zeilen umfassen</li>
</ul>
</li>
<li>Die Tabelle kann spaltenweise sortiert und nach Schüler- und Kursname gefiltert werden.</li>
</ul>
<h4 id="sch%C3%BCler-eines-dozenten-fv05">Schüler eines Dozenten <strong>/FV05/</strong></h4>
<ul>
<li>Es werden alle Schüler des ausgewählten Dozenten angezeigt.</li>
</ul>
<h4 id="raum%C3%BCbersicht-fv06">Raumübersicht <strong>/FV06/</strong></h4>
<ul>
<li>Es werden alle Räume mit Grundlegenden Informationen angezeigt.
<ul>
<li>aktuelle Belegung</li>
<li>Instrumente</li>
</ul>
</li>
<li>Es wird ein Button zum erstellen von neuen Räumen angzeigt</li>
</ul>
<h4 id="raumdetails-fv07">Raumdetails <strong>/FV07/</strong></h4>
<ul>
<li>Es werden alle Informationen zu einem Raum Angzeigt.
<ul>
<li>Name (bearbeitbar)</li>
<li>aktuelle Belegung</li>
<li>Instrumente (bearbeitbar)</li>
<li>Nächste 5 Unterrichtseinheiten in diesem Raum</li>
</ul>
</li>
</ul>
<h4 id="finanz%C3%BCbersicht-fv09">Finanzübersicht <strong>/FV09/</strong></h4>
<ul>
<li>Es werden die gesamten monatlichen Einnahmen der Musikschule angzeigt.</li>
<li>Es werden die Zahlungen an die Dozenten, aufgeschlüsselt nacht Dozent angezeigt.</li>
</ul>
<h3 id="sonstige-funktionen">Sonstige Funktionen</h3>
<h4 id="login-f01">Login <strong>/F01/</strong></h4>
<ul>
<li>Der Nutzer kann sich mit Benutzername und Passwort anmelden.</li>
<li>Benutzername und Passwort können von dem Administrativen Nutzer mithilfe von Direktzugriff auf das System angelegt werden</li>
</ul>
<h4 id="mitglied-zu-kurs-hinzuf%C3%BCgen-f02">Mitglied zu Kurs hinzufügen <strong>/F02/</strong></h4>
<ul>
<li>Wenn ein Schüler einen Gruppenkurs erstellt hat, erhält dieser mit seiner Kursbestätigung einen Einladungslink, welcher auf eine &quot;Antrag-Lite&quot; Seite führt.
<ul>
<li>Hier können sich weiter Mitglieder der Gruppe/Band in diesen Kurs eintragen.</li>
<li>Dafür müssen diese nur Ihre Personenbezogenen Daten angeben, Sie werden in der über den Link identifizierten Kurs eingeschrieben.</li>
<li>Dies muss vor dem ersten Unterrichtstermin geschehen.</li>
</ul>
</li>
</ul>
<h4 id="antrag-stellen-f03">Antrag Stellen <strong>/F03/</strong></h4>
<ul>
<li>Der Nutzer gibt personenbezogene- und kursbezogenen Daten an, aus diesen wird beim Absenden ein Antrag in der Datenbank erstellt, welche von der Verwaltung mithilfe der Funktion <a href="#offene-antr%C3%A4ge-fv01">Offene Anträge</a> eingesehen und weiter verarbeitet werden können.</li>
<li>Personenbezogene Daten:
<ul>
<li>Vorname</li>
<li>Nachname</li>
<li>Geb. Datum</li>
<li>Geb. Ort</li>
<li>PLZ</li>
<li>Ort</li>
<li>Straße</li>
<li>Hausnummer</li>
<li>Telefon</li>
<li>EMail</li>
<li>BLZ</li>
<li>Bankname</li>
<li>Kontonummer</li>
</ul>
</li>
<li>Kursbezogene Daten:
<ul>
<li>Instrumente</li>
<li>Laufzeit</li>
<li>Unterrichtstyp</li>
</ul>
</li>
</ul>
<h2 id="benutzeroberfl%C3%A4che">Benutzeroberfläche</h2>
<blockquote>
<p>Was sind die grundlegenden Anforderungen an die Benutzeroberfläche (Bildschirmlayout, Dialogstruktur, ...)?</p>
</blockquote>
<h3 id="dialogstruktur">Dialogstruktur</h3>
<p>Im Folgenden wird die grobe Dialogstruktur einer fehlerfreien bzw. konfliktfreien Benutzung des Systems gezeigt wird.
Fehlereingaben haben eine akkumulierte Fehlermeldung zur Folge.</p>
<h4 id="startseite">Startseite</h4>
<p><img src="img/Hauptseite.png" alt="Hauptseite" title="Startseite"></p>
<h4 id="%C3%BCbersichtsseite-dozenten">Übersichtsseite Dozenten</h4>
<p>Die Übersichtsseite Dozenten ist die Startseite des Dozenten, die der Dozent nach der Anmeldung /F01/ erreicht.</p>
<p><img src="img/Hauptseite_Dozent.png" alt="Hauptseite" title="Hauptseite Dozent"></p>
<h4 id="%C3%BCbersichtsseite-verwaltung">Übersichtsseite Verwaltung</h4>
<p>Die Übersichtsseite Verwaltung ist die Startseite der Verwaltung, die die Verwaltung nach der Anmeldung /F01/ erreicht.</p>
<p><img src="img/Hauptseite_Verwaltung.png" alt="Hauptseite" title="Hauptseite Dozent"></p>
<h3 id="bildschirmlayout">Bildschirmlayout</h3>
<p>Das Frontend wird mithilfe der JavaScript Bibliothek React erstellt, das Design wird mithilfe der MIT-lizensierten Designbibliothek Material-UI realisiert. Die Anwendung ist für Mobilegeräte optimiert und wird nach den Prinzipien des Responsiven Desings entwickelt.</p>
<blockquote>
<p>Ausnahme sind die Administrationsfunktionen</p>
</blockquote>
<h2 id="testf%C3%A4lle">Testfälle</h2>
<ol>
<li>Der Login funktioniert und erlaubt nur Zugriff auf authorisierte Bereiche / Ansichten.</li>
<li>Anonyme Nutzer können Anträge stellen, diese gehen in der Datenbank ein.</li>
<li>Die Verwaltung kann Anträge verarbeiten und daraus Kurse erstellen.</li>
</ol>
<ul>
<li>Der Antragsteller wird über die Verarbeitung informiert.</li>
</ul>
<ol start="4">
<li>Die Übersichtsseiten zeigen korrekte Informationen an.</li>
</ol>
</body>
</html>

345
_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.md

@ -0,0 +1,345 @@
# Pflichtenheft
## Inhalt
- [Pflichtenheft](#Pflichtenheft)
- [Inhalt](#Inhalt)
- [Zielbestimmung](#Zielbestimmung)
- [Musskriterien](#Musskriterien)
- [Wunschkriterien](#Wunschkriterien)
- [Abgrenzungungskriterien](#Abgrenzungungskriterien)
- [Produktübersicht](#Produkt%C3%BCbersicht)
- [Produktdaten](#Produktdaten)
- [Speichernutzung](#Speichernutzung)
- [Produktleistungen](#Produktleistungen)
- [Benutzeroberfläche **/L01/**](#Benutzeroberfl%C3%A4che-L01)
- [Datenschutz **/L02/**](#Datenschutz-L02)
- [Loggin und Nachvollziehbarkeit **/L03/**](#Loggin-und-Nachvollziehbarkeit-L03)
- [Produkteinsatz](#Produkteinsatz)
- [Anwendungsbereiche](#Anwendungsbereiche)
- [Zielgruppe](#Zielgruppe)
- [Betriebsbedingungen](#Betriebsbedingungen)
- [Produktumgebung](#Produktumgebung)
- [Software](#Software)
- [Hardware](#Hardware)
- [Entwicklungsumgebung](#Entwicklungsumgebung)
- [Software](#Software-1)
- [Backend](#Backend)
- [Frontend](#Frontend)
- [Hardware](#Hardware-1)
- [Backend und Frontend](#Backend-und-Frontend)
- [Orgware](#Orgware)
- [Backend und Frontend](#Backend-und-Frontend-1)
- [Produktfunktionen](#Produktfunktionen)
- [Annahmen und Definitionen zu Produktfunktionen](#Annahmen-und-Definitionen-zu-Produktfunktionen)
- [Dozentenfunktionen](#Dozentenfunktionen)
- [Wochenübersicht **/FD01/**](#Wochen%C3%BCbersicht-FD01)
- [Kursdetails **/FD02/**](#Kursdetails-FD02)
- [Verwaltungsfunktionen](#Verwaltungsfunktionen)
- [Offene Anträge **/FV01/**](#Offene-Antr%C3%A4ge-FV01)
- [Kurs Erstellen **/FV02/**](#Kurs-Erstellen-FV02)
- [Kursübersicht **/FV03/**](#Kurs%C3%BCbersicht-FV03)
- [Schülerübersicht **/FV04/**](#Sch%C3%BCler%C3%BCbersicht-FV04)
- [Schüler eines Dozenten **/FV05/**](#Sch%C3%BCler-eines-Dozenten-FV05)
- [Raumübersicht **/FV06/**](#Raum%C3%BCbersicht-FV06)
- [Raumdetails **/FV07/**](#Raumdetails-FV07)
- [Finanzübersicht **/FV09/**](#Finanz%C3%BCbersicht-FV09)
- [Sonstige Funktionen](#Sonstige-Funktionen)
- [Login **/F01/**](#Login-F01)
- [Mitglied zu Kurs hinzufügen **/F02/**](#Mitglied-zu-Kurs-hinzuf%C3%BCgen-F02)
- [Antrag Stellen **/F03/**](#Antrag-Stellen-F03)
- [Benutzeroberfläche](#Benutzeroberfl%C3%A4che)
- [Dialogstruktur](#Dialogstruktur)
- [Startseite](#Startseite)
- [Übersichtsseite Dozenten](#%C3%9Cbersichtsseite-Dozenten)
- [Übersichtsseite Verwaltung](#%C3%9Cbersichtsseite-Verwaltung)
- [Bildschirmlayout](#Bildschirmlayout)
- [Testfälle](#Testf%C3%A4lle)
<div class="page"/>
## Zielbestimmung
> Das Ziel von Parsec Iron Puffin (*PIP*) ist es, eine Anwendung zu bieten welche die Organisation der Musikschule erlaubt. Hierzu werden für Dozenten und Verwaltung verschiedene administrative Funktionen bereitgestellt. Die aktuellen Betriebsprozesse sollen vereinfacht und beschleunigt werden.
Die Anwendung bietet der Verwaltung Übersichten über die Schüler, Dozenten, Kurse und Finanzen. Es können Schüler der Kurse und Dozenten der Schüler angezeigt werden.
Der Dozent erhält eine Übersicht über die Stunden, welche er in der Woche zu unterrichten hat. Außerdem kann er eine Detailansicht eines Kurses aufrufen, welche ihm Informationen über die Schüler in diesem Kurs und die Unterrichtsinhalte der vergangenen Stunden bietet.
Nutzer können mithilfe der Anwendung Kurse beantragen und "Band"-Kursen beitreten.
### Musskriterien
* Es besteht eine Authentifizierung um den Zugriff auf alle Funktionen auf die jeweils berechtigten Personen zu beschränken.
* Der Dozent
* Kann seine Stunden in der kommenden Woche sehen.
* Kann den Inhalt seiner Kurse für jede Unterrichtseinheit (*UE*) pflegen.
* Kann die Schüler eines Kurses sehen.
* Die Verwaltung
* Kann sehen, welcher Dozent welchen Kurs leitet.
* Kann sehen, welcher Schüler an welchem Kurs teilnimmt.
* Kann sehen, welche Schüler von einem gegebenen Dozent unterrichtet werden.
* Kann Räume anlegen.
* Kann bearbeiten, welche Instrumente in einem Raum zur Verfügung stehen.
* Kann die aktuelle Verfügbarkeit und die nächsten Termine eines Raumes sehen.
* Kann offene Anträge sehen.
* Kann aus eingehenden Anträgen neue Kurse erstellen und UE planen.
* Kann in einer Übersicht die Einnahmen der Musikschule und den Betrag, welcher an jeden Dozent gezahlt wird, sehen.
* Der Administrative Nutzer
* Konfiguriert die Betriebsparameter des Systems.
* Sichert die Datenbank.
* Der Schüler
* Kann einen Aufnahmeantrag über ein Webformular abschicken
* Erhält, nachdem die Verwaltung einen Kurs aus dem Antrag erstellt hat, eine Bestätigung (Kursbestätigung) mit den Zeiten seiner Unterrichtseinheiten.
* Hat bis zum ersten Unterrichtstermin Zeit, um den Unterricht zu bestätigen.
* Sonstiges
* Deutsch ist Verkehrssprache.
* Alle Funktionen sind über das Internet erreichbar.
* Die Anwendung ist für Mobilgeräte optimiert.
### Wunschkriterien
* Der Administrative Nutzer
* Möchte bei der Erstellung eines Kurses durch einen Vorschlag zu passendem Raum, Dozenten und Zeitpunkt unterstützt werden.
* Der Schüler
* Möchte sich einloggen können um die eigenen Unterrichtszeiten und Inhalte einzusehen.
* Sonstiges
* Daten sollen soweit sinnvoll möglich auf dem Endgerät zwischengespeichert werden, damit auch ohne Internetverbindung grundlegende Funktionalität geleistet werden kann.
### Abgrenzungungskriterien
* Das *PIP*
* Soll keine Abrechnung erstellen oder verschicken.
## Produktübersicht
* Das System wird von den Rollen Verwaltung, Dozent und Anonym bedient.
* Die Rollen Verwaltung und Dozent werden über einen Login authentizifiert, ihnen stehen abhängig von ihrer Rolle verschiedene Funktionen zur verfügung, diese werden unter [Produktfunktionen](#produktfunktionen) spezifiziert. Sonstige Funktionen stehen _allen_ Rollen zur verfügung.
<div class="page"/>
## Produktdaten
* Datenstrukturen der Anwendung:
![ERD](EVA&#32;ERD&#32;Umletino.png)
* Aus einem Antrag wird ein _Schüler_, eine von _Person_ erbende Klasse, erstellt, welche alle personenbezogene Daten erhält. (siehe Diagramm)
* Außerdem werden Angaben zu der Auswahl des Antragstellers zu _Instrument_ und _Unterrichtstyp_ gespeichert.
* Einem _Kurs_ wird stehts ein _Schüler_ zugewiesen, es sei denn es handelt sich um einen Kurs mit Typ "Band". In diesem Fall können beliebig viele _Schüler_ zugewiesen werden.
* Ein _Kurs_ hat _Unterrichtseinheiten_. Diese Stellen einzelne eindeutige Zeitpunkte dar, an welchen der _Kurs_ unterrichtet wird/wurde.
* Es wird der Startzeitpunkt gespeichert, "Wed Jun 12 2019 12:15:00 GMT+0200 (Central European Summer Time)" stellt die _Unterrichtseinheit_ von 12:15 bis 12:30 dar.
* Für jede Unterrichtseinheit kann der Dozent den Inhalt pflegen, um die Unterrichtsinhalte zu Dokumentieren.
### Speichernutzung
* Ein Personendatensatz kann bis zu 5KB groß sein, typisch ~300 Byte.
* Ein Kursdatensatzen kann bis zu 55 Byte groß sein.
* Ein Unterrichtseinheitendatensatz kann bis zu 2056 Byte groß sein.
<div class="page"/>
## Produktleistungen
### Benutzeroberfläche **/L01/**
* Die Anwendung bietet eine deutschsprachige Benutzeroberfläche
### Datenschutz **/L02/**
* Daten werden in einer passwordgeschützten Datenbank abgelegt
### Loggin und Nachvollziehbarkeit **/L03/**
* Zugriffe wie das Schreiben von Daten (anlegen und modifizieren von Datensätzen) werden in einem Log dokumentiert und können so nachvollzogen werden.
<div class="page"/>
## Produkteinsatz
### Anwendungsbereiche
Die Anwendung wird von den Dozenten und der Verwaltung zur Planung und Organisation der Musikschule genutzt.
### Zielgruppe
Die Zielgruppe besteht aus der Verwaltung und allen aktuellen und zukünftigen Dozenten der Musikschule. Eventeuell wird die Zielgruppe um die Schüler der Musikschule erweitert.
### Betriebsbedingungen
* Betriebsdauer: täglich, 24 Stunden
* Die Anwendung und ihre Teile werden auf einem virtuellen privaten Server bei einem externen Anbieter bereitgestellt
* Die Anwendung ist global über das Internet erreichbar
* Der Betrieb wird vom Auftragnehmer überwacht
<div class="page"/>
## Produktumgebung
### Software
* Client
* Chrome oder Chromium basierter Browser der Version 74, Firefox 67
* Server
* Docker unter Linux (Version 18.09.5)
### Hardware
* Client
* Internetfähiges Endgerät
* Server
* Internetfähiger Server
* Ausreichende Rechen- und Festplattenkapazität
<div class="page"/>
## Entwicklungsumgebung
### Software
#### Backend
* Entwickler nutzen die IDE Visual Studio 2019 von Microsoft
* Zum Untersuchen der Datenbank wird ein DB Browser genutzt
* Code wird mithilfe des .NET Komplierers kompiliert
* Als Betriebssystem wird Microsoft Windows genutzt
* Als Codeverwaltung wird Gitlab CE genutzt
* Als CI/CD Tool wird Gitlab CI/CD genutzt
#### Frontend
* Entwickler nutzen den Code Editor Visual Studio Code von Microsoft
* Codequality Kontrolle wird von dem Codelinter "ESLint" unterstützt
* Node JS
* Verschiedene Node JS Tools werden zur Unterstützung genutzt (z.B. nodemon)
* Als Betriebssystem wird Microsoft Windows oder Ubuntu 19.04 genutzt
* Als Codeverwaltung wird Gitlab CE genutzt
* Als CI/CD Tool wird Gitlab CI/CD genutzt
### Hardware
#### Backend und Frontend
* Computer mit einem amd64 Mehrkernprozessor, mind. 8 GB RAM und mind. 1 GB freiem Festspeicher
### Orgware
#### Backend und Frontend
* Das Team nutzt Slack zur Kommunikation
* Als Codeverwaltung wird Gitlab CE genutzt
* Als CI/CD Tool wird Gitlab CI/CD genutzt
<div class="page"/>
## Produktfunktionen
#### Annahmen und Definitionen zu Produktfunktionen
> Getroffene Annahmen und Definitionen zu unterliegenen Produktfunktionen und Geschäftsprozessen, mit denen die Nutzer nicht direkt in Kontakt kommen und daher nicht einer speziellen Funktion zugeordnet werden können.
* Aus einem eingegangenen Antrag wird von der Verwaltung mithilfe der gebotenen Funktion ein Kurs erstellt. Hierfür wählt diese einen passenden Dozenten, Raum, und UEs aus. Diese werden dem Antragsteller auf geeignetem Weg, zusammen mit einem ausgefertigtem Vertrag, zustellt. Der Antragsteller hat bis zum ersten Unterrichtszeitpunkt Zeit, um diesen Vertrag unterschrieben vorzulegen. Ansonsten verfällt der Kurs und Dozent und Raum werden zu den Zeitpunkten der geplanten UEs freigegeben.
* Im Falle eines "Band"-Kurses wird dem Antragsteller zusammen mit dem Vertrag ein einzigartiger Link zugestellt. Über diesen Link können sich weitere Mitglieder durch angeben ihrer personenbezogenen Daten zu diesem bereits erstellten Kurs anmelden. Die Anmeldung ist bis zum ersten Unterrichtszeitpunkt möglich.
* Die Laufzeit des Vertrags startet zum ersten Unterrichtstermin.
* Unterrichtszeiten werden in 15min (1/4 Stunden) Blöcken gegeben und geplant.
### Dozentenfunktionen
#### Wochenübersicht **/FD01/**
* Der Nutzer sieht eine Übersicht mit von ihm gegebenen Kursen in den kommenden 7 Tagen, gruppiert nach Wochentag
* Mit einem Klick auf einen Kurs gelangt man zu den entsprechenden Kursdetails
#### Kursdetails **/FD02/**
* Der Nutzer sieht Details zu einem Kurs
* Er sieht alle Schüler, welche an dem Kurs teilnehmen
* Er sieht die Einträge zu den den Unterrichtsinhalten der vergangen Unterrichtseinheiten und kann den Inhalt des letzten Termins bearbeiten / erfassen.
### Verwaltungsfunktionen
#### Offene Anträge **/FV01/**
* Es werden alle neu eingegangenen und nicht bestägtigten Anträge angzeigt.
* Mit einem Klick auf einen eingegangen Antrag wird die [Kurs erstellen](#kurs-erstellen-fv02) Seite aufgerufen.
#### Kurs Erstellen **/FV02/**
* Nach einem eingegegangen Antrag kann basierent auf diesem ein Kurs erstellt werden.
* Typ (Einzel, Gruppe, ), Instrument(e), Laufzeit und Personenbezogne Daten werden in der Kurserstllungs Mask vorausgefüllt
* Es werden Dozenten angezeigt, welche zu den Instrumentenanforderungen passen
* Es werden Räume angezeigt, welche zu den Instrumentenanforderungen passen
* Nach Auswahl von Raum und Dozent wird/werden die Zeit(en) für die Unterrichtseinheiten gewählt werden; Die Möglichkeit der auswahl wird überprüft
* Nach erfolgreicher Auswahl wird der Kurs in der Datenbank angelegt und der Schüler über den Kurs informiert. Dieser muss ihn vor der ersten Unterrichtseinheit bestätigen, ansonster verfällt der Kurs.
#### Kursübersicht **/FV03/**
* In der Kursübersicht werden in Tabellenform alle Kurse zusammen mit ihren Dozenten angezeigt.
* Die Tabelle kann spaltenweise sortiert und nach Dozenten- und Kursname gefiltert werden.
* Ein Klick auf einen Kurs führt zu [Kursdetails](#kursdetails-fd02).
* Ein Klick auf einen Dozenten führt zu [Schüler eines Dozenten](#sch%C3%BCler-eines-dozenten-fv05)
#### Schülerübersicht **/FV04/**
* Es werden in Tabellenform alle Schüler mit ihren Kursen angezeigt; ein Kurs pro Zeile
* Ein Schüler kann also mehrere Zeilen umfassen.
* Die Tabelle kann spaltenweise sortiert und nach Schüler- und Kursname gefiltert werden.
#### Schüler eines Dozenten **/FV05/**
* Es werden alle Schüler des ausgewählten Dozenten angezeigt.
#### Raumübersicht **/FV06/**
* Es werden alle Räume mit Grundlegenden Informationen angezeigt.
* Aktuelle Belegung
* Instrumente
* Es wird ein Button zum erstellen von neuen Räumen angezeigt
#### Raumdetails **/FV07/**
* Es werden alle Informationen zu einem Raum Angzeigt.
* Name (bearbeitbar)
* Aktuelle Belegung
* Instrumente (bearbeitbar)
* Nächste 5 Unterrichtseinheiten in diesem Raum
#### Finanzübersicht **/FV09/**
* Es werden die gesamten monatlichen Einnahmen der Musikschule angzeigt.
* Es werden die Zahlungen an die Dozenten, aufgeschlüsselt nach Dozent angezeigt.
### Sonstige Funktionen
#### Login **/F01/**
* Ein Nutzer kann sich mit Benutzername und Passwort anmelden.
* Benutzername und Passwort können von dem Administrativen Nutzer mithilfe von Direktzugriff auf das System angelegt werden.
#### Mitglied zu Kurs hinzufügen **/F02/**
* Wenn ein Schüler einen Gruppenkurs ("Band"-Kurs) erstellt hat, erhält dieser mit seiner Kursbestätigung einen Einladungslink, welcher auf eine "Antrag-Lite" Seite führt.
* Hier können sich weitere Mitglieder der Gruppe/Band in diesen Kurs eintragen.
* Dafür müssen diese nur Ihre personenbezogenen Daten angeben; Sie werden in der über den Link identifizierten Kurs eingeschrieben.
* Dies muss vor dem ersten Unterrichtstermin geschehen.
#### Antrag Stellen **/F03/**
* Der Nutzer gibt personenbezogene- und kursbezogenen Daten an. Aus diesen wird beim Absenden ein Antrag in der Datenbank erstellt, welche von der Verwaltung mithilfe der Funktion [Offene Anträge](#offene-antr%C3%A4ge-fv01) eingesehen und weiter verarbeitet werden können.
* Personenbezogene Daten:
* Vorname
* Nachname
* Geburtsdatum
* Geburtsort
* PLZ
* Ort
* Straße
* Hausnummer
* Telefon
* EMail
* BLZ
* Bankname
* Kontonummer
* Kursbezogene Daten:
* Instrumente
* Laufzeit
* Unterrichtstyp
<div class="page"/>
## Benutzeroberfläche
> Was sind die grundlegenden Anforderungen an die Benutzeroberfläche (Bildschirmlayout, Dialogstruktur, ...)?
### Dialogstruktur
Im Folgenden wird die grobe Dialogstruktur einer fehlerfreien bzw. konfliktfreien Benutzung des Systems gezeigt.
Fehleingaben haben eine akkumulierte Fehlermeldung zur Folge.
#### Startseite
![Hauptseite](img/Hauptseite.png "Startseite")
#### Übersichtsseite Dozenten
Die Übersichtsseite Dozenten ist die Startseite des Dozenten, die der Dozent nach der Anmeldung /F01/ erreicht.
![Hauptseite](img/Hauptseite_Dozent.png "Hauptseite Dozent")
#### Übersichtsseite Verwaltung
Die Übersichtsseite Verwaltung ist die Startseite der Verwaltung, die die Verwaltung nach der Anmeldung /F01/ erreicht.
![Hauptseite](img/Hauptseite_Verwaltung.png "Hauptseite Dozent")
### Bildschirmlayout
Das Frontend wird mithilfe der JavaScript Bibliothek React erstellt und das Design wird mithilfe der MIT-lizensierten Designbibliothek Material-UI realisiert. Die Anwendung ist für Mobilegeräte optimiert und wird nach den Prinzipien des responsiven Designs entwickelt.
> Ausnahme sind die Administrationsfunktionen
<div class="page"/>
## Testfälle
1. Der Login funktioniert und erlaubt nur Zugriff auf autorisierte Bereiche und Ansichten.
2. Anonyme Nutzer können Anträge stellen, diese gehen in der Datenbank ein.
3. Die Verwaltung kann Anträge verarbeiten und daraus Kurse erstellen.
* Der Antragsteller wird über die Verarbeitung informiert.
4. Die Übersichtsseiten zeigen korrekte Informationen an.

BIN
_Dokumente/Ausgearbeitete Dokumente/Pflichtenheft.pdf

Binary file not shown.

11
_Dokumente/Ausgearbeitete Dokumente/Rollenverteilung.md

@ -0,0 +1,11 @@
# Rollenverteilung
* Teamleitung ( Levin, Alexej )
* Aufgbenverteilung
* Kommuniktion Organisieren (intern und mit Kunden)
* Probleme lösen (intern und extern)
* Übernimmt Controlling Aufgaben
* Prozessbeobachtung ( Tobi )
* Diverse Geschehen beobachten und chronologisch dokumentieren
* Entwickler ( alle )
* Entwicklung

15
_Dokumente/Ausgearbeitete Dokumente/Wasserfalldiagramm.md

@ -0,0 +1,15 @@
## Analyse
1. Ist-Analyse
2. Soll-Konzept
1. Pflichtenheft
## DV Konzept (Datenverarbeitungskonzept)
* UML, ERD, Testfallkatalog, Struktogramm
## Implementierung
* Kommentierter Code
## Testen
* Vom Testfallkatalog
## Abnahme

BIN
_Dokumente/Ausgearbeitete Dokumente/Zeitplan.jpg

Binary file not shown.

After

Width:  |  Height:  |  Size: 535 KiB

BIN
_Dokumente/Ausgearbeitete Dokumente/img/Hauptseite.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

BIN
_Dokumente/Ausgearbeitete Dokumente/img/Hauptseite_Dozent.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.2 KiB

BIN
_Dokumente/Ausgearbeitete Dokumente/img/Hauptseite_Verwaltung.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

21
_Dokumente/Protokolle/2019-05-08_Protokoll.md

@ -0,0 +1,21 @@
# 2019-05-08 Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Rollenverteilung
* Kommunikationsplan besprechen
* Was ist unser erstes Todo
* Brainstroming
* Fragenkatalog erstellen
## Ergebnisse
* Im Vorlauf wurde ein Projektportfolio auf GitLab eingerichtet
* Ein Rollenplan wurde erstellt
* Der KP wurde besprochen
* Erstes ToDo ist: MindMap erstellen
## Resultierende Aufgaben
* Keine

44
_Dokumente/Protokolle/2019-05-15_Protokoll.md

@ -0,0 +1,44 @@
# 2019-05-15 Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Papierprototyp
* Pflichtenheft
* ER-Diagram
* Endpoints für Kommunikation zwischen FE und BE
* Fragenkatalog erstellen
* Verwendete Techniken
* Programmiersprachen
* Frameworks
* Docker
* Datenbank
## Ergebnisse
* Verwendete Techniken
* Frontend
* UI Library "React" (Version 16.8.6)
* Designvorlage "Material UI" (Version 3)
* Backend
* C# mit ASP.NET Core WebAPI (Version 2.1)
* EntityFrameworkCore (Version 6)
* SQLite Datenbank für EntityFrameworkCore (Version 2.1)
* Infrastruktur
* Docker (Version 18.09.6)
* Codeverwaltung Gitlab (Gitlab Cloud)
### Fragenkatalog
|Frage|Antwort|
|-|-|
|Öffnungszeiten||
|Arbeitszeiten||
|Donzenten anlegen||
|Benutzerrollen|Admin, Büro, Schüler|
## Resultierende Aufgaben
|Aufgabe|Verantwortlicher|Erledigt|
|-|-|-|
|Papierprototyp erstellen und im nächsten Metting weiter besprechen|Kai, Levin|X|
|Erstellung ER-Diagram und im nächsten Meeting weiter besprechen|Alexej, Tobias|X|
|Erstellung Pflichtenheft und Definition der Endpoints nach Besprechung von Papierprototyp und ER-Diagram|Alle|X|

18
_Dokumente/Protokolle/2019-05-22_Protokoll.md

@ -0,0 +1,18 @@
# 2019-05-22 Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Papierprototyp
* ER-Diagramm
* Pflichtenheft
* Laufzettel
## Ergebnisse
* Papierprototyp und ER-Diagramm besprochen und angepasst
* Laufzettel: Abnahme von Kommunikationsplan und Papierprototyp
## Resultierende Aufgaben
Keine

21
_Dokumente/Protokolle/2019-05-29_Protokoll.md

@ -0,0 +1,21 @@
# 2019-05-29 Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Planung Pflichtenheft
* Planung Projektsturkturplan inkl. Zeitplan
* Laufzettel
* Abnahme von ERD
## Ergebnisse
* Laufzettel: Abnahme von ERD, MindMap und Fragenkatalog
## Resultierende Aufgaben
|Aufgabe|Verantwortlicher|Erledigt|
|-|-|-|
|Erstellung Pflichtenheft|Kai, Levin|X|
|Erstellung Projektstrukturplan inkl. Zeitplan|Alexej, Tobi|X|
|Erstellung div. Diagramme|Alexej, Tobi|X|

24
_Dokumente/Protokolle/2019-06-05_Protokoll.md

@ -0,0 +1,24 @@
# 2019-06-05 Protokoll
_Teilnehmer: Levin Faber, ~~Alexej Komnik~~, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Projektstrukturplan und Zeitplan
* Erstellung Datenbankschema
* Status Pflichtenheft
* Nächste TODOs
* Vorbereitung Präsentation
* Pipelines erstellen
* Authentifizierung der Benutzer
* Laufzettel
## Ergebnisse
* Pflichtenheft erste Version fast vollständig
## Resultierende Aufgaben
|Aufgabe|Verantwortlicher|Erledigt|
|-|-|-|
|Erstellung Datenbankschema|Tobi|X|
|Vorbereitung Präsensation (Basislayout und Inhaltsgliederung)|Kai||

28
_Dokumente/Protokolle/2019-06-12_Protokoll.md

@ -0,0 +1,28 @@
# 2019-06-12 Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Projektstrukturplan und Zeitplan
* Pflichtenheft
* Abgabe Use-Case-Diagramm
* Endpoints
* Enthaltene Funktionen im Prototyp?
## Ergebnisse
* Pflichtenheft ist abgegeben
* PSP vervollständigt und abgenommen
* Prototyp (enthaltene Funktionen)
* Login
* Antragsgformular
* Wochenübersicht für Dozenten (Dozenten)
* Kurse erstellen/bestätigen (Verwaltung)
* Endpoints kontrolliert
* Use-Case-Diagramm abgegeben
## Resultierende Aufgaben
|Aufgabe|Verantwortlicher|Erledigt|
|Pflichtenheft|Levin|Ja|
|Zeitplan|Alexej|X|

17
_Dokumente/Protokolle/2019-06-19_Protokoll.md

@ -0,0 +1,17 @@
# 2019-06-19 Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Prototyp vorantreiben
* Zeitplan
* Präsentation
## Ergebnisse
* Abschließende Vorgangsliste für Zeitplan
* Weitere Implementation Prototyp (Authentifizierung)
## Resultierende Aufgaben
Keine

15
_Dokumente/Protokolle/Protokoll_Template.md

@ -0,0 +1,15 @@
# 2019-xx-xx Protokoll
_Teilnehmer: Levin Faber, Alexej Komnik, Tobias Schiffarth, Kai Senkowski_
_Ort: Schule_
## Agenda
* Punkt 1
## Ergebnisse
* Punkt 1
## Resultierende Aufgaben
|Aufgabe|Verantwortlicher|Erledigt|
|-|-|-|

3
package-lock.json generated

@ -0,0 +1,3 @@
{
"lockfileVersion": 1
}
Loading…
Cancel
Save