From 09324a9513d7df45864b00585133b80bb6bc9fc8 Mon Sep 17 00:00:00 2001 From: Hermes Agent Date: Wed, 20 May 2026 16:36:18 +0200 Subject: [PATCH] Clean: remove old custom PHP API from www/fahrschultermin.de --- .../Controllers/AppointmentsController.php | 193 ------- .../app/Http/Controllers/AuthController.php | 49 -- .../Http/Controllers/BootstrapController.php | 76 --- .../Controllers/InstructorsController.php | 33 -- .../Controllers/ReferenceDataController.php | 90 --- .../Http/Controllers/StudentsController.php | 78 --- .../Http/Controllers/TenantsController.php | 40 -- .../app/Http/Controllers/UsersController.php | 51 -- .../Repositories/AppointmentRepository.php | 292 ---------- .../AppointmentRequestRepository.php | 104 ---- .../app/Repositories/BaseRepository.php | 28 - .../InstructorAvailabilityRepository.php | 65 --- .../InstructorBreakRuleRepository.php | 96 ---- .../InstructorHomeToTenantRepository.php | 56 -- .../app/Repositories/InstructorRepository.php | 119 ---- .../InstructorTenantRepository.php | 70 --- .../InstructorTravelTimeRepository.php | 66 --- .../InstructorVacationRepository.php | 54 -- .../PrivateAppointmentRepository.php | 56 -- .../Repositories/ReferenceDataRepository.php | 515 ----------------- .../app/Repositories/StudentRepository.php | 294 ---------- .../Repositories/StudentTenantRepository.php | 77 --- .../TenantRegistrationCodeRepository.php | 57 -- .../app/Repositories/TenantRepository.php | 86 --- .../app/Repositories/UserRepository.php | 112 ---- .../app/Services/CalendarService.php | 93 ---- .../app/Services/HolidayService.php | 109 ---- .../app/Services/RequirementService.php | 56 -- .../app/Services/SunTimesService.php | 55 -- www/fahrschultermin.de/app/Support/Auth.php | 42 -- .../app/Support/Database.php | 66 --- .../app/Support/Request.php | 40 -- .../app/Support/Response.php | 22 - www/fahrschultermin.de/app/Support/Router.php | 63 --- www/fahrschultermin.de/app/bootstrap.php | 44 -- www/fahrschultermin.de/bin/migrate.php | 27 - www/fahrschultermin.de/bin/seed.php | 208 ------- www/fahrschultermin.de/config/app.php | 38 -- .../database/import_pgsql.sql | 518 ------------------ .../database/migrations/001_initial.sql | 145 ----- .../migrations/002_instructors_user_link.sql | 1 - .../003_backfill_instructor_user_links.sql | 11 - .../004_lesson_type_template_visibility.sql | 13 - .../migrations/005_tenant_location_sun.sql | 3 - .../migrations/006_tenant_federal_state.sql | 1 - .../007_student_prior_completed_units.sql | 1 - .../migrations/008_lesson_type_system_key.sql | 2 - .../009_requirement_phase_labels.sql | 2 - .../database/migrations/010_student_email.sql | 1 - .../migrations/010_students_contact_flags.sql | 2 - .../migrations/011_student_needs_glasses.sql | 1 - .../012_split_combination_templates.sql | 183 ------- .../013_combo_generic_key_cleanup.sql | 42 -- ...tudent_key_aliases_to_lesson_type_keys.sql | 170 ------ .../015_instructor_pre_start_buffer.sql | 1 - ..._type_allows_student_and_notes_private.sql | 22 - .../016_consolidate_lesson_types.sql | 39 -- .../migrations/017_student_booking_schema.sql | 202 ------- .../database/schema_pgsql.sql | 166 ------ .../storage/database/app.sqlite | Bin 126976 -> 0 bytes .../database/app.sqlite.bak-20260422203538 | 0 .../app.sqlite.bak-users-20260422204004 | Bin 73728 -> 0 bytes .../sess_0006a50819ddb4c83f8927e073726008 | 0 .../sess_00309f86663d537153fcb66685d86df7 | 0 .../sess_00409744a4c7e3bb92d2eb4076f6f9f1 | 0 .../sess_004433bebe95f3233eb3afeacee557d2 | 0 .../sess_01276da25030fe7610e51db01928f92e | 0 .../sess_013cba357db97c86d9affd6f490425d2 | 0 .../sess_01db5cc5dc2af4df786929887036129e | 0 .../sess_025b3db5cdc9307a49bbc4e7c8569322 | 0 .../sess_02ce241714378b298d820865b9f207fa | 0 .../sess_0302bb8051aea505d498b8118cf07cbc | 0 .../sess_033690960537713e4b7584067e851174 | 0 .../sess_0387d0c9c23e92d7c5da1f59219d140a | 0 .../sess_03ab912d95e7096bd5041a815feaaac6 | 0 .../sess_03bec560a62e6282f3c00ee39e0b5185 | 0 .../sess_03f80785c72e82de6dbb20e633f8e70b | 0 .../sess_04921a0b3787740b88c11ab3b2b4d4dc | 0 .../sess_04ba107751852addceb705f95cb01636 | 0 .../sess_04e7eeca7ab45efc4714e55d0e488aab | 0 .../sess_04ec6601cf72642f743fb0ad41d466b8 | 0 .../sess_0521642416caa2fbc62e3f8298109cf1 | 0 .../sess_052b45081be50758c250257b9a65d04a | 0 .../sess_05fa0356f494ca589061fb1f1cda9f38 | 0 .../sess_05fc405f00dd93a93a4e02d048ecfdef | 0 .../sess_05fe8c42f2d6ce2eb298f3773fe7aa46 | 0 .../sess_06322d63f2b61ed856911309f0491b02 | 0 .../sess_068031028f6af11d6206ba4e176e106f | 0 .../sess_06b2450149fb978337c3b300c5177c89 | 0 .../sess_06d7f7359a7c55810206e5722284344a | 0 .../sess_076f1f9b3f3607d85628e676aa3deeef | 0 .../sess_0781485879098048ec9ec26f838e230b | 0 .../sess_0854ff9e45ba1f5477fbbad5e54698f3 | 0 .../sess_087a67b3949d5d39a90f231048dbc168 | 0 .../sess_09013b1da99e4f816a92e860b645e65b | 1 - .../sess_0979ad1bce9bd29c7f78266fb0db9496 | 0 .../sess_09a34f83873ab7845a54ad0e1f123da2 | 0 .../sess_0a1062c7493039579c5b1ccf819017cf | 0 .../sess_0a3a77bb3b296f6ef7c2c58f223522dc | 0 .../sess_0a457d212ce74a302f1245eaadd68550 | 0 .../sess_0a8407b10f0705fb94abc083ef7629a1 | 0 .../sess_0a918e1bf4f81d888710bb6eabccf5b7 | 0 .../sess_0b02235f6c9d7a8fdd13403950def66a | 0 .../sess_0b4c3e7eeb7915687615efbcb7ad351a | 0 .../sess_0b689f1efcd64909309b788ce0aa77a8 | 0 .../sess_0b7a6dd656b413dfa91158a8f36533fe | 0 .../sess_0bee18c4dceb5b1916bfb6d16f940237 | 1 - .../sess_0c6b2d92ad51dc235c8a326a6f15bbde | 0 .../sess_0cc19484bb603a199b713e1506f53ba0 | 0 .../sess_0cf9ec95094969104196ac2547eb3cc5 | 0 .../sess_0d444063fde0f76a4a254962ecc24900 | 0 .../sess_0d674f078cb072a267fab787102b842c | 0 .../sess_0dca6c782e6359327b87294c5be46f45 | 0 .../sess_0df4eb5e781f33fdf8978650b309cd49 | 0 .../sess_0e04def9d162ce239e6947e6321ae8ee | 0 .../sess_0e42f0bcb89c3342f5fd4f7440391e29 | 0 .../sess_0e5c1480078e1d9b5f84eba3b40bb77e | 0 .../sess_0e60def1012c7eb8dcd4e9c711f82bd1 | 0 .../sess_0e98d5ac2834ebc5bf78d2d5f0c91fea | 0 .../sess_0e9b111cebcfc845371544ee02e6ba44 | 0 .../sess_0f07e83c587cd6ba9d4374bad4a0e050 | 1 - .../sess_0f1d85f511393a35984d6532feb1861d | 0 .../sess_0f20d94dbfd397db961146e58523b752 | 0 .../sess_0f2589aadc148fbb95ddae15307b2ea9 | 0 .../sess_0fb288edf359a988efacf668fabed004 | 0 .../sess_0ff28449277d7fe69998599d5c19d934 | 0 .../sess_10009006bdabf68eb0fab5eb37ca2fe3 | 0 .../sess_110b899ae4b4a0c037123345c4e49d27 | 0 .../sess_117db80a15a6ba699f9678b99a1d9de7 | 0 .../sess_1202777c449219fd2aac7b5ffb07de17 | 0 .../sess_1247d7fb0d48d3e756c4dffbc1270e2a | 0 .../sess_124be71b45653d1b3f57538d487fa105 | 0 .../sess_125bf65956128d9a6750548f818c3348 | 0 .../sess_128a4fda8650abb78800f45754ad48be | 0 .../sess_12a821bed8de2d9944c9f8796684d638 | 0 .../sess_14624d98ed0c363b2a095334c7a924c4 | 0 .../sess_14b57fe7649feaf9706aea2773911e8a | 0 .../sess_1506f280114920a5be86dc1437738d5d | 0 .../sess_15ff36ba1e9ccbb86875e7ffe82f935f | 0 .../sess_165fb060e3ebc3fc704b851ac1d01598 | 0 .../sess_16732beb713293cfc64b4a62d20e5cf0 | 0 .../sess_16ef8072fdc04f0357bc1654ccd9b88b | 0 .../sess_16f69df80eee2cd72267465123374bed | 0 .../sess_176074fcad8595788ae0cdc97b974c18 | 0 .../sess_176897c620d6f055c1dbcb598905cc3b | 0 .../sess_1779168ab91c36713aafe5bf02bcc109 | 0 .../sess_1790c58801f9b2487b8c093cc82be8e9 | 0 .../sess_17a0585e95ccd9c51a580839630dc92b | 0 .../sess_180e9fa06a637da36cb1f76f4d0ccb9a | 0 .../sess_18c8679e062e0a332aca916fe40c6859 | 0 .../sess_18e0ea982f318fbb1005dfcda8a8bdf1 | 0 .../sess_192aef27a1fce8903cf7d28379fa497c | 0 .../sess_192bccfcedba055ff11758985c9485f7 | 0 .../sess_194c7cd0b03e84efe00b5484ca2d8aac | 0 .../sess_1950a2ef1291ec9df468535c6b0fc191 | 0 .../sess_19770a921c71cfc42485c3ac4615611b | 0 .../sess_19c0d2d4a229fd60d2099992ea8690a0 | 1 - .../sess_19fa167361a1d43b543976961054333c | 0 .../sess_1a912668b674f48b5ffc7de9e824aa5e | 0 .../sess_1aee1ec32f6fc52fcde579475a6fdf90 | 0 .../sess_1af06631c6a9c42ffe0961f03c21c73b | 0 .../sess_1b62f79b6a161a44066e889fb5890864 | 0 .../sess_1bc34aea1212c788f139097c26f6a232 | 0 .../sess_1bd8426e10991ec9c1856c793196522a | 0 .../sess_1c19ba48c4d66fb010544f9777b0b4f7 | 0 .../sess_1c1eb9653903a3f2ca0cd68b2e2a31c8 | 0 .../sess_1c1f7b1efd31a1165e99abede59cbc0a | 0 .../sess_1c8fd85f2d4fa6c41130f08f87b3068d | 0 .../sess_1daa8c750fa07697f55057eba9f07208 | 0 .../sess_1dfacd171678bbfd3713e55ee6e1c0b0 | 0 .../sess_1e0fe014daf164ddf58fba633fb433ad | 0 .../sess_1e19408096523f324050696e40e78c2c | 0 .../sess_1e3b112ac09b1917473e8d5d1f050a13 | 0 .../sess_1e3fa8cca3f53f006f75140261d3a5d5 | 0 .../sess_1e4606b18533461a9fcd557a11b1339d | 0 .../sess_1e576ef7adf606c5bdcb7341f2dfc7ee | 0 .../sess_1e607b0b5e8b9b44045b78c038ebd342 | 0 .../sess_1e752925b000debefcf8e1b6f462bfc2 | 0 .../sess_1ec360e5d18fce3b53084f54c50523f6 | 0 .../sess_1f3d92dbc703b68c7e795e5f51c1dc19 | 0 .../sess_1f6c34e49bd50f27424f86a2c7f0b2a2 | 0 .../sess_1fb01a63321004f84edde1c2f01b9660 | 0 .../sess_1fb1ae525d180aa6cb59e558984c2072 | 0 .../sess_2041982bc34bf965174b00a51558b7e0 | 0 .../sess_2043674c95a6ab2d3f71332b76dda4ce | 0 .../sess_204d8a56472208a59a1aa70ab737fe89 | 0 .../sess_2123c53e3d0044bd7f2e5cef59a41837 | 0 .../sess_21b513631be5e9c0dfd1b2d517f84398 | 0 .../sess_21d59f9f57be2f40d95c6857ba79b486 | 0 .../sess_21e0c4efd285609f6d2a1f54f58971ff | 1 - .../sess_220bdce3ff2cfd02d7e5fd4851774fdb | 0 .../sess_2230676d13498deef61f7ed59dcdeca3 | 0 .../sess_2292fab487ebf06df95e0036beac57f1 | 0 .../sess_22a4e3c7055808fd4c5a2963e52ffa36 | 0 .../sess_22af559095a190687e0d544b8eee6644 | 0 .../sess_22d9645a0764cd276e1010062ce58708 | 0 .../sess_22f0a00861d4da216089fde3b14fe2ef | 0 .../sess_23a4409db0925d7a59ad29e42bc4884f | 0 .../sess_24390c9968cd8821cd7bc5f2aca39df9 | 0 .../sess_2456d2263cd6a8256041d4b3c89ff307 | 0 .../sess_2470d1af939f31518959c76496aa7a6d | 0 .../sess_248cfaa4e75cbdb490cfe8dce5aeaedc | 0 .../sess_24a867c9d2c15b255232a9d8e1e84f38 | 0 .../sess_24e2550cf6651e9d8a37e82da464ce5d | 0 .../sess_2503f4a5cbae9324cbf3b95b5b97df27 | 0 .../sess_254c55b9ab44a7e81392a361205f9608 | 0 .../sess_255b248494b7bc41838d5e03d8c63f2a | 0 .../sess_2576dfcf73df11914c84eea9030362ee | 0 .../sess_258ba55b7396886da889d6c57b622370 | 0 .../sess_258d74a6647426ebba4ce0f0a0c67c66 | 0 .../sess_25bc952c7944ac5478e505b7d07617b8 | 0 .../sess_25bfb2e99746cac127855aca7dd51a66 | 0 .../sess_2619421cbb71439a217328646badf18b | 0 .../sess_264744b8536d1f0a4942fd4884126ad1 | 0 .../sess_26475586b26e819cbe7ed6b7c91f4353 | 0 .../sess_26817db6139724550add44986d13955b | 0 .../sess_2694eee41fc1488b7bb8cade34db7095 | 0 .../sess_271efa4ff2d546b1e0a65b6f3ddaf929 | 0 .../sess_272592a07264fcde1b184f03d1b63a3d | 0 .../sess_279218f8e2c26131e4ca39dbe14eb7fe | 0 .../sess_27dd196fe7ad686655daf28dbc6ebd34 | 0 .../sess_28136e39aa3fb81f6ea47823e5cff14e | 0 .../sess_2878c22f67e22d014964d1bc29fc80d2 | 0 .../sess_2941e7e905f15d5da543295c53736cb2 | 0 .../sess_2960b8132f30396e838b0ebdbb96dcaf | 0 .../sess_29a45c491f6998a47aa0b0f66fd83f3a | 0 .../sess_29ccade580d9dad87ac1a35ff275d2d0 | 0 .../sess_2a16d5f4beece112f2e67a4bcb781a07 | 0 .../sess_2a64bf1990c00f2b2bc1836c1b96fd2f | 0 .../sess_2ae5a56ff11d55dbcf879524b71f88c9 | 0 .../sess_2b67b6a92be7fcd363c23a7e494057dc | 0 .../sess_2c5719342be78ab42c03ddf812474077 | 0 .../sess_2ce24f0bd9ec5909e465b42fa8d33670 | 0 .../sess_2d1c750f56256eb9ba589168d9b17b65 | 0 .../sess_2d1cba190840b33e6d54f9befd89ae52 | 1 - .../sess_2eb1f32411558996d87b5d8567dcd94a | 0 .../sess_2f4233260393ed2a31e00ac9e2969636 | 0 .../sess_2f52d9fd84045a93ce4bb3a5be6a31e0 | 0 .../sess_2fb5535ba46f2edcc64f6b7c581b9c7f | 0 .../sess_2fb9f36e4449aa120905dde208f60510 | 0 .../sess_2fe3e2083c13b197a53c094156873f5e | 0 .../sess_309ebde30dd24884b70bd8df07279749 | 0 .../sess_311959d4bc3d190ae2499291e9b42220 | 0 .../sess_31210c92118f237f856a58f569a84141 | 0 .../sess_3160a2a2b74ee599bee5f62ac40e1591 | 0 .../sess_31eaca9ab96ee1d5a814bf3202eb3c22 | 0 .../sess_3211e64538a844841fd3167dd09dbef7 | 0 .../sess_3212a8af9dd17c466ab8ea91052c3cc4 | 0 .../sess_32932fd7d38fd6c8279e60d44e48e922 | 0 .../sess_32c66a45bdf19b9f50de688ea047e696 | 0 .../sess_334e686c0876c391c42fb587b3bfa976 | 0 .../sess_338deba0ad100d079f68ea413a6e3048 | 0 .../sess_345384363d30f764d4244e131c21d36d | 0 .../sess_354431ef347b5ba5cfcc7273061da04e | 0 .../sess_35a3681412ab8e77fc498a7699733368 | 0 .../sess_35abdcd2565ba6cebc1d5323c51976ce | 0 .../sess_36323cbf08bff404511acc133ecddf9b | 0 .../sess_3689a40959fc96cd6f3c50abc1203ff7 | 0 .../sess_37282ed122e7b4eaaff47a3883309651 | 0 .../sess_379e5c9dcce57030269caa935f44b608 | 0 .../sess_382329b5050c26c18ecedab29e115c9e | 0 .../sess_386bd2888cf16751430e80917a8f85fd | 0 .../sess_387a266ab74eed24c6346816390f7769 | 0 .../sess_38f8f88f7abb27ac17d9375a5a4cba31 | 0 .../sess_3bcfeced08df9ceb2af9241e3e4204e5 | 0 .../sess_3c6086415f4fcb8af3e7af3207b96d8f | 0 .../sess_3c6c3f9430ffcd8fda0687736ec2d718 | 0 .../sess_3c7b2b014f20046f58b831fd0ad34c9f | 0 .../sess_3d6993df0f462c4ffff7556ec530e435 | 0 .../sess_3da2ba55a8c5d696a5814b42dc0b2e14 | 0 .../sess_3db0a0533c6ffd6078c55906988a594b | 0 .../sess_3dd3b5c1c41191d551256202b307b743 | 0 .../sess_3df20e7c93a01e37ead25a82abcfa7d8 | 0 .../sess_3e081a2d79c698f00a94dff6db2e962f | 0 .../sess_3e0baa6f9f93aef56b4c28cbe7f0892a | 0 .../sess_3e34570e03450813b46f65a5332d9c1e | 0 .../sess_3eba8aa5bdff2f16073b6b03a879f828 | 0 .../sess_3f4d92dfc22756dc3491753c3710d58d | 0 .../sess_3f5d80074117dcf2345eb24489088752 | 0 .../sess_3f7f9ebea56914012835d097cf04ca92 | 0 .../sess_3fae57c4628e0e6de8700f2aefb0b86a | 0 .../sess_3fde18821c79b139e6cb19e20b72a0d0 | 0 .../sess_407b46f6532a47e17ec5babe6c30bc4f | 0 .../sess_409dcbc73298f3e020b7c60a3432fde7 | 0 .../sess_40f2a96e744926f0865a52dcbac9a160 | 0 .../sess_412a5eb5d0597f918c0bb9bab03b2faf | 0 .../sess_413faf6f188d744d9522dd2fcf41495f | 0 .../sess_415f109c0c4fe4d2a1d4979ad5d9bb24 | 0 .../sess_4181fda8edd2d12b37f109fad33ac6a7 | 0 .../sess_420cdf45b5c2330160d506a70eadb33c | 0 .../sess_4247a0c7906fc90ae18a64adaf1aee2c | 0 .../sess_4254feb9a5b1a5b349f5dc3556d1a201 | 0 .../sess_4338f754256fd9a05ffce8620f13f07b | 0 .../sess_4368d3d721b713fe8f89cfbb6e1005dd | 0 .../sess_44b7c1306ee68cfa7a89fbc4e043209a | 0 .../sess_456a3e7bbad68012698a87d1072c1b38 | 0 .../sess_4587b7a5e1e5ef217166c56763ce423f | 0 .../sess_45a98e9ab472b14179dd14db5f14bbff | 0 .../sess_469e07211c9f0f2764b6d7a2c851ee46 | 0 .../sess_46e2408207b1c95658fb7b626ee6958e | 0 .../sess_46e8ebf399968a345980d5a95e8c06ff | 0 .../sess_47b05bb74c2af2828b06cbf5e3ff8477 | 0 .../sess_47bf2f6a7024254fa8971c7a85b0910d | 0 .../sess_4853a954dcf6e2ad4cfa31535490e110 | 0 .../sess_497ce6e38a9c5c1015e856f7589548ad | 0 .../sess_49a86631804a0d6da2aee719475f739a | 0 .../sess_49c66d8f15ac3c3053c8534b28fd2ef0 | 0 .../sess_4a45962e93cea2ed73e1665936bc73a3 | 0 .../sess_4a6501b0989d99b4dab93189ce30fad6 | 0 .../sess_4a8e405b702f60027e17800b0a9ef45b | 0 .../sess_4c9a1aaceaab78fddc55765178473d79 | 0 .../sess_4caafb58e3487c63db3e767199e558f2 | 0 .../sess_4ce44d9d6463335e836ae3de308d4b34 | 0 .../sess_4cfbbd26846fb01c6f9d339c557b03c8 | 0 .../sess_4d29d6096a285987a2b2e625068ff5ed | 0 .../sess_4d7c6193ca1cb655e8d82dfe9c6c7eb4 | 0 .../sess_4e38e1eb4f49de672fed6ed540681642 | 0 .../sess_4e71c4ae079c79d06b3b4199b37c8d6e | 0 .../sess_4e8ab1cc7be41320be57403a5764d80a | 0 .../sess_4f3604d0593e4bad5b3c1a2ee7fbcbe0 | 0 .../sess_4f758a3b77fb168967f90b28555033d0 | 0 .../sess_4f9fd9991f5f3d30dc0ac97c372b731c | 0 .../sess_4fb189b01ba2f06e00ef5f9b5a7f23da | 0 .../sess_4fbfeca9a5fb8855a221e690ef502b38 | 0 .../sess_4fc591afe53506325ffb61b8bb9c88fb | 0 .../sess_4fc8717e82c041e7287a910c435a73fd | 0 .../sess_509426117c6882aa1596380c7cf47a87 | 0 .../sess_50f11f6d3fd52e9b97404943e55c90cc | 0 .../sess_5104ac2b3efed41e0167e8ac230efad4 | 0 .../sess_510691ebd56ac6658a8f0d05def56656 | 0 .../sess_519f45ae9f86f930f3abdcb63300057f | 0 .../sess_51e0aff602241718c4b8416f452b580b | 0 .../sess_51e0b1db7e62b4fdcdd8306d0c23943d | 0 .../sess_5283908e9b80eb47d1f52f4d4400605d | 0 .../sess_5294cb940dc83bcbd4bf57b17a00ba3f | 0 .../sess_5341c2fcecad979f5311ceac1bd28718 | 0 .../sess_53926f2b0c401a2668cdb0ee55739e71 | 0 .../sess_54e9093941ef282786b14c14e94470eb | 0 .../sess_54f3fb06c0aca2a55c2dd5ec4d25512c | 0 .../sess_55398030f9196b2640c7bad95056c2a5 | 0 .../sess_55b079046d294c1c69f287fd4337d04b | 0 .../sess_55e94cdd1ed910c96f22fc4e1f73c0bd | 1 - .../sess_56355cbfc04402cf36d92f821bae5090 | 0 .../sess_564322bb4ff156306233922d7d4fb345 | 0 .../sess_574d1c7a48adf43155170876b326b4aa | 0 .../sess_57744595846324be63e78c3aa28a4f33 | 0 .../sess_5775e29dec1dea074f4fc9c32fa3a34b | 0 .../sess_57e47e62da11c1399a779afd1e78b75e | 0 .../sess_583371d8396ad02e05cf1ed99be48719 | 0 .../sess_587bf41af67b4725cf167a5652622640 | 0 .../sess_5971640cd75544c110ed69c8b2704b38 | 0 .../sess_59d0ba86b7085a23b070b559be815e6d | 0 .../sess_59d76f244bb8bfebfc4b923adbc15419 | 0 .../sess_59df6b8eff37a8f46f806ef70d53862d | 0 .../sess_5a4ae2edb0253f99e7e0d768060c5e83 | 0 .../sess_5afc92d91483488a5e2756611359c02a | 0 .../sess_5b9ebb48cacc40324a7627ed5cd03ea3 | 0 .../sess_5baa5d3d23563e43afa7446486dd72f8 | 0 .../sess_5c0025a4a3bc7edc09d828efe2b28cac | 0 .../sess_5c0f0b21134060b451e12ef30081f540 | 0 .../sess_5c2d18b62ab5f4e62bf93bf01d6a8abc | 0 .../sess_5c49211f43aa46d12999628ab1a4bd28 | 0 .../sess_5c572f6972ef0bbc0fdb158726375a0f | 0 .../sess_5d5cd460d1d5835451d781e05c3adf89 | 0 .../sess_5da65e8529c7df8023ed18faa35d5a9d | 0 .../sess_5e286521edc4303f85116330fe10e8a7 | 0 .../sess_5e7a74bf5069e74d295e89a325872261 | 0 .../sess_5eaa995db9fb15a416a357e533b6b131 | 0 .../sess_5ecbe991d413b362c14567f1f073f4cd | 0 .../sess_60668ea8e3890507478e420a56ddbd5f | 0 .../sess_6143815503ebf3f82c544d21c1b7ad5b | 0 .../sess_61b414feb765617dd3fb38f7eceffcfe | 0 .../sess_61d6228ae940365ff8bbd93a87303a02 | 0 .../sess_61e9d1453030accdf287a54e918ee927 | 0 .../sess_61f558ea9155fbeba01a42a2931d7b7f | 0 .../sess_621511f8d7c30ebc5aa01ce455b8ebaf | 0 .../sess_621ef44ae59c047ff712c18d050011e5 | 0 .../sess_6299dfcc8ce40cafed3a335a341a6336 | 0 .../sess_629f9dd62d1204aba62dfefe65fb0d74 | 0 .../sess_62b5d304a31805cce616357f0e59a9f2 | 0 .../sess_63a233987c509e08fae79917349f9bb3 | 0 .../sess_63e9364f0c944608a17504f9b91784b3 | 0 .../sess_63e9c9819a2de781d792f1d2a60851ba | 0 .../sess_6477fc14a025865e68f2dea333bebea8 | 0 .../sess_64ff70ad1229278f497281f0214ccef0 | 0 .../sess_65468453a39a8a4dfaa1082215ca9836 | 0 .../sess_65b339d0b1ab7066ca6b44ecd8facc40 | 0 .../sess_666d42c52b9ccca9698401d63202cbbf | 0 .../sess_66f307a1423bb488cc26a24cc5c4a42a | 0 .../sess_6719a214f44edb74418e6e890bf5ac08 | 0 .../sess_676be8f36a7e54aa1863917c871eb567 | 0 .../sess_6779e0e89629bc58388284b76bd76192 | 0 .../sess_67c0a94fd2af88c6fe4e5fcd34036c36 | 0 .../sess_67d11c2d90f54a43e96d16bf3c7c45ce | 0 .../sess_685d40735c321a9ffb35d557798cb1b5 | 0 .../sess_686f0c41b1eaaa6c33131bff43058b77 | 0 .../sess_68be2f0cedefb60f859f4c4d9c2a880f | 0 .../sess_6908fafa1345473eb21f5cb9dcb153e6 | 0 .../sess_692cbc36b4318bfe850fc4aede3832db | 0 .../sess_6972dfd4b41c386eeb36cb9140582224 | 0 .../sess_69c6be375919a05a7948264c4db4e9dc | 0 .../sess_69dea144c3340502072b895a59b41b24 | 1 - .../sess_6a4b12a9d81b4f56fdab7814f88b59bd | 0 .../sess_6adef316d6f11d1cfcb4765ee289aa95 | 0 .../sess_6b3dc5917d807ae794a1ed28fc9e99f5 | 0 .../sess_6b45e848464ad9143282b3909897ee8b | 0 .../sess_6b8aea5fa4705e2c8928d1ec20387164 | 0 .../sess_6bf7d9cc4cb88d9fe96dafc8ed1288a9 | 0 .../sess_6c0ab8e461aebf50d0ed2a344176ff8d | 0 .../sess_6c601c0358a1d9724a5252cd756bd64b | 0 .../sess_6c676b2e4c18eff505c1853258b039cc | 0 .../sess_6d894c43c030d8dbe071de186700c5c0 | 0 .../sess_6da8ac394f5fd3b79b6eb9681f810c15 | 0 .../sess_6e5401ff80e23d4dbf547c4a894fc211 | 0 .../sess_6f3a5c611d7a16c43ca25127894ed8f0 | 0 .../sess_6f84b5c8b742313a8b748867bb5dfbc4 | 0 .../sess_6f98287cfdd3ff93e952baba05fd5c31 | 0 .../sess_6fd95d60ca7ff94f3c602ff4753e6a87 | 0 .../sess_700631b2fa80717f2d07a6017d5ff030 | 0 .../sess_700aaf47edb8ff558be85c5bd9ff529e | 0 .../sess_70a66109b64b26d0ac67524166cb72cd | 0 .../sess_70c642898f8f0725b81e4d285eec0787 | 0 .../sess_70ddcec0c3417113fc4c072fa39fe331 | 0 .../sess_70f9c044b76efda9274b32b5ae345d56 | 0 .../sess_7108ed71a1a0054c7ab7c7c2068e8923 | 0 .../sess_71187da2021a77805c96d85b76867d92 | 0 .../sess_712f6993fea7e24e5126734f0aca9a68 | 0 .../sess_71a643c2efaef2d77620f637e5637cf2 | 0 .../sess_71d766001d452c1d949ce85cd327574c | 0 .../sess_720f14d25a4f2ce52fe9d3933e014771 | 0 .../sess_72515b3f3d38bd85e703ef3a80b1bfa9 | 0 .../sess_726860093a0a7908e0e9f66e709ef6b5 | 0 .../sess_72ab8f6fd0fecbe3e0976c623333be7b | 0 .../sess_72d5d6b9df6a55503533e97e340d2311 | 0 .../sess_72d7576d9bfaea5245d54bc6f5ed732a | 0 .../sess_72f0fc1c0ead3468d75f171ff2353eac | 0 .../sess_72f8a1f9caa69b25fa64c6185238c6e7 | 0 .../sess_7316664ff3b366d41d1a0f1d29a21e44 | 0 .../sess_7327bbf8e70879c93cb9fcf18287ef57 | 0 .../sess_73372d764d0b64494a123b95b092e293 | 0 .../sess_73c80e71dcc72c4c3bd422dc2d1c6f22 | 0 .../sess_73fd9c9fd27ea5b4b7e513723fbe0d01 | 1 - .../sess_7401b0da36a0bf586a412bdc32c01932 | 0 .../sess_74169a80690859946b251a7e2789c06f | 0 .../sess_7433d5d741f0c55568cb183264a757d7 | 0 .../sess_755543053755f9827042ecd578a32ce3 | 0 .../sess_757ed514e8bcf21fe484abe2639fd9c8 | 0 .../sess_75ed4967153522837eebaba2104a96bf | 0 .../sess_76036580c2a0124ef45fab001e1b8e85 | 0 .../sess_764eb3d09d7acdadf02a1b1b9e652d38 | 0 .../sess_7751d4611abdb82cdd8307b7db2a94a7 | 0 .../sess_777222d786447c44cba1f61c40722851 | 0 .../sess_78ade15b28ae2ac4544641f92908c944 | 0 .../sess_790eb3970d7871971226a752514c9021 | 0 .../sess_7a39b110e92a44f5cf2cc27318fa8acf | 0 .../sess_7a49c9790485b15f032f1889edfb5e74 | 0 .../sess_7a758afdfa5c19238907ee69e4f1b8e1 | 0 .../sess_7a942e09063d7d053ece5084917a59c6 | 0 .../sess_7adb1835b69eb442280acb1a34e3e4fc | 0 .../sess_7b1b6e128d0bc1b40a30954812f3f2bc | 0 .../sess_7b30a67240cb34b565faab1ee1a43759 | 0 .../sess_7b3b609d4c8713d06961731c28fdfd8e | 0 .../sess_7bb08b912f4e650b85412aefe4225981 | 0 .../sess_7bb50e18de85135463e20f8d52dbd679 | 0 .../sess_7c34f05d08306cd0e725b262006af9c3 | 0 .../sess_7c4815b8c0d9564d5c330dc755b89be4 | 0 .../sess_7c5d6ce984c7f26e83b67c6a785f2919 | 0 .../sess_7cee3f52567d4d995de6c242576e80e6 | 1 - .../sess_7d496df6ac57de8fe4c46d48271fd6b6 | 0 .../sess_7e2cde5aa2397f9c928af07c857d9059 | 0 .../sess_7e394c0ae018145fbf007d66dae56fc1 | 0 .../sess_7e44e9b5e4618ac9c5d5c50156aa9481 | 0 .../sess_7eb154203930535a374d572b26905543 | 0 .../sess_7ebd209f80c9a78715a398ca29339183 | 0 .../sess_7ecdf19414bb4c4fea4ca19850a7a539 | 0 .../sess_7eef0ffbe7eb689711c83038742d15c7 | 0 .../sess_7f11e5dde38e860a69e208aaa622312b | 0 .../sess_7f97b81d9a078302523e924f6cd12861 | 0 .../sess_7faaa1325462a16eb0c09a78eb816c3c | 0 .../sess_7fab50507d10a6d85e79235af15d32d2 | 0 .../sess_802f12cc03180b848c62d75314cea4ad | 0 .../sess_80ddf16c4abf6269af3663c2773029e3 | 0 .../sess_81367cb6c7667b5ce00936f7e4c75ed5 | 0 .../sess_821cee680ccebd68e213681a79f95074 | 0 .../sess_82c9e9a8ca48d231b1a6143016f12161 | 0 .../sess_8390ca0087f926e6dc6acfc1726feac3 | 0 .../sess_83f1a287583b2bc46cd195e1e3b2f943 | 0 .../sess_84323f8c4143d694e44c9fedcb9f9df8 | 0 .../sess_8506d9ad640e8db4c5464ae18b21aeaa | 0 .../sess_854a85d95cf30e598d3dd8071c524182 | 0 .../sess_8556739092f403601805097e7c5515d7 | 0 .../sess_8578f708494846a3ded7c61783b1424d | 0 .../sess_85bde53b19790499e9dd46a1728f2644 | 0 .../sess_8609c314bca4daf7b8d418593296f29d | 1 - .../sess_8631135c2359b355b28b12b251d7cf20 | 0 .../sess_869e70a50cdab0e5dfa7f41decbe164e | 0 .../sess_86b6cee8d0e002bd2cde78c01432c98b | 0 .../sess_87765df5421b4b08ce0285280372e9bd | 0 .../sess_889d219494675742314ef1f2307e5059 | 0 .../sess_88af4a1e93188192b41b898c96537666 | 0 .../sess_88b7f3ed2893c08c3d3a90674de9828f | 0 .../sess_88e7499f47401ce614b4b65ac8356131 | 0 .../sess_891ef4846f2cdff9342aeba0a22d5f98 | 1 - .../sess_892e5cf319f4e18afdb304abb39c54e4 | 0 .../sess_89625043f67d25fa8715915de6bb79c5 | 0 .../sess_89a3b9f54d67342368079a0ac616276e | 0 .../sess_89d0ffe96d3b0ad881121413908b1b83 | 0 .../sess_8a6817782ff0d92875e6235d8ad776fc | 0 .../sess_8aa40af232be8a3ca5282ef5f551afde | 0 .../sess_8ad98e7026500f40515eae94a2fde2ea | 0 .../sess_8b186147e95653d8a3b6c748d2482dcc | 0 .../sess_8b63e5d2df259415a70db075ccaee244 | 0 .../sess_8b8a7cdf7636a6d2aedba08f756d3c8d | 0 .../sess_8b99977c6b9caff09ba87062b2bccadb | 0 .../sess_8c02e46467ce79c739e0a68444178b2b | 0 .../sess_8c6134b631065799b0ec7bee4049c4ab | 0 .../sess_8c7302f6a643e4dee153b7d114ed8783 | 0 .../sess_8c909900d173078a178b390295c8d241 | 0 .../sess_8d2904d8920390de86ee53bd52ff2f95 | 1 - .../sess_8d3b9af6665ae182d39cfecb43e8c67c | 0 .../sess_8d6b378636ae0e195107452f07a9a1b6 | 0 .../sess_8e2e34092cc5092b33f80789bd8cb5dd | 0 .../sess_8eb44802c4c08e84235edd0bf26ac87d | 0 .../sess_8ef6f0dee24d8b4ca5d6d12fc78846d3 | 0 .../sess_8f45c8b37f65f5a3d96d99bbc42afd6a | 0 .../sess_8f59107da2dd4018eaaf396b9d4a5a36 | 0 .../sess_8f7dbcbed4677531f01a98f09b78e579 | 0 .../sess_8fe1ec9a1ace4c1e42a2f556662301f2 | 0 .../sess_9064761135752f81f7ad8b6ebd661023 | 0 .../sess_907c362f4f2f6e400df8ac189f9f1eb1 | 0 .../sess_9087759ac2d7809daa14034e92904b12 | 0 .../sess_90b94e25c780902f5f539c288bfcf537 | 0 .../sess_90ede0d038bcbb6aceea8fbde52f2641 | 0 .../sess_90fe76e7383355fe08eb307219e2d816 | 1 - .../sess_9198bcfeff6d315cf4fafa6370065a03 | 0 .../sess_92c58ef6f3c99152d2ba186841a33c7b | 0 .../sess_92efa0c840cc52c16596b78a5df32412 | 0 .../sess_93f7f0d85f2643a76ef136e26da9e002 | 0 .../sess_945189d26d0ba3469d510a86ca265d85 | 0 .../sess_947481d841466c3a8daac3ad85aa115a | 0 .../sess_947988622ee7c2525e6cd5d894c98ef1 | 0 .../sess_948b86a8e2a1e31167679e4a1470c860 | 0 .../sess_94e7ec5946942ead16448a728abcdc37 | 0 .../sess_953a407fb72605ba0a9a187e23cfe770 | 0 .../sess_959d4c4a242dcfeb97c61a3ea2412504 | 0 .../sess_95f18066efe5fc4f9cc8d0593c8439bd | 0 .../sess_9644fd126a3afc481ee73045a503baa4 | 0 .../sess_967b281af59e4a6dcf1cc1fbc3265a9f | 0 .../sess_975c0b932ae0b2f7e84907a50b8ef1b1 | 0 .../sess_97f50b3d8687d8d47bd563960e1ff455 | 0 .../sess_98892de18bd4ec4aebcc5bee99ab94ac | 0 .../sess_98bf4125aefc7ddc22a20c48a9619989 | 0 .../sess_98d9a575de9d3f13469f22cccc63825b | 0 .../sess_98ea1635d552d9a6892dd0ef71435f1d | 0 .../sess_9959bb4c68666277b4b2c0282a90487f | 0 .../sess_995dec3fc6c2f46d050ebb554f56cd66 | 0 .../sess_99ad47b9cdcc23e23f1e7795dab1738a | 0 .../sess_9a0e601461b3d9b104215919d000998b | 0 .../sess_9a7db4f72bf6ba3b89119eb1577e6915 | 0 .../sess_9a81f6a69cf9a752f08a42af7c04dd7e | 0 .../sess_9b0faa79ebcc182ad631d2427d6ccc41 | 0 .../sess_9b9ffd3f5d1b3b7e7fb4ab8021ee6724 | 0 .../sess_9c87061c647a1863348a102fda0a485b | 0 .../sess_9c98903028ece4cf33487e12338563b0 | 0 .../sess_9cc05cc46ce95864ad3e87c922bd7d6e | 0 .../sess_9cc7d48622827c73b5c2800b90da6c71 | 0 .../sess_9cfbca439e6352c64927f83dfba56d33 | 0 .../sess_9d0f8c2d99f91d53540c981a669307b0 | 0 .../sess_9d585af32abcbce5c19f7dc88013b509 | 0 .../sess_9d95d6e5b127e827982ebd70a7780ac5 | 0 .../sess_9defc0b6e6f8e6a06175fd732c55f9f4 | 0 .../sess_9e0ac6eb04ae0415245380aff8a7fe18 | 0 .../sess_9e48c6c6d01f1fd30c8ebe200c54ae74 | 0 .../sess_9ea742913c11d08c3a459e7cbdc48ea7 | 0 .../sess_9eaed2cf9bc04a09871029820a0febdf | 0 .../sess_9f24d1e11f4da71f33ba80b598bf4635 | 0 .../sess_9f669749877accc7939a55a65470df73 | 0 .../sess_9fd8760c7cb04dc202cb2fcbd65fa171 | 0 .../sess_9fddcfde761802254047b04993e2653a | 0 .../sess_9fee4660d995f9fd6a5586af67f086ea | 0 .../sess_9ff67287131509f45cc8628249181573 | 0 .../sess_a04f945480a6c46840307cfd5cb133c7 | 0 .../sess_a080edfb79e15193b1a986d2bd1c8fa4 | 0 .../sess_a0cf773a2425baa5763a3c5151c1e6a3 | 0 .../sess_a0ece2f1244996e6289cf22fbe69523b | 0 .../sess_a14487d530470e659ef4624121d3c2c1 | 0 .../sess_a267492beef8994b2bea7a841d1a0cd8 | 0 .../sess_a285d45c3472af1ffc36a684c856ec99 | 0 .../sess_a35bdd52888e241d85684a6d02a68bde | 0 .../sess_a3a3b332d752eebbfaa33f846f2011e8 | 0 .../sess_a3d22e835cba5db3a924784879c04be4 | 0 .../sess_a407d22c03234511a8692574b1afdb55 | 0 .../sess_a40a10b60dfb97885a13a60cd56ab03d | 0 .../sess_a41afc440e071af84d3aa05ac5272fc3 | 0 .../sess_a4599efbaa95f71a3a07ef11cbdb2982 | 0 .../sess_a50197cb3ff817a6e011f450bfc33d48 | 0 .../sess_a50e65f017e7c264acc21fba0639a32a | 0 .../sess_a559140c7253e91fcd6a8f6f19e05bff | 0 .../sess_a594961a601d02783f91faf40e98312c | 0 .../sess_a5e3f86f5e484f1b76040bba1e5e14a8 | 0 .../sess_a6ad3eb821ff648a929de3ed3197bcb2 | 0 .../sess_a7cb6058536c2c10eb132b9ea2273034 | 0 .../sess_a7fa2f402ec1a091b24e4dbe172fb7ce | 0 .../sess_a80186e2242223f495ecfdcca4153e08 | 0 .../sess_a81980865d0ec43ef0c5583e07965859 | 0 .../sess_a87aa73edef2fa7a6931806265cea0c9 | 0 .../sess_a894ac582bee396f28b4a5b6d76632d1 | 0 .../sess_a8eed80b4e6c374bce30583a334fd1be | 0 .../sess_a8f1dd35649e9f13895d193df5dcb5ba | 0 .../sess_a9196e31df6affc38cd0927354660e20 | 0 .../sess_a95b3114ad98063dd3ba2e3ff6ee4089 | 0 .../sess_a9641cbe82cd2fba425d8bf3f1fa632b | 0 .../sess_a9dc429cc9b5c625c3b61d1647124d00 | 0 .../sess_aa0e7054e4831c8e95c9d968a25ca3c4 | 0 .../sess_aa6859d5e79333e0b7fbf8152c956007 | 0 .../sess_aa8f8b163bab75cba3311559cd7cc687 | 0 .../sess_ab4e2933297bec79168036dc7f3d1c4c | 0 .../sess_ab893deedb9409a65c6b4c2e1fd21135 | 0 .../sess_ab89791d24d1aaadefc456a1086a2560 | 0 .../sess_abb03b95526f02aafe816672af681ebc | 0 .../sess_abb7a002d65efea430cb0af30b78a078 | 0 .../sess_ac0e42e33c97dd59d436c667a5b3eead | 0 .../sess_ac4027a844896a8a22c308c293a15f65 | 0 .../sess_acab22928f8fdc15eb012b3494e41797 | 0 .../sess_ad5c7d07120b55ddac12237c4bab0e2f | 0 .../sess_ada72e41e49e00d5f656e5da43eb6bc6 | 0 .../sess_ada8c2049e1c9327b3a50dc425f6bfbe | 0 .../sess_ae1d8a22efd12912343d561876fdfdc5 | 0 .../sess_ae234126326f18ee35485c944b7e5848 | 0 .../sess_ae34a72b4fa6668803ea46d383ea6f24 | 0 .../sess_ae52f8b68722f536aa70b7590035f9e3 | 0 .../sess_ae64540044c09c7b795ced78505c9b4d | 0 .../sess_ae70ef607969820ee6fa532c7c516c0b | 0 .../sess_aeafd646edb77412e928721505f984c7 | 0 .../sess_aeb687357e6f692b2199e9e800d56673 | 0 .../sess_aefb95455125a664bb95a1c2ef06f8ad | 0 .../sess_af4792ba9e683db497c8912f32609da9 | 0 .../sess_afab05d39b52ab8998daa2eda66b6aee | 0 .../sess_afeb67ef6a5ce209e756766ec3ffe2ce | 0 .../sess_b024fc7d8e3356fcadfeeeb2d14b1815 | 0 .../sess_b0c1002f2db893b0a6af43e0b577dfe3 | 0 .../sess_b11cbd54af2f7c7e43bcc82b0279e10b | 0 .../sess_b17c2592ffc464b4ba0b679af70ded2b | 0 .../sess_b1929d13ac18473aeea275a695808d5c | 0 .../sess_b1da207d6c31fc9946ba3621f021ae80 | 0 .../sess_b237e22685289229a1db2608891cd30c | 0 .../sess_b2a31fa222e71d201828baf1ecf324d2 | 0 .../sess_b2eaddc565cbb2b2e87616e79caeeffa | 0 .../sess_b359782f5ccdab7e806fbeddf150dcbc | 0 .../sess_b36f9ea866728a5fd33680170aa21c86 | 0 .../sess_b3a6ab8bfc108f99d05e83799ba0c606 | 0 .../sess_b3b8e7ee9034bc9159f2b56875fd7cc8 | 0 .../sess_b41c95ac09de774cf44fb1e10f5e904d | 0 .../sess_b44275f8a8435fbf5025d135126479b1 | 0 .../sess_b491790afd14563692ea36be5588eabb | 0 .../sess_b49f8d76aa16a1f4aa34d99f4cc1e1b4 | 0 .../sess_b4dbf3766611612508d08f46c9b190f2 | 1 - .../sess_b4ea676cb3216a36a1693463ef5b7c82 | 0 .../sess_b529a32f36544fee5e632be00fac097c | 0 .../sess_b53d30d81ffaadae86b647f47f6a1160 | 0 .../sess_b53d83093d2c2083ed7132b123982264 | 0 .../sess_b5510f652a52854c7651f6918feb977e | 0 .../sess_b57a0d89a948fe34f8dacda9cb43bae4 | 0 .../sess_b58721ac9be6edd4764bf6f8780cefc1 | 0 .../sess_b5a60f9daa55f9734f493d6ac0458573 | 0 .../sess_b6ec78ab609d0df2fd508e9163c253e7 | 0 .../sess_b6f50ca4efe83c023d25e4ebaf6487db | 0 .../sess_b79d07314aef27e7f198bbb8b140a36a | 0 .../sess_b820236352b2730de43cf836422e206e | 0 .../sess_b84c49ccaa5176f3f60d430f254f4009 | 0 .../sess_b908569ab6c58bd1746f5f4fd534f934 | 0 .../sess_b91a01b1e5d207e45e16934c8ac97ee8 | 0 .../sess_b9c58c1055898aec49f2b876bee0989a | 0 .../sess_bac0d94744e5d5ef89296100c18f0090 | 0 .../sess_bac2cfc9597d42d210a3862582579fa8 | 0 .../sess_bb4a64bd891cc061c3adefcb44477af4 | 0 .../sess_bb87f20b1e8a384d46d56453cad1e43c | 0 .../sess_bc2eeb565a25074bbb1662c9574c76e6 | 0 .../sess_bc471f7dacb30aaac0280f97b8b2a40a | 0 .../sess_bc6a3acc6bd9424ccd4f53381763a765 | 0 .../sess_bc9a6fcb99473c1d425a69fc74e2816b | 0 .../sess_bcba56fadcb6d5fa33aecbc0accdf024 | 0 .../sess_bd4a221108dfce794cd7f70d523dd168 | 0 .../sess_bdb7dda4a0ef116d409e5e69c1ac3fad | 0 .../sess_bdec0ef240e9a5bb1a666d8984758976 | 0 .../sess_be317991eb08458fb8e9abcf374bed36 | 0 .../sess_bf428a4caf8a7d4c47d26f32e16fe043 | 0 .../sess_bfe6ee4113b5571017455a38ee1e2317 | 0 .../sess_c018a7218b523ecc2ade22f7aedd38f1 | 0 .../sess_c064150f27b1dab4111a60ccc6f9d2fa | 0 .../sess_c0ed531b0f4e24c41d874a91cba8c32e | 0 .../sess_c1f34ca67059e96e6bcd732eea2446bf | 0 .../sess_c1fe8bbe901ba4706855bd9eb723ba70 | 0 .../sess_c21b23debb7c016fc702f87a0294f3e8 | 1 - .../sess_c2426b9d31ca734eabd4e282665bcb9d | 1 - .../sess_c26296dc097c2f01694ee80ae77eb6e9 | 0 .../sess_c2ee1217613c2a80e949b8716990ca88 | 0 .../sess_c38c51006dab56733498c50180b3fabb | 0 .../sess_c3a730d7b6a59d913d50e31df3e4c3a5 | 0 .../sess_c40e44707ce35c5ef27e8802aa39e47f | 0 .../sess_c441f7bf34ccd6ae14805365c2ab89c2 | 0 .../sess_c45b5e61c6d053c4f763d91407f3c91a | 0 .../sess_c475fb1bab33463d842d886993c1571f | 0 .../sess_c47945969b61a07537f19f946a384741 | 0 .../sess_c48155c30b39c8362f86aef75c221163 | 0 .../sess_c542af71129f343b6408eade9270bd54 | 0 .../sess_c54748085a5be98912b747457ee83e87 | 1 - .../sess_c54891068be346717c001cd9135f2f1a | 0 .../sess_c57f6f9decec3156c65ae42ec51d39d2 | 0 .../sess_c621bb0f553660ec429aec2ca0f43023 | 0 .../sess_c6429f27fce95541dab9e8ed4952d4bf | 0 .../sess_c6bf258aae59585a0e4d3baa156de525 | 0 .../sess_c6cc348dc8a6b160339d4efeb4ad5a73 | 0 .../sess_c70b845bd7ace83384142056d6460d23 | 0 .../sess_c721d5b6b93058bc391ed27a94c9b40f | 0 .../sess_c75f86e937db953edf0dc710594a1a34 | 0 .../sess_c78586d22fded1470a8af498186b8e7a | 0 .../sess_c845a8b285996a7f190591807a2e5da3 | 0 .../sess_c84f8233f589f47a1d1f3c95256a6d54 | 0 .../sess_c8c9fc84e7bd6bb28854c759734a4aaf | 0 .../sess_ca26d03afac9fb59c49d2459b766b0e2 | 0 .../sess_cb10ef5334885e0f4bb07e60b95e4bea | 0 .../sess_cb810d18223327abb72bbbce488255a2 | 0 .../sess_cc6ca9b9be103498b3b3f9bebbfcca8e | 0 .../sess_cc7cc7d4d0e038443bc7f215fcf60584 | 0 .../sess_ccbfa7c487f33d217038668dba1c7f98 | 0 .../sess_cd426fff8fdfa8c52522fb101ed1c200 | 0 .../sess_cd6936d236e56a0958f326724caa9f66 | 0 .../sess_cd9a052a6c053712db213bcbd569b448 | 0 .../sess_cdb2d2c089e55ec49e126ffaee9da500 | 0 .../sess_cde83bbf5f7883231a8bcefdf4b5749f | 0 .../sess_cdf9116287630763b1acbe585ed5e0a2 | 0 .../sess_ce5934a087e64591d7f2d218c00ea365 | 0 .../sess_ce8a8426d076db8a3d564204d4e29b24 | 0 .../sess_cea4f34bc0b31c76efbc1ff1a6dd88bb | 0 .../sess_cf7075fc4f5727c449d2b7fa06303609 | 0 .../sess_d0054e42522dc3082a38d55702832585 | 0 .../sess_d053186c866c8aaafb3c49f5fed373fb | 0 .../sess_d082df7384cf4c3855e911af2e4a6d68 | 0 .../sess_d1b6c144193e51c481f30adaa6f5ddb3 | 0 .../sess_d1d621d535d1444562ca2d1b7a43400a | 0 .../sess_d256ce4f2ded89a00bcf19cbcb1bed64 | 0 .../sess_d27d2227ad5637ccbac3579310e60b6d | 0 .../sess_d311a3d90755123ef2e6e86c68eefcf3 | 0 .../sess_d35e6e95a5fdda69f32a5a8bdf8964ac | 0 .../sess_d36cf7d1753dc1ef650e4ad031194f3b | 0 .../sess_d37c9bba5a42b3760ac4fedfe02002ce | 0 .../sess_d438212c8192544d26843d87bfda1e5b | 0 .../sess_d44df14d2838d90e63d1c5ffeee18b63 | 0 .../sess_d48edd5255a24ae738e3a13c31f7bdb2 | 0 .../sess_d51b539ad255419ea6fd83ba3e9caa39 | 0 .../sess_d5ee3033b6819cfd67d2ef4d8feadeae | 0 .../sess_d6173d6126d730e93fa9cd6774f53be7 | 0 .../sess_d655d61f4acc04d61814576220dda1a4 | 0 .../sess_d761d9849d639d0449a853e9965d2558 | 0 .../sess_d764f7b5069d52949a1249384c2bff40 | 0 .../sess_d82cdb26dd412905a1b72ed027a14fe7 | 0 .../sess_d866f688079ed7f6798f6b2c37d479f9 | 0 .../sess_d9079a969cbbecca3cbeab898a7b3d3a | 0 .../sess_d936dba3104d21be80694fa09c3f2e76 | 0 .../sess_d9507094e57544f8c58778996fe93796 | 0 .../sess_d9de9a32167fd3c3625cc28150d3dc59 | 0 .../sess_da17ec2d008cbcf1fccdade5739c1aa3 | 0 .../sess_da4be22b9206de27363e8a6a0e53ed6f | 0 .../sess_da63331a5ba2e04a7f539fa874066438 | 0 .../sess_da8ca3466e87e6afa9199bbf808a6e99 | 0 .../sess_db1dc99bb1ae9f864d590d8d4951ea24 | 0 .../sess_db3413134a45f8caafce26c4f5bf31c9 | 0 .../sess_db5cdce7ad0e207e29c025a404926a56 | 0 .../sess_db6ae4770e9b9d1af93a1aa4823f8b56 | 0 .../sess_db815a56ecd54cd9683ab4a1e5fe00d7 | 0 .../sess_dbe10898134fde8c830ce6125d63547d | 0 .../sess_dc7ca58b2438ace110816de0b89071cb | 0 .../sess_dcd8063123fb5dc4da53f99e3be8a2f6 | 0 .../sess_dce185e29b874f97b24d0246486f3634 | 0 .../sess_dcf331017d5be4b352f8f7234fbf6e50 | 0 .../sess_dcf395666a298642aa662bc593439f57 | 0 .../sess_dd395de0ebabc53b439f4fc9e32d60fc | 0 .../sess_de195005e2ff63bd109984d154a398a3 | 0 .../sess_de495cd1a69c28af3b9398e92e94d21e | 0 .../sess_dfcf80bc29fce6abfed5ac34bebf7c5c | 0 .../sess_e02cf9db82152079377afac29dee9f7e | 0 .../sess_e0d389d5ada1be1011461856fe6026d7 | 0 .../sess_e0fc214acacaab4e1609c3b68e4a04ee | 0 .../sess_e10dbe6740069aee59b04e33d58750cc | 0 .../sess_e13a7684ee74435983312a287efe4c85 | 0 .../sess_e180f60c178c65bb2e9d312b4530a437 | 0 .../sess_e214cc8e60797ecf4e3cbc8dad77b351 | 0 .../sess_e2463cceb2b637358d505ca930d980e5 | 0 .../sess_e28398cafa24c8e0e56db5aed7749dc7 | 0 .../sess_e2c69c8fb699f8ccdd772818cc7a843b | 0 .../sess_e30bb2069903f00d5b2b403e63af7538 | 0 .../sess_e32f151f178fc3473d264598c4cdb3db | 0 .../sess_e3cd81ee2a416b06478fbb48384a4536 | 1 - .../sess_e3df5ff0de2d27045da872d3673acd8f | 0 .../sess_e454faf4a50341fd4fe7d3d7a4a8043a | 0 .../sess_e4e5ec23b16a1f4fa28b55e9fabb367d | 0 .../sess_e50445bf32d3a170f42828268268b95f | 0 .../sess_e511429ccbb1b5bf87fd2654d2c93dfb | 0 .../sess_e512cfa96becba816ff098acd58d67d9 | 0 .../sess_e595133187ee681f4d193ad6d3d98bf7 | 0 .../sess_e62417d00dfab625e2e867bc95c0e6b3 | 0 .../sess_e7294a484f93c841c720dfddaad2fa75 | 0 .../sess_e78b800b29f053b098e046e43e2b5e32 | 0 .../sess_e79da2fabd48f5e436d0a2ae92858814 | 0 .../sess_e7a0cb5ac086583a7c4f433f5566dfe0 | 0 .../sess_e7bf81464f2a282d2b5c37384544d992 | 0 .../sess_e7e0d10f34c130abe39787681ecc7c54 | 0 .../sess_e87478078e020e24d0779351c0f969b6 | 0 .../sess_e8a7bca6e77dfea8a08a9d85ea373b3e | 0 .../sess_ea261e39262abaa69f59218d58152e24 | 0 .../sess_eaca2607ee393620327eea92f80f61dc | 0 .../sess_eafee1426b1ca0cba1fef01042da24af | 0 .../sess_eb0b3aa7fb842573df159a3cbfbc118c | 0 .../sess_eb1423e9f00c7c286a8de731475317ed | 0 .../sess_eb5dc235fb964cb087b0581dc5470dcb | 0 .../sess_eb632c7b379753ce9e0678cc6e1fc4b7 | 0 .../sess_eba6bb7a7e9f84453ff471f0de9c858a | 0 .../sess_ec5dd9dcf14935e06480e595c5378408 | 0 .../sess_ece749dc3266e76f800a73634c290360 | 0 .../sess_ed3e4c977232325dc987613963520ae2 | 0 .../sess_ed5a34fc673a1877970f68358b1c8a2e | 0 .../sess_ed720542b7344966b8a96736178ecaf8 | 0 .../sess_edae8a6f1230dc09b4cb5a54d21be367 | 0 .../sess_ede9c689e49df248407a15a84fc3ab6e | 0 .../sess_ef7f937ea6a6f62a765a435db96aca63 | 0 .../sess_effb84e824295ad73fbe605ac6fe2f88 | 0 .../sess_f0e668329a30681f9bfbc3cb07c4f5cd | 0 .../sess_f0f092cee32c29d95e9bd7c7c30e20f2 | 0 .../sess_f194bc98e8e4096a6b45e7fb11d139b2 | 0 .../sess_f1adc2c0c56dc66a742546fd7f916722 | 0 .../sess_f1b44223c5587e630f814a8dccd57813 | 0 .../sess_f1b6dc29404814c5b7b518731d3ad515 | 0 .../sess_f1ed9645499bb8f575b5dc55017f6482 | 0 .../sess_f1f8d1c3218c6362dcf0711b6e569ec6 | 0 .../sess_f21a3956f18d80fdec12b29b03404111 | 0 .../sess_f2b140d9118c0885e76b7bb1a5b232d0 | 0 .../sess_f2c30586d756f874aa3952a62be05345 | 0 .../sess_f341b63a04b60a2b5b7df9ad6450e9f2 | 0 .../sess_f349b233d747db9b4973592d72ba103e | 0 .../sess_f36a1f4d2ff411d7442cfccbeff9c92f | 0 .../sess_f4a545daab3a7bbc90c7313ce16cd200 | 0 .../sess_f4a6ba717bff574a5108716d3c1b76e8 | 0 .../sess_f54673683192fda4d1c05bc417825a4c | 0 .../sess_f57e67551a8adca075901267474c5e02 | 0 .../sess_f7434453f5c9fefe400762eea3329b9f | 0 .../sess_f86b00b21a16ae362e3e55e5cbbb49ad | 0 .../sess_f88b647727d942b3ff67893febfa83ec | 0 .../sess_f9047caa910fe889f68f301f00706b3b | 0 .../sess_f9288a644472ee1e11539a71da2c16ac | 0 .../sess_f953c927cd6f250afb7d4bc8791a2506 | 0 .../sess_fa32595e8f8e23ab874e9247eb036ec1 | 0 .../sess_fabbd025bed38d86b6c790c3e2ae219e | 0 .../sess_facf7bf4f85611dce0bc1077747eb283 | 0 .../sess_fbd736474197b68a63d2aa66da52e238 | 0 .../sess_fbf559b7fcb34e39382b7beb9e3a3052 | 0 .../sess_fc283dec0f73891e83fc082f138c358e | 0 .../sess_fd3e050332ff331670681adaa7f3a04a | 0 .../sess_fe0b40307095880975721f2e56e653cb | 0 .../sess_fe92bea57dd460a4bde6b5a3b5b9f844 | 0 .../sess_fedd27c97c990386b6b30a35d8da84dc | 0 .../sess_ff4c8da7fd10a870809494bfdefa4cb9 | 0 .../sess_ffb15114fcaa6705fce00c84bef2acf8 | 0 .../sess_ffd5b0789f866679e1b3167ed8323759 | 0 .../sess_ffddcc106e6d3e46d1caa3c2dfddf4da | 0 .../sess_ffdef08140c48ce0375a0a3d6313da12 | 0 .../sess_ffe009470987847df4966990ac35d661 | 0 867 files changed, 5165 deletions(-) delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/AppointmentsController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/AuthController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/BootstrapController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/InstructorsController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/ReferenceDataController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/StudentsController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/TenantsController.php delete mode 100644 www/fahrschultermin.de/app/Http/Controllers/UsersController.php delete mode 100644 www/fahrschultermin.de/app/Repositories/AppointmentRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/AppointmentRequestRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/BaseRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorAvailabilityRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorBreakRuleRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorHomeToTenantRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorTenantRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorTravelTimeRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/InstructorVacationRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/PrivateAppointmentRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/ReferenceDataRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/StudentRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/StudentTenantRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/TenantRegistrationCodeRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/TenantRepository.php delete mode 100644 www/fahrschultermin.de/app/Repositories/UserRepository.php delete mode 100644 www/fahrschultermin.de/app/Services/CalendarService.php delete mode 100644 www/fahrschultermin.de/app/Services/HolidayService.php delete mode 100644 www/fahrschultermin.de/app/Services/RequirementService.php delete mode 100644 www/fahrschultermin.de/app/Services/SunTimesService.php delete mode 100644 www/fahrschultermin.de/app/Support/Auth.php delete mode 100644 www/fahrschultermin.de/app/Support/Database.php delete mode 100644 www/fahrschultermin.de/app/Support/Request.php delete mode 100644 www/fahrschultermin.de/app/Support/Response.php delete mode 100644 www/fahrschultermin.de/app/Support/Router.php delete mode 100644 www/fahrschultermin.de/app/bootstrap.php delete mode 100644 www/fahrschultermin.de/bin/migrate.php delete mode 100644 www/fahrschultermin.de/bin/seed.php delete mode 100644 www/fahrschultermin.de/config/app.php delete mode 100644 www/fahrschultermin.de/database/import_pgsql.sql delete mode 100644 www/fahrschultermin.de/database/migrations/001_initial.sql delete mode 100644 www/fahrschultermin.de/database/migrations/002_instructors_user_link.sql delete mode 100644 www/fahrschultermin.de/database/migrations/003_backfill_instructor_user_links.sql delete mode 100644 www/fahrschultermin.de/database/migrations/004_lesson_type_template_visibility.sql delete mode 100644 www/fahrschultermin.de/database/migrations/005_tenant_location_sun.sql delete mode 100644 www/fahrschultermin.de/database/migrations/006_tenant_federal_state.sql delete mode 100644 www/fahrschultermin.de/database/migrations/007_student_prior_completed_units.sql delete mode 100644 www/fahrschultermin.de/database/migrations/008_lesson_type_system_key.sql delete mode 100644 www/fahrschultermin.de/database/migrations/009_requirement_phase_labels.sql delete mode 100644 www/fahrschultermin.de/database/migrations/010_student_email.sql delete mode 100644 www/fahrschultermin.de/database/migrations/010_students_contact_flags.sql delete mode 100644 www/fahrschultermin.de/database/migrations/011_student_needs_glasses.sql delete mode 100644 www/fahrschultermin.de/database/migrations/012_split_combination_templates.sql delete mode 100644 www/fahrschultermin.de/database/migrations/013_combo_generic_key_cleanup.sql delete mode 100644 www/fahrschultermin.de/database/migrations/014_legacy_student_key_aliases_to_lesson_type_keys.sql delete mode 100644 www/fahrschultermin.de/database/migrations/015_instructor_pre_start_buffer.sql delete mode 100644 www/fahrschultermin.de/database/migrations/015_lesson_type_allows_student_and_notes_private.sql delete mode 100644 www/fahrschultermin.de/database/migrations/016_consolidate_lesson_types.sql delete mode 100644 www/fahrschultermin.de/database/migrations/017_student_booking_schema.sql delete mode 100644 www/fahrschultermin.de/database/schema_pgsql.sql delete mode 100644 www/fahrschultermin.de/storage/database/app.sqlite delete mode 100644 www/fahrschultermin.de/storage/database/app.sqlite.bak-20260422203538 delete mode 100644 www/fahrschultermin.de/storage/database/app.sqlite.bak-users-20260422204004 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0006a50819ddb4c83f8927e073726008 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_00309f86663d537153fcb66685d86df7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_00409744a4c7e3bb92d2eb4076f6f9f1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_004433bebe95f3233eb3afeacee557d2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_01276da25030fe7610e51db01928f92e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_013cba357db97c86d9affd6f490425d2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_01db5cc5dc2af4df786929887036129e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_025b3db5cdc9307a49bbc4e7c8569322 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_02ce241714378b298d820865b9f207fa delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0302bb8051aea505d498b8118cf07cbc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_033690960537713e4b7584067e851174 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0387d0c9c23e92d7c5da1f59219d140a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_03ab912d95e7096bd5041a815feaaac6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_03bec560a62e6282f3c00ee39e0b5185 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_03f80785c72e82de6dbb20e633f8e70b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_04921a0b3787740b88c11ab3b2b4d4dc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_04ba107751852addceb705f95cb01636 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_04e7eeca7ab45efc4714e55d0e488aab delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_04ec6601cf72642f743fb0ad41d466b8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0521642416caa2fbc62e3f8298109cf1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_052b45081be50758c250257b9a65d04a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_05fa0356f494ca589061fb1f1cda9f38 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_05fc405f00dd93a93a4e02d048ecfdef delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_05fe8c42f2d6ce2eb298f3773fe7aa46 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_06322d63f2b61ed856911309f0491b02 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_068031028f6af11d6206ba4e176e106f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_06b2450149fb978337c3b300c5177c89 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_06d7f7359a7c55810206e5722284344a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_076f1f9b3f3607d85628e676aa3deeef delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0781485879098048ec9ec26f838e230b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0854ff9e45ba1f5477fbbad5e54698f3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_087a67b3949d5d39a90f231048dbc168 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_09013b1da99e4f816a92e860b645e65b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0979ad1bce9bd29c7f78266fb0db9496 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_09a34f83873ab7845a54ad0e1f123da2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0a1062c7493039579c5b1ccf819017cf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0a3a77bb3b296f6ef7c2c58f223522dc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0a457d212ce74a302f1245eaadd68550 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0a8407b10f0705fb94abc083ef7629a1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0a918e1bf4f81d888710bb6eabccf5b7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0b02235f6c9d7a8fdd13403950def66a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0b4c3e7eeb7915687615efbcb7ad351a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0b689f1efcd64909309b788ce0aa77a8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0b7a6dd656b413dfa91158a8f36533fe delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0bee18c4dceb5b1916bfb6d16f940237 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0c6b2d92ad51dc235c8a326a6f15bbde delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0cc19484bb603a199b713e1506f53ba0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0cf9ec95094969104196ac2547eb3cc5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0d444063fde0f76a4a254962ecc24900 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0d674f078cb072a267fab787102b842c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0dca6c782e6359327b87294c5be46f45 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0df4eb5e781f33fdf8978650b309cd49 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0e04def9d162ce239e6947e6321ae8ee delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0e42f0bcb89c3342f5fd4f7440391e29 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0e5c1480078e1d9b5f84eba3b40bb77e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0e60def1012c7eb8dcd4e9c711f82bd1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0e98d5ac2834ebc5bf78d2d5f0c91fea delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0e9b111cebcfc845371544ee02e6ba44 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0f07e83c587cd6ba9d4374bad4a0e050 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0f1d85f511393a35984d6532feb1861d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0f20d94dbfd397db961146e58523b752 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0f2589aadc148fbb95ddae15307b2ea9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0fb288edf359a988efacf668fabed004 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_0ff28449277d7fe69998599d5c19d934 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_10009006bdabf68eb0fab5eb37ca2fe3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_110b899ae4b4a0c037123345c4e49d27 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_117db80a15a6ba699f9678b99a1d9de7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1202777c449219fd2aac7b5ffb07de17 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1247d7fb0d48d3e756c4dffbc1270e2a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_124be71b45653d1b3f57538d487fa105 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_125bf65956128d9a6750548f818c3348 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_128a4fda8650abb78800f45754ad48be delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_12a821bed8de2d9944c9f8796684d638 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_14624d98ed0c363b2a095334c7a924c4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_14b57fe7649feaf9706aea2773911e8a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1506f280114920a5be86dc1437738d5d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_15ff36ba1e9ccbb86875e7ffe82f935f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_165fb060e3ebc3fc704b851ac1d01598 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_16732beb713293cfc64b4a62d20e5cf0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_16ef8072fdc04f0357bc1654ccd9b88b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_16f69df80eee2cd72267465123374bed delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_176074fcad8595788ae0cdc97b974c18 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_176897c620d6f055c1dbcb598905cc3b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1779168ab91c36713aafe5bf02bcc109 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1790c58801f9b2487b8c093cc82be8e9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_17a0585e95ccd9c51a580839630dc92b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_180e9fa06a637da36cb1f76f4d0ccb9a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_18c8679e062e0a332aca916fe40c6859 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_18e0ea982f318fbb1005dfcda8a8bdf1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_192aef27a1fce8903cf7d28379fa497c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_192bccfcedba055ff11758985c9485f7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_194c7cd0b03e84efe00b5484ca2d8aac delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1950a2ef1291ec9df468535c6b0fc191 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_19770a921c71cfc42485c3ac4615611b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_19c0d2d4a229fd60d2099992ea8690a0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_19fa167361a1d43b543976961054333c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1a912668b674f48b5ffc7de9e824aa5e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1aee1ec32f6fc52fcde579475a6fdf90 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1af06631c6a9c42ffe0961f03c21c73b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1b62f79b6a161a44066e889fb5890864 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1bc34aea1212c788f139097c26f6a232 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1bd8426e10991ec9c1856c793196522a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1c19ba48c4d66fb010544f9777b0b4f7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1c1eb9653903a3f2ca0cd68b2e2a31c8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1c1f7b1efd31a1165e99abede59cbc0a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1c8fd85f2d4fa6c41130f08f87b3068d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1daa8c750fa07697f55057eba9f07208 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1dfacd171678bbfd3713e55ee6e1c0b0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e0fe014daf164ddf58fba633fb433ad delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e19408096523f324050696e40e78c2c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e3b112ac09b1917473e8d5d1f050a13 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e3fa8cca3f53f006f75140261d3a5d5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e4606b18533461a9fcd557a11b1339d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e576ef7adf606c5bdcb7341f2dfc7ee delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e607b0b5e8b9b44045b78c038ebd342 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1e752925b000debefcf8e1b6f462bfc2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1ec360e5d18fce3b53084f54c50523f6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1f3d92dbc703b68c7e795e5f51c1dc19 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1f6c34e49bd50f27424f86a2c7f0b2a2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1fb01a63321004f84edde1c2f01b9660 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_1fb1ae525d180aa6cb59e558984c2072 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2041982bc34bf965174b00a51558b7e0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2043674c95a6ab2d3f71332b76dda4ce delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_204d8a56472208a59a1aa70ab737fe89 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2123c53e3d0044bd7f2e5cef59a41837 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_21b513631be5e9c0dfd1b2d517f84398 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_21d59f9f57be2f40d95c6857ba79b486 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_21e0c4efd285609f6d2a1f54f58971ff delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_220bdce3ff2cfd02d7e5fd4851774fdb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2230676d13498deef61f7ed59dcdeca3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2292fab487ebf06df95e0036beac57f1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_22a4e3c7055808fd4c5a2963e52ffa36 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_22af559095a190687e0d544b8eee6644 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_22d9645a0764cd276e1010062ce58708 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_22f0a00861d4da216089fde3b14fe2ef delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_23a4409db0925d7a59ad29e42bc4884f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_24390c9968cd8821cd7bc5f2aca39df9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2456d2263cd6a8256041d4b3c89ff307 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2470d1af939f31518959c76496aa7a6d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_248cfaa4e75cbdb490cfe8dce5aeaedc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_24a867c9d2c15b255232a9d8e1e84f38 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_24e2550cf6651e9d8a37e82da464ce5d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2503f4a5cbae9324cbf3b95b5b97df27 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_254c55b9ab44a7e81392a361205f9608 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_255b248494b7bc41838d5e03d8c63f2a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2576dfcf73df11914c84eea9030362ee delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_258ba55b7396886da889d6c57b622370 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_258d74a6647426ebba4ce0f0a0c67c66 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_25bc952c7944ac5478e505b7d07617b8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_25bfb2e99746cac127855aca7dd51a66 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2619421cbb71439a217328646badf18b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_264744b8536d1f0a4942fd4884126ad1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_26475586b26e819cbe7ed6b7c91f4353 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_26817db6139724550add44986d13955b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2694eee41fc1488b7bb8cade34db7095 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_271efa4ff2d546b1e0a65b6f3ddaf929 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_272592a07264fcde1b184f03d1b63a3d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_279218f8e2c26131e4ca39dbe14eb7fe delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_27dd196fe7ad686655daf28dbc6ebd34 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_28136e39aa3fb81f6ea47823e5cff14e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2878c22f67e22d014964d1bc29fc80d2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2941e7e905f15d5da543295c53736cb2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2960b8132f30396e838b0ebdbb96dcaf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_29a45c491f6998a47aa0b0f66fd83f3a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_29ccade580d9dad87ac1a35ff275d2d0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2a16d5f4beece112f2e67a4bcb781a07 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2a64bf1990c00f2b2bc1836c1b96fd2f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2ae5a56ff11d55dbcf879524b71f88c9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2b67b6a92be7fcd363c23a7e494057dc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2c5719342be78ab42c03ddf812474077 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2ce24f0bd9ec5909e465b42fa8d33670 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2d1c750f56256eb9ba589168d9b17b65 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2d1cba190840b33e6d54f9befd89ae52 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2eb1f32411558996d87b5d8567dcd94a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2f4233260393ed2a31e00ac9e2969636 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2f52d9fd84045a93ce4bb3a5be6a31e0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2fb5535ba46f2edcc64f6b7c581b9c7f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2fb9f36e4449aa120905dde208f60510 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_2fe3e2083c13b197a53c094156873f5e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_309ebde30dd24884b70bd8df07279749 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_311959d4bc3d190ae2499291e9b42220 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_31210c92118f237f856a58f569a84141 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3160a2a2b74ee599bee5f62ac40e1591 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_31eaca9ab96ee1d5a814bf3202eb3c22 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3211e64538a844841fd3167dd09dbef7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3212a8af9dd17c466ab8ea91052c3cc4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_32932fd7d38fd6c8279e60d44e48e922 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_32c66a45bdf19b9f50de688ea047e696 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_334e686c0876c391c42fb587b3bfa976 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_338deba0ad100d079f68ea413a6e3048 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_345384363d30f764d4244e131c21d36d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_354431ef347b5ba5cfcc7273061da04e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_35a3681412ab8e77fc498a7699733368 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_35abdcd2565ba6cebc1d5323c51976ce delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_36323cbf08bff404511acc133ecddf9b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3689a40959fc96cd6f3c50abc1203ff7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_37282ed122e7b4eaaff47a3883309651 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_379e5c9dcce57030269caa935f44b608 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_382329b5050c26c18ecedab29e115c9e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_386bd2888cf16751430e80917a8f85fd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_387a266ab74eed24c6346816390f7769 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_38f8f88f7abb27ac17d9375a5a4cba31 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3bcfeced08df9ceb2af9241e3e4204e5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3c6086415f4fcb8af3e7af3207b96d8f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3c6c3f9430ffcd8fda0687736ec2d718 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3c7b2b014f20046f58b831fd0ad34c9f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3d6993df0f462c4ffff7556ec530e435 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3da2ba55a8c5d696a5814b42dc0b2e14 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3db0a0533c6ffd6078c55906988a594b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3dd3b5c1c41191d551256202b307b743 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3df20e7c93a01e37ead25a82abcfa7d8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3e081a2d79c698f00a94dff6db2e962f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3e0baa6f9f93aef56b4c28cbe7f0892a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3e34570e03450813b46f65a5332d9c1e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3eba8aa5bdff2f16073b6b03a879f828 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3f4d92dfc22756dc3491753c3710d58d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3f5d80074117dcf2345eb24489088752 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3f7f9ebea56914012835d097cf04ca92 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3fae57c4628e0e6de8700f2aefb0b86a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_3fde18821c79b139e6cb19e20b72a0d0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_407b46f6532a47e17ec5babe6c30bc4f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_409dcbc73298f3e020b7c60a3432fde7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_40f2a96e744926f0865a52dcbac9a160 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_412a5eb5d0597f918c0bb9bab03b2faf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_413faf6f188d744d9522dd2fcf41495f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_415f109c0c4fe4d2a1d4979ad5d9bb24 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4181fda8edd2d12b37f109fad33ac6a7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_420cdf45b5c2330160d506a70eadb33c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4247a0c7906fc90ae18a64adaf1aee2c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4254feb9a5b1a5b349f5dc3556d1a201 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4338f754256fd9a05ffce8620f13f07b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4368d3d721b713fe8f89cfbb6e1005dd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_44b7c1306ee68cfa7a89fbc4e043209a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_456a3e7bbad68012698a87d1072c1b38 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4587b7a5e1e5ef217166c56763ce423f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_45a98e9ab472b14179dd14db5f14bbff delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_469e07211c9f0f2764b6d7a2c851ee46 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_46e2408207b1c95658fb7b626ee6958e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_46e8ebf399968a345980d5a95e8c06ff delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_47b05bb74c2af2828b06cbf5e3ff8477 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_47bf2f6a7024254fa8971c7a85b0910d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4853a954dcf6e2ad4cfa31535490e110 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_497ce6e38a9c5c1015e856f7589548ad delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_49a86631804a0d6da2aee719475f739a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_49c66d8f15ac3c3053c8534b28fd2ef0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4a45962e93cea2ed73e1665936bc73a3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4a6501b0989d99b4dab93189ce30fad6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4a8e405b702f60027e17800b0a9ef45b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4c9a1aaceaab78fddc55765178473d79 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4caafb58e3487c63db3e767199e558f2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4ce44d9d6463335e836ae3de308d4b34 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4cfbbd26846fb01c6f9d339c557b03c8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4d29d6096a285987a2b2e625068ff5ed delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4d7c6193ca1cb655e8d82dfe9c6c7eb4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4e38e1eb4f49de672fed6ed540681642 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4e71c4ae079c79d06b3b4199b37c8d6e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4e8ab1cc7be41320be57403a5764d80a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4f3604d0593e4bad5b3c1a2ee7fbcbe0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4f758a3b77fb168967f90b28555033d0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4f9fd9991f5f3d30dc0ac97c372b731c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4fb189b01ba2f06e00ef5f9b5a7f23da delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4fbfeca9a5fb8855a221e690ef502b38 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4fc591afe53506325ffb61b8bb9c88fb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_4fc8717e82c041e7287a910c435a73fd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_509426117c6882aa1596380c7cf47a87 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_50f11f6d3fd52e9b97404943e55c90cc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5104ac2b3efed41e0167e8ac230efad4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_510691ebd56ac6658a8f0d05def56656 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_519f45ae9f86f930f3abdcb63300057f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_51e0aff602241718c4b8416f452b580b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_51e0b1db7e62b4fdcdd8306d0c23943d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5283908e9b80eb47d1f52f4d4400605d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5294cb940dc83bcbd4bf57b17a00ba3f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5341c2fcecad979f5311ceac1bd28718 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_53926f2b0c401a2668cdb0ee55739e71 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_54e9093941ef282786b14c14e94470eb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_54f3fb06c0aca2a55c2dd5ec4d25512c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_55398030f9196b2640c7bad95056c2a5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_55b079046d294c1c69f287fd4337d04b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_55e94cdd1ed910c96f22fc4e1f73c0bd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_56355cbfc04402cf36d92f821bae5090 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_564322bb4ff156306233922d7d4fb345 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_574d1c7a48adf43155170876b326b4aa delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_57744595846324be63e78c3aa28a4f33 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5775e29dec1dea074f4fc9c32fa3a34b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_57e47e62da11c1399a779afd1e78b75e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_583371d8396ad02e05cf1ed99be48719 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_587bf41af67b4725cf167a5652622640 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5971640cd75544c110ed69c8b2704b38 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_59d0ba86b7085a23b070b559be815e6d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_59d76f244bb8bfebfc4b923adbc15419 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_59df6b8eff37a8f46f806ef70d53862d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5a4ae2edb0253f99e7e0d768060c5e83 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5afc92d91483488a5e2756611359c02a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5b9ebb48cacc40324a7627ed5cd03ea3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5baa5d3d23563e43afa7446486dd72f8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5c0025a4a3bc7edc09d828efe2b28cac delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5c0f0b21134060b451e12ef30081f540 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5c2d18b62ab5f4e62bf93bf01d6a8abc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5c49211f43aa46d12999628ab1a4bd28 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5c572f6972ef0bbc0fdb158726375a0f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5d5cd460d1d5835451d781e05c3adf89 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5da65e8529c7df8023ed18faa35d5a9d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5e286521edc4303f85116330fe10e8a7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5e7a74bf5069e74d295e89a325872261 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5eaa995db9fb15a416a357e533b6b131 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_5ecbe991d413b362c14567f1f073f4cd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_60668ea8e3890507478e420a56ddbd5f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6143815503ebf3f82c544d21c1b7ad5b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_61b414feb765617dd3fb38f7eceffcfe delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_61d6228ae940365ff8bbd93a87303a02 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_61e9d1453030accdf287a54e918ee927 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_61f558ea9155fbeba01a42a2931d7b7f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_621511f8d7c30ebc5aa01ce455b8ebaf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_621ef44ae59c047ff712c18d050011e5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6299dfcc8ce40cafed3a335a341a6336 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_629f9dd62d1204aba62dfefe65fb0d74 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_62b5d304a31805cce616357f0e59a9f2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_63a233987c509e08fae79917349f9bb3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_63e9364f0c944608a17504f9b91784b3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_63e9c9819a2de781d792f1d2a60851ba delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6477fc14a025865e68f2dea333bebea8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_64ff70ad1229278f497281f0214ccef0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_65468453a39a8a4dfaa1082215ca9836 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_65b339d0b1ab7066ca6b44ecd8facc40 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_666d42c52b9ccca9698401d63202cbbf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_66f307a1423bb488cc26a24cc5c4a42a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6719a214f44edb74418e6e890bf5ac08 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_676be8f36a7e54aa1863917c871eb567 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6779e0e89629bc58388284b76bd76192 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_67c0a94fd2af88c6fe4e5fcd34036c36 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_67d11c2d90f54a43e96d16bf3c7c45ce delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_685d40735c321a9ffb35d557798cb1b5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_686f0c41b1eaaa6c33131bff43058b77 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_68be2f0cedefb60f859f4c4d9c2a880f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6908fafa1345473eb21f5cb9dcb153e6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_692cbc36b4318bfe850fc4aede3832db delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6972dfd4b41c386eeb36cb9140582224 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_69c6be375919a05a7948264c4db4e9dc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_69dea144c3340502072b895a59b41b24 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6a4b12a9d81b4f56fdab7814f88b59bd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6adef316d6f11d1cfcb4765ee289aa95 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6b3dc5917d807ae794a1ed28fc9e99f5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6b45e848464ad9143282b3909897ee8b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6b8aea5fa4705e2c8928d1ec20387164 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6bf7d9cc4cb88d9fe96dafc8ed1288a9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6c0ab8e461aebf50d0ed2a344176ff8d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6c601c0358a1d9724a5252cd756bd64b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6c676b2e4c18eff505c1853258b039cc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6d894c43c030d8dbe071de186700c5c0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6da8ac394f5fd3b79b6eb9681f810c15 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6e5401ff80e23d4dbf547c4a894fc211 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6f3a5c611d7a16c43ca25127894ed8f0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6f84b5c8b742313a8b748867bb5dfbc4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6f98287cfdd3ff93e952baba05fd5c31 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_6fd95d60ca7ff94f3c602ff4753e6a87 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_700631b2fa80717f2d07a6017d5ff030 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_700aaf47edb8ff558be85c5bd9ff529e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_70a66109b64b26d0ac67524166cb72cd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_70c642898f8f0725b81e4d285eec0787 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_70ddcec0c3417113fc4c072fa39fe331 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_70f9c044b76efda9274b32b5ae345d56 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7108ed71a1a0054c7ab7c7c2068e8923 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_71187da2021a77805c96d85b76867d92 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_712f6993fea7e24e5126734f0aca9a68 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_71a643c2efaef2d77620f637e5637cf2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_71d766001d452c1d949ce85cd327574c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_720f14d25a4f2ce52fe9d3933e014771 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_72515b3f3d38bd85e703ef3a80b1bfa9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_726860093a0a7908e0e9f66e709ef6b5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_72ab8f6fd0fecbe3e0976c623333be7b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_72d5d6b9df6a55503533e97e340d2311 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_72d7576d9bfaea5245d54bc6f5ed732a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_72f0fc1c0ead3468d75f171ff2353eac delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_72f8a1f9caa69b25fa64c6185238c6e7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7316664ff3b366d41d1a0f1d29a21e44 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7327bbf8e70879c93cb9fcf18287ef57 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_73372d764d0b64494a123b95b092e293 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_73c80e71dcc72c4c3bd422dc2d1c6f22 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_73fd9c9fd27ea5b4b7e513723fbe0d01 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7401b0da36a0bf586a412bdc32c01932 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_74169a80690859946b251a7e2789c06f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7433d5d741f0c55568cb183264a757d7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_755543053755f9827042ecd578a32ce3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_757ed514e8bcf21fe484abe2639fd9c8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_75ed4967153522837eebaba2104a96bf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_76036580c2a0124ef45fab001e1b8e85 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_764eb3d09d7acdadf02a1b1b9e652d38 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7751d4611abdb82cdd8307b7db2a94a7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_777222d786447c44cba1f61c40722851 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_78ade15b28ae2ac4544641f92908c944 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_790eb3970d7871971226a752514c9021 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7a39b110e92a44f5cf2cc27318fa8acf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7a49c9790485b15f032f1889edfb5e74 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7a758afdfa5c19238907ee69e4f1b8e1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7a942e09063d7d053ece5084917a59c6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7adb1835b69eb442280acb1a34e3e4fc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7b1b6e128d0bc1b40a30954812f3f2bc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7b30a67240cb34b565faab1ee1a43759 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7b3b609d4c8713d06961731c28fdfd8e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7bb08b912f4e650b85412aefe4225981 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7bb50e18de85135463e20f8d52dbd679 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7c34f05d08306cd0e725b262006af9c3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7c4815b8c0d9564d5c330dc755b89be4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7c5d6ce984c7f26e83b67c6a785f2919 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7cee3f52567d4d995de6c242576e80e6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7d496df6ac57de8fe4c46d48271fd6b6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7e2cde5aa2397f9c928af07c857d9059 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7e394c0ae018145fbf007d66dae56fc1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7e44e9b5e4618ac9c5d5c50156aa9481 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7eb154203930535a374d572b26905543 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7ebd209f80c9a78715a398ca29339183 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7ecdf19414bb4c4fea4ca19850a7a539 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7eef0ffbe7eb689711c83038742d15c7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7f11e5dde38e860a69e208aaa622312b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7f97b81d9a078302523e924f6cd12861 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7faaa1325462a16eb0c09a78eb816c3c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_7fab50507d10a6d85e79235af15d32d2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_802f12cc03180b848c62d75314cea4ad delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_80ddf16c4abf6269af3663c2773029e3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_81367cb6c7667b5ce00936f7e4c75ed5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_821cee680ccebd68e213681a79f95074 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_82c9e9a8ca48d231b1a6143016f12161 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8390ca0087f926e6dc6acfc1726feac3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_83f1a287583b2bc46cd195e1e3b2f943 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_84323f8c4143d694e44c9fedcb9f9df8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8506d9ad640e8db4c5464ae18b21aeaa delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_854a85d95cf30e598d3dd8071c524182 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8556739092f403601805097e7c5515d7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8578f708494846a3ded7c61783b1424d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_85bde53b19790499e9dd46a1728f2644 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8609c314bca4daf7b8d418593296f29d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8631135c2359b355b28b12b251d7cf20 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_869e70a50cdab0e5dfa7f41decbe164e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_86b6cee8d0e002bd2cde78c01432c98b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_87765df5421b4b08ce0285280372e9bd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_889d219494675742314ef1f2307e5059 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_88af4a1e93188192b41b898c96537666 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_88b7f3ed2893c08c3d3a90674de9828f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_88e7499f47401ce614b4b65ac8356131 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_891ef4846f2cdff9342aeba0a22d5f98 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_892e5cf319f4e18afdb304abb39c54e4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_89625043f67d25fa8715915de6bb79c5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_89a3b9f54d67342368079a0ac616276e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_89d0ffe96d3b0ad881121413908b1b83 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8a6817782ff0d92875e6235d8ad776fc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8aa40af232be8a3ca5282ef5f551afde delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8ad98e7026500f40515eae94a2fde2ea delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8b186147e95653d8a3b6c748d2482dcc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8b63e5d2df259415a70db075ccaee244 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8b8a7cdf7636a6d2aedba08f756d3c8d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8b99977c6b9caff09ba87062b2bccadb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8c02e46467ce79c739e0a68444178b2b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8c6134b631065799b0ec7bee4049c4ab delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8c7302f6a643e4dee153b7d114ed8783 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8c909900d173078a178b390295c8d241 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8d2904d8920390de86ee53bd52ff2f95 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8d3b9af6665ae182d39cfecb43e8c67c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8d6b378636ae0e195107452f07a9a1b6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8e2e34092cc5092b33f80789bd8cb5dd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8eb44802c4c08e84235edd0bf26ac87d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8ef6f0dee24d8b4ca5d6d12fc78846d3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8f45c8b37f65f5a3d96d99bbc42afd6a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8f59107da2dd4018eaaf396b9d4a5a36 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8f7dbcbed4677531f01a98f09b78e579 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_8fe1ec9a1ace4c1e42a2f556662301f2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9064761135752f81f7ad8b6ebd661023 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_907c362f4f2f6e400df8ac189f9f1eb1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9087759ac2d7809daa14034e92904b12 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_90b94e25c780902f5f539c288bfcf537 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_90ede0d038bcbb6aceea8fbde52f2641 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_90fe76e7383355fe08eb307219e2d816 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9198bcfeff6d315cf4fafa6370065a03 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_92c58ef6f3c99152d2ba186841a33c7b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_92efa0c840cc52c16596b78a5df32412 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_93f7f0d85f2643a76ef136e26da9e002 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_945189d26d0ba3469d510a86ca265d85 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_947481d841466c3a8daac3ad85aa115a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_947988622ee7c2525e6cd5d894c98ef1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_948b86a8e2a1e31167679e4a1470c860 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_94e7ec5946942ead16448a728abcdc37 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_953a407fb72605ba0a9a187e23cfe770 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_959d4c4a242dcfeb97c61a3ea2412504 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_95f18066efe5fc4f9cc8d0593c8439bd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9644fd126a3afc481ee73045a503baa4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_967b281af59e4a6dcf1cc1fbc3265a9f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_975c0b932ae0b2f7e84907a50b8ef1b1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_97f50b3d8687d8d47bd563960e1ff455 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_98892de18bd4ec4aebcc5bee99ab94ac delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_98bf4125aefc7ddc22a20c48a9619989 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_98d9a575de9d3f13469f22cccc63825b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_98ea1635d552d9a6892dd0ef71435f1d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9959bb4c68666277b4b2c0282a90487f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_995dec3fc6c2f46d050ebb554f56cd66 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_99ad47b9cdcc23e23f1e7795dab1738a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9a0e601461b3d9b104215919d000998b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9a7db4f72bf6ba3b89119eb1577e6915 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9a81f6a69cf9a752f08a42af7c04dd7e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9b0faa79ebcc182ad631d2427d6ccc41 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9b9ffd3f5d1b3b7e7fb4ab8021ee6724 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9c87061c647a1863348a102fda0a485b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9c98903028ece4cf33487e12338563b0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9cc05cc46ce95864ad3e87c922bd7d6e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9cc7d48622827c73b5c2800b90da6c71 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9cfbca439e6352c64927f83dfba56d33 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9d0f8c2d99f91d53540c981a669307b0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9d585af32abcbce5c19f7dc88013b509 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9d95d6e5b127e827982ebd70a7780ac5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9defc0b6e6f8e6a06175fd732c55f9f4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9e0ac6eb04ae0415245380aff8a7fe18 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9e48c6c6d01f1fd30c8ebe200c54ae74 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9ea742913c11d08c3a459e7cbdc48ea7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9eaed2cf9bc04a09871029820a0febdf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9f24d1e11f4da71f33ba80b598bf4635 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9f669749877accc7939a55a65470df73 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9fd8760c7cb04dc202cb2fcbd65fa171 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9fddcfde761802254047b04993e2653a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9fee4660d995f9fd6a5586af67f086ea delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_9ff67287131509f45cc8628249181573 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a04f945480a6c46840307cfd5cb133c7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a080edfb79e15193b1a986d2bd1c8fa4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a0cf773a2425baa5763a3c5151c1e6a3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a0ece2f1244996e6289cf22fbe69523b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a14487d530470e659ef4624121d3c2c1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a267492beef8994b2bea7a841d1a0cd8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a285d45c3472af1ffc36a684c856ec99 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a35bdd52888e241d85684a6d02a68bde delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a3a3b332d752eebbfaa33f846f2011e8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a3d22e835cba5db3a924784879c04be4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a407d22c03234511a8692574b1afdb55 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a40a10b60dfb97885a13a60cd56ab03d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a41afc440e071af84d3aa05ac5272fc3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a4599efbaa95f71a3a07ef11cbdb2982 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a50197cb3ff817a6e011f450bfc33d48 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a50e65f017e7c264acc21fba0639a32a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a559140c7253e91fcd6a8f6f19e05bff delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a594961a601d02783f91faf40e98312c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a5e3f86f5e484f1b76040bba1e5e14a8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a6ad3eb821ff648a929de3ed3197bcb2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a7cb6058536c2c10eb132b9ea2273034 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a7fa2f402ec1a091b24e4dbe172fb7ce delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a80186e2242223f495ecfdcca4153e08 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a81980865d0ec43ef0c5583e07965859 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a87aa73edef2fa7a6931806265cea0c9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a894ac582bee396f28b4a5b6d76632d1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a8eed80b4e6c374bce30583a334fd1be delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a8f1dd35649e9f13895d193df5dcb5ba delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a9196e31df6affc38cd0927354660e20 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a95b3114ad98063dd3ba2e3ff6ee4089 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a9641cbe82cd2fba425d8bf3f1fa632b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_a9dc429cc9b5c625c3b61d1647124d00 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_aa0e7054e4831c8e95c9d968a25ca3c4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_aa6859d5e79333e0b7fbf8152c956007 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_aa8f8b163bab75cba3311559cd7cc687 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ab4e2933297bec79168036dc7f3d1c4c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ab893deedb9409a65c6b4c2e1fd21135 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ab89791d24d1aaadefc456a1086a2560 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_abb03b95526f02aafe816672af681ebc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_abb7a002d65efea430cb0af30b78a078 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ac0e42e33c97dd59d436c667a5b3eead delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ac4027a844896a8a22c308c293a15f65 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_acab22928f8fdc15eb012b3494e41797 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ad5c7d07120b55ddac12237c4bab0e2f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ada72e41e49e00d5f656e5da43eb6bc6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ada8c2049e1c9327b3a50dc425f6bfbe delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ae1d8a22efd12912343d561876fdfdc5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ae234126326f18ee35485c944b7e5848 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ae34a72b4fa6668803ea46d383ea6f24 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ae52f8b68722f536aa70b7590035f9e3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ae64540044c09c7b795ced78505c9b4d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ae70ef607969820ee6fa532c7c516c0b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_aeafd646edb77412e928721505f984c7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_aeb687357e6f692b2199e9e800d56673 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_aefb95455125a664bb95a1c2ef06f8ad delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_af4792ba9e683db497c8912f32609da9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_afab05d39b52ab8998daa2eda66b6aee delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_afeb67ef6a5ce209e756766ec3ffe2ce delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b024fc7d8e3356fcadfeeeb2d14b1815 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b0c1002f2db893b0a6af43e0b577dfe3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b11cbd54af2f7c7e43bcc82b0279e10b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b17c2592ffc464b4ba0b679af70ded2b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b1929d13ac18473aeea275a695808d5c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b1da207d6c31fc9946ba3621f021ae80 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b237e22685289229a1db2608891cd30c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b2a31fa222e71d201828baf1ecf324d2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b2eaddc565cbb2b2e87616e79caeeffa delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b359782f5ccdab7e806fbeddf150dcbc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b36f9ea866728a5fd33680170aa21c86 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b3a6ab8bfc108f99d05e83799ba0c606 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b3b8e7ee9034bc9159f2b56875fd7cc8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b41c95ac09de774cf44fb1e10f5e904d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b44275f8a8435fbf5025d135126479b1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b491790afd14563692ea36be5588eabb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b49f8d76aa16a1f4aa34d99f4cc1e1b4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b4dbf3766611612508d08f46c9b190f2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b4ea676cb3216a36a1693463ef5b7c82 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b529a32f36544fee5e632be00fac097c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b53d30d81ffaadae86b647f47f6a1160 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b53d83093d2c2083ed7132b123982264 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b5510f652a52854c7651f6918feb977e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b57a0d89a948fe34f8dacda9cb43bae4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b58721ac9be6edd4764bf6f8780cefc1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b5a60f9daa55f9734f493d6ac0458573 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b6ec78ab609d0df2fd508e9163c253e7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b6f50ca4efe83c023d25e4ebaf6487db delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b79d07314aef27e7f198bbb8b140a36a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b820236352b2730de43cf836422e206e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b84c49ccaa5176f3f60d430f254f4009 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b908569ab6c58bd1746f5f4fd534f934 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b91a01b1e5d207e45e16934c8ac97ee8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_b9c58c1055898aec49f2b876bee0989a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bac0d94744e5d5ef89296100c18f0090 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bac2cfc9597d42d210a3862582579fa8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bb4a64bd891cc061c3adefcb44477af4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bb87f20b1e8a384d46d56453cad1e43c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bc2eeb565a25074bbb1662c9574c76e6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bc471f7dacb30aaac0280f97b8b2a40a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bc6a3acc6bd9424ccd4f53381763a765 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bc9a6fcb99473c1d425a69fc74e2816b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bcba56fadcb6d5fa33aecbc0accdf024 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bd4a221108dfce794cd7f70d523dd168 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bdb7dda4a0ef116d409e5e69c1ac3fad delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bdec0ef240e9a5bb1a666d8984758976 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_be317991eb08458fb8e9abcf374bed36 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bf428a4caf8a7d4c47d26f32e16fe043 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_bfe6ee4113b5571017455a38ee1e2317 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c018a7218b523ecc2ade22f7aedd38f1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c064150f27b1dab4111a60ccc6f9d2fa delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c0ed531b0f4e24c41d874a91cba8c32e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c1f34ca67059e96e6bcd732eea2446bf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c1fe8bbe901ba4706855bd9eb723ba70 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c21b23debb7c016fc702f87a0294f3e8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c2426b9d31ca734eabd4e282665bcb9d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c26296dc097c2f01694ee80ae77eb6e9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c2ee1217613c2a80e949b8716990ca88 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c38c51006dab56733498c50180b3fabb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c3a730d7b6a59d913d50e31df3e4c3a5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c40e44707ce35c5ef27e8802aa39e47f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c441f7bf34ccd6ae14805365c2ab89c2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c45b5e61c6d053c4f763d91407f3c91a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c475fb1bab33463d842d886993c1571f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c47945969b61a07537f19f946a384741 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c48155c30b39c8362f86aef75c221163 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c542af71129f343b6408eade9270bd54 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c54748085a5be98912b747457ee83e87 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c54891068be346717c001cd9135f2f1a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c57f6f9decec3156c65ae42ec51d39d2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c621bb0f553660ec429aec2ca0f43023 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c6429f27fce95541dab9e8ed4952d4bf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c6bf258aae59585a0e4d3baa156de525 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c6cc348dc8a6b160339d4efeb4ad5a73 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c70b845bd7ace83384142056d6460d23 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c721d5b6b93058bc391ed27a94c9b40f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c75f86e937db953edf0dc710594a1a34 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c78586d22fded1470a8af498186b8e7a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c845a8b285996a7f190591807a2e5da3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c84f8233f589f47a1d1f3c95256a6d54 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_c8c9fc84e7bd6bb28854c759734a4aaf delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ca26d03afac9fb59c49d2459b766b0e2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cb10ef5334885e0f4bb07e60b95e4bea delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cb810d18223327abb72bbbce488255a2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cc6ca9b9be103498b3b3f9bebbfcca8e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cc7cc7d4d0e038443bc7f215fcf60584 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ccbfa7c487f33d217038668dba1c7f98 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cd426fff8fdfa8c52522fb101ed1c200 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cd6936d236e56a0958f326724caa9f66 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cd9a052a6c053712db213bcbd569b448 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cdb2d2c089e55ec49e126ffaee9da500 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cde83bbf5f7883231a8bcefdf4b5749f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cdf9116287630763b1acbe585ed5e0a2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ce5934a087e64591d7f2d218c00ea365 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ce8a8426d076db8a3d564204d4e29b24 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cea4f34bc0b31c76efbc1ff1a6dd88bb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_cf7075fc4f5727c449d2b7fa06303609 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d0054e42522dc3082a38d55702832585 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d053186c866c8aaafb3c49f5fed373fb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d082df7384cf4c3855e911af2e4a6d68 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d1b6c144193e51c481f30adaa6f5ddb3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d1d621d535d1444562ca2d1b7a43400a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d256ce4f2ded89a00bcf19cbcb1bed64 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d27d2227ad5637ccbac3579310e60b6d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d311a3d90755123ef2e6e86c68eefcf3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d35e6e95a5fdda69f32a5a8bdf8964ac delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d36cf7d1753dc1ef650e4ad031194f3b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d37c9bba5a42b3760ac4fedfe02002ce delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d438212c8192544d26843d87bfda1e5b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d44df14d2838d90e63d1c5ffeee18b63 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d48edd5255a24ae738e3a13c31f7bdb2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d51b539ad255419ea6fd83ba3e9caa39 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d5ee3033b6819cfd67d2ef4d8feadeae delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d6173d6126d730e93fa9cd6774f53be7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d655d61f4acc04d61814576220dda1a4 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d761d9849d639d0449a853e9965d2558 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d764f7b5069d52949a1249384c2bff40 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d82cdb26dd412905a1b72ed027a14fe7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d866f688079ed7f6798f6b2c37d479f9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d9079a969cbbecca3cbeab898a7b3d3a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d936dba3104d21be80694fa09c3f2e76 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d9507094e57544f8c58778996fe93796 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_d9de9a32167fd3c3625cc28150d3dc59 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_da17ec2d008cbcf1fccdade5739c1aa3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_da4be22b9206de27363e8a6a0e53ed6f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_da63331a5ba2e04a7f539fa874066438 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_da8ca3466e87e6afa9199bbf808a6e99 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_db1dc99bb1ae9f864d590d8d4951ea24 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_db3413134a45f8caafce26c4f5bf31c9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_db5cdce7ad0e207e29c025a404926a56 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_db6ae4770e9b9d1af93a1aa4823f8b56 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_db815a56ecd54cd9683ab4a1e5fe00d7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dbe10898134fde8c830ce6125d63547d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dc7ca58b2438ace110816de0b89071cb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dcd8063123fb5dc4da53f99e3be8a2f6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dce185e29b874f97b24d0246486f3634 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dcf331017d5be4b352f8f7234fbf6e50 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dcf395666a298642aa662bc593439f57 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dd395de0ebabc53b439f4fc9e32d60fc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_de195005e2ff63bd109984d154a398a3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_de495cd1a69c28af3b9398e92e94d21e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_dfcf80bc29fce6abfed5ac34bebf7c5c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e02cf9db82152079377afac29dee9f7e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e0d389d5ada1be1011461856fe6026d7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e0fc214acacaab4e1609c3b68e4a04ee delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e10dbe6740069aee59b04e33d58750cc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e13a7684ee74435983312a287efe4c85 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e180f60c178c65bb2e9d312b4530a437 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e214cc8e60797ecf4e3cbc8dad77b351 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e2463cceb2b637358d505ca930d980e5 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e28398cafa24c8e0e56db5aed7749dc7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e2c69c8fb699f8ccdd772818cc7a843b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e30bb2069903f00d5b2b403e63af7538 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e32f151f178fc3473d264598c4cdb3db delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e3cd81ee2a416b06478fbb48384a4536 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e3df5ff0de2d27045da872d3673acd8f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e454faf4a50341fd4fe7d3d7a4a8043a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e4e5ec23b16a1f4fa28b55e9fabb367d delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e50445bf32d3a170f42828268268b95f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e511429ccbb1b5bf87fd2654d2c93dfb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e512cfa96becba816ff098acd58d67d9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e595133187ee681f4d193ad6d3d98bf7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e62417d00dfab625e2e867bc95c0e6b3 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e7294a484f93c841c720dfddaad2fa75 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e78b800b29f053b098e046e43e2b5e32 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e79da2fabd48f5e436d0a2ae92858814 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e7a0cb5ac086583a7c4f433f5566dfe0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e7bf81464f2a282d2b5c37384544d992 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e7e0d10f34c130abe39787681ecc7c54 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e87478078e020e24d0779351c0f969b6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_e8a7bca6e77dfea8a08a9d85ea373b3e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ea261e39262abaa69f59218d58152e24 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eaca2607ee393620327eea92f80f61dc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eafee1426b1ca0cba1fef01042da24af delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eb0b3aa7fb842573df159a3cbfbc118c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eb1423e9f00c7c286a8de731475317ed delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eb5dc235fb964cb087b0581dc5470dcb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eb632c7b379753ce9e0678cc6e1fc4b7 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_eba6bb7a7e9f84453ff471f0de9c858a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ec5dd9dcf14935e06480e595c5378408 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ece749dc3266e76f800a73634c290360 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ed3e4c977232325dc987613963520ae2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ed5a34fc673a1877970f68358b1c8a2e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ed720542b7344966b8a96736178ecaf8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_edae8a6f1230dc09b4cb5a54d21be367 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ede9c689e49df248407a15a84fc3ab6e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ef7f937ea6a6f62a765a435db96aca63 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_effb84e824295ad73fbe605ac6fe2f88 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f0e668329a30681f9bfbc3cb07c4f5cd delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f0f092cee32c29d95e9bd7c7c30e20f2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f194bc98e8e4096a6b45e7fb11d139b2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f1adc2c0c56dc66a742546fd7f916722 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f1b44223c5587e630f814a8dccd57813 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f1b6dc29404814c5b7b518731d3ad515 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f1ed9645499bb8f575b5dc55017f6482 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f1f8d1c3218c6362dcf0711b6e569ec6 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f21a3956f18d80fdec12b29b03404111 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f2b140d9118c0885e76b7bb1a5b232d0 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f2c30586d756f874aa3952a62be05345 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f341b63a04b60a2b5b7df9ad6450e9f2 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f349b233d747db9b4973592d72ba103e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f36a1f4d2ff411d7442cfccbeff9c92f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f4a545daab3a7bbc90c7313ce16cd200 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f4a6ba717bff574a5108716d3c1b76e8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f54673683192fda4d1c05bc417825a4c delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f57e67551a8adca075901267474c5e02 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f7434453f5c9fefe400762eea3329b9f delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f86b00b21a16ae362e3e55e5cbbb49ad delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f88b647727d942b3ff67893febfa83ec delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f9047caa910fe889f68f301f00706b3b delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f9288a644472ee1e11539a71da2c16ac delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_f953c927cd6f250afb7d4bc8791a2506 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fa32595e8f8e23ab874e9247eb036ec1 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fabbd025bed38d86b6c790c3e2ae219e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_facf7bf4f85611dce0bc1077747eb283 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fbd736474197b68a63d2aa66da52e238 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fbf559b7fcb34e39382b7beb9e3a3052 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fc283dec0f73891e83fc082f138c358e delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fd3e050332ff331670681adaa7f3a04a delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fe0b40307095880975721f2e56e653cb delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fe92bea57dd460a4bde6b5a3b5b9f844 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_fedd27c97c990386b6b30a35d8da84dc delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ff4c8da7fd10a870809494bfdefa4cb9 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ffb15114fcaa6705fce00c84bef2acf8 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ffd5b0789f866679e1b3167ed8323759 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ffddcc106e6d3e46d1caa3c2dfddf4da delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ffdef08140c48ce0375a0a3d6313da12 delete mode 100644 www/fahrschultermin.de/storage/sessions/sess_ffe009470987847df4966990ac35d661 diff --git a/www/fahrschultermin.de/app/Http/Controllers/AppointmentsController.php b/www/fahrschultermin.de/app/Http/Controllers/AppointmentsController.php deleted file mode 100644 index 059c31e..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/AppointmentsController.php +++ /dev/null @@ -1,193 +0,0 @@ -query('from'); - $to = (string) $request->query('to'); - $instructorId = null; - if ($user['role'] === 'instructor') { - $instructor = (new InstructorRepository())->findByUserId((int) $user['tenant_id'], (int) $user['id']); - $instructorId = $instructor ? (int) $instructor['id'] : null; - } - $data = (new AppointmentRepository())->listForTenant( - (int) $user['tenant_id'], - $from, - $to, - $instructorId - ); - Response::json(['data' => $data]); - } - - public function validate(Request $request): void - { - $user = Auth::requireUser(); - $payload = $this->normalizePayload((int) $user['tenant_id'], $request->input()); - $warnings = (new CalendarService())->validate((int) $user['tenant_id'], $payload); - Response::json(['warnings' => $warnings, 'payload' => $payload]); - } - - public function store(Request $request): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher', 'instructor']); - $payload = $this->normalizePayload((int) $user['tenant_id'], $request->input()); - $warnings = (new CalendarService())->validate((int) $user['tenant_id'], $payload); - - if ($this->hasWarnings($warnings) && empty($payload['warning_acknowledged'])) { - Response::json(['message' => 'Warnings require acknowledgement', 'warnings' => $warnings], 409); - } - - $record = (new AppointmentRepository())->create((int) $user['tenant_id'], $payload, (int) $user['id']); - Response::json([ - 'data' => $record, - 'warnings' => $warnings, - 'progress' => $payload['student_id'] ? (new RequirementService())->progressForStudent((int) $payload['student_id']) : [], - ], 201); - } - - public function update(Request $request, array $params): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher', 'instructor']); - $payload = $this->normalizePayload((int) $user['tenant_id'], $request->input()); - $warnings = (new CalendarService())->validate((int) $user['tenant_id'], $payload, (int) $params['id']); - - if ($this->hasWarnings($warnings) && empty($payload['warning_acknowledged'])) { - Response::json(['message' => 'Warnings require acknowledgement', 'warnings' => $warnings], 409); - } - - $record = (new AppointmentRepository())->update((int) $user['tenant_id'], (int) $params['id'], $payload, (int) $user['id']); - Response::json([ - 'data' => $record, - 'warnings' => $warnings, - 'progress' => $payload['student_id'] ? (new RequirementService())->progressForStudent((int) $payload['student_id']) : [], - ]); - } - - public function destroy(Request $request, array $params): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher']); - (new AppointmentRepository())->delete((int) $user['tenant_id'], (int) $params['id']); - Response::noContent(); - } - - private function normalizePayload(int $tenantId, array $payload): array - { - $referenceRepository = new ReferenceDataRepository(); - $lessonType = $referenceRepository->findLessonType($tenantId, (int) $payload['lesson_type_id']); - if ($lessonType === null) { - Response::json(['message' => 'Unbekannte Stundenart'], 422); - } - - $student = null; - if (!empty($payload['student_id'])) { - // Reject student_id if lesson_type does not allow it - if ((int) $lessonType['allows_student'] !== 1) { - Response::json(['message' => 'Bei dieser Stundenart kann kein Fahrschüler ausgewählt werden'], 422); - } - - $student = (new StudentRepository())->find($tenantId, (int) $payload['student_id']); - if ($student === null) { - Response::json(['message' => 'Unbekannter Fahrschueler'], 422); - } - - if ( - $lessonType['category'] === 'student' - && !$referenceRepository->isLessonTypeVisibleForTemplate($tenantId, (int) $lessonType['id'], (int) $student['template_id']) - ) { - Response::json(['message' => 'Diese Stundenart ist fuer die Fuehrerscheinklasse nicht freigegeben'], 422); - } - } - - $startAt = new \DateTimeImmutable((string) $payload['start_at']); - $baseDuration = max(1, (int) $lessonType['default_duration']); - $providedEndAt = !empty($payload['end_at']) ? new \DateTimeImmutable((string) $payload['end_at']) : null; - - if ($providedEndAt instanceof \DateTimeImmutable && $providedEndAt > $startAt) { - $endAt = $providedEndAt; - $duration = max(1, (int) round(($endAt->getTimestamp() - $startAt->getTimestamp()) / 60)); - $units = (int) $lessonType['fixed_duration'] === 1 - ? 1 - : max(1, (int) round($duration / $baseDuration)); - } else { - $units = max(1, (int) ($payload['units'] ?? 1)); - $duration = (int) $lessonType['fixed_duration'] === 1 - ? $baseDuration - : $baseDuration * $units; - $endAt = $startAt->modify(sprintf('+%d minutes', $duration)); - } - - $title = $payload['title'] ?? $lessonType['name'] ?? 'Termin'; - $unitsBreakdown = []; - - if ($lessonType && (int) $lessonType['is_counted'] === 1 && !empty($payload['student_id'])) { - $requirementKey = $lessonType['effective_requirement_key'] ?? $lessonType['requirement_key']; - if ($student !== null && (int) ($student['template_is_combination'] ?? 0) === 1) { - $requirementKey = $this->requirementKeyForPhase($student['requirements'] ?? [], $requirementKey, (string) ($payload['requirement_phase'] ?? '')); - } - - $unitsBreakdown[] = [ - 'requirement_key' => $requirementKey, - 'label' => $lessonType['name'], - 'units_counted' => $units, - ]; - } - - return [ - 'student_id' => $payload['student_id'] ?? null, - 'instructor_id' => (int) $payload['instructor_id'], - 'lesson_type_id' => (int) $payload['lesson_type_id'], - 'title' => $title, - 'category' => $lessonType['category'] ?? ($payload['category'] ?? 'student'), - 'start_at' => $startAt->format(DATE_ATOM), - 'end_at' => $endAt->format(DATE_ATOM), - 'units' => $units, - 'status' => $payload['status'] ?? 'planned', - 'notes' => $payload['notes'] ?? '', - 'notes_private' => $payload['notes_private'] ?? '', - 'warning_acknowledged' => !empty($payload['warning_acknowledged']), - 'units_breakdown' => $unitsBreakdown, - ]; - } - - private function hasWarnings(array $warnings): bool - { - return !empty($warnings['conflicts']) || !empty($warnings['rest_period_warnings']); - } - - private function requirementKeyForPhase(array $requirements, string $baseRequirementKey, string $phaseLabel): string - { - $matchingRows = array_values(array_filter( - $requirements, - static fn (array $row): bool => str_ends_with((string) $row['requirement_key'], '::' . $baseRequirementKey) - || (string) $row['requirement_key'] === $baseRequirementKey - )); - - if ($matchingRows === []) { - return $baseRequirementKey; - } - - foreach ($matchingRows as $row) { - if ((string) ($row['phase_label'] ?? '') === $phaseLabel) { - return (string) $row['requirement_key']; - } - } - - return (string) $matchingRows[0]['requirement_key']; - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/AuthController.php b/www/fahrschultermin.de/app/Http/Controllers/AuthController.php deleted file mode 100644 index a71b131..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/AuthController.php +++ /dev/null @@ -1,49 +0,0 @@ -input(); - $user = (new UserRepository())->findByEmail(trim((string) ($payload['email'] ?? ''))); - - if ($user === null || !password_verify((string) ($payload['password'] ?? ''), $user['password_hash'])) { - Response::json(['message' => 'Ungueltige Zugangsdaten'], 422); - } - - if (!(int) $user['is_active'] || ((int) ($user['tenant_is_active'] ?? 1) !== 1 && $user['role'] !== 'superadmin')) { - Response::json(['message' => 'Benutzer oder Mandant ist deaktiviert'], 403); - } - - $_SESSION['user_id'] = (int) $user['id']; - - Response::json(['user' => $this->sanitizeUser($user)]); - } - - public function logout(): void - { - session_destroy(); - Response::noContent(); - } - - public function me(): void - { - $user = Auth::user(); - Response::json(['user' => $user ? $this->sanitizeUser($user) : null]); - } - - private function sanitizeUser(array $user): array - { - unset($user['password_hash']); - return $user; - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/BootstrapController.php b/www/fahrschultermin.de/app/Http/Controllers/BootstrapController.php deleted file mode 100644 index 0a9bf53..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/BootstrapController.php +++ /dev/null @@ -1,76 +0,0 @@ - ['user' => $user]]; - - if ($user['role'] === 'superadmin') { - $payload['tenants'] = (new TenantRepository())->all(); - $payload['users'] = (new UserRepository())->allUsers(); - Response::json($payload); - } - - $tenantId = (int) $user['tenant_id']; - $studentRepository = new StudentRepository(); - $students = $studentRepository->allForTenant($tenantId); - $requirementService = new RequirementService(); - - foreach ($students as &$student) { - $student['progress'] = $requirementService->progressForStudent((int) $student['id']); - } - - $payload['tenant'] = (new TenantRepository())->find($tenantId); - $payload['students'] = $students; - $payload['templates'] = (new ReferenceDataRepository())->templates($tenantId); - $payload['lessonTypes'] = (new ReferenceDataRepository())->lessonTypes($tenantId); - $payload['instructors'] = (new InstructorRepository())->allForTenant($tenantId); - $payload['users'] = $user['role'] === 'tenant_admin' - ? (new UserRepository())->allForTenant($tenantId) - : []; - $instructorId = null; - if ($user['role'] === 'instructor') { - $instructor = (new InstructorRepository())->findByUserId($tenantId, (int) $user['id']); - $instructorId = $instructor ? (int) $instructor['id'] : null; - } - - $from = $request->query('from', gmdate('Y-m-d\T00:00:00\Z', strtotime('monday this week'))); - $to = $request->query('to', gmdate('Y-m-d\T00:00:00\Z', strtotime('+7 day', strtotime($from)))); - $payload['sunTimes'] = (new SunTimesService())->forRange($payload['tenant'], (string) $from, (string) $to); - $payload['dayMeta'] = (new HolidayService())->forRange($payload['tenant'], (string) $from, (string) $to); - $payload['appointments'] = (new AppointmentRepository())->listForTenant( - $tenantId, - (string) $from, - (string) $to, - $instructorId - ); - $payload['nextAppointment'] = (new AppointmentRepository())->nextForTenant( - $tenantId, - gmdate(DATE_ATOM), - $instructorId - ); - - Response::json($payload); - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/InstructorsController.php b/www/fahrschultermin.de/app/Http/Controllers/InstructorsController.php deleted file mode 100644 index b72c60a..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/InstructorsController.php +++ /dev/null @@ -1,33 +0,0 @@ - (new InstructorRepository())->allForTenant((int) $user['tenant_id'])]); - } - - public function store(Request $request): void - { - $user = Auth::requireRole('tenant_admin'); - $record = (new InstructorRepository())->create((int) $user['tenant_id'], $request->input()); - Response::json(['data' => $record], 201); - } - - public function update(Request $request, array $params): void - { - $user = Auth::requireRole('tenant_admin'); - $record = (new InstructorRepository())->update((int) $user['tenant_id'], (int) $params['id'], $request->input()); - Response::json(['data' => $record]); - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/ReferenceDataController.php b/www/fahrschultermin.de/app/Http/Controllers/ReferenceDataController.php deleted file mode 100644 index 71b091c..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/ReferenceDataController.php +++ /dev/null @@ -1,90 +0,0 @@ - (new ReferenceDataRepository())->lessonTypes((int) $user['tenant_id'])]); - } - - public function storeLessonType(Request $request): void - { - $user = Auth::requireRole('tenant_admin'); - $record = (new ReferenceDataRepository())->createLessonType((int) $user['tenant_id'], $request->input()); - Response::json(['data' => $record], 201); - } - - public function updateLessonType(Request $request, array $params): void - { - $user = Auth::requireRole('tenant_admin'); - $record = (new ReferenceDataRepository())->updateLessonType((int) $user['tenant_id'], (int) $params['id'], $request->input()); - Response::json(['data' => $record]); - } - - public function destroyLessonType(Request $request, array $params): void - { - $user = Auth::requireRole('tenant_admin'); - - try { - $deleted = (new ReferenceDataRepository())->deleteLessonType((int) $user['tenant_id'], (int) $params['id']); - } catch (\RuntimeException $exception) { - Response::json(['message' => $exception->getMessage()], 409); - } - - if (!$deleted) { - Response::json(['message' => 'Not found'], 404); - } - - Response::noContent(); - } - - public function reorderLessonTypes(Request $request): void - { - $user = Auth::requireRole('tenant_admin'); - $records = (new ReferenceDataRepository())->reorderLessonTypes( - (int) $user['tenant_id'], - (array) ($request->input()['lesson_type_ids'] ?? []) - ); - Response::json(['data' => $records]); - } - - public function updateLessonTypeMatrix(Request $request): void - { - $user = Auth::requireRole('tenant_admin'); - $records = (new ReferenceDataRepository())->updateLessonTypeMatrix( - (int) $user['tenant_id'], - (array) ($request->input()['rows'] ?? []) - ); - Response::json(['data' => $records]); - } - - public function templates(): void - { - $user = Auth::requireUser(); - Response::json(['data' => (new ReferenceDataRepository())->templates((int) $user['tenant_id'])]); - } - - public function storeTemplate(Request $request): void - { - $user = Auth::requireRole('tenant_admin'); - $record = (new ReferenceDataRepository())->createTemplate((int) $user['tenant_id'], $request->input()); - Response::json(['data' => $record], 201); - } - - public function updateTemplate(Request $request, array $params): void - { - $user = Auth::requireRole('tenant_admin'); - $record = (new ReferenceDataRepository())->updateTemplate((int) $user['tenant_id'], (int) $params['id'], $request->input()); - Response::json(['data' => $record]); - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/StudentsController.php b/www/fahrschultermin.de/app/Http/Controllers/StudentsController.php deleted file mode 100644 index 8323549..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/StudentsController.php +++ /dev/null @@ -1,78 +0,0 @@ -allForTenant((int) $user['tenant_id']); - $requirements = new RequirementService(); - - foreach ($students as &$student) { - $student['progress'] = $requirements->progressForStudent((int) $student['id']); - } - - Response::json(['data' => $students]); - } - - public function store(Request $request): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher']); - $student = (new StudentRepository())->create((int) $user['tenant_id'], $request->input()); - $student['progress'] = (new RequirementService())->progressForStudent((int) $student['id']); - - Response::json(['data' => $student], 201); - } - - public function update(Request $request, array $params): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher']); - $student = (new StudentRepository())->update((int) $user['tenant_id'], (int) $params['id'], $request->input()); - - if ($student === null) { - Response::json(['message' => 'Not found'], 404); - } - - $student['progress'] = (new RequirementService())->progressForStudent((int) $student['id']); - Response::json(['data' => $student]); - } - - public function updateTraining(Request $request, array $params): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher']); - $student = (new StudentRepository())->updatePriorCompletedUnits( - (int) $user['tenant_id'], - (int) $params['id'], - $request->input()['rows'] ?? [] - ); - - if ($student === null) { - Response::json(['message' => 'Not found'], 404); - } - - $student['progress'] = (new RequirementService())->progressForStudent((int) $student['id']); - Response::json(['data' => $student]); - } - - public function destroy(Request $request, array $params): void - { - $user = Auth::requireRole(['tenant_admin', 'dispatcher']); - $deleted = (new StudentRepository())->delete((int) $user['tenant_id'], (int) $params['id']); - - if (!$deleted) { - Response::json(['message' => 'Not found'], 404); - } - - Response::noContent(); - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/TenantsController.php b/www/fahrschultermin.de/app/Http/Controllers/TenantsController.php deleted file mode 100644 index cf238c6..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/TenantsController.php +++ /dev/null @@ -1,40 +0,0 @@ - (new TenantRepository())->all()]); - } - - public function store(Request $request): void - { - Auth::requireRole('superadmin'); - $tenant = (new TenantRepository())->create($request->input()); - Response::json(['data' => $tenant], 201); - } - - public function update(Request $request, array $params): void - { - Auth::requireRole('superadmin'); - $tenant = (new TenantRepository())->update((int) $params['id'], $request->input()); - Response::json(['data' => $tenant]); - } - - public function updateOwn(Request $request): void - { - $user = Auth::requireRole('tenant_admin'); - $tenant = (new TenantRepository())->updateForTenantAdmin((int) $user['tenant_id'], $request->input()); - Response::json(['data' => $tenant]); - } -} diff --git a/www/fahrschultermin.de/app/Http/Controllers/UsersController.php b/www/fahrschultermin.de/app/Http/Controllers/UsersController.php deleted file mode 100644 index 364acc5..0000000 --- a/www/fahrschultermin.de/app/Http/Controllers/UsersController.php +++ /dev/null @@ -1,51 +0,0 @@ - (new UserRepository())->allUsers()]); - } - - Response::json(['data' => (new UserRepository())->allForTenant((int) $user['tenant_id'])]); - } - - public function store(Request $request): void - { - $user = Auth::requireRole(['tenant_admin', 'superadmin']); - $payload = $request->input(); - if ($user['role'] !== 'superadmin') { - $payload['tenant_id'] = (int) $user['tenant_id']; - } - $record = (new UserRepository())->create($payload); - unset($record['password_hash']); - Response::json(['data' => $record], 201); - } - - public function update(Request $request, array $params): void - { - $user = Auth::requireRole(['tenant_admin', 'superadmin']); - $payload = $request->input(); - if ($user['role'] !== 'superadmin') { - $payload['tenant_id'] = (int) $user['tenant_id']; - } - $record = (new UserRepository())->update((int) $params['id'], $payload); - if ($record === null) { - Response::json(['message' => 'Not found'], 404); - } - unset($record['password_hash']); - Response::json(['data' => $record]); - } -} diff --git a/www/fahrschultermin.de/app/Repositories/AppointmentRepository.php b/www/fahrschultermin.de/app/Repositories/AppointmentRepository.php deleted file mode 100644 index afe0f47..0000000 --- a/www/fahrschultermin.de/app/Repositories/AppointmentRepository.php +++ /dev/null @@ -1,292 +0,0 @@ - :from'; - $params = [ - 'tenant_id' => $tenantId, - 'from' => $from, - 'to' => $to, - ]; - - if ($instructorId !== null) { - $sql .= ' AND a.instructor_id = :instructor_id'; - $params['instructor_id'] = $instructorId; - } - - $sql .= ' ORDER BY a.start_at'; - $statement = $this->db->prepare($sql); - $statement->execute($params); - - return $statement->fetchAll(); - } - - public function find(int $tenantId, int $id): ?array - { - $statement = $this->db->prepare('SELECT * FROM appointments WHERE tenant_id = :tenant_id AND id = :id'); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - $appointment = $statement->fetch() ?: null; - - if ($appointment !== null) { - $appointment['units_breakdown'] = $this->units((int) $appointment['id']); - } - - return $appointment; - } - - public function create(int $tenantId, array $data, int $actorId): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO appointments - (tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, notes_private, warning_acknowledged, created_by, updated_by, created_at, updated_at) - VALUES - (:tenant_id, :student_id, :instructor_id, :lesson_type_id, :title, :category, :start_at, :end_at, :units, :status, :notes, :notes_private, :warning_acknowledged, :created_by, :updated_by, :created_at, :updated_at)' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'student_id' => $data['student_id'] ?: null, - 'instructor_id' => $data['instructor_id'], - 'lesson_type_id' => $data['lesson_type_id'], - 'title' => $data['title'], - 'category' => $data['category'], - 'start_at' => $data['start_at'], - 'end_at' => $data['end_at'], - 'units' => (int) $data['units'], - 'status' => $data['status'], - 'notes' => $data['notes'] ?? '', - 'notes_private' => $data['notes_private'] ?? '', - 'warning_acknowledged' => !empty($data['warning_acknowledged']) ? 1 : 0, - 'created_by' => $actorId, - 'updated_by' => $actorId, - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - - $appointmentId = (int) $this->lastInsertId(); - $this->replaceUnits($appointmentId, $data['units_breakdown'] ?? []); - - return $this->find($tenantId, $appointmentId); - } - - public function update(int $tenantId, int $id, array $data, int $actorId): ?array - { - $statement = $this->db->prepare( - 'UPDATE appointments - SET student_id = :student_id, instructor_id = :instructor_id, lesson_type_id = :lesson_type_id, - title = :title, category = :category, start_at = :start_at, end_at = :end_at, units = :units, - status = :status, notes = :notes, notes_private = :notes_private, warning_acknowledged = :warning_acknowledged, - updated_by = :updated_by, updated_at = :updated_at - WHERE tenant_id = :tenant_id AND id = :id' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'id' => $id, - 'student_id' => $data['student_id'] ?: null, - 'instructor_id' => $data['instructor_id'], - 'lesson_type_id' => $data['lesson_type_id'], - 'title' => $data['title'], - 'category' => $data['category'], - 'start_at' => $data['start_at'], - 'end_at' => $data['end_at'], - 'units' => (int) $data['units'], - 'status' => $data['status'], - 'notes' => $data['notes'] ?? '', - 'notes_private' => $data['notes_private'] ?? '', - 'warning_acknowledged' => !empty($data['warning_acknowledged']) ? 1 : 0, - 'updated_by' => $actorId, - 'updated_at' => $this->now(), - ]); - - $this->replaceUnits($id, $data['units_breakdown'] ?? []); - - return $this->find($tenantId, $id); - } - - public function delete(int $tenantId, int $id): void - { - $statement = $this->db->prepare('DELETE FROM appointments WHERE tenant_id = :tenant_id AND id = :id'); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - } - - public function units(int $appointmentId): array - { - $statement = $this->db->prepare('SELECT * FROM appointment_units WHERE appointment_id = :appointment_id'); - $statement->execute(['appointment_id' => $appointmentId]); - - return $statement->fetchAll(); - } - - public function overlappingForInstructor(int $tenantId, int $instructorId, string $from, string $to, ?int $ignoreId = null): array - { - $sql = 'SELECT * FROM appointments - WHERE tenant_id = :tenant_id AND instructor_id = :instructor_id - AND start_at < :to AND end_at > :from'; - $params = [ - 'tenant_id' => $tenantId, - 'instructor_id' => $instructorId, - 'from' => $from, - 'to' => $to, - ]; - - if ($ignoreId !== null) { - $sql .= ' AND id != :ignore_id'; - $params['ignore_id'] = $ignoreId; - } - - $statement = $this->db->prepare($sql); - $statement->execute($params); - - return $statement->fetchAll(); - } - - public function overlappingForStudent(int $tenantId, int $studentId, string $from, string $to, ?int $ignoreId = null): array - { - $sql = 'SELECT * FROM appointments - WHERE tenant_id = :tenant_id AND student_id = :student_id - AND start_at < :to AND end_at > :from'; - $params = [ - 'tenant_id' => $tenantId, - 'student_id' => $studentId, - 'from' => $from, - 'to' => $to, - ]; - - if ($ignoreId !== null) { - $sql .= ' AND id != :ignore_id'; - $params['ignore_id'] = $ignoreId; - } - - $statement = $this->db->prepare($sql); - $statement->execute($params); - - return $statement->fetchAll(); - } - - public function lastRestRelevantForInstructor(int $tenantId, int $instructorId, string $beforeStart, ?int $ignoreId = null): ?array - { - $sql = 'SELECT a.*, lt.name AS lesson_type_name - FROM appointments a - JOIN lesson_types lt ON lt.id = a.lesson_type_id - WHERE a.tenant_id = :tenant_id - AND a.instructor_id = :instructor_id - AND lt.is_rest_relevant = 1 - AND a.end_at <= :before_start'; - $params = [ - 'tenant_id' => $tenantId, - 'instructor_id' => $instructorId, - 'before_start' => $beforeStart, - ]; - - if ($ignoreId !== null) { - $sql .= ' AND a.id != :ignore_id'; - $params['ignore_id'] = $ignoreId; - } - - $sql .= ' ORDER BY a.end_at DESC LIMIT 1'; - $statement = $this->db->prepare($sql); - $statement->execute($params); - - return $statement->fetch() ?: null; - } - - public function hasRestRelevantAfterStartOnDay(int $tenantId, int $instructorId, string $dayStart, string $dayEnd, string $startAt): bool - { - $statement = $this->db->prepare( - 'SELECT 1 - FROM appointments a - JOIN lesson_types lt ON lt.id = a.lesson_type_id - WHERE a.tenant_id = :tenant_id - AND a.instructor_id = :instructor_id - AND lt.is_rest_relevant = 1 - AND a.start_at < :day_end - AND a.end_at > :day_start - AND a.end_at > :start_at - LIMIT 1' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'instructor_id' => $instructorId, - 'day_start' => $dayStart, - 'day_end' => $dayEnd, - 'start_at' => $startAt, - ]); - - return (bool) $statement->fetchColumn(); - } - - public function nextForTenant(int $tenantId, string $from, ?int $instructorId = null): ?array - { - $sql = 'SELECT a.*, s.first_name AS student_first_name, s.last_name AS student_last_name, - i.first_name AS instructor_first_name, i.last_name AS instructor_last_name, - lt.name AS lesson_type_name - FROM appointments a - JOIN instructors i ON i.id = a.instructor_id - LEFT JOIN students s ON s.id = a.student_id - JOIN lesson_types lt ON lt.id = a.lesson_type_id - WHERE a.tenant_id = :tenant_id - AND a.start_at >= :from'; - $params = [ - 'tenant_id' => $tenantId, - 'from' => $from, - ]; - - if ($instructorId !== null) { - $sql .= ' AND a.instructor_id = :instructor_id'; - $params['instructor_id'] = $instructorId; - } - - $sql .= ' ORDER BY a.start_at ASC LIMIT 1'; - $statement = $this->db->prepare($sql); - $statement->execute($params); - - return $statement->fetch() ?: null; - } - - private function replaceUnits(int $appointmentId, array $rows): void - { - $delete = $this->db->prepare('DELETE FROM appointment_units WHERE appointment_id = :appointment_id'); - $delete->execute(['appointment_id' => $appointmentId]); - - $insert = $this->db->prepare( - 'INSERT INTO appointment_units (appointment_id, requirement_key, label, units_counted, created_at) - VALUES (:appointment_id, :requirement_key, :label, :units_counted, :created_at)' - ); - - foreach ($rows as $row) { - if ((int) ($row['units_counted'] ?? 0) <= 0) { - continue; - } - - $insert->execute([ - 'appointment_id' => $appointmentId, - 'requirement_key' => $row['requirement_key'] ?? null, - 'label' => $row['label'] ?? null, - 'units_counted' => (int) $row['units_counted'], - 'created_at' => $this->now(), - ]); - } - } -} diff --git a/www/fahrschultermin.de/app/Repositories/AppointmentRequestRepository.php b/www/fahrschultermin.de/app/Repositories/AppointmentRequestRepository.php deleted file mode 100644 index d7ce147..0000000 --- a/www/fahrschultermin.de/app/Repositories/AppointmentRequestRepository.php +++ /dev/null @@ -1,104 +0,0 @@ -db->prepare( - 'INSERT INTO appointment_requests - (student_user_id, instructor_id, lesson_type_id, requested_start, requested_end, notes) - VALUES (:student_user_id, :instructor_id, :lesson_type_id, :start, :end, :notes) - RETURNING *' - ); - $stmt->execute([ - 'student_user_id' => $studentUserId, - 'instructor_id' => $instructorId, - 'lesson_type_id' => $lessonTypeId, - 'start' => $start, - 'end' => $end, - 'notes' => $notes, - ]); - return $stmt->fetch(); - } - - public function findById(int $id): ?array - { - $stmt = $this->db->prepare('SELECT * FROM appointment_requests WHERE id = :id'); - $stmt->execute(['id' => $id]); - $result = $stmt->fetch(); - return $result ?: null; - } - - public function getPendingForInstructor(int $instructorId): array - { - $stmt = $this->db->prepare( - 'SELECT ar.*, - u.first_name AS student_first_name, u.last_name AS student_last_name, - lt.name AS lesson_type_name, lt.category - FROM appointment_requests ar - JOIN users u ON u.id = ar.student_user_id - JOIN lesson_types lt ON lt.id = ar.lesson_type_id - WHERE ar.instructor_id = :instructor_id AND ar.status = \'pending\' - ORDER BY ar.requested_start ASC' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getForStudent(int $studentUserId): array - { - $stmt = $this->db->prepare( - 'SELECT ar.*, lt.name AS lesson_type_name - FROM appointment_requests ar - JOIN lesson_types lt ON lt.id = ar.lesson_type_id - WHERE ar.student_user_id = :student_user_id - ORDER BY ar.requested_start DESC' - ); - $stmt->execute(['student_user_id' => $studentUserId]); - return $stmt->fetchAll(); - } - - public function confirm(int $id, int $responseBy, int $appointmentId): bool - { - $stmt = $this->db->prepare( - 'UPDATE appointment_requests - SET status = \'confirmed\', responded_at = NOW(), response_by = :response_by, - confirmed_appointment_id = :appointment_id - WHERE id = :id AND status = \'pending\' - RETURNING id' - ); - $stmt->execute(['id' => $id, 'response_by' => $responseBy, 'appointment_id' => $appointmentId]); - return (bool) $stmt->fetch(); - } - - public function reject(int $id, int $responseBy): bool - { - $stmt = $this->db->prepare( - 'UPDATE appointment_requests - SET status = \'rejected\', responded_at = NOW(), response_by = :response_by - WHERE id = :id AND status = \'pending\' - RETURNING id' - ); - $stmt->execute(['id' => $id, 'response_by' => $responseBy]); - return (bool) $stmt->fetch(); - } - - public function cancel(int $id): bool - { - $stmt = $this->db->prepare( - 'UPDATE appointment_requests SET status = \'cancelled\' WHERE id = :id RETURNING id' - ); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/BaseRepository.php b/www/fahrschultermin.de/app/Repositories/BaseRepository.php deleted file mode 100644 index 6e356f9..0000000 --- a/www/fahrschultermin.de/app/Repositories/BaseRepository.php +++ /dev/null @@ -1,28 +0,0 @@ -db = Database::connection(); - } - - protected function lastInsertId(): string - { - return Database::lastInsertId(); - } - - protected function now(): string - { - return gmdate('c'); - } -} diff --git a/www/fahrschultermin.de/app/Repositories/InstructorAvailabilityRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorAvailabilityRepository.php deleted file mode 100644 index ac371d8..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorAvailabilityRepository.php +++ /dev/null @@ -1,65 +0,0 @@ -db->prepare( - 'SELECT * FROM instructor_availability - WHERE instructor_id = :instructor_id - ORDER BY weekday, time_from' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getActiveForInstructor(int $instructorId): array - { - $stmt = $this->db->prepare( - 'SELECT * FROM instructor_availability - WHERE instructor_id = :instructor_id AND is_active = 1 - ORDER BY weekday, time_from' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function upsert(int $instructorId, array $entries): void - { - // Delete all existing, then insert new (full replace) - $this->db->beginTransaction(); - try { - $stmt = $this->db->prepare('DELETE FROM instructor_availability WHERE instructor_id = :instructor_id'); - $stmt->execute(['instructor_id' => $instructorId]); - - $insert = $this->db->prepare( - 'INSERT INTO instructor_availability (instructor_id, weekday, time_from, time_to, is_active) - VALUES (:instructor_id, :weekday, :time_from, :time_to, :is_active)' - ); - foreach ($entries as $e) { - $insert->execute([ - 'instructor_id' => $instructorId, - 'weekday' => (int) $e['weekday'], - 'time_from' => $e['time_from'], - 'time_to' => $e['time_to'], - 'is_active' => (int) ($e['is_active'] ?? 1), - ]); - } - $this->db->commit(); - } catch (\Throwable $e) { - $this->db->rollBack(); - throw $e; - } - } - - public function delete(int $id): bool - { - $stmt = $this->db->prepare('DELETE FROM instructor_availability WHERE id = :id RETURNING id'); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/InstructorBreakRuleRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorBreakRuleRepository.php deleted file mode 100644 index 779e036..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorBreakRuleRepository.php +++ /dev/null @@ -1,96 +0,0 @@ -db->prepare( - 'SELECT * FROM instructor_break_rules - WHERE instructor_id = :instructor_id - ORDER BY condition_type, threshold' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getActiveForInstructor(int $instructorId): array - { - $stmt = $this->db->prepare( - 'SELECT * FROM instructor_break_rules - WHERE instructor_id = :instructor_id AND is_active = 1 - ORDER BY condition_type, threshold' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function create( - int $instructorId, - string $conditionType, - string $operator, - float $threshold, - int $breakMinutes, - bool $isActive = true - ): array { - $stmt = $this->db->prepare( - 'INSERT INTO instructor_break_rules - (instructor_id, condition_type, operator, threshold, break_minutes, is_active) - VALUES (:instructor_id, :condition_type, :operator, :threshold, :break_minutes, :is_active) - RETURNING *' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'condition_type' => $conditionType, - 'operator' => $operator, - 'threshold' => $threshold, - 'break_minutes' => $breakMinutes, - 'is_active' => $isActive ? 1 : 0, - ]); - return $stmt->fetch(); - } - - public function update( - int $id, - string $conditionType, - string $operator, - float $threshold, - int $breakMinutes, - bool $isActive - ): bool { - $stmt = $this->db->prepare( - 'UPDATE instructor_break_rules - SET condition_type = :condition_type, operator = :operator, - threshold = :threshold, break_minutes = :break_minutes, is_active = :is_active - WHERE id = :id RETURNING id' - ); - $stmt->execute([ - 'id' => $id, - 'condition_type' => $conditionType, - 'operator' => $operator, - 'threshold' => $threshold, - 'break_minutes' => $breakMinutes, - 'is_active' => $isActive ? 1 : 0, - ]); - return (bool) $stmt->fetch(); - } - - public function delete(int $id): bool - { - $stmt = $this->db->prepare('DELETE FROM instructor_break_rules WHERE id = :id RETURNING id'); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } - - public function setActive(int $id, bool $isActive): bool - { - $stmt = $this->db->prepare( - 'UPDATE instructor_break_rules SET is_active = :is_active WHERE id = :id RETURNING id' - ); - $stmt->execute(['id' => $id, 'is_active' => $isActive ? 1 : 0]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/InstructorHomeToTenantRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorHomeToTenantRepository.php deleted file mode 100644 index 1eede00..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorHomeToTenantRepository.php +++ /dev/null @@ -1,56 +0,0 @@ -db->prepare( - 'SELECT h.*, t.name AS tenant_name - FROM instructor_home_to_tenant h - JOIN tenants t ON t.id = h.tenant_id - WHERE h.instructor_id = :instructor_id - ORDER BY t.name' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getMinutes(int $instructorId, int $tenantId): ?int - { - $stmt = $this->db->prepare( - 'SELECT minutes FROM instructor_home_to_tenant - WHERE instructor_id = :instructor_id AND tenant_id = :tenant_id' - ); - $stmt->execute(['instructor_id' => $instructorId, 'tenant_id' => $tenantId]); - $result = $stmt->fetch(); - return $result ? (int) $result['minutes'] : null; - } - - public function upsert(int $instructorId, int $tenantId, int $minutes): array - { - $stmt = $this->db->prepare( - 'INSERT INTO instructor_home_to_tenant (instructor_id, tenant_id, minutes) - VALUES (:instructor_id, :tenant_id, :minutes) - ON CONFLICT (instructor_id, tenant_id) - DO UPDATE SET minutes = :minutes - RETURNING *' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'tenant_id' => $tenantId, - 'minutes' => $minutes, - ]); - return $stmt->fetch(); - } - - public function delete(int $id): bool - { - $stmt = $this->db->prepare('DELETE FROM instructor_home_to_tenant WHERE id = :id RETURNING id'); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/InstructorRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorRepository.php deleted file mode 100644 index b4d90cf..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorRepository.php +++ /dev/null @@ -1,119 +0,0 @@ -db->prepare('SELECT * FROM instructors WHERE tenant_id = :tenant_id ORDER BY last_name, first_name'); - $statement->execute(['tenant_id' => $tenantId]); - - return $statement->fetchAll(); - } - - public function findByUserId(int $tenantId, int $userId): ?array - { - $statement = $this->db->prepare( - 'SELECT * FROM instructors WHERE tenant_id = :tenant_id AND user_id = :user_id LIMIT 1' - ); - $statement->execute(['tenant_id' => $tenantId, 'user_id' => $userId]); - - return $statement->fetch() ?: null; - } - - public function create(int $tenantId, array $data): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO instructors - (tenant_id, user_id, first_name, last_name, color, notes, is_active, pre_start_buffer_minutes, created_at, updated_at) - VALUES (:tenant_id, :user_id, :first_name, :last_name, :color, :notes, :is_active, :pre_start_buffer_minutes, :created_at, :updated_at)' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'user_id' => $data['user_id'] ?? null, - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'color' => $data['color'], - 'notes' => $data['notes'] ?? '', - 'is_active' => !empty($data['is_active']) ? 1 : 0, - 'pre_start_buffer_minutes' => max(0, (int) ($data['pre_start_buffer_minutes'] ?? 0)), - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - - return $this->find($tenantId, (int) $this->lastInsertId()); - } - - public function update(int $tenantId, int $id, array $data): ?array - { - $statement = $this->db->prepare( - 'UPDATE instructors - SET user_id = :user_id, first_name = :first_name, last_name = :last_name, color = :color, - notes = :notes, is_active = :is_active, pre_start_buffer_minutes = :pre_start_buffer_minutes, updated_at = :updated_at - WHERE tenant_id = :tenant_id AND id = :id' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'id' => $id, - 'user_id' => $data['user_id'] ?? null, - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'color' => $data['color'], - 'notes' => $data['notes'] ?? '', - 'is_active' => !empty($data['is_active']) ? 1 : 0, - 'pre_start_buffer_minutes' => max(0, (int) ($data['pre_start_buffer_minutes'] ?? 0)), - 'updated_at' => $this->now(), - ]); - - return $this->find($tenantId, $id); - } - - public function find(int $tenantId, int $id): ?array - { - $statement = $this->db->prepare('SELECT * FROM instructors WHERE tenant_id = :tenant_id AND id = :id'); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - - return $statement->fetch() ?: null; - } - - public function findById(int $id): ?array - { - $statement = $this->db->prepare('SELECT * FROM instructors WHERE id = :id'); - $statement->execute(['id' => $id]); - - return $statement->fetch() ?: null; - } - - public function listForTenant(int $tenantId): array - { - $statement = $this->db->prepare('SELECT * FROM instructors WHERE tenant_id = :tenant_id AND is_active = 1 ORDER BY last_name, first_name'); - $statement->execute(['tenant_id' => $tenantId]); - - return $statement->fetchAll(); - } - - public function updateSettings(int $instructorId, array $settings): bool - { - $allowed = ['max_daily_units', 'max_daily_override', 'max_weekly_units', 'max_weekly_override', 'booking_enabled']; - $sets = []; - $params = ['id' => $instructorId]; - foreach ($allowed as $key) { - if (array_key_exists($key, $settings)) { - $sets[] = "{$key} = :{$key}"; - $params[$key] = $settings[$key]; - } - } - if (empty($sets)) { - return false; - } - $sql = 'UPDATE instructors SET ' . implode(', ', $sets) . ', updated_at = :updated_at WHERE id = :id'; - $params['updated_at'] = $this->now(); - $statement = $this->db->prepare($sql); - $statement->execute($params); - return (bool) $statement->rowCount(); - } -} diff --git a/www/fahrschultermin.de/app/Repositories/InstructorTenantRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorTenantRepository.php deleted file mode 100644 index 6e4a0a8..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorTenantRepository.php +++ /dev/null @@ -1,70 +0,0 @@ -db->prepare( - 'SELECT it.*, t.name AS tenant_name - FROM instructor_tenants it - JOIN tenants t ON t.id = it.tenant_id - WHERE it.instructor_id = :instructor_id - ORDER BY it.is_primary DESC, t.name' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function isPrimary(int $instructorId, int $tenantId): bool - { - $stmt = $this->db->prepare( - 'SELECT 1 FROM instructor_tenants WHERE instructor_id = :instructor_id AND tenant_id = :tenant_id AND is_primary = 1' - ); - $stmt->execute(['instructor_id' => $instructorId, 'tenant_id' => $tenantId]); - return (bool) $stmt->fetch(); - } - - public function add(int $instructorId, int $tenantId, bool $isPrimary = false): array - { - $stmt = $this->db->prepare( - 'INSERT INTO instructor_tenants (instructor_id, tenant_id, is_primary) - VALUES (:instructor_id, :tenant_id, :is_primary) - ON CONFLICT (instructor_id, tenant_id) DO UPDATE SET is_primary = :is_primary - RETURNING *' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'tenant_id' => $tenantId, - 'is_primary' => $isPrimary ? 1 : 0, - ]); - return $stmt->fetch(); - } - - public function remove(int $instructorId, int $tenantId): bool - { - $stmt = $this->db->prepare( - 'DELETE FROM instructor_tenants WHERE instructor_id = :instructor_id AND tenant_id = :tenant_id RETURNING id' - ); - $stmt->execute(['instructor_id' => $instructorId, 'tenant_id' => $tenantId]); - return (bool) $stmt->fetch(); - } - - public function setPrimary(int $instructorId, int $tenantId): void - { - $this->db->beginTransaction(); - try { - $stmt = $this->db->prepare('UPDATE instructor_tenants SET is_primary = 0 WHERE instructor_id = :instructor_id'); - $stmt->execute(['instructor_id' => $instructorId]); - $stmt = $this->db->prepare('UPDATE instructor_tenants SET is_primary = 1 WHERE instructor_id = :instructor_id AND tenant_id = :tenant_id'); - $stmt->execute(['instructor_id' => $instructorId, 'tenant_id' => $tenantId]); - $this->db->commit(); - } catch (\Throwable $e) { - $this->db->rollBack(); - throw $e; - } - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/InstructorTravelTimeRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorTravelTimeRepository.php deleted file mode 100644 index 5d345df..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorTravelTimeRepository.php +++ /dev/null @@ -1,66 +0,0 @@ -db->prepare( - 'SELECT t.*, - ft.name AS from_tenant_name, - tt.name AS to_tenant_name - FROM instructor_travel_times t - JOIN tenants ft ON ft.id = t.from_tenant_id - JOIN tenants tt ON tt.id = t.to_tenant_id - WHERE t.instructor_id = :instructor_id - ORDER BY ft.name, tt.name' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getMinutes(int $instructorId, int $fromTenantId, int $toTenantId): ?int - { - $stmt = $this->db->prepare( - 'SELECT minutes FROM instructor_travel_times - WHERE instructor_id = :instructor_id - AND from_tenant_id = :from_tenant_id - AND to_tenant_id = :to_tenant_id' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'from_tenant_id' => $fromTenantId, - 'to_tenant_id' => $toTenantId, - ]); - $result = $stmt->fetch(); - return $result ? (int) $result['minutes'] : null; - } - - public function upsert(int $instructorId, int $fromTenantId, int $toTenantId, int $minutes): array - { - $stmt = $this->db->prepare( - 'INSERT INTO instructor_travel_times (instructor_id, from_tenant_id, to_tenant_id, minutes) - VALUES (:instructor_id, :from_tenant_id, :to_tenant_id, :minutes) - ON CONFLICT (instructor_id, from_tenant_id, to_tenant_id) - DO UPDATE SET minutes = :minutes - RETURNING *' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'from_tenant_id' => $fromTenantId, - 'to_tenant_id' => $toTenantId, - 'minutes' => $minutes, - ]); - return $stmt->fetch(); - } - - public function delete(int $id): bool - { - $stmt = $this->db->prepare('DELETE FROM instructor_travel_times WHERE id = :id RETURNING id'); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/InstructorVacationRepository.php b/www/fahrschultermin.de/app/Repositories/InstructorVacationRepository.php deleted file mode 100644 index 0824592..0000000 --- a/www/fahrschultermin.de/app/Repositories/InstructorVacationRepository.php +++ /dev/null @@ -1,54 +0,0 @@ -db->prepare( - 'SELECT * FROM instructor_vacations - WHERE instructor_id = :instructor_id - ORDER BY date_from ASC' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getForInstructorInRange(int $instructorId, string $from, string $to): array - { - $stmt = $this->db->prepare( - 'SELECT * FROM instructor_vacations - WHERE instructor_id = :instructor_id - AND date_from <= :to AND date_to >= :from - ORDER BY date_from ASC' - ); - $stmt->execute(['instructor_id' => $instructorId, 'from' => $from, 'to' => $to]); - return $stmt->fetchAll(); - } - - public function create(int $instructorId, string $dateFrom, string $dateTo, string $notes = ''): array - { - $stmt = $this->db->prepare( - 'INSERT INTO instructor_vacations (instructor_id, date_from, date_to, notes) - VALUES (:instructor_id, :date_from, :date_to, :notes) - RETURNING *' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'date_from' => $dateFrom, - 'date_to' => $dateTo, - 'notes' => $notes, - ]); - return $stmt->fetch(); - } - - public function delete(int $id): bool - { - $stmt = $this->db->prepare('DELETE FROM instructor_vacations WHERE id = :id RETURNING id'); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/PrivateAppointmentRepository.php b/www/fahrschultermin.de/app/Repositories/PrivateAppointmentRepository.php deleted file mode 100644 index f2040ec..0000000 --- a/www/fahrschultermin.de/app/Repositories/PrivateAppointmentRepository.php +++ /dev/null @@ -1,56 +0,0 @@ -db->prepare( - 'SELECT * FROM private_appointments - WHERE instructor_id = :instructor_id - ORDER BY date ASC, time_from ASC' - ); - $stmt->execute(['instructor_id' => $instructorId]); - return $stmt->fetchAll(); - } - - public function getForInstructorInRange(int $instructorId, string $from, string $to): array - { - $stmt = $this->db->prepare( - 'SELECT * FROM private_appointments - WHERE instructor_id = :instructor_id - AND date >= :from AND date <= :to - ORDER BY date ASC, time_from ASC' - ); - $stmt->execute(['instructor_id' => $instructorId, 'from' => $from, 'to' => $to]); - return $stmt->fetchAll(); - } - - public function create(int $instructorId, string $title, string $date, string $timeFrom, string $timeTo, string $color = '#9ca3af'): array - { - $stmt = $this->db->prepare( - 'INSERT INTO private_appointments (instructor_id, title, date, time_from, time_to, color) - VALUES (:instructor_id, :title, :date, :time_from, :time_to, :color) - RETURNING *' - ); - $stmt->execute([ - 'instructor_id' => $instructorId, - 'title' => $title, - 'date' => $date, - 'time_from' => $timeFrom, - 'time_to' => $timeTo, - 'color' => $color, - ]); - return $stmt->fetch(); - } - - public function delete(int $id): bool - { - $stmt = $this->db->prepare('DELETE FROM private_appointments WHERE id = :id RETURNING id'); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/ReferenceDataRepository.php b/www/fahrschultermin.de/app/Repositories/ReferenceDataRepository.php deleted file mode 100644 index 715930a..0000000 --- a/www/fahrschultermin.de/app/Repositories/ReferenceDataRepository.php +++ /dev/null @@ -1,515 +0,0 @@ - 'private_block', 'name' => 'Privat', 'color' => '#6B7280', 'default_duration' => 60, 'category' => 'private', 'sort_order' => 900], - ['system_key' => 'work_vehicle_care', 'name' => 'Fahrzeugpflege', 'color' => '#0E5D80', 'default_duration' => 60, 'category' => 'work', 'sort_order' => 910], - ['system_key' => 'work_office', 'name' => 'Buero', 'color' => '#8B5A2B', 'default_duration' => 60, 'category' => 'work', 'sort_order' => 920], - ['system_key' => 'work_transfer_drive', 'name' => 'Wechselfahrt', 'color' => '#3B7A57', 'default_duration' => 45, 'category' => 'work', 'sort_order' => 930], - ['system_key' => 'work_other', 'name' => 'Sonstige Taetigkeit', 'color' => '#7C3AED', 'default_duration' => 60, 'category' => 'work', 'sort_order' => 940], - ['system_key' => 'theory_a', 'name' => 'Theorie A', 'color' => '#C2410C', 'default_duration' => 90, 'category' => 'theory', 'sort_order' => 950], - ['system_key' => 'theory_b', 'name' => 'Theorie B', 'color' => '#A74826', 'default_duration' => 90, 'category' => 'theory', 'sort_order' => 960], - ['system_key' => 'theory_c', 'name' => 'Theorie C', 'color' => '#B45309', 'default_duration' => 90, 'category' => 'theory', 'sort_order' => 970], - ['system_key' => 'theory_d', 'name' => 'Theorie D', 'color' => '#BE123C', 'default_duration' => 90, 'category' => 'theory', 'sort_order' => 980], - ['system_key' => 'theory_t', 'name' => 'Theorie T', 'color' => '#047857', 'default_duration' => 90, 'category' => 'theory', 'sort_order' => 990], - ['system_key' => 'theory_bkf', 'name' => 'Theorie BKF', 'color' => '#1D4ED8', 'default_duration' => 90, 'category' => 'theory', 'sort_order' => 1000], - ]; - - public function requirementKeyForLessonType(array $lessonType): string - { - $key = trim((string) ($lessonType['requirement_key'] ?? '')); - return $key !== '' ? $key : 'lesson_type_' . (int) $lessonType['id']; - } - - public function lessonTypes(int $tenantId): array - { - $this->ensureDefaultPlanningTypes($tenantId); - $statement = $this->db->prepare('SELECT * FROM lesson_types WHERE tenant_id = :tenant_id ORDER BY sort_order, name'); - $statement->execute(['tenant_id' => $tenantId]); - $lessonTypes = $statement->fetchAll(); - $visibilityMap = $this->lessonTypeVisibilityMap($tenantId); - - foreach ($lessonTypes as &$lessonType) { - $lessonType['visible_template_ids'] = $visibilityMap[(int) $lessonType['id']] ?? []; - $lessonType['effective_requirement_key'] = $this->requirementKeyForLessonType($lessonType); - } - - return $lessonTypes; - } - - public function createLessonType(int $tenantId, array $data): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO lesson_types - (tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at) - VALUES - (:tenant_id, :name, :color, :default_duration, :category, :requirement_key, :is_billable, :is_counted, :is_rest_relevant, :fixed_duration, :sort_order, :created_at, :updated_at)' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'name' => $data['name'], - 'color' => $data['color'], - 'default_duration' => (int) $data['default_duration'], - 'category' => $data['category'], - 'requirement_key' => $data['requirement_key'] ?: null, - 'is_billable' => !empty($data['is_billable']) ? 1 : 0, - 'is_counted' => !empty($data['is_counted']) ? 1 : 0, - 'is_rest_relevant' => !empty($data['is_rest_relevant']) ? 1 : 0, - 'fixed_duration' => !empty($data['fixed_duration']) ? 1 : 0, - 'sort_order' => (int) ($data['sort_order'] ?? 0), - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - $lessonTypeId = (int) $this->lastInsertId(); - $this->replaceLessonTypeVisibility($tenantId, $lessonTypeId, $data['visible_template_ids'] ?? null); - - return $this->findLessonType($tenantId, $lessonTypeId); - } - - public function updateLessonType(int $tenantId, int $id, array $data): ?array - { - $statement = $this->db->prepare( - 'UPDATE lesson_types - SET name = :name, color = :color, default_duration = :default_duration, category = :category, - requirement_key = :requirement_key, is_billable = :is_billable, is_counted = :is_counted, - is_rest_relevant = :is_rest_relevant, fixed_duration = :fixed_duration, sort_order = :sort_order, - updated_at = :updated_at - WHERE id = :id AND tenant_id = :tenant_id' - ); - $statement->execute([ - 'id' => $id, - 'tenant_id' => $tenantId, - 'name' => $data['name'], - 'color' => $data['color'], - 'default_duration' => (int) $data['default_duration'], - 'category' => $data['category'], - 'requirement_key' => $data['requirement_key'] ?: null, - 'is_billable' => !empty($data['is_billable']) ? 1 : 0, - 'is_counted' => !empty($data['is_counted']) ? 1 : 0, - 'is_rest_relevant' => !empty($data['is_rest_relevant']) ? 1 : 0, - 'fixed_duration' => !empty($data['fixed_duration']) ? 1 : 0, - 'sort_order' => (int) ($data['sort_order'] ?? 0), - 'updated_at' => $this->now(), - ]); - - $this->replaceLessonTypeVisibility($tenantId, $id, $data['visible_template_ids'] ?? null); - - return $this->findLessonType($tenantId, $id); - } - - public function deleteLessonType(int $tenantId, int $id): bool - { - $lessonType = $this->findLessonTypeRecord($tenantId, $id); - if ($lessonType === null) { - return false; - } - - if (($lessonType['system_key'] ?? null) === 'private_block') { - throw new \RuntimeException('Der feste Privat-Baustein kann nicht geloescht werden.'); - } - - $usage = $this->db->prepare('SELECT COUNT(*) AS count FROM appointments WHERE tenant_id = :tenant_id AND lesson_type_id = :lesson_type_id'); - $usage->execute(['tenant_id' => $tenantId, 'lesson_type_id' => $id]); - if ((int) ($usage->fetch()['count'] ?? 0) > 0) { - throw new \RuntimeException('Diese Stundenart wird bereits in Terminen verwendet und kann nicht geloescht werden.'); - } - - $this->db->beginTransaction(); - try { - $visibility = $this->db->prepare('DELETE FROM lesson_type_template_visibility WHERE lesson_type_id = :lesson_type_id'); - $visibility->execute(['lesson_type_id' => $id]); - - $delete = $this->db->prepare('DELETE FROM lesson_types WHERE tenant_id = :tenant_id AND id = :id'); - $delete->execute(['tenant_id' => $tenantId, 'id' => $id]); - - $this->db->commit(); - return true; - } catch (\Throwable $exception) { - $this->db->rollBack(); - throw $exception; - } - } - - public function reorderLessonTypes(int $tenantId, array $lessonTypeIds): array - { - $allowedIds = array_map( - static fn (array $lessonType): int => (int) $lessonType['id'], - $this->lessonTypes($tenantId) - ); - - $statement = $this->db->prepare( - 'UPDATE lesson_types - SET sort_order = :sort_order, updated_at = :updated_at - WHERE tenant_id = :tenant_id AND id = :id' - ); - - $sortOrder = 1; - foreach ($lessonTypeIds as $lessonTypeId) { - $lessonTypeId = (int) $lessonTypeId; - if (!in_array($lessonTypeId, $allowedIds, true)) { - continue; - } - - $statement->execute([ - 'sort_order' => $sortOrder, - 'updated_at' => $this->now(), - 'tenant_id' => $tenantId, - 'id' => $lessonTypeId, - ]); - $sortOrder++; - } - - return $this->lessonTypes($tenantId); - } - - public function findLessonType(int $tenantId, int $id): ?array - { - $statement = $this->db->prepare('SELECT * FROM lesson_types WHERE tenant_id = :tenant_id AND id = :id'); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - $lessonType = $statement->fetch() ?: null; - if ($lessonType === null) { - return null; - } - - $lessonType['visible_template_ids'] = $this->visibleTemplateIdsForLessonType($tenantId, $id); - $lessonType['effective_requirement_key'] = $this->requirementKeyForLessonType($lessonType); - - return $lessonType; - } - - public function templates(int $tenantId): array - { - $statement = $this->db->prepare( - 'SELECT * FROM license_class_templates WHERE tenant_id = :tenant_id ORDER BY name' - ); - $statement->execute(['tenant_id' => $tenantId]); - $templates = $statement->fetchAll(); - - foreach ($templates as &$template) { - $template['requirements'] = $this->templateRequirements((int) $template['id']); - $template['lesson_type_ids'] = $this->lessonTypeIdsForTemplate((int) $template['id']); - } - - return $templates; - } - - public function templateRequirements(int $templateId): array - { - $statement = $this->db->prepare( - 'SELECT * FROM license_template_requirements WHERE template_id = :template_id ORDER BY sort_order, phase_label, label' - ); - $statement->execute(['template_id' => $templateId]); - - return $statement->fetchAll(); - } - - public function createTemplate(int $tenantId, array $data): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO license_class_templates - (tenant_id, code, name, is_combination, created_at, updated_at) - VALUES (:tenant_id, :code, :name, :is_combination, :created_at, :updated_at)' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'code' => $data['code'], - 'name' => $data['name'], - 'is_combination' => !empty($data['is_combination']) ? 1 : 0, - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - $templateId = (int) $this->lastInsertId(); - - $this->replaceTemplateRequirements($templateId, $data['requirements'] ?? []); - $this->attachTemplateToExistingStudentLessonTypes($tenantId, $templateId); - - return $this->findTemplate($tenantId, $templateId); - } - - public function updateTemplate(int $tenantId, int $id, array $data): ?array - { - $statement = $this->db->prepare( - 'UPDATE license_class_templates - SET code = :code, name = :name, is_combination = :is_combination, updated_at = :updated_at - WHERE id = :id AND tenant_id = :tenant_id' - ); - $statement->execute([ - 'id' => $id, - 'tenant_id' => $tenantId, - 'code' => $data['code'], - 'name' => $data['name'], - 'is_combination' => !empty($data['is_combination']) ? 1 : 0, - 'updated_at' => $this->now(), - ]); - - $this->replaceTemplateRequirements($id, $data['requirements'] ?? []); - - return $this->findTemplate($tenantId, $id); - } - - public function updateLessonTypeMatrix(int $tenantId, array $rows): array - { - $templates = $this->templates($tenantId); - $templateIds = array_map(static fn (array $template): int => (int) $template['id'], $templates); - $allowedLessonTypeIds = array_map( - static fn (array $lessonType): int => (int) $lessonType['id'], - array_filter($this->lessonTypes($tenantId), static fn (array $lessonType): bool => $lessonType['category'] === 'student') - ); - - $delete = $this->db->prepare( - 'DELETE FROM lesson_type_template_visibility - WHERE template_id = :template_id - AND lesson_type_id IN ( - SELECT id FROM lesson_types WHERE tenant_id = :tenant_id AND category = \'student\' - )' - ); - $insert = $this->db->prepare( - 'INSERT OR IGNORE INTO lesson_type_template_visibility (lesson_type_id, template_id) - VALUES (:lesson_type_id, :template_id)' - ); - - foreach ($rows as $row) { - $templateId = (int) ($row['template_id'] ?? 0); - if (!in_array($templateId, $templateIds, true)) { - continue; - } - - $delete->execute([ - 'template_id' => $templateId, - 'tenant_id' => $tenantId, - ]); - - foreach ((array) ($row['lesson_type_ids'] ?? []) as $lessonTypeId) { - $lessonTypeId = (int) $lessonTypeId; - if (!in_array($lessonTypeId, $allowedLessonTypeIds, true)) { - continue; - } - - $insert->execute([ - 'lesson_type_id' => $lessonTypeId, - 'template_id' => $templateId, - ]); - } - } - - return $this->templates($tenantId); - } - - public function isLessonTypeVisibleForTemplate(int $tenantId, int $lessonTypeId, int $templateId): bool - { - $lessonType = $this->findLessonType($tenantId, $lessonTypeId); - if ($lessonType === null) { - return false; - } - - if ($lessonType['category'] !== 'student') { - return true; - } - - return in_array($templateId, array_map('intval', $lessonType['visible_template_ids'] ?? []), true); - } - - private function replaceTemplateRequirements(int $templateId, array $requirements): void - { - $delete = $this->db->prepare('DELETE FROM license_template_requirements WHERE template_id = :template_id'); - $delete->execute(['template_id' => $templateId]); - - $insert = $this->db->prepare( - 'INSERT INTO license_template_requirements - (template_id, requirement_key, label, required_units, sort_order, phase_label) - VALUES (:template_id, :requirement_key, :label, :required_units, :sort_order, :phase_label)' - ); - - foreach ($requirements as $index => $requirement) { - if (($requirement['label'] ?? '') === '') { - continue; - } - - $insert->execute([ - 'template_id' => $templateId, - 'requirement_key' => $requirement['requirement_key'], - 'label' => $requirement['label'], - 'required_units' => (int) $requirement['required_units'], - 'sort_order' => (int) ($requirement['sort_order'] ?? $index), - 'phase_label' => trim((string) ($requirement['phase_label'] ?? '')), - ]); - } - } - - public function findTemplate(int $tenantId, int $id): ?array - { - $statement = $this->db->prepare( - 'SELECT * FROM license_class_templates WHERE tenant_id = :tenant_id AND id = :id' - ); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - $template = $statement->fetch() ?: null; - - if ($template !== null) { - $template['requirements'] = $this->templateRequirements($id); - $template['lesson_type_ids'] = $this->lessonTypeIdsForTemplate($id); - } - - return $template; - } - - private function replaceLessonTypeVisibility(int $tenantId, int $lessonTypeId, ?array $visibleTemplateIds): void - { - $lessonType = $this->findLessonTypeRecord($tenantId, $lessonTypeId); - if ($lessonType === null) { - return; - } - - $delete = $this->db->prepare('DELETE FROM lesson_type_template_visibility WHERE lesson_type_id = :lesson_type_id'); - $delete->execute(['lesson_type_id' => $lessonTypeId]); - - if ($lessonType['category'] !== 'student') { - return; - } - - $templateIds = $visibleTemplateIds ?? $this->templateIdsForTenant($tenantId); - $templateIds = array_values(array_unique(array_map('intval', $templateIds))); - if ($templateIds === []) { - return; - } - - $allowedTemplateIds = $this->templateIdsForTenant($tenantId); - $insert = $this->db->prepare( - 'INSERT OR IGNORE INTO lesson_type_template_visibility (lesson_type_id, template_id) - VALUES (:lesson_type_id, :template_id)' - ); - - foreach ($templateIds as $templateId) { - if (!in_array($templateId, $allowedTemplateIds, true)) { - continue; - } - - $insert->execute([ - 'lesson_type_id' => $lessonTypeId, - 'template_id' => $templateId, - ]); - } - } - - private function lessonTypeVisibilityMap(int $tenantId): array - { - $statement = $this->db->prepare( - 'SELECT lt.id AS lesson_type_id, vis.template_id - FROM lesson_types lt - LEFT JOIN lesson_type_template_visibility vis ON vis.lesson_type_id = lt.id - WHERE lt.tenant_id = :tenant_id AND lt.category = \'student\' - ORDER BY vis.template_id' - ); - $statement->execute(['tenant_id' => $tenantId]); - - $map = []; - foreach ($statement->fetchAll() as $row) { - $lessonTypeId = (int) $row['lesson_type_id']; - $map[$lessonTypeId] ??= []; - if ($row['template_id'] !== null) { - $map[$lessonTypeId][] = (int) $row['template_id']; - } - } - - return $map; - } - - private function visibleTemplateIdsForLessonType(int $tenantId, int $lessonTypeId): array - { - $lessonType = $this->findLessonTypeRecord($tenantId, $lessonTypeId); - if ($lessonType === null || $lessonType['category'] !== 'student') { - return []; - } - - $statement = $this->db->prepare( - 'SELECT template_id FROM lesson_type_template_visibility - WHERE lesson_type_id = :lesson_type_id - ORDER BY template_id' - ); - $statement->execute(['lesson_type_id' => $lessonTypeId]); - - return array_map( - static fn (array $row): int => (int) $row['template_id'], - $statement->fetchAll() - ); - } - - private function lessonTypeIdsForTemplate(int $templateId): array - { - $statement = $this->db->prepare( - 'SELECT lesson_type_id FROM lesson_type_template_visibility - WHERE template_id = :template_id - ORDER BY lesson_type_id' - ); - $statement->execute(['template_id' => $templateId]); - - return array_map( - static fn (array $row): int => (int) $row['lesson_type_id'], - $statement->fetchAll() - ); - } - - private function templateIdsForTenant(int $tenantId): array - { - $statement = $this->db->prepare('SELECT id FROM license_class_templates WHERE tenant_id = :tenant_id ORDER BY id'); - $statement->execute(['tenant_id' => $tenantId]); - - return array_map( - static fn (array $row): int => (int) $row['id'], - $statement->fetchAll() - ); - } - - private function attachTemplateToExistingStudentLessonTypes(int $tenantId, int $templateId): void - { - $statement = $this->db->prepare( - 'INSERT OR IGNORE INTO lesson_type_template_visibility (lesson_type_id, template_id) - SELECT id, :template_id FROM lesson_types - WHERE tenant_id = :tenant_id AND category = \'student\'' - ); - $statement->execute([ - 'template_id' => $templateId, - 'tenant_id' => $tenantId, - ]); - } - - private function findLessonTypeRecord(int $tenantId, int $id): ?array - { - $statement = $this->db->prepare('SELECT * FROM lesson_types WHERE tenant_id = :tenant_id AND id = :id'); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - - return $statement->fetch() ?: null; - } - - private function ensureDefaultPlanningTypes(int $tenantId): void - { - $statement = $this->db->prepare( - 'INSERT OR IGNORE INTO lesson_types - (tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, system_key, created_at, updated_at) - VALUES - (:tenant_id, :name, :color, :default_duration, :category, NULL, 0, 0, :is_rest_relevant, 0, :sort_order, :system_key, :created_at, :updated_at)' - ); - - $timestamp = $this->now(); - foreach (self::DEFAULT_PLANNING_TYPES as $row) { - $statement->execute([ - 'tenant_id' => $tenantId, - 'name' => $row['name'], - 'color' => $row['color'], - 'default_duration' => $row['default_duration'], - 'category' => $row['category'], - 'is_rest_relevant' => $row['category'] === 'private' ? 0 : 1, - 'sort_order' => $row['sort_order'], - 'system_key' => $row['system_key'], - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - } - } -} diff --git a/www/fahrschultermin.de/app/Repositories/StudentRepository.php b/www/fahrschultermin.de/app/Repositories/StudentRepository.php deleted file mode 100644 index 8042efa..0000000 --- a/www/fahrschultermin.de/app/Repositories/StudentRepository.php +++ /dev/null @@ -1,294 +0,0 @@ -db->prepare( - 'SELECT s.*, t.code AS template_code, t.name AS template_name, t.is_combination AS template_is_combination - FROM students s - JOIN license_class_templates t ON t.id = s.template_id - WHERE s.tenant_id = :tenant_id - ORDER BY s.last_name, s.first_name' - ); - $statement->execute(['tenant_id' => $tenantId]); - - return $statement->fetchAll(); - } - - public function find(int $tenantId, int $id): ?array - { - $statement = $this->db->prepare( - 'SELECT s.*, t.code AS template_code, t.name AS template_name, t.is_combination AS template_is_combination - FROM students s - JOIN license_class_templates t ON t.id = s.template_id - WHERE s.tenant_id = :tenant_id AND s.id = :id' - ); - $statement->execute(['tenant_id' => $tenantId, 'id' => $id]); - $student = $statement->fetch() ?: null; - - if ($student !== null) { - $student['requirements'] = $this->requirements($id); - } - - return $student; - } - - public function create(int $tenantId, array $data): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO students - (tenant_id, template_id, first_name, last_name, phone, email, needs_glasses, notes, status, created_at, updated_at) - VALUES (:tenant_id, :template_id, :first_name, :last_name, :phone, :email, :needs_glasses, :notes, :status, :created_at, :updated_at)' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'template_id' => $data['template_id'], - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'phone' => $data['phone'] ?? '', - 'email' => $data['email'] ?? '', - 'needs_glasses' => !empty($data['needs_glasses']) ? 1 : 0, - 'notes' => $data['notes'] ?? '', - 'status' => $data['status'] ?? 'active', - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - - $studentId = (int) $this->lastInsertId(); - $this->snapshotRequirements($studentId, (int) $data['template_id']); - - return $this->find($tenantId, $studentId); - } - - public function update(int $tenantId, int $id, array $data): ?array - { - $statement = $this->db->prepare( - 'UPDATE students - SET template_id = :template_id, first_name = :first_name, last_name = :last_name, phone = :phone, email = :email, needs_glasses = :needs_glasses, - notes = :notes, status = :status, updated_at = :updated_at - WHERE tenant_id = :tenant_id AND id = :id' - ); - $statement->execute([ - 'tenant_id' => $tenantId, - 'id' => $id, - 'template_id' => $data['template_id'], - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'phone' => $data['phone'] ?? '', - 'email' => $data['email'] ?? '', - 'needs_glasses' => !empty($data['needs_glasses']) ? 1 : 0, - 'notes' => $data['notes'] ?? '', - 'status' => $data['status'] ?? 'active', - 'updated_at' => $this->now(), - ]); - - return $this->find($tenantId, $id); - } - - public function delete(int $tenantId, int $id): bool - { - $student = $this->find($tenantId, $id); - if ($student === null) { - return false; - } - - $this->db->beginTransaction(); - try { - $updateAppointments = $this->db->prepare( - 'UPDATE appointments SET student_id = NULL, updated_at = :updated_at WHERE tenant_id = :tenant_id AND student_id = :student_id' - ); - $updateAppointments->execute([ - 'tenant_id' => $tenantId, - 'student_id' => $id, - 'updated_at' => $this->now(), - ]); - - $deleteSnapshots = $this->db->prepare('DELETE FROM student_requirement_snapshots WHERE student_id = :student_id'); - $deleteSnapshots->execute(['student_id' => $id]); - - $deleteStudent = $this->db->prepare('DELETE FROM students WHERE tenant_id = :tenant_id AND id = :id'); - $deleteStudent->execute(['tenant_id' => $tenantId, 'id' => $id]); - - $this->db->commit(); - return true; - } catch (\Throwable $exception) { - $this->db->rollBack(); - throw $exception; - } - } - - public function requirements(int $studentId): array - { - $this->syncRequirementSnapshots($studentId); - - $statement = $this->db->prepare( - 'SELECT * FROM student_requirement_snapshots WHERE student_id = :student_id ORDER BY sort_order, phase_label, label' - ); - $statement->execute(['student_id' => $studentId]); - - return $statement->fetchAll(); - } - - public function updatePriorCompletedUnits(int $tenantId, int $studentId, array $rows): ?array - { - $student = $this->find($tenantId, $studentId); - if ($student === null) { - return null; - } - - $statement = $this->db->prepare( - 'UPDATE student_requirement_snapshots - SET prior_completed_units = :prior_completed_units - WHERE student_id = :student_id AND requirement_key = :requirement_key' - ); - - foreach ($rows as $row) { - $statement->execute([ - 'student_id' => $studentId, - 'requirement_key' => (string) ($row['requirement_key'] ?? ''), - 'prior_completed_units' => max(0, (int) ($row['prior_completed_units'] ?? 0)), - ]); - } - - return $this->find($tenantId, $studentId); - } - - private function snapshotRequirements(int $studentId, int $templateId): void - { - $this->syncRequirementSnapshots($studentId, $templateId); - } - - private function syncRequirementSnapshots(int $studentId, ?int $templateId = null): void - { - if ($templateId === null) { - $student = $this->db->prepare('SELECT template_id FROM students WHERE id = :student_id'); - $student->execute(['student_id' => $studentId]); - $templateId = (int) ($student->fetch()['template_id'] ?? 0); - } - - if ($templateId <= 0) { - return; - } - - $requirements = $this->db->prepare( - 'SELECT requirement_key, label, required_units, sort_order, phase_label - FROM license_template_requirements WHERE template_id = :template_id' - ); - $requirements->execute(['template_id' => $templateId]); - $rows = []; - - foreach ($requirements->fetchAll() as $row) { - $rows[$row['requirement_key']] = $row; - } - $hasPhasedRequirements = array_reduce( - $rows, - static fn (bool $carry, array $row): bool => $carry || trim((string) ($row['phase_label'] ?? '')) !== '', - false - ); - - $lessonTypes = $this->db->prepare( - 'SELECT COALESCE(NULLIF(TRIM(lt.requirement_key), \'\'), \'lesson_type_\' || lt.id) AS requirement_key, - lt.name AS label, - lt.sort_order - FROM lesson_types lt - JOIN lesson_type_template_visibility vis ON vis.lesson_type_id = lt.id - WHERE vis.template_id = :template_id - AND lt.category = \'student\' - AND lt.is_counted = 1 - ORDER BY lt.sort_order, lt.name' - ); - $lessonTypes->execute(['template_id' => $templateId]); - - foreach ($lessonTypes->fetchAll() as $row) { - if (isset($rows[$row['requirement_key']])) { - continue; - } - - if ($hasPhasedRequirements) { - $hasMatchingPhasedRequirement = false; - foreach ($rows as $existingRow) { - $phaseLabel = trim((string) ($existingRow['phase_label'] ?? '')); - if ($phaseLabel === '') { - continue; - } - - if (str_ends_with((string) $existingRow['requirement_key'], '::' . $row['requirement_key'])) { - $hasMatchingPhasedRequirement = true; - break; - } - } - - if ($hasMatchingPhasedRequirement) { - continue; - } - } - - $rows[$row['requirement_key']] = [ - 'requirement_key' => $row['requirement_key'], - 'label' => $row['label'], - 'required_units' => 0, - 'sort_order' => $row['sort_order'], - ]; - } - - $insert = $this->db->prepare( - 'INSERT INTO student_requirement_snapshots - (student_id, requirement_key, label, required_units, prior_completed_units, sort_order, phase_label) - SELECT :student_id, :requirement_key, :label, :required_units, 0, :sort_order, :phase_label - WHERE NOT EXISTS ( - SELECT 1 FROM student_requirement_snapshots - WHERE student_id = :student_id AND requirement_key = :requirement_key - )' - ); - $update = $this->db->prepare( - 'UPDATE student_requirement_snapshots - SET label = :label, - required_units = :required_units, - sort_order = :sort_order, - phase_label = :phase_label - WHERE student_id = :student_id AND requirement_key = :requirement_key' - ); - - foreach ($rows as $row) { - $insert->execute([ - 'student_id' => $studentId, - 'requirement_key' => $row['requirement_key'], - 'label' => $row['label'], - 'required_units' => $row['required_units'], - 'sort_order' => $row['sort_order'], - 'phase_label' => $row['phase_label'] ?? '', - ]); - $update->execute([ - 'student_id' => $studentId, - 'requirement_key' => $row['requirement_key'], - 'label' => $row['label'], - 'required_units' => $row['required_units'], - 'sort_order' => $row['sort_order'], - 'phase_label' => $row['phase_label'] ?? '', - ]); - } - - if ($rows !== []) { - $placeholders = implode(', ', array_fill(0, count($rows), '?')); - $delete = $this->db->prepare( - "DELETE FROM student_requirement_snapshots - WHERE student_id = ? - AND requirement_key NOT IN ($placeholders) - AND prior_completed_units = 0 - AND NOT EXISTS ( - SELECT 1 FROM appointment_units au - JOIN appointments a ON a.id = au.appointment_id - WHERE a.student_id = student_requirement_snapshots.student_id - AND au.requirement_key = student_requirement_snapshots.requirement_key - )" - ); - $delete->execute(array_merge([$studentId], array_keys($rows))); - } - } -} diff --git a/www/fahrschultermin.de/app/Repositories/StudentTenantRepository.php b/www/fahrschultermin.de/app/Repositories/StudentTenantRepository.php deleted file mode 100644 index d4135de..0000000 --- a/www/fahrschultermin.de/app/Repositories/StudentTenantRepository.php +++ /dev/null @@ -1,77 +0,0 @@ -db->prepare( - 'SELECT * FROM student_tenants WHERE student_user_id = :user_id AND tenant_id = :tenant_id' - ); - $stmt->execute(['user_id' => $userId, 'tenant_id' => $tenantId]); - $result = $stmt->fetch(); - return $result ?: null; - } - - public function create(int $userId, int $tenantId, string $status = 'pending'): array - { - $stmt = $this->db->prepare( - 'INSERT INTO student_tenants (student_user_id, tenant_id, status) - VALUES (:user_id, :tenant_id, :status) RETURNING *' - ); - $stmt->execute([ - 'user_id' => $userId, - 'tenant_id' => $tenantId, - 'status' => $status, - ]); - return $stmt->fetch(); - } - - public function confirm(int $id, int $confirmedBy): bool - { - $stmt = $this->db->prepare( - 'UPDATE student_tenants - SET status = \'active\', confirmed_at = NOW(), confirmed_by = :confirmed_by - WHERE id = :id RETURNING id' - ); - $stmt->execute(['id' => $id, 'confirmed_by' => $confirmedBy]); - return (bool) $stmt->fetch(); - } - - public function suspend(int $id): bool - { - $stmt = $this->db->prepare( - 'UPDATE student_tenants SET status = \'suspended\' WHERE id = :id RETURNING id' - ); - $stmt->execute(['id' => $id]); - return (bool) $stmt->fetch(); - } - - public function getPendingForTenant(int $tenantId): array - { - $stmt = $this->db->prepare( - 'SELECT st.*, u.email, u.first_name, u.last_name - FROM student_tenants st - JOIN users u ON u.id = st.student_user_id - WHERE st.tenant_id = :tenant_id AND st.status = \'pending\' - ORDER BY st.registered_at DESC' - ); - $stmt->execute(['tenant_id' => $tenantId]); - return $stmt->fetchAll(); - } - - public function getActiveForUser(int $userId): array - { - $stmt = $this->db->prepare( - 'SELECT st.*, t.name AS tenant_name - FROM student_tenants st - JOIN tenants t ON t.id = st.tenant_id - WHERE st.student_user_id = :user_id AND st.status = \'active\'' - ); - $stmt->execute(['user_id' => $userId]); - return $stmt->fetchAll(); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/TenantRegistrationCodeRepository.php b/www/fahrschultermin.de/app/Repositories/TenantRegistrationCodeRepository.php deleted file mode 100644 index fdb988b..0000000 --- a/www/fahrschultermin.de/app/Repositories/TenantRegistrationCodeRepository.php +++ /dev/null @@ -1,57 +0,0 @@ -db->prepare( - 'SELECT trc.*, t.name AS tenant_name - FROM tenant_registration_codes trc - JOIN tenants t ON t.id = trc.tenant_id - WHERE trc.code = :code AND trc.is_active = 1' - ); - $stmt->execute(['code' => $code]); - $result = $stmt->fetch(); - return $result ?: null; - } - - public function findByTenant(int $tenantId): ?array - { - $stmt = $this->db->prepare( - 'SELECT * FROM tenant_registration_codes WHERE tenant_id = :tenant_id AND is_active = 1' - ); - $stmt->execute(['tenant_id' => $tenantId]); - $result = $stmt->fetch(); - return $result ?: null; - } - - public function create(int $tenantId, string $code): array - { - $stmt = $this->db->prepare( - 'INSERT INTO tenant_registration_codes (tenant_id, code) VALUES (:tenant_id, :code) RETURNING *' - ); - $stmt->execute(['tenant_id' => $tenantId, 'code' => $code]); - return $stmt->fetch(); - } - - public function update(int $tenantId, string $code): bool - { - $stmt = $this->db->prepare( - 'UPDATE tenant_registration_codes SET code = :code WHERE tenant_id = :tenant_id RETURNING id' - ); - $stmt->execute(['tenant_id' => $tenantId, 'code' => $code]); - return (bool) $stmt->fetch(); - } - - public function incrementUsedCount(int $tenantId): void - { - $stmt = $this->db->prepare( - 'UPDATE tenant_registration_codes SET used_count = used_count + 1 WHERE tenant_id = :tenant_id' - ); - $stmt->execute(['tenant_id' => $tenantId]); - } -} \ No newline at end of file diff --git a/www/fahrschultermin.de/app/Repositories/TenantRepository.php b/www/fahrschultermin.de/app/Repositories/TenantRepository.php deleted file mode 100644 index bc47c4f..0000000 --- a/www/fahrschultermin.de/app/Repositories/TenantRepository.php +++ /dev/null @@ -1,86 +0,0 @@ -db->query('SELECT * FROM tenants ORDER BY name')->fetchAll(); - } - - public function find(int $id): ?array - { - $statement = $this->db->prepare('SELECT * FROM tenants WHERE id = :id'); - $statement->execute(['id' => $id]); - - return $statement->fetch() ?: null; - } - - public function create(array $data): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO tenants (name, timezone, federal_state, location_label, latitude, longitude, is_active, created_at, updated_at) - VALUES (:name, :timezone, :federal_state, :location_label, :latitude, :longitude, :is_active, :created_at, :updated_at)' - ); - $statement->execute([ - 'name' => $data['name'], - 'timezone' => $data['timezone'] ?? 'Europe/Berlin', - 'federal_state' => $data['federal_state'] ?? 'BE', - 'location_label' => $data['location_label'] ?? '', - 'latitude' => $data['latitude'] !== '' ? $data['latitude'] : null, - 'longitude' => $data['longitude'] !== '' ? $data['longitude'] : null, - 'is_active' => !empty($data['is_active']) ? 1 : 0, - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - - return $this->find((int) $this->lastInsertId()); - } - - public function update(int $id, array $data): ?array - { - $statement = $this->db->prepare( - 'UPDATE tenants - SET name = :name, timezone = :timezone, federal_state = :federal_state, location_label = :location_label, - latitude = :latitude, longitude = :longitude, is_active = :is_active, updated_at = :updated_at - WHERE id = :id' - ); - $statement->execute([ - 'id' => $id, - 'name' => $data['name'], - 'timezone' => $data['timezone'], - 'federal_state' => $data['federal_state'] ?? 'BE', - 'location_label' => $data['location_label'] ?? '', - 'latitude' => $data['latitude'] !== '' ? $data['latitude'] : null, - 'longitude' => $data['longitude'] !== '' ? $data['longitude'] : null, - 'is_active' => !empty($data['is_active']) ? 1 : 0, - 'updated_at' => $this->now(), - ]); - - return $this->find($id); - } - - public function updateForTenantAdmin(int $id, array $data): ?array - { - $current = $this->find($id); - if ($current === null) { - return null; - } - - return $this->update($id, [ - 'name' => $data['name'] ?? $current['name'], - 'timezone' => $data['timezone'] ?? $current['timezone'], - 'federal_state' => $data['federal_state'] ?? ($current['federal_state'] ?? 'BE'), - 'location_label' => $data['location_label'] ?? ($current['location_label'] ?? ''), - 'latitude' => array_key_exists('latitude', $data) ? $data['latitude'] : ($current['latitude'] ?? null), - 'longitude' => array_key_exists('longitude', $data) ? $data['longitude'] : ($current['longitude'] ?? null), - 'is_active' => $current['is_active'], - ]); - } -} diff --git a/www/fahrschultermin.de/app/Repositories/UserRepository.php b/www/fahrschultermin.de/app/Repositories/UserRepository.php deleted file mode 100644 index bce3629..0000000 --- a/www/fahrschultermin.de/app/Repositories/UserRepository.php +++ /dev/null @@ -1,112 +0,0 @@ -db->prepare( - 'SELECT id, tenant_id, role, email, first_name, last_name, is_active, created_at, updated_at - FROM users WHERE tenant_id = :tenant_id ORDER BY role, last_name, first_name' - ); - $statement->execute(['tenant_id' => $tenantId]); - - return $statement->fetchAll(); - } - - public function allUsers(): array - { - return $this->db->query( - 'SELECT u.id, u.tenant_id, u.role, u.email, u.first_name, u.last_name, u.is_active, - u.created_at, u.updated_at, t.name AS tenant_name - FROM users u - LEFT JOIN tenants t ON t.id = u.tenant_id - ORDER BY COALESCE(t.name, "System"), u.role, u.last_name, u.first_name' - )->fetchAll(); - } - - public function findByEmail(string $email): ?array - { - $statement = $this->db->prepare( - 'SELECT u.*, t.name AS tenant_name, t.timezone AS tenant_timezone, t.is_active AS tenant_is_active - FROM users u - LEFT JOIN tenants t ON t.id = u.tenant_id - WHERE u.email = :email' - ); - $statement->execute(['email' => $email]); - - return $statement->fetch() ?: null; - } - - public function findById(int $id): ?array - { - $statement = $this->db->prepare( - 'SELECT u.*, t.name AS tenant_name, t.timezone AS tenant_timezone, t.is_active AS tenant_is_active - FROM users u - LEFT JOIN tenants t ON t.id = u.tenant_id - WHERE u.id = :id' - ); - $statement->execute(['id' => $id]); - - return $statement->fetch() ?: null; - } - - public function create(array $data): array - { - $timestamp = $this->now(); - $statement = $this->db->prepare( - 'INSERT INTO users - (tenant_id, role, email, password_hash, first_name, last_name, is_active, created_at, updated_at) - VALUES (:tenant_id, :role, :email, :password_hash, :first_name, :last_name, :is_active, :created_at, :updated_at)' - ); - $statement->execute([ - 'tenant_id' => $data['tenant_id'], - 'role' => $data['role'], - 'email' => $data['email'], - 'password_hash' => password_hash($data['password'], PASSWORD_DEFAULT), - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'is_active' => !empty($data['is_active']) ? 1 : 0, - 'created_at' => $timestamp, - 'updated_at' => $timestamp, - ]); - - return $this->findById((int) $this->lastInsertId()); - } - - public function update(int $id, array $data): ?array - { - $current = $this->findById($id); - if ($current === null) { - return null; - } - - $passwordHash = $current['password_hash']; - if (!empty($data['password'])) { - $passwordHash = password_hash($data['password'], PASSWORD_DEFAULT); - } - - $statement = $this->db->prepare( - 'UPDATE users - SET tenant_id = :tenant_id, role = :role, email = :email, password_hash = :password_hash, - first_name = :first_name, last_name = :last_name, is_active = :is_active, updated_at = :updated_at - WHERE id = :id' - ); - $statement->execute([ - 'id' => $id, - 'tenant_id' => $data['tenant_id'], - 'role' => $data['role'], - 'email' => $data['email'], - 'password_hash' => $passwordHash, - 'first_name' => $data['first_name'], - 'last_name' => $data['last_name'], - 'is_active' => !empty($data['is_active']) ? 1 : 0, - 'updated_at' => $this->now(), - ]); - - return $this->findById($id); - } -} diff --git a/www/fahrschultermin.de/app/Services/CalendarService.php b/www/fahrschultermin.de/app/Services/CalendarService.php deleted file mode 100644 index 76fcbd0..0000000 --- a/www/fahrschultermin.de/app/Services/CalendarService.php +++ /dev/null @@ -1,93 +0,0 @@ -findLessonType($tenantId, (int) $payload['lesson_type_id']); - $warnings = [ - 'conflicts' => [], - 'rest_period_warnings' => [], - ]; - - $conflicts = $appointmentRepository->overlappingForInstructor( - $tenantId, - (int) $payload['instructor_id'], - $payload['start_at'], - $payload['end_at'], - $appointmentId - ); - - foreach ($conflicts as $conflict) { - $warnings['conflicts'][] = [ - 'type' => 'instructor_overlap', - 'message' => 'Fahrlehrer ist in diesem Zeitraum bereits verplant.', - 'appointment_id' => (int) $conflict['id'], - ]; - } - - if (!empty($payload['student_id'])) { - $studentConflicts = $appointmentRepository->overlappingForStudent( - $tenantId, - (int) $payload['student_id'], - $payload['start_at'], - $payload['end_at'], - $appointmentId - ); - foreach ($studentConflicts as $conflict) { - $warnings['conflicts'][] = [ - 'type' => 'student_overlap', - 'message' => 'Fahrschueler ist in diesem Zeitraum bereits verplant.', - 'appointment_id' => (int) $conflict['id'], - ]; - } - } - - if ($lessonType !== null && (int) $lessonType['is_rest_relevant'] === 1) { - $newStart = new DateTimeImmutable($payload['start_at']); - $dayStart = $newStart->setTime(0, 0, 0); - $dayEnd = $dayStart->modify('+1 day'); - $hasLaterRelevantOnDay = $appointmentRepository->hasRestRelevantAfterStartOnDay( - $tenantId, - (int) $payload['instructor_id'], - $dayStart->format(DATE_ATOM), - $dayEnd->format(DATE_ATOM), - $payload['start_at'] - ); - - if ($hasLaterRelevantOnDay) { - return $warnings; - } - - $lastRelevant = $appointmentRepository->lastRestRelevantForInstructor( - $tenantId, - (int) $payload['instructor_id'], - $payload['start_at'], - $appointmentId - ); - if ($lastRelevant !== null) { - $restEnds = (new DateTimeImmutable($lastRelevant['end_at']))->add(new DateInterval('PT11H')); - if ($newStart < $restEnds) { - $warnings['rest_period_warnings'][] = [ - 'type' => 'rest_period', - 'message' => 'Achtung: Dieser Termin liegt innerhalb der 11-Stunden-Ruhezeit.', - 'rest_until' => $restEnds->format(DATE_ATOM), - 'blocking_appointment_id' => (int) $lastRelevant['id'], - ]; - } - } - } - - return $warnings; - } -} diff --git a/www/fahrschultermin.de/app/Services/HolidayService.php b/www/fahrschultermin.de/app/Services/HolidayService.php deleted file mode 100644 index 1b6d66b..0000000 --- a/www/fahrschultermin.de/app/Services/HolidayService.php +++ /dev/null @@ -1,109 +0,0 @@ -setTimezone($timezone)->setTime(0, 0); - $end = (new DateTimeImmutable($to, new DateTimeZone('UTC')))->setTimezone($timezone)->setTime(0, 0); - - $years = []; - $day = $start; - while ($day <= $end) { - $years[(int) $day->format('Y')] = true; - $day = $day->add(new DateInterval('P1D')); - } - - $holidaysByDate = []; - foreach (array_keys($years) as $year) { - foreach ($this->holidaysForYear((int) $year, $state, $timezone) as $date => $name) { - $holidaysByDate[$date] = $name; - } - } - - $result = []; - $day = $start; - while ($day < $end) { - $key = $day->format('Y-m-d'); - $result[$key] = [ - 'isSunday' => (int) $day->format('N') === 7, - 'holidayName' => $holidaysByDate[$key] ?? null, - ]; - $day = $day->add(new DateInterval('P1D')); - } - - return $result; - } - - private function holidaysForYear(int $year, string $state, DateTimeZone $timezone): array - { - $easter = (new DateTimeImmutable('@' . (string) easter_date($year)))->setTimezone($timezone)->setTime(0, 0); - $holidays = [ - $this->dateKey($year, 1, 1, $timezone) => 'Neujahr', - $easter->sub(new DateInterval('P2D'))->format('Y-m-d') => 'Karfreitag', - $easter->add(new DateInterval('P1D'))->format('Y-m-d') => 'Ostermontag', - $this->dateKey($year, 5, 1, $timezone) => 'Tag der Arbeit', - $easter->add(new DateInterval('P39D'))->format('Y-m-d') => 'Christi Himmelfahrt', - $easter->add(new DateInterval('P50D'))->format('Y-m-d') => 'Pfingstmontag', - $this->dateKey($year, 10, 3, $timezone) => 'Tag der Deutschen Einheit', - $this->dateKey($year, 12, 25, $timezone) => '1. Weihnachtstag', - $this->dateKey($year, 12, 26, $timezone) => '2. Weihnachtstag', - ]; - - if (in_array($state, self::STATES_WITH_EPIPHANY, true)) { - $holidays[$this->dateKey($year, 1, 6, $timezone)] = 'Heilige Drei Koenige'; - } - if (in_array($state, self::STATES_WITH_WOMENS_DAY, true)) { - $holidays[$this->dateKey($year, 3, 8, $timezone)] = 'Internationaler Frauentag'; - } - if (in_array($state, self::STATES_WITH_CORPUS_CHRISTI, true)) { - $holidays[$easter->add(new DateInterval('P60D'))->format('Y-m-d')] = 'Fronleichnam'; - } - if (in_array($state, self::STATES_WITH_ASSUMPTION, true)) { - $holidays[$this->dateKey($year, 8, 15, $timezone)] = 'Mariae Himmelfahrt'; - } - if (in_array($state, self::STATES_WITH_REFORMATION, true)) { - $holidays[$this->dateKey($year, 10, 31, $timezone)] = 'Reformationstag'; - } - if (in_array($state, self::STATES_WITH_ALL_SAINTS, true)) { - $holidays[$this->dateKey($year, 11, 1, $timezone)] = 'Allerheiligen'; - } - if (in_array($state, self::STATES_WITH_REPENTANCE, true)) { - $holidays[$this->repentanceDay($year, $timezone)->format('Y-m-d')] = 'Buss- und Bettag'; - } - - return $holidays; - } - - private function dateKey(int $year, int $month, int $day, DateTimeZone $timezone): string - { - return (new DateTimeImmutable(sprintf('%04d-%02d-%02d', $year, $month, $day), $timezone))->format('Y-m-d'); - } - - private function repentanceDay(int $year, DateTimeZone $timezone): DateTimeImmutable - { - $day = new DateTimeImmutable(sprintf('%04d-11-23', $year), $timezone); - while ((int) $day->format('N') !== 3) { - $day = $day->sub(new DateInterval('P1D')); - } - return $day; - } -} diff --git a/www/fahrschultermin.de/app/Services/RequirementService.php b/www/fahrschultermin.de/app/Services/RequirementService.php deleted file mode 100644 index fa646fc..0000000 --- a/www/fahrschultermin.de/app/Services/RequirementService.php +++ /dev/null @@ -1,56 +0,0 @@ -requirements($studentId); - - $statement = $db->prepare( - 'SELECT au.requirement_key, - SUM(CASE WHEN a.status = "planned" THEN au.units_counted ELSE 0 END) AS planned_units, - SUM(CASE WHEN a.status = "completed" THEN au.units_counted ELSE 0 END) AS completed_units - FROM appointment_units au - JOIN appointments a ON a.id = au.appointment_id - WHERE a.student_id = :student_id - GROUP BY au.requirement_key' - ); - $statement->execute(['student_id' => $studentId]); - $totals = []; - foreach ($statement->fetchAll() as $row) { - $totals[$row['requirement_key']] = [ - 'planned' => (int) $row['planned_units'], - 'completed' => (int) $row['completed_units'], - ]; - } - - return array_map(static function (array $snapshot) use ($totals): array { - $row = $totals[$snapshot['requirement_key']] ?? ['planned' => 0, 'completed' => 0]; - $priorCompleted = (int) ($snapshot['prior_completed_units'] ?? 0); - $appointmentCompleted = (int) $row['completed']; - $completed = $priorCompleted + $appointmentCompleted; - $open = (int) $snapshot['required_units'] - $row['planned'] - $completed; - - return [ - 'requirement_key' => $snapshot['requirement_key'], - 'phase_label' => $snapshot['phase_label'] ?? '', - 'label' => $snapshot['label'], - 'required_units' => (int) $snapshot['required_units'], - 'planned_units' => $row['planned'], - 'completed_units' => $completed, - 'prior_completed_units' => $priorCompleted, - 'appointment_completed_units' => $appointmentCompleted, - 'open_units' => $open, - ]; - }, $snapshots); - } -} diff --git a/www/fahrschultermin.de/app/Services/SunTimesService.php b/www/fahrschultermin.de/app/Services/SunTimesService.php deleted file mode 100644 index 041fef0..0000000 --- a/www/fahrschultermin.de/app/Services/SunTimesService.php +++ /dev/null @@ -1,55 +0,0 @@ -setTimezone($timezone)->setTime(0, 0); - $lastDay = $end->setTimezone($timezone)->setTime(0, 0); - - $result = []; - while ($day < $lastDay) { - $solar = date_sun_info($day->setTime(12, 0)->getTimestamp(), $latitude, $longitude); - $key = $day->format('Y-m-d'); - - $result[$key] = [ - 'sunrise' => $this->formatSolarTimestamp($solar['sunrise'] ?? false, $timezone), - 'sunset' => $this->formatSolarTimestamp($solar['sunset'] ?? false, $timezone), - ]; - - $day = $day->add(new DateInterval('P1D')); - } - - return $result; - } - - private function formatSolarTimestamp(int|float|bool $timestamp, DateTimeZone $timezone): ?string - { - if (!is_int($timestamp) && !is_float($timestamp)) { - return null; - } - - return (new DateTimeImmutable('@' . (string) (int) $timestamp)) - ->setTimezone($timezone) - ->format('H:i'); - } -} diff --git a/www/fahrschultermin.de/app/Support/Auth.php b/www/fahrschultermin.de/app/Support/Auth.php deleted file mode 100644 index 488c54f..0000000 --- a/www/fahrschultermin.de/app/Support/Auth.php +++ /dev/null @@ -1,42 +0,0 @@ -findById((int) $userId); - } - - public static function requireUser(): array - { - $user = self::user(); - if ($user === null) { - Response::json(['message' => 'Unauthenticated'], 401); - } - - return $user; - } - - public static function requireRole(array|string $roles): array - { - $user = self::requireUser(); - $roles = (array) $roles; - - if (!in_array($user['role'], $roles, true)) { - Response::json(['message' => 'Forbidden'], 403); - } - - return $user; - } -} diff --git a/www/fahrschultermin.de/app/Support/Database.php b/www/fahrschultermin.de/app/Support/Database.php deleted file mode 100644 index a60ee17..0000000 --- a/www/fahrschultermin.de/app/Support/Database.php +++ /dev/null @@ -1,66 +0,0 @@ -exec('PRAGMA foreign_keys = ON'); - } - - self::$connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); - self::$connection->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); - - return self::$connection; - } - - public static function isPostgres(): bool - { - return (self::$config['db_driver'] ?? 'sqlite') === 'pgsql'; - } - - public static function lastInsertId(): string - { - if (self::isPostgres()) { - return self::$connection->query('SELECT lastval()')->fetchColumn(); - } - return self::$connection->lastInsertId(); - } -} diff --git a/www/fahrschultermin.de/app/Support/Request.php b/www/fahrschultermin.de/app/Support/Request.php deleted file mode 100644 index ca66565..0000000 --- a/www/fahrschultermin.de/app/Support/Request.php +++ /dev/null @@ -1,40 +0,0 @@ -map('GET', $path, $handler); - } - - public function post(string $path, callable $handler): void - { - $this->map('POST', $path, $handler); - } - - public function patch(string $path, callable $handler): void - { - $this->map('PATCH', $path, $handler); - } - - public function delete(string $path, callable $handler): void - { - $this->map('DELETE', $path, $handler); - } - - public function dispatch(): void - { - $method = $this->request->method(); - $path = $this->request->path(); - - foreach ($this->routes[$method] ?? [] as $route) { - $pattern = preg_replace('#\{([a-zA-Z_][a-zA-Z0-9_]*)\}#', '(?P<$1>[^/]+)', $route['path']); - $pattern = '#^' . $pattern . '$#'; - - if (!preg_match($pattern, $path, $matches)) { - continue; - } - - $params = array_filter($matches, static fn (string|int $key): bool => is_string($key), ARRAY_FILTER_USE_KEY); - $route['handler']($this->request, $params); - return; - } - - Response::json(['message' => 'Route not found', 'path' => $path], 404); - } - - private function map(string $method, string $path, callable $handler): void - { - $this->routes[$method][] = [ - 'path' => rtrim($path, '/') ?: '/', - 'handler' => $handler, - ]; - } -} diff --git a/www/fahrschultermin.de/app/bootstrap.php b/www/fahrschultermin.de/app/bootstrap.php deleted file mode 100644 index 591c80e..0000000 --- a/www/fahrschultermin.de/app/bootstrap.php +++ /dev/null @@ -1,44 +0,0 @@ - $config, - 'router' => new Router(new Request()), -]; diff --git a/www/fahrschultermin.de/bin/migrate.php b/www/fahrschultermin.de/bin/migrate.php deleted file mode 100644 index 33bc9d5..0000000 --- a/www/fahrschultermin.de/bin/migrate.php +++ /dev/null @@ -1,27 +0,0 @@ -query('PRAGMA table_info(' . $matches[1] . ')')->fetchAll(); - $columnNames = array_map(static fn (array $column): string => strtolower((string) $column['name']), $columns); - if (in_array(strtolower($matches[2]), $columnNames, true)) { - continue; - } - } - - $db->exec($statement); - } - fwrite(STDOUT, "Applied: " . basename($migration) . PHP_EOL); -} diff --git a/www/fahrschultermin.de/bin/seed.php b/www/fahrschultermin.de/bin/seed.php deleted file mode 100644 index 38babcb..0000000 --- a/www/fahrschultermin.de/bin/seed.php +++ /dev/null @@ -1,208 +0,0 @@ -query('SELECT COUNT(*) AS count FROM users')->fetch(); -if ((int) $existing['count'] > 0) { - fwrite(STDOUT, "Seed skipped: data already exists." . PHP_EOL); - exit(0); -} - -$tenant = $tenantRepository->create([ - 'name' => 'Fahrschule Nordring', - 'timezone' => 'Europe/Berlin', - 'is_active' => true, -]); - -$db->prepare('INSERT INTO settings (tenant_id, key_name, value) VALUES (:tenant_id, :key_name, :value)') - ->execute([ - 'tenant_id' => $tenant['id'], - 'key_name' => 'app.theme', - 'value' => 'signal', - ]); - -$superadmin = $userRepository->create([ - 'tenant_id' => null, - 'role' => 'superadmin', - 'email' => 'superadmin@example.com', - 'password' => 'secret123', - 'first_name' => 'System', - 'last_name' => 'Admin', - 'is_active' => true, -]); - -$tenantAdmin = $userRepository->create([ - 'tenant_id' => $tenant['id'], - 'role' => 'tenant_admin', - 'email' => 'admin@nordring.test', - 'password' => 'secret123', - 'first_name' => 'Jana', - 'last_name' => 'Koester', - 'is_active' => true, -]); - -$dispatcher = $userRepository->create([ - 'tenant_id' => $tenant['id'], - 'role' => 'dispatcher', - 'email' => 'planung@nordring.test', - 'password' => 'secret123', - 'first_name' => 'Mara', - 'last_name' => 'Dispo', - 'is_active' => true, -]); - -$instructorUser = $userRepository->create([ - 'tenant_id' => $tenant['id'], - 'role' => 'instructor', - 'email' => 'fahrlehrer@nordring.test', - 'password' => 'secret123', - 'first_name' => 'Tobias', - 'last_name' => 'Fahr', - 'is_active' => true, -]); - -$instructors = [ - ['user_id' => $instructorUser['id'], 'first_name' => 'Tobias', 'last_name' => 'Fahr', 'color' => '#0E5D80'], - ['user_id' => null, 'first_name' => 'Leonie', 'last_name' => 'Kraft', 'color' => '#A74826'], -]; - -foreach ($instructors as $instructor) { - $instructorRepository->create($tenant['id'], $instructor + ['notes' => '', 'is_active' => true]); -} - -$lessonTypes = [ - ['name' => 'Einweisung', 'color' => '#0E5D80', 'default_duration' => 45, 'category' => 'student', 'requirement_key' => 'intro', 'is_billable' => 1, 'is_counted' => 1, 'is_rest_relevant' => 1, 'fixed_duration' => 0, 'sort_order' => 1], - ['name' => 'Uebungsstunde', 'color' => '#2C7A4B', 'default_duration' => 45, 'category' => 'student', 'requirement_key' => 'practice', 'is_billable' => 1, 'is_counted' => 1, 'is_rest_relevant' => 1, 'fixed_duration' => 0, 'sort_order' => 2], - ['name' => 'Bundes- / Landstrasse', 'color' => '#D99A1A', 'default_duration' => 45, 'category' => 'student', 'requirement_key' => 'rural', 'is_billable' => 1, 'is_counted' => 1, 'is_rest_relevant' => 1, 'fixed_duration' => 0, 'sort_order' => 3], - ['name' => 'Autobahn', 'color' => '#C86C1E', 'default_duration' => 45, 'category' => 'student', 'requirement_key' => 'highway', 'is_billable' => 1, 'is_counted' => 1, 'is_rest_relevant' => 1, 'fixed_duration' => 0, 'sort_order' => 4], - ['name' => 'Daemmerung / Dunkelheit', 'color' => '#4B356B', 'default_duration' => 45, 'category' => 'student', 'requirement_key' => 'night', 'is_billable' => 1, 'is_counted' => 1, 'is_rest_relevant' => 1, 'fixed_duration' => 0, 'sort_order' => 5], - ['name' => 'Pruefungsfahrt', 'color' => '#A83333', 'default_duration' => 70, 'category' => 'student', 'requirement_key' => null, 'is_billable' => 1, 'is_counted' => 0, 'is_rest_relevant' => 1, 'fixed_duration' => 1, 'sort_order' => 6], - ['name' => 'Theorieunterricht', 'color' => '#2B8793', 'default_duration' => 90, 'category' => 'other', 'requirement_key' => null, 'is_billable' => 0, 'is_counted' => 0, 'is_rest_relevant' => 0, 'fixed_duration' => 1, 'sort_order' => 7], - ['name' => 'Sonstige Arbeiten', 'color' => '#70747C', 'default_duration' => 60, 'category' => 'other', 'requirement_key' => null, 'is_billable' => 0, 'is_counted' => 0, 'is_rest_relevant' => 0, 'fixed_duration' => 1, 'sort_order' => 8], - ['name' => 'Privater Termin', 'color' => '#44444A', 'default_duration' => 60, 'category' => 'private', 'requirement_key' => null, 'is_billable' => 0, 'is_counted' => 0, 'is_rest_relevant' => 0, 'fixed_duration' => 1, 'sort_order' => 9], - ['name' => 'Sperrzeit / Blockierung', 'color' => '#111111', 'default_duration' => 60, 'category' => 'blocked', 'requirement_key' => null, 'is_billable' => 0, 'is_counted' => 0, 'is_rest_relevant' => 0, 'fixed_duration' => 1, 'sort_order' => 10], -]; - -foreach ($lessonTypes as $lessonType) { - $referenceRepository->createLessonType($tenant['id'], $lessonType); -} - -$templates = [ - [ - 'code' => 'C', - 'name' => 'Klasse C', - 'is_combination' => false, - 'requirements' => [ - ['requirement_key' => 'practice', 'label' => 'Uebungsstunden', 'required_units' => 8], - ['requirement_key' => 'rural', 'label' => 'Ueberland', 'required_units' => 5], - ['requirement_key' => 'highway', 'label' => 'Autobahn', 'required_units' => 4], - ['requirement_key' => 'night', 'label' => 'Nachtfahrt', 'required_units' => 3], - ], - ], - [ - 'code' => 'CE', - 'name' => 'Klasse CE', - 'is_combination' => false, - 'requirements' => [ - ['requirement_key' => 'practice', 'label' => 'Uebungsstunden', 'required_units' => 10], - ['requirement_key' => 'rural', 'label' => 'Ueberland', 'required_units' => 5], - ['requirement_key' => 'highway', 'label' => 'Autobahn', 'required_units' => 5], - ['requirement_key' => 'night', 'label' => 'Nachtfahrt', 'required_units' => 3], - ], - ], - [ - 'code' => 'C+CE', - 'name' => 'Klasse C + CE', - 'is_combination' => true, - 'requirements' => [ - ['requirement_key' => 'C::practice', 'phase_label' => 'C', 'label' => 'Uebungsstunden', 'required_units' => 8], - ['requirement_key' => 'C::rural', 'phase_label' => 'C', 'label' => 'Ueberland', 'required_units' => 5], - ['requirement_key' => 'C::highway', 'phase_label' => 'C', 'label' => 'Autobahn', 'required_units' => 4], - ['requirement_key' => 'C::night', 'phase_label' => 'C', 'label' => 'Nachtfahrt', 'required_units' => 3], - ['requirement_key' => 'CE::practice', 'phase_label' => 'CE', 'label' => 'Uebungsstunden', 'required_units' => 6], - ['requirement_key' => 'CE::rural', 'phase_label' => 'CE', 'label' => 'Ueberland', 'required_units' => 3], - ['requirement_key' => 'CE::highway', 'phase_label' => 'CE', 'label' => 'Autobahn', 'required_units' => 3], - ['requirement_key' => 'CE::night', 'phase_label' => 'CE', 'label' => 'Nachtfahrt', 'required_units' => 2], - ], - ], - [ - 'code' => 'C1', - 'name' => 'Klasse C1', - 'is_combination' => false, - 'requirements' => [ - ['requirement_key' => 'practice', 'label' => 'Uebungsstunden', 'required_units' => 6], - ['requirement_key' => 'rural', 'label' => 'Ueberland', 'required_units' => 4], - ['requirement_key' => 'highway', 'label' => 'Autobahn', 'required_units' => 3], - ['requirement_key' => 'night', 'label' => 'Nachtfahrt', 'required_units' => 2], - ], - ], - [ - 'code' => 'C1E', - 'name' => 'Klasse C1E', - 'is_combination' => false, - 'requirements' => [ - ['requirement_key' => 'practice', 'label' => 'Uebungsstunden', 'required_units' => 7], - ['requirement_key' => 'rural', 'label' => 'Ueberland', 'required_units' => 4], - ['requirement_key' => 'highway', 'label' => 'Autobahn', 'required_units' => 3], - ['requirement_key' => 'night', 'label' => 'Nachtfahrt', 'required_units' => 2], - ], - ], - [ - 'code' => 'C1+C1E', - 'name' => 'Klasse C1 + C1E', - 'is_combination' => true, - 'requirements' => [ - ['requirement_key' => 'C1::practice', 'phase_label' => 'C1', 'label' => 'Uebungsstunden', 'required_units' => 6], - ['requirement_key' => 'C1::rural', 'phase_label' => 'C1', 'label' => 'Ueberland', 'required_units' => 4], - ['requirement_key' => 'C1::highway', 'phase_label' => 'C1', 'label' => 'Autobahn', 'required_units' => 3], - ['requirement_key' => 'C1::night', 'phase_label' => 'C1', 'label' => 'Nachtfahrt', 'required_units' => 2], - ['requirement_key' => 'C1E::practice', 'phase_label' => 'C1E', 'label' => 'Uebungsstunden', 'required_units' => 4], - ['requirement_key' => 'C1E::rural', 'phase_label' => 'C1E', 'label' => 'Ueberland', 'required_units' => 2], - ['requirement_key' => 'C1E::highway', 'phase_label' => 'C1E', 'label' => 'Autobahn', 'required_units' => 2], - ['requirement_key' => 'C1E::night', 'phase_label' => 'C1E', 'label' => 'Nachtfahrt', 'required_units' => 1], - ], - ], -]; - -$templateIds = []; -foreach ($templates as $template) { - $record = $referenceRepository->createTemplate($tenant['id'], $template); - $templateIds[$record['code']] = $record['id']; -} - -$studentRepository->create($tenant['id'], [ - 'template_id' => $templateIds['C+CE'], - 'first_name' => 'Mila', - 'last_name' => 'Hansen', - 'phone' => '0170 1234567', - 'notes' => 'Startet naechste Woche mit Nachtfahrten.', - 'status' => 'active', -]); - -$studentRepository->create($tenant['id'], [ - 'template_id' => $templateIds['C1'], - 'first_name' => 'Jonas', - 'last_name' => 'Winter', - 'phone' => '0172 999000', - 'notes' => 'Braucht fruehe Termine.', - 'status' => 'active', -]); - -fwrite(STDOUT, "Seed complete." . PHP_EOL); diff --git a/www/fahrschultermin.de/config/app.php b/www/fahrschultermin.de/config/app.php deleted file mode 100644 index 40dcdfe..0000000 --- a/www/fahrschultermin.de/config/app.php +++ /dev/null @@ -1,38 +0,0 @@ - 'DriveTime Planner', - 'env' => 'production', - 'debug' => false, - - // Database: set db_driver to 'pgsql' or 'sqlite' - 'db_driver' => 'pgsql', - 'db_host' => '127.0.0.1', - 'db_port' => '5433', - 'db_database' => 'fahrschultermin', - 'db_username' => 'fahrschultermin_api', - 'db_password' => 'X9wL3pN7kRtHvMbZs4cGfYu2Dj6qAe8t', - - // Legacy SQLite path (used when db_driver = 'sqlite') - 'db_path' => __DIR__ . '/../storage/database/app.sqlite', - - // Session - 'session_path' => __DIR__ . '/../storage/sessions', - 'session_name' => 'drive_time_session', - 'session_domain' => '.fahrschultermin.de', - - // API - 'api_base_url' => 'https://api.fahrschultermin.de', - 'frontend_url' => 'https://fahrschultermin.de', - - // CORS - 'cors_allowed_origins' => [ - 'https://fahrschultermin.de', - 'https://www.fahrschultermin.de', - ], - - // Frontend asset path (for fahrschultermin.de frontend) - 'frontend_entry' => __DIR__ . '/../public/assets/index.js', -]; diff --git a/www/fahrschultermin.de/database/import_pgsql.sql b/www/fahrschultermin.de/database/import_pgsql.sql deleted file mode 100644 index 64e7a28..0000000 --- a/www/fahrschultermin.de/database/import_pgsql.sql +++ /dev/null @@ -1,518 +0,0 @@ -INSERT INTO tenants (id, name, timezone, is_active, created_at, updated_at, location_label, latitude, longitude, federal_state) VALUES (1, 'Fahrschule Nordring', 'Europe/Berlin', 1, '2026-04-22T18:35:38+00:00', '2026-04-22T18:35:38+00:00', NULL, NULL, NULL, NULL); -INSERT INTO tenants (id, name, timezone, is_active, created_at, updated_at, location_label, latitude, longitude, federal_state) VALUES (2, 'madgerm', 'Europe/Berlin', 1, '2026-04-22 18:40:04', '2026-04-22T22:13:13+00:00', 'Dorsten', 51.656, 6.9643, 'NW'); -INSERT INTO users (id, tenant_id, role, email, password_hash, first_name, last_name, is_active, created_at, updated_at) VALUES (2, 1, 'tenant_admin', 'admin@nordring.test', '$2y$12$IIbaLmgMr9IH0pXxtuGUNeS73tyK7v/pfR0sMw5Edz4eDflX4W9RG', 'Jana', 'Koester', 1, '2026-04-22T18:35:38+00:00', '2026-04-22T18:35:38+00:00'); -INSERT INTO users (id, tenant_id, role, email, password_hash, first_name, last_name, is_active, created_at, updated_at) VALUES (3, 1, 'dispatcher', 'planung@nordring.test', '$2y$12$EdKSdiQwqoMz6btxR2nZBuo59F6EqdqdQboI06IeHUAkfpqjuIa8q', 'Mara', 'Dispo', 1, '2026-04-22T18:35:38+00:00', '2026-04-22T18:35:38+00:00'); -INSERT INTO users (id, tenant_id, role, email, password_hash, first_name, last_name, is_active, created_at, updated_at) VALUES (4, 1, 'instructor', 'fahrlehrer@nordring.test', '$2y$12$JGNkoZrs/Ga2qgz0r2BZy.LJLv4WZm/EqkfauWe1Avsn7n8lymXGy', 'Tobias', 'Fahr', 1, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO users (id, tenant_id, role, email, password_hash, first_name, last_name, is_active, created_at, updated_at) VALUES (5, NULL, 'superadmin', 'armin.ploeger@live.de', '$2y$12$oZmKClGFa380ugvANeYX1OcVpjRWs9gNiJtWE6KhfzqTBMMgJlTFS', 'Armin', 'Ploeger', 1, '2026-04-22 18:40:04', '2026-04-22T18:40:49+00:00'); -INSERT INTO users (id, tenant_id, role, email, password_hash, first_name, last_name, is_active, created_at, updated_at) VALUES (6, 2, 'tenant_admin', 'madgerm@msn.com', '$2y$12$c6VKMJBHSdMHNZoxKB8UP.6i3zPVvAURudyOPMKmVn000TTADGZLC', 'madgerm', '', 1, '2026-04-22 18:40:04', '2026-04-22T19:20:46+00:00'); -INSERT INTO instructors (id, tenant_id, first_name, last_name, color, notes, is_active, created_at, updated_at, user_id, pre_start_buffer_minutes) VALUES (1, 1, 'Tobias', 'Fahr', '#0E5D80', '', 1, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', 4, 0); -INSERT INTO instructors (id, tenant_id, first_name, last_name, color, notes, is_active, created_at, updated_at, user_id, pre_start_buffer_minutes) VALUES (2, 1, 'Leonie', 'Kraft', '#A74826', '', 1, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL, 0); -INSERT INTO instructors (id, tenant_id, first_name, last_name, color, notes, is_active, created_at, updated_at, user_id, pre_start_buffer_minutes) VALUES (3, 2, 'Armin', '', '#0e5d80', '', 1, '2026-04-22T19:37:18+00:00', '2026-04-24T09:00:39+00:00', NULL, 60); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (1, 1, 'C', 'Klasse C', 0, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (2, 1, 'CE', 'Klasse CE', 0, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (3, 1, 'C+CE', 'Klasse C + CE', 1, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (4, 1, 'C1', 'Klasse C1', 0, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (5, 1, 'C1E', 'Klasse C1E', 0, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (6, 1, 'C1+C1E', 'Klasse C1 + C1E', 1, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (7, 2, 'Feuerwehren C', 'Feuerwehren C', 0, '2026-04-22T18:43:17+00:00', '2026-04-24T07:39:17+00:00'); -INSERT INTO license_class_templates (id, tenant_id, code, name, is_combination, created_at, updated_at) VALUES (8, 2, 'Feuerwehr C+CE', 'Feuerwehr C+CE', 1, '2026-04-22T19:19:55+00:00', '2026-04-24T06:50:58+00:00'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (1, 1, 'practice', 'Uebungsstunden', 8, 0, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (2, 1, 'rural', 'Ueberland', 5, 1, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (3, 1, 'highway', 'Autobahn', 4, 2, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (4, 1, 'night', 'Nachtfahrt', 3, 3, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (5, 2, 'practice', 'Uebungsstunden', 10, 0, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (6, 2, 'rural', 'Ueberland', 5, 1, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (7, 2, 'highway', 'Autobahn', 5, 2, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (8, 2, 'night', 'Nachtfahrt', 3, 3, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (13, 4, 'practice', 'Uebungsstunden', 6, 0, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (14, 4, 'rural', 'Ueberland', 4, 1, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (15, 4, 'highway', 'Autobahn', 3, 2, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (16, 4, 'night', 'Nachtfahrt', 2, 3, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (17, 5, 'practice', 'Uebungsstunden', 7, 0, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (18, 5, 'rural', 'Ueberland', 4, 1, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (19, 5, 'highway', 'Autobahn', 3, 2, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (20, 5, 'night', 'Nachtfahrt', 2, 3, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (56, 8, 'C::lesson_type_14', 'Einweisung', 1, 0, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (57, 8, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (58, 8, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (59, 8, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (60, 8, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (61, 8, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (62, 8, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (63, 8, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (64, 8, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (65, 8, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (66, 8, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (67, 8, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (100, 7, 'lesson_type_14', 'Einweisung', 1, 0, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (101, 7, 'lesson_type_15', 'Übungsstunde', 8, 1, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (102, 7, 'lesson_type_12', 'Überlandfahrt', 5, 2, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (103, 7, 'lesson_type_13', 'Autobahnfahrt', 2, 3, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (104, 7, 'lesson_type_11', 'Nachtfahrten', 3, 4, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (105, 7, 'lesson_type_16', 'Praktische Prüfung', 1, 5, ''); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (138, 3, 'C::practice', 'Uebungsstunden', 8, 0, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (139, 3, 'C::rural', 'Ueberland', 5, 1, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (140, 3, 'C::highway', 'Autobahn', 4, 2, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (141, 3, 'C::night', 'Nachtfahrt', 3, 3, 'C'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (142, 3, 'CE::practice', 'Uebungsstunden', 6, 100, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (143, 3, 'CE::rural', 'Ueberland', 3, 101, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (144, 3, 'CE::highway', 'Autobahn', 3, 102, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (145, 3, 'CE::night', 'Nachtfahrt', 2, 103, 'CE'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (146, 6, 'C1::practice', 'Uebungsstunden', 6, 0, 'C1'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (147, 6, 'C1::rural', 'Ueberland', 4, 1, 'C1'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (148, 6, 'C1::highway', 'Autobahn', 3, 2, 'C1'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (149, 6, 'C1::night', 'Nachtfahrt', 2, 3, 'C1'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (150, 6, 'C1E::practice', 'Uebungsstunden', 4, 100, 'C1E'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (151, 6, 'C1E::rural', 'Ueberland', 2, 101, 'C1E'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (152, 6, 'C1E::highway', 'Autobahn', 2, 102, 'C1E'); -INSERT INTO license_template_requirements (id, template_id, requirement_key, label, required_units, sort_order, phase_label) VALUES (153, 6, 'C1E::night', 'Nachtfahrt', 1, 103, 'C1E'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (1, 1, 'Einweisung', '#0E5D80', 45, 'student', 'intro', 1, 1, 1, 0, 1, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2, 1, 'Uebungsstunde', '#2C7A4B', 45, 'student', 'practice', 1, 1, 1, 0, 2, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (3, 1, 'Bundes- / Landstrasse', '#D99A1A', 45, 'student', 'rural', 1, 1, 1, 0, 3, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (4, 1, 'Autobahn', '#C86C1E', 45, 'student', 'highway', 1, 1, 1, 0, 4, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (5, 1, 'Daemmerung / Dunkelheit', '#4B356B', 45, 'student', 'night', 1, 1, 1, 0, 5, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (6, 1, 'Pruefungsfahrt', '#A83333', 70, 'student', NULL, 1, 0, 1, 1, 6, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (7, 1, 'Theorieunterricht', '#2B8793', 90, 'work', NULL, 0, 0, 0, 1, 7, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (8, 1, 'Sonstige Arbeiten', '#70747C', 60, 'work', NULL, 0, 0, 0, 1, 8, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (9, 1, 'Privater Termin', '#44444A', 60, 'private', NULL, 0, 0, 0, 1, 9, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (10, 1, 'Sperrzeit / Blockierung', '#111111', 60, 'blocked', NULL, 0, 0, 0, 1, 10, '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (11, 2, 'Nachtfahrten', '#000000', 45, 'student', NULL, 1, 1, 1, 0, 5, '2026-04-22T18:49:50+00:00', '2026-04-22T19:23:23+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (12, 2, 'Überlandfahrt', '#02882a', 45, 'student', NULL, 1, 1, 1, 0, 3, '2026-04-22T19:01:19+00:00', '2026-04-22T19:23:23+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (13, 2, 'Autobahnfahrt', '#c4660e', 45, 'student', NULL, 1, 1, 1, 0, 4, '2026-04-22T19:05:14+00:00', '2026-04-22T19:23:23+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (14, 2, 'Einweisung', '#e65c4c', 45, 'student', NULL, 1, 1, 1, 0, 1, '2026-04-22T19:06:35+00:00', '2026-04-22T19:23:23+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (15, 2, 'Übungsstunde', '#e65c4c', 45, 'student', NULL, 1, 1, 1, 0, 2, '2026-04-22T19:06:36+00:00', '2026-04-22T19:23:23+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (16, 2, 'Praktische Prüfung', '#11ff00', 85, 'student', NULL, 1, 1, 1, 0, 6, '2026-04-23T05:14:13+00:00', '2026-05-05T19:03:08+00:00', NULL); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (17, 2, 'Privat', '#6B7280', 60, 'private', NULL, 0, 0, 0, 0, 900, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'private_block'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (18, 2, 'Fahrzeugpflege', '#0E5D80', 60, 'work', NULL, 0, 0, 1, 0, 910, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'work_vehicle_care'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (19, 2, 'Buero', '#8B5A2B', 60, 'work', NULL, 0, 0, 1, 0, 920, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'work_office'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (20, 2, 'Wechselfahrt', '#3B7A57', 45, 'work', NULL, 0, 0, 1, 0, 930, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'work_transfer_drive'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (21, 2, 'Sonstige Taetigkeit', '#7C3AED', 60, 'work', NULL, 0, 0, 1, 0, 940, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'work_other'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (22, 2, 'Theorie A', '#C2410C', 90, 'theory', NULL, 0, 0, 1, 0, 950, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'theory_a'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (23, 2, 'Theorie B', '#A74826', 90, 'theory', NULL, 0, 0, 1, 0, 960, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'theory_b'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (24, 2, 'Theorie C', '#B45309', 90, 'theory', NULL, 0, 0, 1, 0, 970, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'theory_c'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (25, 2, 'Theorie D', '#BE123C', 90, 'theory', NULL, 0, 0, 1, 0, 980, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'theory_d'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (26, 2, 'Theorie T', '#047857', 90, 'theory', NULL, 0, 0, 1, 0, 990, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'theory_t'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (27, 2, 'Theorie BKF', '#1D4ED8', 90, 'theory', NULL, 0, 0, 1, 0, 1000, '2026-04-23T07:26:51+00:00', '2026-04-23T07:26:51+00:00', 'theory_bkf'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2327, 1, 'Privat', '#6B7280', 60, 'private', NULL, 0, 0, 0, 0, 900, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'private_block'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2328, 1, 'Fahrzeugpflege', '#0E5D80', 60, 'work', NULL, 0, 0, 1, 0, 910, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'work_vehicle_care'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2329, 1, 'Buero', '#8B5A2B', 60, 'work', NULL, 0, 0, 1, 0, 920, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'work_office'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2330, 1, 'Wechselfahrt', '#3B7A57', 45, 'work', NULL, 0, 0, 1, 0, 930, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'work_transfer_drive'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2331, 1, 'Sonstige Taetigkeit', '#7C3AED', 60, 'work', NULL, 0, 0, 1, 0, 940, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'work_other'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2332, 1, 'Theorie A', '#C2410C', 90, 'theory', NULL, 0, 0, 1, 0, 950, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'theory_a'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2333, 1, 'Theorie B', '#A74826', 90, 'theory', NULL, 0, 0, 1, 0, 960, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'theory_b'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2334, 1, 'Theorie C', '#B45309', 90, 'theory', NULL, 0, 0, 1, 0, 970, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'theory_c'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2335, 1, 'Theorie D', '#BE123C', 90, 'theory', NULL, 0, 0, 1, 0, 980, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'theory_d'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2336, 1, 'Theorie T', '#047857', 90, 'theory', NULL, 0, 0, 1, 0, 990, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'theory_t'); -INSERT INTO lesson_types (id, tenant_id, name, color, default_duration, category, requirement_key, is_billable, is_counted, is_rest_relevant, fixed_duration, sort_order, created_at, updated_at, system_key) VALUES (2337, 1, 'Theorie BKF', '#1D4ED8', 90, 'theory', NULL, 0, 0, 1, 0, 1000, '2026-04-24T06:39:44+00:00', '2026-04-24T06:39:44+00:00', 'theory_bkf'); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (1, 1); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (1, 3); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (1, 4); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (1, 6); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (1, 5); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (1, 2); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (2, 1); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (2, 3); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (2, 4); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (2, 6); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (2, 5); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (2, 2); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (3, 1); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (3, 3); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (3, 4); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (3, 6); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (3, 5); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (3, 2); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (4, 1); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (4, 3); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (4, 4); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (4, 6); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (4, 5); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (4, 2); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (5, 1); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (5, 3); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (5, 4); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (5, 6); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (5, 5); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (5, 2); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (6, 1); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (6, 3); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (6, 4); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (6, 6); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (6, 5); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (6, 2); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (11, 7); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (12, 7); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (13, 7); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (14, 7); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (15, 7); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (11, 8); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (12, 8); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (13, 8); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (14, 8); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (15, 8); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (16, 7); -INSERT INTO lesson_type_template_visibility (lesson_type_id, template_id) VALUES (16, 8); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (1, 1, 3, 'Mila', 'Hansen', '0170 1234567', 'Startet naechste Woche mit Nachtfahrten.', 'active', '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (2, 1, 4, 'Jonas', 'Winter', '0172 999000', 'Braucht fruehe Termine.', 'active', '2026-04-22T18:35:39+00:00', '2026-04-22T18:35:39+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (3, 2, 7, '-', 'Nöllecke', '', '', 'active', '2026-04-22T18:48:52+00:00', '2026-04-23T07:37:52+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (4, 2, 7, '-', 'Nappenfeld', '', '', 'active', '2026-04-22T19:31:04+00:00', '2026-04-23T07:37:12+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (6, 2, 7, '-', 'Storck', '', '', 'active', '2026-04-22T19:31:45+00:00', '2026-04-23T07:38:05+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (7, 2, 7, '-', 'Ronneburger', '', '', 'active', '2026-04-22T19:31:58+00:00', '2026-04-23T07:38:02+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (9, 2, 8, '-', 'Mrowitzki', '', '', 'active', '2026-04-23T05:20:18+00:00', '2026-04-23T07:37:46+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (10, 2, 8, '-', 'Klaas', '', '', 'active', '2026-04-23T05:20:58+00:00', '2026-04-23T08:37:10+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (11, 2, 8, '-', 'Wioliczkp', '', '', 'active', '2026-04-23T05:21:33+00:00', '2026-04-23T08:36:13+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (13, 2, 8, '-', 'Pölling', '', '', 'active', '2026-04-23T05:22:18+00:00', '2026-04-24T07:22:23+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (14, 2, 8, '-', 'Hardameck', '', '', 'active', '2026-04-23T05:22:26+00:00', '2026-04-23T07:37:28+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (15, 2, 7, '-', 'Lawniczek', '', '', 'active', '2026-04-23T05:22:52+00:00', '2026-04-23T08:37:22+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (17, 2, 8, '-', 'Lackmann', '', '', 'active', '2026-04-23T07:34:23+00:00', '2026-04-23T07:34:23+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (19, 2, 8, 'egal', 'bowens', '', '', 'active', '2026-05-07T12:00:21+00:00', '2026-05-07T12:00:21+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (20, 2, 8, 'egal', 'gröning', '', '', 'active', '2026-05-07T12:00:38+00:00', '2026-05-07T12:00:38+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (21, 2, 7, 'egal', 'kobitzsch', '', '', 'active', '2026-05-07T12:00:52+00:00', '2026-05-07T12:01:20+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (22, 2, 8, 'egal', 'gregor schlosser', '', '', 'active', '2026-05-07T12:01:02+00:00', '2026-05-07T12:01:02+00:00', '', 0); -INSERT INTO students (id, tenant_id, template_id, first_name, last_name, phone, notes, status, created_at, updated_at, email, needs_glasses) VALUES (23, 2, 8, '-', 'Kuckel', '', '', 'active', '2026-05-11T17:44:52+00:00', '2026-05-11T17:44:52+00:00', '', 0); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (13, 4, 'lesson_type_14', 'Einweisung', 1, 0, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (14, 4, 'lesson_type_15', 'Übungsstunde', 8, 1, 6, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (15, 4, 'lesson_type_12', 'Überlandfahrt', 5, 2, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (16, 4, 'lesson_type_13', 'Autobahnfahrt', 2, 3, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (17, 4, 'lesson_type_11', 'Nachtfahrten', 3, 4, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (23, 6, 'lesson_type_14', 'Einweisung', 1, 0, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (24, 6, 'lesson_type_15', 'Übungsstunde', 8, 1, 4, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (25, 6, 'lesson_type_12', 'Überlandfahrt', 5, 2, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (26, 6, 'lesson_type_13', 'Autobahnfahrt', 2, 3, 2, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (27, 6, 'lesson_type_11', 'Nachtfahrten', 3, 4, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (28, 7, 'lesson_type_14', 'Einweisung', 1, 0, 1, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (29, 7, 'lesson_type_15', 'Übungsstunde', 8, 1, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (30, 7, 'lesson_type_12', 'Überlandfahrt', 5, 2, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (31, 7, 'lesson_type_13', 'Autobahnfahrt', 2, 3, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (32, 7, 'lesson_type_11', 'Nachtfahrten', 3, 4, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (68, 15, 'lesson_type_14', 'Einweisung', 1, 0, 1, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (69, 15, 'lesson_type_11', 'Nachtfahrten', 3, 4, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (70, 15, 'lesson_type_13', 'Autobahnfahrt', 2, 3, 2, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (71, 15, 'lesson_type_12', 'Überlandfahrt', 5, 2, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (72, 15, 'lesson_type_15', 'Übungsstunde', 8, 1, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (86, 15, 'lesson_type_16', 'Praktische Prüfung', 1, 5, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (88, 4, 'lesson_type_16', 'Praktische Prüfung', 1, 5, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (89, 3, 'lesson_type_14', 'Einweisung', 1, 0, 1, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (90, 3, 'lesson_type_15', 'Übungsstunde', 8, 1, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (91, 3, 'lesson_type_12', 'Überlandfahrt', 5, 2, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (92, 3, 'lesson_type_13', 'Autobahnfahrt', 2, 3, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (93, 3, 'lesson_type_11', 'Nachtfahrten', 3, 4, 3, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (94, 3, 'lesson_type_16', 'Praktische Prüfung', 1, 5, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (96, 7, 'lesson_type_16', 'Praktische Prüfung', 1, 5, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (97, 6, 'lesson_type_16', 'Praktische Prüfung', 1, 5, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (101, 14, 'C::lesson_type_14', 'Einweisung', 1, 0, 1, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (102, 14, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (103, 14, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 2, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (104, 14, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (105, 14, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (106, 14, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (107, 14, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (108, 14, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (109, 14, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (110, 14, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (111, 14, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (112, 14, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (113, 10, 'C::lesson_type_14', 'Einweisung', 1, 0, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (114, 10, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (115, 10, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 3, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (116, 10, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (117, 10, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (118, 10, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (119, 10, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (120, 10, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (121, 10, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (122, 10, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (123, 10, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (124, 10, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (125, 17, 'C::lesson_type_14', 'Einweisung', 1, 0, 1, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (126, 17, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (127, 17, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 6, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (128, 17, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (129, 17, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (130, 17, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (131, 17, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (132, 17, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (133, 17, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (134, 17, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (135, 17, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (136, 17, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (137, 9, 'C::lesson_type_14', 'Einweisung', 1, 0, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (138, 9, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (139, 9, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 5, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (140, 9, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (141, 9, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 1, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (142, 9, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (143, 9, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (144, 9, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (145, 9, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (146, 9, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (147, 9, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (148, 9, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (149, 13, 'C::lesson_type_14', 'Einweisung', 1, 0, 1, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (150, 13, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (151, 13, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 4, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (152, 13, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (153, 13, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 2, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (154, 13, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (155, 13, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (156, 13, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (157, 13, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (158, 13, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (159, 13, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (160, 13, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (161, 11, 'C::lesson_type_14', 'Einweisung', 1, 0, 1, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (162, 11, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (163, 11, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 6, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (164, 11, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (165, 11, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (166, 11, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (167, 11, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (168, 11, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (169, 11, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (170, 11, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (171, 11, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (172, 11, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (205, 1, 'C::highway', 'Autobahn', 4, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (206, 1, 'C::night', 'Nachtfahrt', 3, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (207, 1, 'C::practice', 'Uebungsstunden', 8, 0, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (208, 1, 'C::rural', 'Ueberland', 5, 1, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (209, 1, 'CE::highway', 'Autobahn', 3, 102, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (210, 1, 'CE::night', 'Nachtfahrt', 2, 103, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (211, 1, 'CE::practice', 'Uebungsstunden', 6, 100, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (212, 1, 'CE::rural', 'Ueberland', 3, 101, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (225, 19, 'C::lesson_type_14', 'Einweisung', 1, 0, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (226, 19, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (227, 19, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (228, 19, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (229, 19, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (230, 19, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (231, 19, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (232, 19, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (233, 19, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (234, 19, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (235, 19, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (236, 19, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (237, 20, 'C::lesson_type_14', 'Einweisung', 1, 0, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (238, 20, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (239, 20, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (240, 20, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (241, 20, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (242, 20, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (243, 20, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (244, 20, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (245, 20, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (246, 20, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (247, 20, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (248, 20, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (261, 22, 'C::lesson_type_14', 'Einweisung', 1, 0, 1, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (262, 22, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (263, 22, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 7, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (264, 22, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (265, 22, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 2, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (266, 22, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (267, 22, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 2, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (268, 22, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (269, 22, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (270, 22, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (271, 22, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (272, 22, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (273, 21, 'lesson_type_14', 'Einweisung', 1, 0, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (274, 21, 'lesson_type_15', 'Übungsstunde', 8, 1, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (275, 21, 'lesson_type_12', 'Überlandfahrt', 5, 2, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (276, 21, 'lesson_type_13', 'Autobahnfahrt', 2, 3, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (277, 21, 'lesson_type_11', 'Nachtfahrten', 3, 4, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (278, 21, 'lesson_type_16', 'Praktische Prüfung', 1, 5, 0, ''); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (279, 23, 'C::lesson_type_14', 'Einweisung', 1, 0, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (280, 23, 'CE::lesson_type_14', 'Einweisung', 0, 1000, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (281, 23, 'C::lesson_type_15', 'Übungsstunde', 7, 1, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (282, 23, 'CE::lesson_type_15', 'Übungsstunde', 8, 1001, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (283, 23, 'C::lesson_type_12', 'Überlandfahrt', 5, 2, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (284, 23, 'CE::lesson_type_12', 'Überlandfahrt', 3, 1002, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (285, 23, 'C::lesson_type_13', 'Autobahnfahrt', 2, 3, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (286, 23, 'CE::lesson_type_13', 'Autobahnfahrt', 1, 1003, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (287, 23, 'C::lesson_type_11', 'Nachtfahrten', 3, 4, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (288, 23, 'CE::lesson_type_11', 'Nachtfahrten', 0, 1004, 0, 'CE'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (289, 23, 'C::lesson_type_16', 'Praktische Prüfung', 1, 5, 0, 'C'); -INSERT INTO student_requirement_snapshots (id, student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) VALUES (290, 23, 'CE::lesson_type_16', 'Praktische Prüfung', 1, 1005, 0, 'CE'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (11, 2, 7, 3, 15, 'Übungsstunde', 'student', '2026-04-23T12:00:00+00:00', '2026-04-23T13:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T07:15:35+00:00', '2026-04-23T07:38:40+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (14, 2, 9, 3, 15, 'Übungsstunde', 'student', '2026-04-23T13:45:00+00:00', '2026-04-23T16:00:00+00:00', 3, 'planned', '', 1, 6, 6, '2026-04-23T07:19:46+00:00', '2026-04-23T07:19:46+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (15, 2, 10, 3, 14, 'Einweisung', 'student', '2026-04-23T16:15:00+00:00', '2026-04-23T17:00:00+00:00', 1, 'planned', 'Erste Fahrstunde', 1, 6, 6, '2026-04-23T07:20:34+00:00', '2026-04-23T08:34:15+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (16, 2, 11, 3, 11, 'Nachtfahrten', 'student', '2026-04-23T19:15:00+00:00', '2026-04-23T21:30:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:21:23+00:00', '2026-04-24T09:12:56+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (17, 2, 6, 3, 15, 'Übungsstunde', 'student', '2026-04-24T13:45:00+00:00', '2026-04-24T16:00:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:22:07+00:00', '2026-04-24T08:19:09+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (18, 2, 10, 3, 15, 'Übungsstunde', 'student', '2026-04-24T16:15:00+00:00', '2026-04-24T18:30:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:22:58+00:00', '2026-04-24T07:43:59+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (19, 2, 13, 3, 11, 'Nachtfahrten', 'student', '2026-04-24T18:45:00+00:00', '2026-04-24T21:00:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:23:26+00:00', '2026-04-24T06:56:17+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (20, 2, 14, 3, 11, 'Nachtfahrten', 'student', '2026-04-24T21:00:00+00:00', '2026-04-24T23:15:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:24:01+00:00', '2026-04-24T07:30:07+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (22, 2, 3, 3, 15, 'Übungsstunde', 'student', '2026-04-27T07:45:00+00:00', '2026-04-27T10:45:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-04-23T07:26:26+00:00', '2026-04-24T07:36:25+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (23, 2, 13, 3, 12, 'Überlandfahrt', 'student', '2026-04-28T06:00:00+00:00', '2026-04-28T08:15:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:26:51+00:00', '2026-04-24T07:24:01+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (24, 2, 3, 3, 15, 'Übungsstunde', 'student', '2026-04-28T14:15:00+00:00', '2026-04-28T15:00:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-23T07:29:01+00:00', '2026-04-24T07:42:24+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (25, 2, 9, 3, 12, 'Überlandfahrt', 'student', '2026-04-29T09:00:00+00:00', '2026-04-29T10:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T07:29:48+00:00', '2026-04-24T07:47:37+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (26, 2, 11, 3, 13, 'Autobahnfahrt', 'student', '2026-04-29T06:30:00+00:00', '2026-04-29T08:00:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T07:31:31+00:00', '2026-04-24T08:10:04+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (27, 2, 3, 3, 12, 'Überlandfahrt', 'student', '2026-04-29T12:15:00+00:00', '2026-04-29T13:45:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T07:32:13+00:00', '2026-04-24T07:41:27+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (28, 2, 17, 3, 12, 'Überlandfahrt', 'student', '2026-04-28T08:30:00+00:00', '2026-04-28T10:45:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T07:36:17+00:00', '2026-04-24T08:02:02+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (29, 2, NULL, 3, 21, 'Sonstige Taetigkeit', 'work', '2026-04-23T10:00:00+00:00', '2026-04-23T11:45:00+00:00', 2, 'completed', '', 0, 6, 6, '2026-04-23T07:38:58+00:00', '2026-04-24T09:12:18+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (39, 2, 13, 3, 13, 'Autobahnfahrt', 'student', '2026-04-30T08:15:00+00:00', '2026-04-30T09:45:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T08:05:22+00:00', '2026-04-24T07:24:28+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (40, 2, 14, 3, 15, 'Übungsstunde', 'student', '2026-04-30T10:30:00+00:00', '2026-04-30T13:30:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-04-23T08:05:59+00:00', '2026-04-24T07:33:13+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (41, 2, 17, 3, 13, 'Autobahnfahrt', 'student', '2026-04-30T13:30:00+00:00', '2026-04-30T15:00:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T08:06:20+00:00', '2026-04-24T08:01:06+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (43, 2, 6, 3, 12, 'Überlandfahrt', 'student', '2026-05-04T11:15:00+00:00', '2026-05-04T14:15:00+00:00', 4, 'planned', '', 1, 6, 6, '2026-04-23T08:08:46+00:00', '2026-04-27T13:38:49+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (44, 2, 3, 3, 13, 'Autobahnfahrt', 'student', '2026-05-04T14:30:00+00:00', '2026-05-04T16:00:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-04-23T08:08:57+00:00', '2026-04-23T08:16:03+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (46, 2, 17, 3, 11, 'Nachtfahrten', 'student', '2026-05-02T18:15:00+00:00', '2026-05-02T20:30:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-23T08:09:52+00:00', '2026-04-24T08:39:51+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (49, 2, 7, 3, 13, 'Autobahnfahrt', 'student', '2026-05-04T16:15:00+00:00', '2026-05-04T17:45:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-04-23T08:16:18+00:00', '2026-04-23T08:30:07+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (51, 2, 14, 3, 12, 'Überlandfahrt', 'student', '2026-05-05T07:00:00+00:00', '2026-05-05T07:45:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-23T08:17:45+00:00', '2026-05-04T06:37:04+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (52, 2, 14, 3, 12, 'Überlandfahrt', 'student', '2026-05-08T11:30:00+00:00', '2026-05-08T14:30:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-04-23T08:18:12+00:00', '2026-05-06T08:09:09+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (54, 2, 15, 3, 15, 'Übungsstunde', 'student', '2026-05-12T06:00:00+00:00', '2026-05-12T07:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T08:21:26+00:00', '2026-04-23T08:21:32+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (55, 2, 7, 3, 12, 'Überlandfahrt', 'student', '2026-04-28T12:30:00+00:00', '2026-04-28T14:00:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-04-23T08:29:26+00:00', '2026-04-23T08:29:26+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (56, 2, 7, 3, 15, 'Übungsstunde', 'student', '2026-05-04T17:45:00+00:00', '2026-05-04T18:30:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-04-23T08:30:16+00:00', '2026-04-23T08:30:16+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (57, 2, 7, 3, 15, 'Übungsstunde', 'student', '2026-04-28T11:00:00+00:00', '2026-04-28T12:30:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-04-23T08:30:35+00:00', '2026-04-23T08:30:35+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (58, 2, 10, 3, 15, 'Übungsstunde', 'student', '2026-04-23T17:00:00+00:00', '2026-04-23T18:30:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-04-23T08:34:06+00:00', '2026-04-23T08:34:10+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (59, 2, 15, 3, 16, 'Praktische Prüfung', 'student', '2026-05-13T08:50:00+00:00', '2026-05-13T10:05:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-23T09:04:23+00:00', '2026-05-07T11:54:19+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (61, 2, 3, 3, 16, 'Praktische Prüfung', 'student', '2026-05-05T12:15:00+00:00', '2026-05-05T13:30:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-23T09:06:24+00:00', '2026-05-04T06:36:24+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (62, 2, 7, 3, 16, 'Praktische Prüfung', 'student', '2026-05-05T11:00:00+00:00', '2026-05-05T12:15:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-23T09:06:47+00:00', '2026-05-04T18:38:20+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (63, 2, 11, 3, 12, 'Überlandfahrt', 'student', '2026-04-27T11:00:00+00:00', '2026-04-27T12:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-23T21:47:43+00:00', '2026-04-27T11:00:51+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (67, 2, 13, 3, 15, 'Übungsstunde', 'student', '2026-04-30T09:45:00+00:00', '2026-04-30T10:30:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-24T07:24:36+00:00', '2026-04-24T07:24:43+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (68, 2, 14, 3, 13, 'Autobahnfahrt', 'student', '2026-05-05T07:45:00+00:00', '2026-05-05T09:15:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-24T07:29:55+00:00', '2026-05-04T06:36:52+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (69, 2, 14, 3, 16, 'Praktische Prüfung', 'student', '2026-05-11T11:40:00+00:00', '2026-05-11T13:05:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-04-24T07:31:52+00:00', '2026-05-08T07:28:05+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (70, 2, 3, 3, 12, 'Überlandfahrt', 'student', '2026-04-28T15:00:00+00:00', '2026-04-28T15:45:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-04-24T07:42:39+00:00', '2026-04-24T07:42:39+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (72, 2, 13, 3, 16, 'Praktische Prüfung', 'student', '2026-05-06T11:20:00+00:00', '2026-05-06T12:35:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-24T07:44:24+00:00', '2026-05-04T06:34:51+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (73, 2, 9, 3, 13, 'Autobahnfahrt', 'student', '2026-04-29T10:30:00+00:00', '2026-04-29T12:00:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-24T07:47:49+00:00', '2026-04-24T07:47:52+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (74, 2, 11, 3, 16, 'Praktische Prüfung', 'student', '2026-05-06T10:15:00+00:00', '2026-05-06T11:40:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-04-24T07:48:36+00:00', '2026-05-07T11:48:54+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (76, 2, 11, 3, 15, 'Übungsstunde', 'student', '2026-04-27T12:30:00+00:00', '2026-04-27T13:15:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-24T07:49:49+00:00', '2026-04-27T12:05:20+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (78, 2, NULL, 3, 17, 'Privat', 'private', '2026-04-30T06:00:00+00:00', '2026-04-30T08:15:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-24T07:59:59+00:00', '2026-04-24T08:02:57+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (80, 2, 17, 3, 12, 'Überlandfahrt', 'student', '2026-04-30T15:00:00+00:00', '2026-04-30T16:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-24T08:01:22+00:00', '2026-04-24T08:42:10+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (81, 2, 11, 3, 12, 'Überlandfahrt', 'student', '2026-04-29T08:00:00+00:00', '2026-04-29T08:45:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-24T08:10:10+00:00', '2026-04-24T08:10:20+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (82, 2, 9, 3, 16, 'Praktische Prüfung', 'student', '2026-05-06T08:50:00+00:00', '2026-05-06T10:15:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-04-24T08:10:58+00:00', '2026-05-07T11:48:41+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (83, 2, 11, 3, 12, 'Überlandfahrt', 'student', '2026-05-05T14:00:00+00:00', '2026-05-05T15:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-24T08:11:27+00:00', '2026-05-05T07:13:35+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (86, 2, 6, 3, 16, 'Praktische Prüfung', 'student', '2026-05-05T09:45:00+00:00', '2026-05-05T11:00:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-24T08:18:47+00:00', '2026-05-04T06:35:48+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (87, 2, 9, 3, 11, 'Nachtfahrten', 'student', '2026-04-25T18:30:00+00:00', '2026-04-25T20:45:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-24T08:25:38+00:00', '2026-04-24T08:39:40+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (88, 2, NULL, 3, 20, 'Wechselfahrt', 'work', '2026-04-23T11:45:00+00:00', '2026-04-23T12:00:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-24T09:12:32+00:00', '2026-04-24T09:12:32+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (89, 2, NULL, 3, 21, 'Sonstige Taetigkeit', 'work', '2026-04-23T18:30:00+00:00', '2026-04-23T19:30:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-04-24T09:13:12+00:00', '2026-04-24T09:13:12+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (91, 2, 15, 3, 15, 'Übungsstunde', 'student', '2026-05-11T08:30:00+00:00', '2026-05-11T10:45:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-04-27T07:08:36+00:00', '2026-05-08T07:28:16+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (92, 2, 15, 3, 12, 'Überlandfahrt', 'student', '2026-05-12T07:30:00+00:00', '2026-05-12T09:00:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-04-27T07:09:19+00:00', '2026-04-27T07:09:19+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (95, 2, 17, 3, 15, 'Übungsstunde', 'student', '2026-05-02T17:30:00+00:00', '2026-05-02T18:15:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-04-28T10:51:37+00:00', '2026-04-28T10:51:37+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (96, 2, 9, 3, 12, 'Überlandfahrt', 'student', '2026-05-04T09:30:00+00:00', '2026-05-04T11:00:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-04-29T19:22:31+00:00', '2026-04-29T19:22:48+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (97, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-08T00:15:00+00:00', '2026-05-08T11:30:00+00:00', 11, 'planned', '', 1, 6, 6, '2026-05-05T19:28:33+00:00', '2026-05-05T19:28:33+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (99, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-19T09:00:00+00:00', '2026-05-19T10:00:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-06T16:05:05+00:00', '2026-05-06T16:05:05+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (100, 2, 22, 3, 11, 'Nachtfahrten', 'student', '2026-05-07T18:30:00+00:00', '2026-05-07T20:45:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-07T11:36:23+00:00', '2026-05-07T12:03:24+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (101, 2, 20, 3, 14, 'Einweisung', 'student', '2026-05-07T15:45:00+00:00', '2026-05-07T16:30:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-07T11:36:40+00:00', '2026-05-07T12:12:40+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (102, 2, 20, 3, 15, 'Übungsstunde', 'student', '2026-05-08T15:00:00+00:00', '2026-05-08T17:15:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-07T11:37:51+00:00', '2026-05-13T10:31:47+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (103, 2, 17, 3, 16, 'Praktische Prüfung', 'student', '2026-05-06T12:30:00+00:00', '2026-05-06T13:55:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-05-07T11:48:01+00:00', '2026-05-07T11:48:31+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (104, 2, 20, 3, 15, 'Übungsstunde', 'student', '2026-05-07T16:30:00+00:00', '2026-05-07T18:00:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-07T12:12:48+00:00', '2026-05-07T12:13:08+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (108, 2, NULL, 3, 20, 'Wechselfahrt', 'work', '2026-05-11T13:00:00+00:00', '2026-05-11T14:00:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-05-08T07:29:03+00:00', '2026-05-08T07:29:03+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (110, 2, NULL, 3, 20, 'Wechselfahrt', 'work', '2026-05-13T10:00:00+00:00', '2026-05-13T11:00:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-05-08T07:30:18+00:00', '2026-05-08T07:30:18+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (116, 2, 20, 3, 15, 'Übungsstunde', 'student', '2026-05-13T11:15:00+00:00', '2026-05-13T12:45:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-08T07:39:55+00:00', '2026-05-13T10:32:15+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (119, 2, 21, 3, 14, 'Einweisung', 'student', '2026-05-12T09:15:00+00:00', '2026-05-12T10:00:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-08T07:45:42+00:00', '2026-05-09T13:43:04+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (120, 2, 21, 3, 14, 'Einweisung', 'student', '2026-05-12T10:00:00+00:00', '2026-05-12T11:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-08T07:45:50+00:00', '2026-05-09T13:43:18+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (123, 2, 19, 3, 14, 'Einweisung', 'student', '2026-05-12T12:00:00+00:00', '2026-05-12T12:45:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-05-09T13:45:05+00:00', '2026-05-09T13:45:05+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (124, 2, 19, 3, 15, 'Übungsstunde', 'student', '2026-05-12T12:45:00+00:00', '2026-05-12T14:15:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-05-09T13:45:20+00:00', '2026-05-09T13:45:20+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (125, 2, 23, 3, 14, 'Einweisung', 'student', '2026-05-13T05:30:00+00:00', '2026-05-13T06:15:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-11T17:45:00+00:00', '2026-05-11T17:47:29+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (126, 2, 23, 3, 15, 'Übungsstunde', 'student', '2026-05-13T06:15:00+00:00', '2026-05-13T07:45:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-11T17:47:35+00:00', '2026-05-13T07:03:13+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (128, 2, 20, 3, 11, 'Nachtfahrten', 'student', '2026-05-15T18:00:00+00:00', '2026-05-15T20:15:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-11T17:50:12+00:00', '2026-05-13T14:12:08+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (130, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-16T09:00:00+00:00', '2026-05-16T10:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-11T17:52:04+00:00', '2026-05-11T17:52:24+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (131, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-16T10:45:00+00:00', '2026-05-16T12:15:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-11T17:52:33+00:00', '2026-05-11T17:52:33+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (133, 2, NULL, 3, 21, 'Sonstige Taetigkeit', 'work', '2026-05-11T10:45:00+00:00', '2026-05-11T11:30:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-11T18:09:30+00:00', '2026-05-11T18:09:30+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (134, 2, NULL, 3, 21, 'Sonstige Taetigkeit', 'work', '2026-05-13T08:00:00+00:00', '2026-05-13T08:45:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-11T18:09:58+00:00', '2026-05-11T18:10:10+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (136, 2, 20, 3, 12, 'Überlandfahrt', 'student', '2026-05-13T12:45:00+00:00', '2026-05-13T14:15:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-05-13T10:32:27+00:00', '2026-05-13T10:32:27+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (137, 2, 19, 3, 15, 'Übungsstunde', 'student', '2026-05-15T14:45:00+00:00', '2026-05-15T17:45:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-13T10:34:50+00:00', '2026-05-14T12:29:05+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (138, 2, 19, 3, 11, 'Nachtfahrten', 'student', '2026-05-22T18:00:00+00:00', '2026-05-22T20:15:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-14T12:15:48+00:00', '2026-05-14T12:15:48+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (139, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-18T15:00:00+00:00', '2026-05-18T19:00:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-14T12:16:59+00:00', '2026-05-14T12:17:16+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (140, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-20T15:00:00+00:00', '2026-05-20T19:00:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-14T12:17:10+00:00', '2026-05-14T12:17:13+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (141, 2, 23, 3, 15, 'Übungsstunde', 'student', '2026-05-19T05:30:00+00:00', '2026-05-19T08:30:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-14T12:21:43+00:00', '2026-05-14T12:22:57+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (142, 2, 22, 3, 14, 'Einweisung', 'student', '2026-05-22T11:30:00+00:00', '2026-05-22T14:30:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-14T12:24:02+00:00', '2026-05-14T12:25:48+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (144, 2, 19, 3, 15, 'Übungsstunde', 'student', '2026-05-27T12:00:00+00:00', '2026-05-27T12:45:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-14T12:31:05+00:00', '2026-05-14T12:41:13+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (145, 2, 19, 3, 12, 'Überlandfahrt', 'student', '2026-05-27T12:45:00+00:00', '2026-05-27T15:00:00+00:00', 3, 'planned', '', 1, 6, 6, '2026-05-14T12:31:42+00:00', '2026-05-14T12:41:18+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (146, 2, 19, 3, 16, 'Praktische Prüfung', 'student', '2026-06-01T06:00:00+00:00', '2026-06-01T07:25:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-14T12:31:59+00:00', '2026-05-14T12:31:59+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (147, 2, 22, 3, 16, 'Praktische Prüfung', 'student', '2026-06-01T07:45:00+00:00', '2026-06-01T09:10:00+00:00', 1, 'planned', '', 1, 6, 6, '2026-05-14T12:32:51+00:00', '2026-05-14T12:32:51+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (148, 2, 19, 3, 12, 'Überlandfahrt', 'student', '2026-05-28T12:00:00+00:00', '2026-05-28T13:30:00+00:00', 2, 'planned', '', 0, 6, 6, '2026-05-14T12:33:31+00:00', '2026-05-14T12:33:31+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (149, 2, 19, 3, 13, 'Autobahnfahrt', 'student', '2026-05-28T13:30:00+00:00', '2026-05-28T15:00:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-05-14T12:33:43+00:00', '2026-05-14T12:33:43+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (150, 2, 3, 3, 15, 'Übungsstunde', 'student', '2026-05-26T11:00:00+00:00', '2026-05-26T14:00:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-14T12:37:39+00:00', '2026-05-14T12:41:57+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (151, 2, NULL, 3, 17, 'Privat', 'private', '2026-05-26T15:00:00+00:00', '2026-05-26T16:00:00+00:00', 1, 'planned', '', 0, 6, 6, '2026-05-14T12:41:38+00:00', '2026-05-14T12:41:38+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (152, 2, 15, 3, 14, 'Einweisung', 'student', '2026-05-22T14:45:00+00:00', '2026-05-22T17:45:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-14T12:46:48+00:00', '2026-05-14T12:46:48+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (154, 2, 22, 3, 15, 'Übungsstunde', 'student', '2026-05-29T06:30:00+00:00', '2026-05-29T09:30:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-15T10:50:45+00:00', '2026-05-15T10:51:24+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (155, 2, 20, 3, 12, 'Überlandfahrt', 'student', '2026-05-19T10:30:00+00:00', '2026-05-19T12:45:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-15T20:50:25+00:00', '2026-05-15T20:50:36+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (156, 2, 20, 3, 13, 'Autobahnfahrt', 'student', '2026-05-21T11:45:00+00:00', '2026-05-21T13:15:00+00:00', 2, 'planned', '', 1, 6, 6, '2026-05-15T20:50:59+00:00', '2026-05-15T20:54:45+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (157, 2, 20, 3, 15, 'Übungsstunde', 'student', '2026-05-21T06:00:00+00:00', '2026-05-21T09:00:00+00:00', 4, 'planned', '', 0, 6, 6, '2026-05-15T20:51:35+00:00', '2026-05-15T20:54:04+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (158, 2, 20, 3, 15, 'Übungsstunde', 'student', '2026-05-21T09:15:00+00:00', '2026-05-21T11:30:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-15T20:51:41+00:00', '2026-05-15T20:54:19+00:00'); -INSERT INTO appointments (id, tenant_id, student_id, instructor_id, lesson_type_id, title, category, start_at, end_at, units, status, notes, warning_acknowledged, created_by, updated_by, created_at, updated_at) VALUES (159, 2, 14, 3, 14, 'Einweisung', 'student', '2026-05-18T11:30:00+00:00', '2026-05-18T14:00:00+00:00', 3, 'planned', '', 0, 6, 6, '2026-05-18T14:07:24+00:00', '2026-05-18T14:07:24+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (16, 14, 'C::lesson_type_15', 'Übungsstunde', 3, '2026-04-23T07:19:46+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (44, 11, 'lesson_type_15', 'Übungsstunde', 2, '2026-04-23T07:38:40+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (59, 44, 'lesson_type_13', 'Autobahnfahrt', 2, '2026-04-23T08:16:03+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (66, 54, 'lesson_type_15', 'Übungsstunde', 2, '2026-04-23T08:21:32+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (68, 55, 'lesson_type_12', 'Überlandfahrt', 2, '2026-04-23T08:29:26+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (69, 49, 'lesson_type_13', 'Autobahnfahrt', 2, '2026-04-23T08:30:07+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (70, 56, 'lesson_type_15', 'Übungsstunde', 1, '2026-04-23T08:30:16+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (71, 57, 'lesson_type_15', 'Übungsstunde', 2, '2026-04-23T08:30:35+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (74, 58, 'C::lesson_type_15', 'Übungsstunde', 2, '2026-04-23T08:34:10+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (75, 15, 'C::lesson_type_14', 'Einweisung', 1, '2026-04-23T08:34:15+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (88, 19, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-04-24T06:56:17+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (101, 23, 'C::lesson_type_12', 'Überlandfahrt', 3, '2026-04-24T07:24:01+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (103, 39, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-04-24T07:24:28+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (105, 67, 'C::lesson_type_15', 'Übungsstunde', 1, '2026-04-24T07:24:43+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (109, 20, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-04-24T07:30:07+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (114, 40, 'C::lesson_type_15', 'Übungsstunde', 4, '2026-04-24T07:33:13+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (116, 22, 'lesson_type_15', 'Übungsstunde', 4, '2026-04-24T07:36:25+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (118, 27, 'lesson_type_12', 'Überlandfahrt', 2, '2026-04-24T07:41:27+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (119, 24, 'lesson_type_15', 'Übungsstunde', 1, '2026-04-24T07:42:24+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (120, 70, 'lesson_type_12', 'Überlandfahrt', 1, '2026-04-24T07:42:39+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (123, 18, 'C::lesson_type_15', 'Übungsstunde', 3, '2026-04-24T07:43:59+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (125, 25, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-04-24T07:47:37+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (127, 73, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-04-24T07:47:52+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (134, 41, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-04-24T08:01:06+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (137, 28, 'C::lesson_type_12', 'Überlandfahrt', 3, '2026-04-24T08:02:02+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (139, 26, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-04-24T08:10:04+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (141, 81, 'C::lesson_type_12', 'Überlandfahrt', 1, '2026-04-24T08:10:20+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (150, 17, 'lesson_type_15', 'Übungsstunde', 3, '2026-04-24T08:19:09+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (165, 87, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-04-24T08:39:40+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (166, 46, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-04-24T08:39:51+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (168, 80, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-04-24T08:42:10+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (169, 16, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-04-24T09:12:56+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (175, 92, 'lesson_type_12', 'Überlandfahrt', 2, '2026-04-27T07:09:19+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (176, 63, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-04-27T11:00:51+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (179, 76, 'C::lesson_type_15', 'Übungsstunde', 1, '2026-04-27T12:05:20+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (183, 43, 'lesson_type_12', 'Überlandfahrt', 4, '2026-04-27T13:38:49+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (188, 95, 'C::lesson_type_15', 'Übungsstunde', 1, '2026-04-28T10:51:37+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (191, 96, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-04-29T19:22:48+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (218, 72, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-04T06:34:51+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (221, 86, 'lesson_type_16', 'Praktische Prüfung', 1, '2026-05-04T06:35:48+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (224, 61, 'lesson_type_16', 'Praktische Prüfung', 1, '2026-05-04T06:36:24+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (226, 68, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-05-04T06:36:52+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (227, 51, 'C::lesson_type_12', 'Überlandfahrt', 1, '2026-05-04T06:37:04+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (230, 62, 'lesson_type_16', 'Praktische Prüfung', 1, '2026-05-04T18:38:20+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (231, 83, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-05-05T07:13:35+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (234, 52, 'C::lesson_type_12', 'Überlandfahrt', 4, '2026-05-06T08:09:09+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (242, 103, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-07T11:48:31+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (243, 82, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-07T11:48:41+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (244, 74, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-07T11:48:54+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (250, 59, 'lesson_type_16', 'Praktische Prüfung', 1, '2026-05-07T11:54:19+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (253, 100, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-05-07T12:03:24+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (255, 101, 'C::lesson_type_14', 'Einweisung', 1, '2026-05-07T12:12:40+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (257, 104, 'C::lesson_type_15', 'Übungsstunde', 2, '2026-05-07T12:13:08+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (258, 69, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-08T07:28:05+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (259, 91, 'lesson_type_15', 'Übungsstunde', 3, '2026-05-08T07:28:16+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (284, 119, 'lesson_type_14', 'Einweisung', 1, '2026-05-09T13:43:04+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (285, 120, 'lesson_type_14', 'Einweisung', 2, '2026-05-09T13:43:18+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (286, 123, 'C::lesson_type_14', 'Einweisung', 1, '2026-05-09T13:45:05+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (287, 124, 'C::lesson_type_15', 'Übungsstunde', 2, '2026-05-09T13:45:20+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (291, 125, 'C::lesson_type_14', 'Einweisung', 1, '2026-05-11T17:47:29+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (301, 126, 'C::lesson_type_15', 'Übungsstunde', 2, '2026-05-13T07:03:13+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (304, 102, 'C::lesson_type_15', 'Übungsstunde', 3, '2026-05-13T10:31:47+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (305, 116, 'C::lesson_type_15', 'Übungsstunde', 2, '2026-05-13T10:32:15+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (306, 136, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-05-13T10:32:27+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (309, 128, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-05-13T14:12:08+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (313, 138, 'C::lesson_type_11', 'Nachtfahrten', 3, '2026-05-14T12:15:48+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (319, 141, 'C::lesson_type_15', 'Übungsstunde', 4, '2026-05-14T12:22:57+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (328, 142, 'C::lesson_type_14', 'Einweisung', 4, '2026-05-14T12:25:48+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (330, 137, 'C::lesson_type_15', 'Übungsstunde', 4, '2026-05-14T12:29:05+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (335, 146, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-14T12:31:59+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (336, 147, 'C::lesson_type_16', 'Praktische Prüfung', 1, '2026-05-14T12:32:51+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (337, 148, 'C::lesson_type_12', 'Überlandfahrt', 2, '2026-05-14T12:33:31+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (338, 149, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-05-14T12:33:43+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (341, 144, 'C::lesson_type_15', 'Übungsstunde', 1, '2026-05-14T12:41:13+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (342, 145, 'C::lesson_type_12', 'Überlandfahrt', 3, '2026-05-14T12:41:18+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (344, 150, 'lesson_type_15', 'Übungsstunde', 4, '2026-05-14T12:41:57+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (345, 152, 'lesson_type_14', 'Einweisung', 4, '2026-05-14T12:46:48+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (349, 154, 'C::lesson_type_15', 'Übungsstunde', 4, '2026-05-15T10:51:24+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (352, 155, 'C::lesson_type_12', 'Überlandfahrt', 3, '2026-05-15T20:50:36+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (359, 157, 'C::lesson_type_15', 'Übungsstunde', 4, '2026-05-15T20:54:04+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (360, 158, 'C::lesson_type_15', 'Übungsstunde', 3, '2026-05-15T20:54:19+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (362, 156, 'C::lesson_type_13', 'Autobahnfahrt', 2, '2026-05-15T20:54:45+00:00'); -INSERT INTO appointment_units (id, appointment_id, requirement_key, label, units_counted, created_at) VALUES (363, 159, 'C::lesson_type_14', 'Einweisung', 3, '2026-05-18T14:07:24+00:00'); -INSERT INTO settings (id, tenant_id, key_name, value) VALUES (1, 1, 'app.theme', 'signal'); \ No newline at end of file diff --git a/www/fahrschultermin.de/database/migrations/001_initial.sql b/www/fahrschultermin.de/database/migrations/001_initial.sql deleted file mode 100644 index c9ec8b6..0000000 --- a/www/fahrschultermin.de/database/migrations/001_initial.sql +++ /dev/null @@ -1,145 +0,0 @@ -CREATE TABLE IF NOT EXISTS tenants ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - name TEXT NOT NULL, - timezone TEXT NOT NULL DEFAULT 'Europe/Berlin', - is_active INTEGER NOT NULL DEFAULT 1, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL -); - -CREATE TABLE IF NOT EXISTS users ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NULL, - role TEXT NOT NULL, - email TEXT NOT NULL UNIQUE, - password_hash TEXT NOT NULL, - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - is_active INTEGER NOT NULL DEFAULT 1, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS instructors ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NOT NULL, - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - color TEXT NOT NULL, - notes TEXT DEFAULT '', - is_active INTEGER NOT NULL DEFAULT 1, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS lesson_types ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NOT NULL, - name TEXT NOT NULL, - color TEXT NOT NULL, - default_duration INTEGER NOT NULL, - category TEXT NOT NULL, - requirement_key TEXT DEFAULT NULL, - is_billable INTEGER NOT NULL DEFAULT 0, - is_counted INTEGER NOT NULL DEFAULT 0, - is_rest_relevant INTEGER NOT NULL DEFAULT 0, - fixed_duration INTEGER NOT NULL DEFAULT 0, - sort_order INTEGER NOT NULL DEFAULT 0, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS license_class_templates ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NOT NULL, - code TEXT NOT NULL, - name TEXT NOT NULL, - is_combination INTEGER NOT NULL DEFAULT 0, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - UNIQUE (tenant_id, code), - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS license_template_requirements ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - template_id INTEGER NOT NULL, - requirement_key TEXT NOT NULL, - label TEXT NOT NULL, - required_units INTEGER NOT NULL, - sort_order INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY (template_id) REFERENCES license_class_templates (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS students ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NOT NULL, - template_id INTEGER NOT NULL, - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - phone TEXT DEFAULT '', - notes TEXT DEFAULT '', - status TEXT NOT NULL DEFAULT 'active', - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE, - FOREIGN KEY (template_id) REFERENCES license_class_templates (id) -); - -CREATE TABLE IF NOT EXISTS student_requirement_snapshots ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - student_id INTEGER NOT NULL, - requirement_key TEXT NOT NULL, - label TEXT NOT NULL, - required_units INTEGER NOT NULL, - sort_order INTEGER NOT NULL DEFAULT 0, - FOREIGN KEY (student_id) REFERENCES students (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS appointments ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NOT NULL, - student_id INTEGER DEFAULT NULL, - instructor_id INTEGER NOT NULL, - lesson_type_id INTEGER NOT NULL, - title TEXT NOT NULL, - category TEXT NOT NULL, - start_at TEXT NOT NULL, - end_at TEXT NOT NULL, - units INTEGER NOT NULL DEFAULT 1, - status TEXT NOT NULL DEFAULT 'planned', - notes TEXT DEFAULT '', - warning_acknowledged INTEGER NOT NULL DEFAULT 0, - created_by INTEGER NOT NULL, - updated_by INTEGER NOT NULL, - created_at TEXT NOT NULL, - updated_at TEXT NOT NULL, - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE, - FOREIGN KEY (student_id) REFERENCES students (id) ON DELETE SET NULL, - FOREIGN KEY (instructor_id) REFERENCES instructors (id), - FOREIGN KEY (lesson_type_id) REFERENCES lesson_types (id), - FOREIGN KEY (created_by) REFERENCES users (id), - FOREIGN KEY (updated_by) REFERENCES users (id) -); - -CREATE TABLE IF NOT EXISTS appointment_units ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - appointment_id INTEGER NOT NULL, - requirement_key TEXT DEFAULT NULL, - label TEXT DEFAULT NULL, - units_counted INTEGER NOT NULL DEFAULT 0, - created_at TEXT NOT NULL, - FOREIGN KEY (appointment_id) REFERENCES appointments (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS settings ( - id INTEGER PRIMARY KEY AUTOINCREMENT, - tenant_id INTEGER NOT NULL, - key_name TEXT NOT NULL, - value TEXT NOT NULL, - UNIQUE (tenant_id, key_name), - FOREIGN KEY (tenant_id) REFERENCES tenants (id) ON DELETE CASCADE -); diff --git a/www/fahrschultermin.de/database/migrations/002_instructors_user_link.sql b/www/fahrschultermin.de/database/migrations/002_instructors_user_link.sql deleted file mode 100644 index d1a755e..0000000 --- a/www/fahrschultermin.de/database/migrations/002_instructors_user_link.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE instructors ADD COLUMN user_id INTEGER DEFAULT NULL; diff --git a/www/fahrschultermin.de/database/migrations/003_backfill_instructor_user_links.sql b/www/fahrschultermin.de/database/migrations/003_backfill_instructor_user_links.sql deleted file mode 100644 index c41d2fd..0000000 --- a/www/fahrschultermin.de/database/migrations/003_backfill_instructor_user_links.sql +++ /dev/null @@ -1,11 +0,0 @@ -UPDATE instructors -SET user_id = ( - SELECT u.id - FROM users u - WHERE u.tenant_id = instructors.tenant_id - AND u.role = 'instructor' - AND u.first_name = instructors.first_name - AND u.last_name = instructors.last_name - LIMIT 1 -) -WHERE user_id IS NULL; diff --git a/www/fahrschultermin.de/database/migrations/004_lesson_type_template_visibility.sql b/www/fahrschultermin.de/database/migrations/004_lesson_type_template_visibility.sql deleted file mode 100644 index 084a4f3..0000000 --- a/www/fahrschultermin.de/database/migrations/004_lesson_type_template_visibility.sql +++ /dev/null @@ -1,13 +0,0 @@ -CREATE TABLE IF NOT EXISTS lesson_type_template_visibility ( - lesson_type_id INTEGER NOT NULL, - template_id INTEGER NOT NULL, - PRIMARY KEY (lesson_type_id, template_id), - FOREIGN KEY (lesson_type_id) REFERENCES lesson_types (id) ON DELETE CASCADE, - FOREIGN KEY (template_id) REFERENCES license_class_templates (id) ON DELETE CASCADE -); - -INSERT OR IGNORE INTO lesson_type_template_visibility (lesson_type_id, template_id) -SELECT lt.id, tpl.id -FROM lesson_types lt -JOIN license_class_templates tpl ON tpl.tenant_id = lt.tenant_id -WHERE lt.category = 'student'; diff --git a/www/fahrschultermin.de/database/migrations/005_tenant_location_sun.sql b/www/fahrschultermin.de/database/migrations/005_tenant_location_sun.sql deleted file mode 100644 index 154f13a..0000000 --- a/www/fahrschultermin.de/database/migrations/005_tenant_location_sun.sql +++ /dev/null @@ -1,3 +0,0 @@ -ALTER TABLE tenants ADD COLUMN location_label TEXT DEFAULT ''; -ALTER TABLE tenants ADD COLUMN latitude REAL DEFAULT NULL; -ALTER TABLE tenants ADD COLUMN longitude REAL DEFAULT NULL; diff --git a/www/fahrschultermin.de/database/migrations/006_tenant_federal_state.sql b/www/fahrschultermin.de/database/migrations/006_tenant_federal_state.sql deleted file mode 100644 index 7af0b1b..0000000 --- a/www/fahrschultermin.de/database/migrations/006_tenant_federal_state.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE tenants ADD COLUMN federal_state TEXT DEFAULT 'BE'; diff --git a/www/fahrschultermin.de/database/migrations/007_student_prior_completed_units.sql b/www/fahrschultermin.de/database/migrations/007_student_prior_completed_units.sql deleted file mode 100644 index 0d181c8..0000000 --- a/www/fahrschultermin.de/database/migrations/007_student_prior_completed_units.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE student_requirement_snapshots ADD COLUMN prior_completed_units INTEGER NOT NULL DEFAULT 0; diff --git a/www/fahrschultermin.de/database/migrations/008_lesson_type_system_key.sql b/www/fahrschultermin.de/database/migrations/008_lesson_type_system_key.sql deleted file mode 100644 index 623f0ff..0000000 --- a/www/fahrschultermin.de/database/migrations/008_lesson_type_system_key.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE lesson_types ADD COLUMN system_key TEXT DEFAULT NULL; -CREATE UNIQUE INDEX IF NOT EXISTS idx_lesson_types_tenant_system_key ON lesson_types (tenant_id, system_key) WHERE system_key IS NOT NULL; diff --git a/www/fahrschultermin.de/database/migrations/009_requirement_phase_labels.sql b/www/fahrschultermin.de/database/migrations/009_requirement_phase_labels.sql deleted file mode 100644 index 8d403ba..0000000 --- a/www/fahrschultermin.de/database/migrations/009_requirement_phase_labels.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE license_template_requirements ADD COLUMN phase_label TEXT NOT NULL DEFAULT ''; -ALTER TABLE student_requirement_snapshots ADD COLUMN phase_label TEXT NOT NULL DEFAULT ''; diff --git a/www/fahrschultermin.de/database/migrations/010_student_email.sql b/www/fahrschultermin.de/database/migrations/010_student_email.sql deleted file mode 100644 index 64fbf40..0000000 --- a/www/fahrschultermin.de/database/migrations/010_student_email.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE students ADD COLUMN email TEXT NOT NULL DEFAULT ''; diff --git a/www/fahrschultermin.de/database/migrations/010_students_contact_flags.sql b/www/fahrschultermin.de/database/migrations/010_students_contact_flags.sql deleted file mode 100644 index 1c1d76f..0000000 --- a/www/fahrschultermin.de/database/migrations/010_students_contact_flags.sql +++ /dev/null @@ -1,2 +0,0 @@ -ALTER TABLE students ADD COLUMN email TEXT DEFAULT ''; -ALTER TABLE students ADD COLUMN needs_glasses INTEGER NOT NULL DEFAULT 0; diff --git a/www/fahrschultermin.de/database/migrations/011_student_needs_glasses.sql b/www/fahrschultermin.de/database/migrations/011_student_needs_glasses.sql deleted file mode 100644 index 9e31849..0000000 --- a/www/fahrschultermin.de/database/migrations/011_student_needs_glasses.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE students ADD COLUMN needs_glasses INTEGER NOT NULL DEFAULT 0; diff --git a/www/fahrschultermin.de/database/migrations/012_split_combination_templates.sql b/www/fahrschultermin.de/database/migrations/012_split_combination_templates.sql deleted file mode 100644 index 9e37494..0000000 --- a/www/fahrschultermin.de/database/migrations/012_split_combination_templates.sql +++ /dev/null @@ -1,183 +0,0 @@ -DROP TABLE IF EXISTS student_requirement_snapshots_old; -CREATE TEMP TABLE student_requirement_snapshots_old AS -SELECT * -FROM student_requirement_snapshots -WHERE student_id IN ( - SELECT s.id - FROM students s - JOIN license_class_templates t ON t.id = s.template_id - WHERE t.code IN ('C+CE', 'C1+C1E') -); - -DELETE FROM license_template_requirements -WHERE template_id IN ( - SELECT id FROM license_class_templates WHERE code IN ('C+CE', 'C1+C1E') -); - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C::practice', 'Uebungsstunden', 8, 0, 'C' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C::rural', 'Ueberland', 5, 1, 'C' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C::highway', 'Autobahn', 4, 2, 'C' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C::night', 'Nachtfahrt', 3, 3, 'C' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'CE::practice', 'Uebungsstunden', 6, 100, 'CE' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'CE::rural', 'Ueberland', 3, 101, 'CE' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'CE::highway', 'Autobahn', 3, 102, 'CE' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'CE::night', 'Nachtfahrt', 2, 103, 'CE' -FROM license_class_templates -WHERE code = 'C+CE'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1::practice', 'Uebungsstunden', 6, 0, 'C1' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1::rural', 'Ueberland', 4, 1, 'C1' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1::highway', 'Autobahn', 3, 2, 'C1' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1::night', 'Nachtfahrt', 2, 3, 'C1' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1E::practice', 'Uebungsstunden', 4, 100, 'C1E' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1E::rural', 'Ueberland', 2, 101, 'C1E' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1E::highway', 'Autobahn', 2, 102, 'C1E' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -INSERT INTO license_template_requirements (template_id, requirement_key, label, required_units, sort_order, phase_label) -SELECT id, 'C1E::night', 'Nachtfahrt', 1, 103, 'C1E' -FROM license_class_templates -WHERE code = 'C1+C1E'; - -UPDATE appointment_units -SET requirement_key = 'C::' || requirement_key -WHERE requirement_key IN ('practice', 'rural', 'highway', 'night') - AND appointment_id IN ( - SELECT a.id - FROM appointments a - JOIN students s ON s.id = a.student_id - JOIN license_class_templates t ON t.id = s.template_id - WHERE t.code = 'C+CE' - ); - -UPDATE appointment_units -SET requirement_key = 'C1::' || requirement_key -WHERE requirement_key IN ('practice', 'rural', 'highway', 'night') - AND appointment_id IN ( - SELECT a.id - FROM appointments a - JOIN students s ON s.id = a.student_id - JOIN license_class_templates t ON t.id = s.template_id - WHERE t.code = 'C1+C1E' - ); - -DELETE FROM student_requirement_snapshots -WHERE student_id IN ( - SELECT s.id - FROM students s - JOIN license_class_templates t ON t.id = s.template_id - WHERE t.code IN ('C+CE', 'C1+C1E') -); - -INSERT INTO student_requirement_snapshots (student_id, requirement_key, label, required_units, sort_order, prior_completed_units, phase_label) -SELECT - s.id, - r.requirement_key, - r.label, - r.required_units, - r.sort_order, - CASE - WHEN r.requirement_key = 'C::practice' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'practice' - ), 0) - WHEN r.requirement_key = 'C::rural' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'rural' - ), 0) - WHEN r.requirement_key = 'C::highway' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'highway' - ), 0) - WHEN r.requirement_key = 'C::night' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'night' - ), 0) - WHEN r.requirement_key = 'C1::practice' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'practice' - ), 0) - WHEN r.requirement_key = 'C1::rural' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'rural' - ), 0) - WHEN r.requirement_key = 'C1::highway' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'highway' - ), 0) - WHEN r.requirement_key = 'C1::night' THEN COALESCE(( - SELECT prior_completed_units - FROM student_requirement_snapshots_old old - WHERE old.student_id = s.id AND old.requirement_key = 'night' - ), 0) - ELSE 0 - END, - r.phase_label -FROM students s -JOIN license_class_templates t ON t.id = s.template_id -JOIN license_template_requirements r ON r.template_id = t.id -WHERE t.code IN ('C+CE', 'C1+C1E'); - -DROP TABLE IF EXISTS student_requirement_snapshots_old; diff --git a/www/fahrschultermin.de/database/migrations/013_combo_generic_key_cleanup.sql b/www/fahrschultermin.de/database/migrations/013_combo_generic_key_cleanup.sql deleted file mode 100644 index 2cc654a..0000000 --- a/www/fahrschultermin.de/database/migrations/013_combo_generic_key_cleanup.sql +++ /dev/null @@ -1,42 +0,0 @@ -UPDATE appointment_units -SET requirement_key = COALESCE( - ( - SELECT r.requirement_key - FROM appointments a - JOIN students s ON s.id = a.student_id - JOIN license_class_templates t ON t.id = s.template_id - JOIN license_template_requirements r ON r.template_id = t.id - WHERE a.id = appointment_units.appointment_id - AND t.is_combination = 1 - AND COALESCE(r.phase_label, '') <> '' - AND substr(r.requirement_key, instr(r.requirement_key, '::') + 2) = appointment_units.requirement_key - ORDER BY r.sort_order - LIMIT 1 - ), - requirement_key -) -WHERE requirement_key NOT LIKE '%::%' - AND appointment_id IN ( - SELECT a.id - FROM appointments a - JOIN students s ON s.id = a.student_id - JOIN license_class_templates t ON t.id = s.template_id - WHERE t.is_combination = 1 - ); - -DELETE FROM student_requirement_snapshots -WHERE requirement_key NOT LIKE '%::%' - AND student_id IN ( - SELECT s.id - FROM students s - JOIN license_class_templates t ON t.id = s.template_id - WHERE t.is_combination = 1 - ) - AND EXISTS ( - SELECT 1 - FROM students s - JOIN license_template_requirements r ON r.template_id = s.template_id - WHERE s.id = student_requirement_snapshots.student_id - AND COALESCE(r.phase_label, '') <> '' - AND substr(r.requirement_key, instr(r.requirement_key, '::') + 2) = student_requirement_snapshots.requirement_key - ); diff --git a/www/fahrschultermin.de/database/migrations/014_legacy_student_key_aliases_to_lesson_type_keys.sql b/www/fahrschultermin.de/database/migrations/014_legacy_student_key_aliases_to_lesson_type_keys.sql deleted file mode 100644 index 94a52ef..0000000 --- a/www/fahrschultermin.de/database/migrations/014_legacy_student_key_aliases_to_lesson_type_keys.sql +++ /dev/null @@ -1,170 +0,0 @@ -UPDATE appointment_units -SET requirement_key = COALESCE(( - SELECT 'lesson_type_' || lt.id - FROM appointments a - JOIN students s ON s.id = a.student_id - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE a.id = appointment_units.appointment_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND ( - (appointment_units.requirement_key = 'intro' AND lt.name = 'Einweisung') - OR (appointment_units.requirement_key = 'practice' AND lt.name IN ('Uebungsstunde', 'Übungsstunde', 'Uebungsstunden', 'Übungsstunden')) - OR (appointment_units.requirement_key = 'rural' AND lt.name IN ('Ueberlandfahrt', 'Überlandfahrt', 'Bundes- / Landstrasse')) - OR (appointment_units.requirement_key = 'highway' AND lt.name IN ('Autobahn', 'Autobahnfahrt')) - OR (appointment_units.requirement_key = 'night' AND lt.name IN ('Nachtfahrt', 'Nachtfahrten', 'Daemmerung / Dunkelheit')) - ) - ORDER BY lt.sort_order, lt.id - LIMIT 1 -), requirement_key) -WHERE requirement_key IN ('intro', 'practice', 'rural', 'highway', 'night'); - -UPDATE student_requirement_snapshots AS target -SET prior_completed_units = prior_completed_units + COALESCE(( - SELECT SUM(src.prior_completed_units) - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'intro' -), 0) -WHERE target.requirement_key = COALESCE(( - SELECT 'lesson_type_' || lt.id - FROM students s - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE s.id = target.student_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND lt.name = 'Einweisung' - ORDER BY lt.sort_order, lt.id - LIMIT 1 -), target.requirement_key) - AND EXISTS ( - SELECT 1 - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'intro' - ); - -UPDATE student_requirement_snapshots AS target -SET prior_completed_units = prior_completed_units + COALESCE(( - SELECT SUM(src.prior_completed_units) - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'practice' -), 0) -WHERE target.requirement_key = COALESCE(( - SELECT 'lesson_type_' || lt.id - FROM students s - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE s.id = target.student_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND lt.name IN ('Uebungsstunde', 'Übungsstunde', 'Uebungsstunden', 'Übungsstunden') - ORDER BY lt.sort_order, lt.id - LIMIT 1 -), target.requirement_key) - AND EXISTS ( - SELECT 1 - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'practice' - ); - -UPDATE student_requirement_snapshots AS target -SET prior_completed_units = prior_completed_units + COALESCE(( - SELECT SUM(src.prior_completed_units) - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'rural' -), 0) -WHERE target.requirement_key = COALESCE(( - SELECT 'lesson_type_' || lt.id - FROM students s - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE s.id = target.student_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND lt.name IN ('Ueberlandfahrt', 'Überlandfahrt', 'Bundes- / Landstrasse') - ORDER BY lt.sort_order, lt.id - LIMIT 1 -), target.requirement_key) - AND EXISTS ( - SELECT 1 - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'rural' - ); - -UPDATE student_requirement_snapshots AS target -SET prior_completed_units = prior_completed_units + COALESCE(( - SELECT SUM(src.prior_completed_units) - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'highway' -), 0) -WHERE target.requirement_key = COALESCE(( - SELECT 'lesson_type_' || lt.id - FROM students s - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE s.id = target.student_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND lt.name IN ('Autobahn', 'Autobahnfahrt') - ORDER BY lt.sort_order, lt.id - LIMIT 1 -), target.requirement_key) - AND EXISTS ( - SELECT 1 - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'highway' - ); - -UPDATE student_requirement_snapshots AS target -SET prior_completed_units = prior_completed_units + COALESCE(( - SELECT SUM(src.prior_completed_units) - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'night' -), 0) -WHERE target.requirement_key = COALESCE(( - SELECT 'lesson_type_' || lt.id - FROM students s - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE s.id = target.student_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND lt.name IN ('Nachtfahrt', 'Nachtfahrten', 'Daemmerung / Dunkelheit') - ORDER BY lt.sort_order, lt.id - LIMIT 1 -), target.requirement_key) - AND EXISTS ( - SELECT 1 - FROM student_requirement_snapshots src - WHERE src.student_id = target.student_id - AND src.requirement_key = 'night' - ); - -DELETE FROM student_requirement_snapshots -WHERE requirement_key IN ('intro', 'practice', 'rural', 'highway', 'night') - AND EXISTS ( - SELECT 1 - FROM students s - JOIN lesson_type_template_visibility vis ON vis.template_id = s.template_id - JOIN lesson_types lt ON lt.id = vis.lesson_type_id - WHERE s.id = student_requirement_snapshots.student_id - AND lt.category = 'student' - AND lt.is_counted = 1 - AND ( - (student_requirement_snapshots.requirement_key = 'intro' AND lt.name = 'Einweisung') - OR (student_requirement_snapshots.requirement_key = 'practice' AND lt.name IN ('Uebungsstunde', 'Übungsstunde', 'Uebungsstunden', 'Übungsstunden')) - OR (student_requirement_snapshots.requirement_key = 'rural' AND lt.name IN ('Ueberlandfahrt', 'Überlandfahrt', 'Bundes- / Landstrasse')) - OR (student_requirement_snapshots.requirement_key = 'highway' AND lt.name IN ('Autobahn', 'Autobahnfahrt')) - OR (student_requirement_snapshots.requirement_key = 'night' AND lt.name IN ('Nachtfahrt', 'Nachtfahrten', 'Daemmerung / Dunkelheit')) - ) - ); diff --git a/www/fahrschultermin.de/database/migrations/015_instructor_pre_start_buffer.sql b/www/fahrschultermin.de/database/migrations/015_instructor_pre_start_buffer.sql deleted file mode 100644 index 60c1107..0000000 --- a/www/fahrschultermin.de/database/migrations/015_instructor_pre_start_buffer.sql +++ /dev/null @@ -1 +0,0 @@ -ALTER TABLE instructors ADD COLUMN pre_start_buffer_minutes INTEGER NOT NULL DEFAULT 0; diff --git a/www/fahrschultermin.de/database/migrations/015_lesson_type_allows_student_and_notes_private.sql b/www/fahrschultermin.de/database/migrations/015_lesson_type_allows_student_and_notes_private.sql deleted file mode 100644 index 6954809..0000000 --- a/www/fahrschultermin.de/database/migrations/015_lesson_type_allows_student_and_notes_private.sql +++ /dev/null @@ -1,22 +0,0 @@ --- Migration: 015_lesson_type_allows_student_and_notes_private.sql --- Adds allows_student column to lesson_types and notes_private to appointments - --- 1. lesson_types.allows_student: which lesson types can be assigned a student -ALTER TABLE lesson_types ADD COLUMN IF NOT EXISTS allows_student integer NOT NULL DEFAULT 0; -COMMENT ON COLUMN lesson_types.allows_student IS '1 = lesson type can have a student_id (e.g. driving lessons), 0 = no student (theory, work, private)'; - --- 2. appointments.notes_private: private note only visible to the instructor (not chef/office) -ALTER TABLE appointments ADD COLUMN IF NOT EXISTS notes_private text DEFAULT ''; - --- Default: only 'student' category allows student_id, all other categories = 0 -UPDATE lesson_types SET allows_student = 1 WHERE category = 'student'; -UPDATE lesson_types SET allows_student = 0 WHERE category != 'student'; - --- For existing appointments, clear student_id if the lesson_type doesn't allow it --- (data cleanup - not normally needed but defensive) -UPDATE appointments -SET student_id = NULL -WHERE student_id IS NOT NULL - AND lesson_type_id IN ( - SELECT id FROM lesson_types WHERE allows_student = 0 - ); \ No newline at end of file diff --git a/www/fahrschultermin.de/database/migrations/016_consolidate_lesson_types.sql b/www/fahrschultermin.de/database/migrations/016_consolidate_lesson_types.sql deleted file mode 100644 index 5d4334f..0000000 --- a/www/fahrschultermin.de/database/migrations/016_consolidate_lesson_types.sql +++ /dev/null @@ -1,39 +0,0 @@ --- Migration: 016_consolidate_lesson_types.sql --- Reihen: tenant 1 und tenant 2 bereinigen, konsistente Einstellungen - --- ══════════════════════════════════════════════════════ --- TENANT 1 --- ══════════════════════════════════════════════════════ - --- Tenant 1: Doppelte Einweisung (id=1, id=14 → id=14 renamed to avoid conflict via rename approach) --- Already unique (no action needed) - --- Tenant 1: Doppelte Übungsstunde (id=2, id=15 → id=15 is in tenant 1 but was already unique) --- Actually tenant 1 has only id=2 (Uebungsstunde) - no duplicate - --- Tenant 1 work type fixes: --- Sonstige Arbeiten (id=8): is_rest_relevant=1 (zählt für Ruhezeit) -UPDATE lesson_types SET is_rest_relevant = 1, fixed_duration = 0 WHERE id = 8 AND tenant_id = 1; - --- Theorieunterricht (id=7): is_rest_relevant=1, is_billable=1, fixed_duration=0 -UPDATE lesson_types SET is_rest_relevant = 1, fixed_duration = 0, is_billable = 1 WHERE id = 7 AND tenant_id = 1; - --- ══════════════════════════════════════════════════════ --- TENANT 2 --- ══════════════════════════════════════════════════════ - --- Tenant 2: Doppelte Namen konsolidieren --- Autobahnfahrt → Autobahn (id=13 → name='Autobahn') -UPDATE lesson_types SET name = 'Autobahn' WHERE id = 13 AND tenant_id = 2; --- Übungsstunde (id=15 already named correctly) - --- Verify tenant 2 student types --- Note: id=11 Nachtfahrten stays (different from tenant 1 which has no Nachtfahrten) --- id=16 Praktische Prüfung stays --- id=12 Überlandfahrt stays - --- ══════════════════════════════════════════════════════ --- ALL TENANTS: allows_student defaults --- ══════════════════════════════════════════════════════ --- already done in migration 015 --- student=1, all others=0 \ No newline at end of file diff --git a/www/fahrschultermin.de/database/migrations/017_student_booking_schema.sql b/www/fahrschultermin.de/database/migrations/017_student_booking_schema.sql deleted file mode 100644 index b3053bf..0000000 --- a/www/fahrschultermin.de/database/migrations/017_student_booking_schema.sql +++ /dev/null @@ -1,202 +0,0 @@ --- Migration: 017_student_booking_schema.sql --- Fahrschüler-Buchungssystem + Multi-Tenant Instructor + Break-Rules - -BEGIN; - --- ══════════════════════════════════════════════════════ --- 1. users.role ist bereits text (kein ENUM), keine Änderung nötig --- ══════════════════════════════════════════════════════ - --- ══════════════════════════════════════════════════════ --- 2. instructors erweitern: UE-Limits + Booking-Settings --- ══════════════════════════════════════════════════════ -ALTER TABLE instructors ADD COLUMN IF NOT EXISTS max_daily_units integer DEFAULT NULL; -ALTER TABLE instructors ADD COLUMN IF NOT EXISTS max_daily_override integer DEFAULT 0; -ALTER TABLE instructors ADD COLUMN IF NOT EXISTS max_weekly_units integer DEFAULT NULL; -ALTER TABLE instructors ADD COLUMN IF NOT EXISTS max_weekly_override integer DEFAULT 0; -ALTER TABLE instructors ADD COLUMN IF NOT EXISTS booking_enabled integer DEFAULT 1; - --- ══════════════════════════════════════════════════════ --- 3. students erweitern: user_id FK --- ══════════════════════════════════════════════════════ -ALTER TABLE students ADD COLUMN IF NOT EXISTS user_id bigint REFERENCES users(id) NULL; - --- ══════════════════════════════════════════════════════ --- 4. tenants erweitern: free_cancellation_hours --- ══════════════════════════════════════════════════════ -ALTER TABLE tenants ADD COLUMN IF NOT EXISTS free_cancellation_hours integer DEFAULT 24; - --- ══════════════════════════════════════════════════════ --- 5. tenant_registration_codes --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS tenant_registration_codes ( - id bigserial PRIMARY KEY, - tenant_id bigint NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - code text NOT NULL UNIQUE, - is_active integer DEFAULT 1, - used_count integer DEFAULT 0, - created_at timestamptz DEFAULT NOW() -); -CREATE INDEX IF NOT EXISTS idx_tenant_reg_codes_code ON tenant_registration_codes(code); -CREATE INDEX IF NOT EXISTS idx_tenant_reg_codes_tenant ON tenant_registration_codes(tenant_id); - --- ══════════════════════════════════════════════════════ --- 6. student_tenants --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS student_tenants ( - id bigserial PRIMARY KEY, - student_user_id bigint NOT NULL REFERENCES users(id) ON DELETE CASCADE, - tenant_id bigint NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'active', 'suspended')), - registered_at timestamptz DEFAULT NOW(), - confirmed_at timestamptz NULL, - confirmed_by bigint NULL REFERENCES users(id), - UNIQUE(student_user_id, tenant_id) -); -CREATE INDEX IF NOT EXISTS idx_student_tenants_user ON student_tenants(student_user_id); -CREATE INDEX IF NOT EXISTS idx_student_tenants_tenant ON student_tenants(tenant_id); - --- ══════════════════════════════════════════════════════ --- 7. instructor_availability --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS instructor_availability ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - weekday integer NOT NULL CHECK (weekday BETWEEN 0 AND 6), - time_from text NOT NULL, - time_to text NOT NULL, - is_active integer DEFAULT 1, - UNIQUE(instructor_id, weekday, time_from) -); -CREATE INDEX IF NOT EXISTS idx_instructor_avail_instructor ON instructor_availability(instructor_id); - --- ══════════════════════════════════════════════════════ --- 8. appointment_requests --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS appointment_requests ( - id bigserial PRIMARY KEY, - student_user_id bigint NOT NULL REFERENCES users(id) ON DELETE CASCADE, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - lesson_type_id bigint NOT NULL REFERENCES lesson_types(id), - requested_start timestamptz NOT NULL, - requested_end timestamptz NOT NULL, - status text NOT NULL DEFAULT 'pending' CHECK (status IN ('pending', 'confirmed', 'rejected', 'cancelled')), - requested_at timestamptz DEFAULT NOW(), - responded_at timestamptz NULL, - response_by bigint NULL REFERENCES users(id), - notes text DEFAULT '', - confirmed_appointment_id bigint NULL REFERENCES appointments(id) -); -CREATE INDEX IF NOT EXISTS idx_appt_req_student ON appointment_requests(student_user_id); -CREATE INDEX IF NOT EXISTS idx_appt_req_instructor ON appointment_requests(instructor_id); -CREATE INDEX IF NOT EXISTS idx_appt_req_status ON appointment_requests(status); - --- ══════════════════════════════════════════════════════ --- 9. instructor_vacations --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS instructor_vacations ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - date_from date NOT NULL, - date_to date NOT NULL, - notes text DEFAULT '', - created_at timestamptz DEFAULT NOW(), - UNIQUE(instructor_id, date_from, date_to) -); -CREATE INDEX IF NOT EXISTS idx_instructor_vacations_instructor ON instructor_vacations(instructor_id); -CREATE INDEX IF NOT EXISTS idx_instructor_vacations_dates ON instructor_vacations(date_from, date_to); - --- ══════════════════════════════════════════════════════ --- 10. private_appointments --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS private_appointments ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - title text NOT NULL DEFAULT 'Privat', - date date NOT NULL, - time_from text NOT NULL, - time_to text NOT NULL, - color text DEFAULT '#9ca3af', - created_at timestamptz DEFAULT NOW() -); -CREATE INDEX IF NOT EXISTS idx_private_appts_instructor ON private_appointments(instructor_id); -CREATE INDEX IF NOT EXISTS idx_private_appts_date ON private_appointments(date); - --- ══════════════════════════════════════════════════════ --- 11. instructor_tenants --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS instructor_tenants ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - tenant_id bigint NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - is_primary integer DEFAULT 0, - created_at timestamptz DEFAULT NOW(), - UNIQUE(instructor_id, tenant_id) -); -CREATE INDEX IF NOT EXISTS idx_instructor_tenants_instructor ON instructor_tenants(instructor_id); -CREATE INDEX IF NOT EXISTS idx_instructor_tenants_tenant ON instructor_tenants(tenant_id); - --- ══════════════════════════════════════════════════════ --- 12. instructor_travel_times --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS instructor_travel_times ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - from_tenant_id bigint NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - to_tenant_id bigint NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - minutes integer NOT NULL, - UNIQUE(instructor_id, from_tenant_id, to_tenant_id) -); -CREATE INDEX IF NOT EXISTS idx_travel_times_instructor ON instructor_travel_times(instructor_id); - --- ══════════════════════════════════════════════════════ --- 13. instructor_home_to_tenant --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS instructor_home_to_tenant ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - tenant_id bigint NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - minutes integer NOT NULL, - UNIQUE(instructor_id, tenant_id) -); -CREATE INDEX IF NOT EXISTS idx_home_to_tenant_instructor ON instructor_home_to_tenant(instructor_id); - --- ══════════════════════════════════════════════════════ --- 14. instructor_break_rules --- ══════════════════════════════════════════════════════ -CREATE TABLE IF NOT EXISTS instructor_break_rules ( - id bigserial PRIMARY KEY, - instructor_id bigint NOT NULL REFERENCES instructors(id) ON DELETE CASCADE, - condition_type text NOT NULL CHECK (condition_type IN ('daily_units', 'weekly_units', 'hours_daily', 'between_appointments', 'continuous_minutes')), - operator text NOT NULL CHECK (operator IN ('greater_than', 'equals', 'at_least')), - threshold numeric NOT NULL, - break_minutes integer NOT NULL, - is_active integer DEFAULT 1, - created_at timestamptz DEFAULT NOW(), - UNIQUE(instructor_id, condition_type, operator, threshold) -); -CREATE INDEX IF NOT EXISTS idx_break_rules_instructor ON instructor_break_rules(instructor_id); - --- ══════════════════════════════════════════════════════ --- 15. Default Registration-Codes für bestehende Tenants --- ══════════════════════════════════════════════════════ -INSERT INTO tenant_registration_codes (tenant_id, code, is_active) -SELECT id, LPAD(id::text, 8, '0') || '-' || UPPER(SUBSTRING(MD5(id::text || 'salt') FROM 1 FOR 4)), 1 -FROM tenants -WHERE id NOT IN (SELECT tenant_id FROM tenant_registration_codes) -ON CONFLICT (code) DO NOTHING; - --- ══════════════════════════════════════════════════════ --- 16. Default Availability für alle Instructors (Mo-So 08:00-19:00) --- ══════════════════════════════════════════════════════ -INSERT INTO instructor_availability (instructor_id, weekday, time_from, time_to, is_active) -SELECT i.id, w.day, '08:00', '19:00', 1 -FROM instructors i -CROSS JOIN (VALUES (0),(1),(2),(3),(4),(5),(6)) AS w(day) -WHERE i.is_active = 1 -AND NOT EXISTS ( - SELECT 1 FROM instructor_availability ia - WHERE ia.instructor_id = i.id AND ia.weekday = w.day -); - -COMMIT; \ No newline at end of file diff --git a/www/fahrschultermin.de/database/schema_pgsql.sql b/www/fahrschultermin.de/database/schema_pgsql.sql deleted file mode 100644 index 34204d1..0000000 --- a/www/fahrschultermin.de/database/schema_pgsql.sql +++ /dev/null @@ -1,166 +0,0 @@ --- PostgreSQL Schema for fahrschultermin.de --- Run this BEFORE importing data - -BEGIN; - --- ── Tenants ─────────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS tenants ( - id BIGSERIAL PRIMARY KEY, - name TEXT NOT NULL, - timezone TEXT NOT NULL DEFAULT 'Europe/Berlin', - is_active INTEGER NOT NULL DEFAULT 1, - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL, - location_label TEXT DEFAULT '', - latitude DOUBLE PRECISION DEFAULT NULL, - longitude DOUBLE PRECISION DEFAULT NULL, - federal_state TEXT DEFAULT 'BE' -); - --- ── Users ───────────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS users ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT REFERENCES tenants(id) ON DELETE CASCADE, - role TEXT NOT NULL, - email TEXT NOT NULL UNIQUE, - password_hash TEXT NOT NULL, - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - is_active INTEGER NOT NULL DEFAULT 1, - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL -); - --- ── Instructors ──────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS instructors ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - color TEXT NOT NULL, - notes TEXT DEFAULT '', - is_active INTEGER NOT NULL DEFAULT 1, - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL, - user_id BIGINT REFERENCES users(id) ON DELETE SET NULL, - pre_start_buffer_minutes INTEGER NOT NULL DEFAULT 0 -); - --- ── License Class Templates ─────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS license_class_templates ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - code TEXT NOT NULL, - name TEXT NOT NULL, - is_combination INTEGER NOT NULL DEFAULT 0, - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL, - UNIQUE (tenant_id, code) -); - --- ── License Template Requirements ───────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS license_template_requirements ( - id BIGSERIAL PRIMARY KEY, - template_id BIGINT NOT NULL REFERENCES license_class_templates(id) ON DELETE CASCADE, - requirement_key TEXT NOT NULL, - label TEXT NOT NULL, - required_units INTEGER NOT NULL, - sort_order INTEGER NOT NULL DEFAULT 0, - phase_label TEXT NOT NULL DEFAULT '' -); - --- ── Lesson Types ────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS lesson_types ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - name TEXT NOT NULL, - color TEXT NOT NULL, - default_duration INTEGER NOT NULL, - category TEXT NOT NULL, - requirement_key TEXT DEFAULT NULL, - is_billable INTEGER NOT NULL DEFAULT 0, - is_counted INTEGER NOT NULL DEFAULT 0, - is_rest_relevant INTEGER NOT NULL DEFAULT 0, - fixed_duration INTEGER NOT NULL DEFAULT 0, - sort_order INTEGER NOT NULL DEFAULT 0, - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL, - system_key TEXT DEFAULT NULL -); - --- ── Lesson Type ↔ Template Visibility ────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS lesson_type_template_visibility ( - lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id) ON DELETE CASCADE, - template_id BIGINT NOT NULL REFERENCES license_class_templates(id) ON DELETE CASCADE, - PRIMARY KEY (lesson_type_id, template_id) -); - --- ── Students ────────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS students ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - template_id BIGINT NOT NULL REFERENCES license_class_templates(id), - first_name TEXT NOT NULL, - last_name TEXT NOT NULL, - phone TEXT DEFAULT '', - notes TEXT DEFAULT '', - status TEXT NOT NULL DEFAULT 'active', - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL, - email TEXT NOT NULL DEFAULT '', - needs_glasses INTEGER NOT NULL DEFAULT 0 -); - --- ── Student Requirement Snapshots ────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS student_requirement_snapshots ( - id BIGSERIAL PRIMARY KEY, - student_id BIGINT NOT NULL REFERENCES students(id) ON DELETE CASCADE, - requirement_key TEXT NOT NULL, - label TEXT NOT NULL, - required_units INTEGER NOT NULL, - sort_order INTEGER NOT NULL DEFAULT 0, - prior_completed_units INTEGER NOT NULL DEFAULT 0, - phase_label TEXT NOT NULL DEFAULT '' -); - --- ── Appointments ────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS appointments ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - student_id BIGINT REFERENCES students(id) ON DELETE SET NULL, - instructor_id BIGINT NOT NULL REFERENCES instructors(id), - lesson_type_id BIGINT NOT NULL REFERENCES lesson_types(id), - title TEXT NOT NULL, - category TEXT NOT NULL, - start_at TIMESTAMPTZ NOT NULL, - end_at TIMESTAMPTZ NOT NULL, - units INTEGER NOT NULL DEFAULT 1, - status TEXT NOT NULL DEFAULT 'planned', - notes TEXT DEFAULT '', - warning_acknowledged INTEGER NOT NULL DEFAULT 0, - created_by BIGINT NOT NULL REFERENCES users(id), - updated_by BIGINT NOT NULL REFERENCES users(id), - created_at TIMESTAMPTZ NOT NULL, - updated_at TIMESTAMPTZ NOT NULL -); - --- ── Appointment Units ───────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS appointment_units ( - id BIGSERIAL PRIMARY KEY, - appointment_id BIGINT NOT NULL REFERENCES appointments(id) ON DELETE CASCADE, - requirement_key TEXT DEFAULT NULL, - label TEXT DEFAULT NULL, - units_counted INTEGER NOT NULL DEFAULT 0, - created_at TIMESTAMPTZ NOT NULL -); - --- ── Settings ─────────────────────────────────────────────────────────────────── -CREATE TABLE IF NOT EXISTS settings ( - id BIGSERIAL PRIMARY KEY, - tenant_id BIGINT NOT NULL REFERENCES tenants(id) ON DELETE CASCADE, - key_name TEXT NOT NULL, - value TEXT NOT NULL, - UNIQUE (tenant_id, key_name) -); - -COMMIT; \ No newline at end of file diff --git a/www/fahrschultermin.de/storage/database/app.sqlite b/www/fahrschultermin.de/storage/database/app.sqlite deleted file mode 100644 index aff7010de53509f2ca087989483c95f35217dfc2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 126976 zcmeHw33wdGb!H#aGt+Z5L4q7WAjpA05`=iofm@^gSVj*r-iH(5Jz;$3H7 zRrOWXJu@Ip%TiKfnT46EdhgZ$UcEZ{RrT4^$4WIlHMd+@D%MgtVVxj~!huvu5C%^P zg0L0-Z+$x9kAU?BQqlEygFk`B-s_hYR9O2SDx;C4L2>>wM}Q;15#R`L1ULd50geDi zfFr;W;0SO8I08Qe1QOvmP?fZCLHkAchkrN%90861M}Q;15#R`L1ULd50geDifFr;W z@Izo$iV9tQYHqwM6lz;4&d%$VrNU}uc}3qhsaFSgqER%!(cBLUBeQ>!_t?A_hM?U*cfAqOcPaWv`AD36((DRlP=N}S7Lat98A3s!F zs8nYbRu}cuiRH>{rBt48z-S^x zqF-JuRrDqFcePwxsV*$ns^Xn(io9J~)T`Cy@^tOmieB9t(XI>V894d0MIgVpva(z% z*HGQ6@a{W9Kz6Y-qnE4tbWLAcSuECcH~p&c_DxZFpS#-hYPkgLE_DUvyG5(+%wn-x zwJB7?+HVQH7T*SGRFu0!*byj#B$5yd%iW^cz-m(awy>VArUm3)u~e?sDyuU!*h-L9 zSx$=;y`TFj~%*B%s<*r$ZVhZC{*jP`Q)lYck@90861M}Q;1 z5#R`L1ULd50gk|n8v!F3j0xiQU53&Xhv%^pSvE}(JKea z=F{B0HN9Fh<-7mziA&2DD%E|5i`mQb*VC2kTK9U|fqThFJ z;?ms8<;PZ!6h|%}FII{Nf&8*p$W{-mjcpPLxjhF$c7c#?HDg`-3VGzn#p1E0`Qw$* zBlo3O9(=sEdidN4{p@hAcJ1i!m3=F7XVTTbM}Q;15#R`L1ULd5 z0geDifFr;W;0U}#5!fK_5}6&U;AVNh*l2qw&?yg#zFRVKQqGA!yC4#(;k)Iapx6gl zTPJ8A(q0Y;|8N920vrL307rl$z!BgGa0EC490861N8sND0>>Z(LQKXXhGcwP5GDLr zy*I57&W@y=$LdoM;E@|1%dkNJ15@cyILAMhGas(sa}urxP&<=^+A)2(T+)wLigUHz ziQ$2f?2wxxIj-L-MB}802yVm#MJLvyH(eM!NK3djdI7Zl-ywWR(B7>LC!S3##Q!<| zw)jx&xmYC@j{ZvYP~>kSuaESpA6Fj;e>rS~wa~jmqruMxmx3YX7nI?^9|azf|5<)Y zPD&q^j*5RHzDDc>Vn4jk{EePJhZ&5gKB^yaeznY4}AM{k)+ap^`EaLILv8*Mu~y9`HbO7nVZs;EPHNiWrUhx56K z!ohp4E>|wezjpK7P`&A8u(`_ejXQwfb{D_gd3|P~sxP8lz*=u^a(H5Jcn@au-dki; zs}#%CIlVFs_l8{2AHC5D9Fs1Ny_2gTNbktx;6!$kwCQcP$ZC0R4o*xh-{=4q{Vo>! zP+;11eRY0iZV@7%Ot(dNz2O#lUC|dxGmHB4OtGTR-ADq*&MvVF)D}kWq3;wlwpi;O znjFrKr0-e5-*ox4H_yzhI(>0*dFIjrn1@KYA<6O%&HPYqDm^@w9U2?VFn);5aQx6L z7=}o>A)8ZUKg5!=Tgzscd}^~`3=Oz6_CqYOR$OLh!5$iLY3zq?mdng6*gyj=js4Kg za=AFWsUerfe&}Yo6w4cd3+0BSwfmtpb94OAN;~kQ+>o>eKXh}9Xg^fk030bdBsKFx zH^++jp_TQ(f^tLBn*7ks@pAj2`8ME4xgn{QA6hdr$`8%014dvUU4p8rVG-u6z^Hhs zR)Sli^wg=!Gas9Sz}?K4%^t4Z1t(;8@ zhdl!U)4)hBtA`@rhz7QgN!%DTwTPcHanpxz-_fzbbc+@&L^MIY8_|bxQw2jh3!%y|RF`V0eW^(_FmT!vn*4Jo58svy&skqqz&nw}x(>!*mc( zA{G@^kv>jUR&~^utHhutMsn~uhQ}_uK-PR_7p&%wqPy<&R6dj11^*P> zGOlgidsqR28+rg!H?>@IK-rhm#(KGWGA zf+JPX!xc~c&JB>&1$|rb)Jv{MwV+okbdL^fZG((%=+BCOUk-JyGx-I){4|qaz{@XT z@(Zy1;wHauvUr14~F<*L&BtX=&)gBRO29gc~Lcg&I%JhN8%#p>PS6~*(c81ON zNlg1>xie(8Ph#4qNXektK8a?pY*ozmN&Y+|9f1&>%mw{<*mcN|gVe`x3rL$JR0p)j zFxw)+??`$6yu$J5JB9V(?+3M4XyMqOCFT+xkznNiMvuo{8_PyM5P2xRBmN2X!|KD~ z???X^12g~15#R`L1ULd50geDi;3bH_!<*uQC~n*nk9Urb$HP)spD!-XSM>SiN(xTU zFD^qAD?Yq=MJJ(^a5R2+Dw7>cXU5W5cL1+X#?(eke5*w~gos~)_jA>*18sC9)I$}5 zbQ@94nkTr=wqvT@7FAQ^XFghnS35T#nxihNvPFf9s?3bjp(x;>^I|qn}K+$aVNtGseys~^1lyj-%D`MJv z-Njdq3{FusuM|MFj}W=Fnf-! z&cNYrw_JmJGMTB&Fx-#D=)ouBR2XFj^P$XFjyAl9tkHEBq#_T3LBqqH8* zmzEd7R4%Q!MYIWK#&YJJ5e#%g_B9qKWjDdlo)btwFch63h!4vTj4*8`oFEo|*v>f7 zh6$23OJOkPnM+H>a+#q=>|wxem|H-g=VS;%;=c&Te_+*G1Ws?jKEY8j@-!EhufjX) z-4ePwewMm`$S31i5Vx3+gzkG5-YDV2>OSAix=z8K(l6T94&lP83&G^zxj( zIO~=VfVU{7*&8>ku9mU9fgqf+ntwae%jl*)G1=LBH;e><`UlU)uUFEU;cRMj zbQG@Fn5-06;bw=_99+c!x2urrD)hbHCamp@gCU{I{KSo&+g}De<>RHr;(c&KmtF>z z=@eZ3HZV9ee707s)bv`aTtwG_)%4W)WpuO465Pw--oLzMArt^l(!PTr+^l_%{Bb+* zo(bX-B}|A6)lB+yn^|No=* z_v8!ufqysx90861M}Q;15#R`L1ULd50geDifFr;Wcqt;#WuW{1?wEsrl1Jd5O?Sn^ zuMxt5r-bOkiFd|6l6WleRQN+dBb*L=PWoeUB=P2#Vk^1K9088NOA3J}t}3BqZ?E{& zV6Av@Q7^%(7AvbW5OY>_{Ta-kDNIZiQd1L?#|kM|Mrvmy1)tJv>d1+y!r{W1)TuK^ zj!&F4o#dpHkIn@BkW4mX%a+c%WpAESw%CX zdLHtZfX_cnBC2_$l@laRx0{*6$P42UtFC-Z-|7~Fs&kKEjT^m zq=`6(PM#?oIeY@cywe7?KXs;XsBormB40S0BEMEsJ4>_usgoz5LB|T9!~DeA{KUaR zr2mQCp-}SfyTvD$vF0K06QUO3ZI0*$;pv*bw6X|Isy6sJOj$&OLbu&IW|n7t?V^#r zfO=<^moApd#ad~(+!EAV)G;>fb0?0RK37ONy4amU()QmrbsY}}lf}D5p#<+%dc1mh z5niS>U4)mZ;qTK8G%%fMkfFi^BYiWD>dF3KD7k&R_!Aq6wdmFAa(TLTZ3Rrk^>>K2 z3s=r3Yv={C zIE~T@G=IGv-ItoXTQf@cWY`+$NN4>4`r^uh?Q^Zs*qY)unf)WrwrZ{nEKwX+O%?{G zkG|FM&d)))ButfceYQG1kKfwy0?hh-XQO1M4|<`N4-F=ccsT)!hs9_pdHAsSy7O+E zf|-dkKdP3CE7gT%+tBU-YI;(zNi#7Uve%p3Yg8K(KNKOnZbO8D`zt>D6+n z=2aajw6+-)ECWl+6|_`YS=7-Y)1Rbmn(5uC6&TQT*Jy4FXBV>UpBg|ML?~TbuAuQ+ z@u*7FZO;D9wW8gpT|n9^M&HZ`rEbf{e2d<+x@{^AcNbh@I#bXeg}!f1d#(mj>a$>E zmhKI;X$-9oB~Nb`>oQ(EmS!KHcCX=J@sBrYoVmI?ccZC6bHRJ$#KFRYumRMH1loac zlc8414yXRq`TJl4!@W*8a@IEPC+=7mN*+BbKDi5f9Tz=&!(#eMsak@?SE+WbMfL{T z6rH82A1%`u-6R`YnM+Ncbrf+6?oG0tG|k>7wSz9o9`DmkQrdw>AqoXU>sBnb$Q$TyYJAr30uZ@!tN3Yf35TQ)`X_{VD7kN+_~bqe zC>#uiy`&o6+Q8$F=ZAF^#GdS%#@bDxVQ2Dn+13oo**A6#)80(n92j2Lw#(9dsz>!j zx&>5UbY(T_i;@1PuEp@C+E0_scXu84-|)1A2DcCq-wje8dkSZy?BkPYHo4?7CtO3tQ*#e z^rQHHQTrFP)Zapq+q>%L)Hnhh0geDifFr;W;0SO8I0762jsQo1Bft^(5hKuT>_pH1 zMeT0|_>X@$0vrL307rl$z!BgGa0EC490861M}Q;15qQZX&@L*1y0sG`diK^9;Otnn zG+!<*qWb_u?H>gAkAFA<90861M}Q;15#R`L1ULd50geDifFr;W_&0+?Og!$ z{6C%en1J5>r+rKNy7ndQ^V*+lf1-U#`+e=VwU21OuKlw19_{Vg4edW@Pin8$u4*e< zNxP^$qMg%DXos}}+NhS(c5BUBh_+H}MiRTkvNqiyk7m3d#o=rRh4ETp5 zz!BgGa0EC490861M}Q;15#R`L1ULe>h=7unMR8qN$)F^pq#@D5%05UEVP!8Q@vyQ7 zl2};T4M{Yt?1DrKDR)7V2q}G##6!vsNMa#nJ0#JNvJH};r1YXhQSL-ZQ0YNQKuMuQ z4s4Z0HK=TXFN&meqeM|Qqa>(wp(LQ(ff6~;2?Z6U1HJ?#C5aM6*@TjyvJoW#r5z=5 zU;`8kDC^;iEGca$QIvHk2`U;&0!jiUav%-`WhDk*BuR;)L{TCr2`VZ|0!kPqav%f+ zr9e^&~+IzL@+B;zNU)O#@t7=EJOWKTfR(n`GsBPBn(FU|_u=d}WcwUQZO5!_-|Cjii z#P1|NpZL#-KTCWt@#(}bCO(mPXX4GkfPXjw90861M}Q;15#R`L1ULd50geDifFocb z5DJKBL7ydQD1%cioW^M)ybq`G@Lrt8!h3KU4e!RO7TSf=MCdM@#zTELjfHmLG#c8D z)1b7Cq)IPIgLjfN&_hx=6%2^5R^E!gD$*8`D%~UvZYF7o$t=g|>&spl?DMx@Kz!BgGa0EC490861M}Q;15#R`L1eznTE}-^E za0(sXZ#sSP(wy3p2&moG4>dLA{yM8}b$^{vx46GvRJ+|@i|S@f8{W2fX?htrRMf7{ zfSQx=54B3MTt)9Uo~@Lw=;|G90kxOpEYHos%cRuKWI)|Vez~GAlx7y;Ma0F5u6Aq) zsC^Q=AL|Od5n}oxyvOpAnp_tUdqhiUXhl~dAa>h7)b60Z&UR8?XF8~_7n9W2;wD1d zX~o9QfS42gTG8GX5PQuW(uxhqfVj{6#odba8vF}TosRxy#E_!l-w-~l9u=3BUs2TH7vxFlm!)4;;>xcnZGo#$?Zx^rIy=`3u#qJ8 zca4vWUGcCej*m;K9DC;HFTx8?i{;t5;zFfnzW*Vc&JOKK5A4Z~PNhf3(rNf_7yj3k zkx7r`oD9i)0Y@-s7s*YfhsUy`V*?{h-2s#_Fg%tUCK*O&myc|6YuPf{vCN>aY`L)k zC!>*UIjElVl`S)twPj2C$QExU+sIUU$QL)r7;y_NH^OabY%t>|TXtY9ZDtr9{Y17t zw@%yS_yoLr`eJdR?5EOPdMcB1YtGUa%0QUec>2ROG6pTnvgQCPg^Ud3nJVqr=_6V~ z*1+6W(W{|qtMIOD#@dhslu@}wqht>Fq6QKSjt!3bp_a?pstz6$cfVMB>5EM+V{+20k)rk@ z7RyL>I0{v*!Ch|dZIQJPxQ8NJDUd-81isD|5AD`SWLG6adv+{4Kze~-bll;HX3smK z&20@$JBECFC}e<_Z#722)FK1_c?SX*dZDf%#ZHq7`n|KSrf3M0EYfV-LnlQnR7*+EmI!i(3h zCEE#V+uie_gd9CloLQ*h$&e1?7Jjw1t9@CRwm25$&VWgSgJwg0IukNiT?85swPumY z4L*{^TS*26a@rWCCmA$6K0mq_yu0g=xFmXwqWaiKuxk;(m@At0oqVH7%P1T z(G09O%t@S)T<3#Zv^j1t`G8r1qc~f#+!WyETC+5i45t4+>jFIW7_=t1+cY9s57?U8 zwFe$7!+I(rCkmzVRlQV2lU&BqKrVmJ0U5(?#7uu%s8nlu>JTi;$ZVONA!T8%Y`QX6 z6Tv^`kXt9c)#yl2x+P+&Ep!V4`Rf)pVGX(k1q`r`1TP0&8AeBx5{;}#L#;&vyYcC+ zSZ0@U{bwP=$S`syIBwLSyFzC(mo@R=y~0N6t%Cen<$a0@y8!#*Z;X96_DJ;iqkWN| zRKFSiwQx)x4lIW*2S1~pmfo6pR{SUNWl-t&Uc{3GF4{{S0i*jq(qnSi=a{RpxV-LE zrFf}Us?IFvsZ*6_J~qcXpTRxpp{WdbHMZZ7j4bpB=u^aFcqe;gP6u;z%Gp3w$bebe zfW1*+bdD4Gs6D1=tK}HXPW(q;$Nz;LeH|x@@Af0lm;4wRacIc z%vz3Fa2mt+^y1n2`)>(&B4sXz2mF66~Y}1~zCfR5xu;m%%-M(5Gv_WE6gF)-{NJ zVNj(8F3>L?xCUWtu?B~ZF(RM2$xonbwMzj4P)iCMImn=PDSWyHZWRpc)?U7=E;u^0 zxG<**M#rd+Xsu@OpgaHJ9x_@F_ecU5M5ta1#aPKJ>jaYVBXuBm9GZ^2Z;QJdW# zVAF>}&1-L#02y{jWiyPsTC>qR6ePKh(b;}KR4p6XJBSbR~0vg4}<~QJD z*jyQn=5J^!L(N5i=n&q7bnQ}fzFeBKt&JVm8dw|j@BykHU<*d0 z7j%7lkMoF+M%88mD}L$=?#l&^ZET~ci@HSi(I|1eAez799d-uRjtnK5)e)LJy~GXl z+e9H5RNwUx4Vycv&OTSN`lz)Z6&K$pq=mm$6CX;vF7Zermx#u{8h<+eM)A9WQ}Hda z@5G*s{X*>V@cYBB44(=2g}xs&g4=_l{EYG;<#oXam2}{_z%K>5qiN{AE2rifGq!QzOc83DnOuwUxh*Hp>A0IdcLslF`GeRZ44G{2Hpxj3<7y!Tcg&we&4+c zWcT%pVpxmho3~Su@;mQ<(*1o9B@qu&kmRT*>XIx8!d(?4a8KA5kpX8HQ2tuJu;Vh4 zqDKw;NZ~4)&#fSuITdJnK^XE`<;&0K3+ZJL~f$WyEGX65Y!tVL^_0{_BNA1!f3J~AYyXI{{JYX||NO@uR%Wc{; z*uJ!t&j~v%WSXUYk07eZIv5qQrm^#3R1jGPQ_y1;!Lw^)edj}nBGNKL(WTBh{aa8$?4oFjUKiEZO=!Z5i7v{zy*oFfg4pxW z1znye@tkn_w!+xoX*YzPn)@`Q!)^#&lxaxd&ZOB8b^_&U$c{Et2D@W=lxI}Zw~jCc zw@sI0HL_Df1@UBsF6e1UUxJVXh0rCLb_9Fls30hWE$C{83~#jKVXtd6$++|(;XdJu zg7#VM{o3Q&{aQ!jONrl3{B+`CB9oBfe-eLhyb>?OH^sgb`(W&~vGcM1=y#)^ioP{k zijGEOk28rh=$Z}sEqPpdCe_l5s8{HNjfg;&C3;kMA1Lmv%28G0bJE%=YY zKM1}(_*if_C@No6KCZk?xu!gzXd*Xi+-ytrF_lOz@)aZX}Y?oDR zw}F@Ecm=q@vplCQ8?68hy!1kyK-<7BG3nB<1T@G>9<2erwCUb}*MNq()bJxt7l%dQ zJ_E1S@Xm#oI@5*l&c$v6uh>wB^9s*YfOX?uV-`9S+3D~yV0s?f>A1_7feL8N=0l$@ zAIjflTtw9IQqxP_-CfbHfq@oyWZS?4yQ^$o5Tp@HwLIkrtQCQ+#*_+gKivvlqYZh1 z%4(&!cuqIZ1Ic>6&}W>565CPd!6jBI#hDtM34=n;DUNb*HeW~?XArF(t7N$}zfg0w zlB9W5&U5F9(#9l_UZ^fRtA928**u#M?jXd#AL>uqMd1=$Gm3ZPlL>zC&d5F`+ zu_xYvsAEs;rOr53(-Ut;^sy)Q&}S-OPrMC_kM^9s3~0}a_ndbby+nT4J@e3~%ZGyC zitj|^u`BkHcez)*>u2;J(rC`>CG9E;hJ&W?#Bky_VK`_$PYfr%R>MIvdtx|VMzkql z!$GrqVmKZSbZKNbXogP=$4i^G1Y$U7f0G!Fhd5mv8xGoKCx+vt&e#DqoIM7b{3F8= zH4lBJf+C?Y9IXJz81CgjTY_mhXeB`QT|Erw@}U4&&L%`2TaK5!%NmH~Y(%87<#JrUG_3F)TiEIbH^|A((~}CGvyI z@zAHshZHcJ2qKRS$4lO248(9$L>dey>?Q3g3x*R$RI%aULAvFzL&mBQB99HHZLNkA zM2xWEcp1^AfDK1M9Pn7>;Xs#0h7&-v@mS@hOeYxiHXAQ-mnmSgc@-jz z-HnH^t7ty=N<iSeq8=X`2w5(_(Y-~?g98# z>_YVEXm8{x^?CJl_-VLg@ka1_(#Mr&g#Rndif@!>q))AN^3BWrTR{M{|FbWuwiq3A zRAdc_m1=Ju#)U$qP~@8(&TEGwK?XiHW5xNhVcQUVgM$_!?8u7Fw(3HJB#I=PpevcdsT3$ElbN0WABS+toZ zp<$p6Dv;6=4P{VA8ohyKBzg-@Z?TeLnh?=y-TYv5-%li?BFdv{37bV{QPRE#1n?mh zSEzX-`5+dPiWjsjZ~&t7?XY8!?}^=lS2EglqE~XR(L7_+-tb%_fu0J+wmLuZ3RLH0 z)M;rAg6*w?ckZgtF|&4tk(?!BQ3p{rH9v>~{Hds27j-y@;)?Ta=+PjI-6uX9LLlK} ztrcOZ&46U4*RZ>&uh)Q(*iqm6bZ`cW7QmYkL$M%6Ir46M(0Bynt5prD3rjqrb}ylgaghniJ{EUt5R&JXl(VF zV*r>=hOz!ZBHMPjP{%elx&6F8vryF+@f`*1O*$}pVvi&cp{P*oMnXXk@E6L-Fp}qq zE-B}#HgT@NAG)|dT7&46pG#uaxk6n$^UA_OY&H-ZXTT{xYdkQzA0U!ZCtibVnq}Za zU@kfA9tx6E2T**GgDD&w(DWX@LgDo=+SwNnoh9;7ey#b5S8yI60d;1>EgGQWi~>GA z6hj0Jur4Tb)rJ0nj%}IagVBA4!j5zUbxqje6AnHHn>Y1*FL#-+o;2Jr)dzXcj1L6nbZ;8Jp&>_E4`jWU#sKWpF=Y>ST=rB}b zM${#E8=4Q_8QcS1#$xp%ltCRMVb2A@SVh*faO~YY)@0X(Q(|!Q5e%_r4~+h$^w0~5 z1?Tne1OcOa-p94Kt*%<-*BVf$4_E_-6rLN2tl@-ci?U@u&F^#fuJP_umKltjI7LxZ(Z(NUue zY)!kusQ36@fPyk8%WH%fy0e4Xv9PEuGku^imcA=XI@xbS4IQ8 zV2W*N%Q69?Uss0Fv2gQvdG@?)@^~}KC7BOiP=suH`AnT515{~QSf>#rfT4R?Z4+y; z#KpMzO`ffcX5A7wGMIORG8y4W26QWHRt?Tyxh3J)JpcDVe}BT*hsy z4h!34K@07%WU~B}UDwL6cUqH11Z08_wNJ63$v(y4o-BA!pY+K2rl@TTPd_9+6s>^R4PmlJ=VU-1G&){Q5Th1u$rcMYn2J#|E?Xs#K~1z8SwFgW z-a8(ltwk8YO|j$ZmxbM-rv>fP@NU1dHlejc{QpN1^~6+STl}BmpNzjbJ{|dfmvu%kElab!P^ZA`8?l6rR?MRk+wG&Z&jp;dO&QCv4U7)lps z0u}q}D6X4aV?h^W!wz@WQ7kt(8cLV+1f1@uqZn>o|5BM}ux!V+3&>2XNzXP%k4II1~Fj~du4(s@k1C9#zTDePh6cv0|9fxk?!d~i3;T?4xxQ%0oJ(9c1 z!ns3X@7nurx{lA#V0-ak-5`3nj!)BId-1lBwg7A|_!teg7Y_%zG_n_bfCdK;duh`O z!U4o}e1Zl?5POKz#Zkn09Uq~=_Tr`PZ!h=|O+Px5=AqA2KoRG4e2NC!i0Nn0GsYem%tL;`qb@ zzFrL5kC!^50rSMdWf&63i3JaRrUE{(umZ)&87VIVT4nge!d=EPqL1yzL!T~>&N-J6 zb?k4v)LlM=oOD@2l(7@`Px4(j-6RsseGhJ+JsdBBJw5+K4IED2^_>>*)2Gn_C~EQL6}nI*wU!L$U< zT3IjbJYWP(G5T2=O~r7%_4dGPObSPCf&x6XaxTT5c$L|XPL=}G4$7)93F~dj2VP+c zv7RN-M5jQ(dHdl0$ALnBzdC-1G6_Zkw=$qQJXAI#neMrYs`shm9aMFiyQjAGl=t2% zn7KIKMb&1Qv(0znq4(D?cX50ZRiEY_pxL`#Z+M^r)sZdkY>pmF!FhN%zJw@1r}nI6 z8h2`PUc-!B8!urI)bV_C5$HC+>wK)Y_8gcu+t9}nXky3^iRQe9bwWoJ`o(e2P649_ zsyks4R&e0>gC-1~HCJO8s5cYda}*KiQOD60J(Mn8YeE|Xa)mnzc_ZO;2ktj97-MVG zmf#qYO~H&I*?$-)AjddLF>hYoc>~2ghj4Xue56TrMtpdhZ=P%1Uoe?xsM?M6M`VXb z_NEEldk|Fz{S8yq8Rao;cfAN=|D?%&h^pVT?XH(K?7!QrzMHDvRC;u{&3yd6f45mZ zN>y*d9r_O(EHD*!U>#IPUAV=~)sF4r*Z~;StT%PVgMTgzNO3vw9eC=$lGq!6KK_CD ze0*!{FJo_xor!7DXQQu+PDcJE@}DA)MYgM7Qs1u@)z0weLVu+_6TYDRSon_6&jsJ4 z?GK&|Js6BBpH!X-wFg!MyXCLS?^6y2{x$G)`0etve1~*HIwAdc$+;-}1)aihW@|#= z-uk7GAnofB$Ax#ZzQpB;OlyKL893huVKT@W5?3@)UqA%FAcc3a1ZbOfXy5=K*IR%l z>fqA}jdwPuVGc|nhegAlB-J0YX#6}&!?$a?Xjm^AnXEsGXnCCEEiA~YcG#z52?9GY}MJ!8>$GfSgUV{p_~4q~27KQmcBZ8hdiEDfeHrmF-* zEFxB{`=R&@i}>q@(*r>zmR10%n$1 zsqW!2Da#~1LG<_3dl7r6`zn^bPjwR83d=j|kcV(jeT!ND6>F$(vWJjf6TrLc4*`Jv zs7Ji5k?aio18}>783`%~`|C1lI=F_1sp>Rzwgs8-oapVAWGE}tB_uvLy8A0>tDHv6g&Y4@HV;#yZ7MY3~r1%o@*h9?Kj{=G4&p{1I9%}0u25jOQOMS#eBQ6^CHqo1EyZs z-uB;2Q;;0a+c+l;n0jF%58NyfXIL#57f@rsNbX}B)6{4QD9-z$Ckz;#v5`E=(qW9m zR4_jNO|JE@eA>8i5269njA@nz?MaAgfC78{#=XWcf&|QL7X=9;f@!Bf0QxZX`sQ&X zXNquajUr%Q=DJL2!oXuYh%nAlV5D$>z@7x6^sVXRy~aMX8ILq;hMNEy7M-g;#*Kc| z4Dg8SSRwp8BH7P|>M&I@M+cZT1O?$hJ%iy8$7?JdS|fI^^_&MgP~U2jc;y;N*dwKN zm~pJ$jo^Th@^K0d*Vth5w?}zv?ur)V8v=D9+8=qd`p@d4;ZKBjYSW3Q6Fu=KV_%Ow z5dEFdPX@mgJgfYs(gnr%ha_CHz%4MZe}m+vL++uhLm%l z%jcvUyJyAJbvCo$zKtzD$F^ErE}4akpL`EELk4}e(?>S4j|IzE>LxGO=9G0=70A|o zYqI&=r!TQqay6}(%5h(>w0O-;NTI>$>L0=MOYi~+Y5`Y06hhsT@NqkgL{k=V6i z2*wt7Ftgomt3#<^Q~vjZKn8V5T0_}DpC&epY|cg`9LbJ>Z01dqwrsNhy^dM`D|5l6 zKnCo{IX2cvCO9c>9qFfKLK&7K*BQ~Z%Y+6Z%Dip5kg+zIU^&csGpt-Bler23UX}SanUfoTm^V+eS(@ z%egjvK|EUC!|L2IZ;L+4pz!oLAdXGR^?=B#YkD^4$q_jIb|M=!VzzYrAOm%2qs71@ zbra#NEjFvJEu58MbQ>FpaMaz*n_6EFHMA!Ua~{gz2^W$9GdKs=237}8EUX;~MnES6 i1YA!ENQU$cYZZ{Pez$-yO?A3zBLSTUWsHDM#{UO?Jj4?K diff --git a/www/fahrschultermin.de/storage/database/app.sqlite.bak-20260422203538 b/www/fahrschultermin.de/storage/database/app.sqlite.bak-20260422203538 deleted file mode 100644 index e69de29..0000000 diff --git a/www/fahrschultermin.de/storage/database/app.sqlite.bak-users-20260422204004 b/www/fahrschultermin.de/storage/database/app.sqlite.bak-users-20260422204004 deleted file mode 100644 index 1627d63e73f4b482685efca50352f1d5b41e7bf3..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 73728 zcmeI5-EZ606~IZ6`k-uyN!wHrJTJ_gEHRwK^0%F|NM)OL9DgM72l4@QDlJ`EtR+(B zM;v<(MVh9?p7yX69R?J88ul|Iw(Eb6#3al>$h5-ZGr)}s`#bku-gE9HxpHekHi%GEwTfg2L)0;frl}VMfug7x`2Q6AcehU1 zVckFAH{Gxwv^zsx+T99UC-eWZ&f#mnf=gi=HKUk%fHC)@;`?|xFG=~fCP{L5NiJWObUkN~O0_H*M30<~!u4*Vd$>`M zeiA4r_egifm~L009y%6g&eCO~>#CA7cB({=^DNUt%ZhGjX5LUWJ;X6giZ*qk>1;=c z>E?7|7!Wbg<22L78AOp3L$~Jt*+ib=?<9Yf?1UZMkN^@u0!RP}AOR$R1dsp{KmthM zpadR%o9(2y)6YK)r%%8f?w*HMgxTCODQQG|L2+htFM(%hoEh9XGcb7O`s~uCdQa2) zXQjcdjopkkIC*d9(!%wH`@^^IRrw-_sD;#Og+aBE$i%Z$#EYirrfVs-0fb50uHT9hn~S#x7^QlTO%_7C4o&dse$3zdyUZDQ_Prh4arVa~2Ck(IF_V`qNset)&NoY5Dz zN5sPJFqtlv?+o9bSf0HuDblki_s!;68lIOwJpo3ySn6h#Xmo+I#mFm51W!faGGnvgHbMo5O`uO7bsIpw%91+QGwKzO` z=h}mnDHOs$6@qggo;@{!_a?nbS*C7EUfCP{L5wg^E@3C9%9qX80{O9VN%Qx?GptFrI`uNKk#79|A+YRQ2a092X06J2_OL^ zfCP{L5>a{Q5BiYYf{nZ$&L+=5017@*YCGP z;|6UBJYfr@_ttv!WW~q!HVeSALVxXbFi%!+c zqQX2nNutX<=|6$A@5>ah^Yqw6CBN1_hSEQyj;|K*6*` zDizztVDV{F*(Bu>!0H*E92yy&yy$3Bd?kr+%%_kn*pHP8p%{Jiz9J0eUC2z~HFY~Syl4THd^Psc2Qd(sXdNMu3K@l&>- zdal~f&pZQSPFSztpX!^cXUHnuLGl!;=cz900Ai+S5W{y{MRQBme!;Bg|0DeS6#q~D zZ~Vvb{{KJnpZS^?4Fn1dsp{Kmter2_OL^fCP{L5@;ciJ{hIx z)M=WI*sJH4BzQi+Ud7Ka=@cY&bwiS~@ZDV&9}cCSwXQlva}j%yIxH}UPrSoI_QT3d&HqP&=KsS?(ENWiX#PL8&-{PV^8cx0`w_r&B!C2v01`j~NB{{S z0VIF~kN^@u0!ZMiOd!#bpknNMRPxj0+nw(uUuNHny%KpC%dme6eL#;V-~1|<4fBo! zkigL;@Mtm|P4)E9ug@FOdYQ=Zksr;>8>*%^>_(=R#q6pmtY#+{M4=%;I3E{alMBM! z(yBNsE(_@y)m~0*Di`ns~7Au;k!YSV&obwSh}$)EUhgp)Y6Nx zrW-j$s=(4P@eZVTQsIrb!HIdbtitz?TCY-6gXpz{X>lgIwy-LkJ6BUD>$%#>vwHqr zg@SwPK<&)DM&SEOg`8ygsW7Vr|5U-$iPl(LSL|MqXKpNubF)h}vGa94y~46MBQA?e zQ{swHJE{xkBX))gW=t4A_x^jhntlCB_!*_CE4O}j7y+Jr< zkV>@-xzhs<$2`UjIO)(0omUIKCJr(^SSqhp)@4O9WK{_^SLO?u%dVqqOLMo@L}AYs z7X&M}y*0^)V6MejBqd#;DH%R<^g!P#!`HNO5`41^wOMmZf z&H6;wRV8QaRKes8`%$l*8&VG4xIsn?Y@!8Hl+3b`E5N6ueC_L46{_)us_pnSL5*yg zvPLQdx|dDjoYLCbpdPKu<+9b+?OTcLI%j>3Y_EH3=^mW=2B&HSIwy^k$$jYI_LW_f zA3$#sSl)W~%X<&i1bqah}mN~P%6 zMZ43mZd1DbgY|S1_MyY*AL@5_O@)@{bC)I+NiKU6gj!ErYx`BWmu*7}$dx3$9#>Jw}CL?2hi zm2-IROg|q)rZJOEzmw!3}c-p5RLGXX9S(pX#aC^;+Vo()Hn_Zycz>_~Qv=h` zHG31Bq84&?{~S>1+X%gQYRq2FJyvrLx759QF!!}++#YVcAvK!CwSeB?2OFdvayRTo zjf1<+FW_%iOLZU4?c3dm{1f`LCwGlC2j1x!-4^5D)3|NJKh;J#b?je>P2_OL^fCP{L5