edupsyadmin 8.1.4__tar.gz → 8.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.pre-commit-config.yaml +15 -2
  2. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/CHANGELOG.md +13 -0
  3. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/PKG-INFO +98 -26
  4. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/README.md +97 -25
  5. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/helpfunction.rst +1 -1
  6. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/update.rst +6 -0
  7. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/pyproject.toml +7 -3
  8. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/__version__.py +1 -1
  9. edupsyadmin-8.2.0/src/edupsyadmin/alembic/versions/2026_03_02_1222-635a9d68fbe8_add_case_active_column_to_clients.py +30 -0
  10. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/managers.py +33 -30
  11. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/migrate_encryption.py +15 -2
  12. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/db/clients.py +38 -33
  13. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/clients_overview.py +16 -6
  14. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edit_client.py +106 -29
  15. edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user0].svg +623 -0
  16. edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user1].svg +625 -0
  17. edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_new_client.svg +624 -0
  18. edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_edupsyadmintui/test_edupsyadmintui_initial_layout.svg +228 -0
  19. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_editclient.py +35 -14
  20. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_edupsyadmintui.py +1 -1
  21. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/uv.lock +253 -205
  22. edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user0].svg +0 -587
  23. edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user1].svg +0 -589
  24. edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_new_client.svg +0 -588
  25. edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_edupsyadmintui/test_edupsyadmintui_initial_layout.svg +0 -162
  26. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.github/workflows/publish.yml +0 -0
  27. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.gitignore +0 -0
  28. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.python-version +0 -0
  29. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.readthedocs.yaml +0 -0
  30. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/LICENSE.txt +0 -0
  31. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/Makefile +0 -0
  32. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/_static/samplewebuntisfile.csv +0 -0
  33. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/clients_model.rst +0 -0
  34. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/conf.py +0 -0
  35. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/faq.rst +0 -0
  36. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/index.rst +0 -0
  37. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/make.bat +0 -0
  38. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/requirements.txt +0 -0
  39. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/taetigkeitsbericht_keywords.rst +0 -0
  40. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/cli.rst +0 -0
  41. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/configuration.rst +0 -0
  42. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/creatingdocumentation.rst +0 -0
  43. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/editingclients.rst +0 -0
  44. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/encryption.rst +0 -0
  45. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/installation.rst +0 -0
  46. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/taetigkeitsbericht.rst +0 -0
  47. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/tui.rst +0 -0
  48. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/py.typed +0 -0
  49. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_iLst.sh +0 -0
  50. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_iRst.sh +0 -0
  51. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_lrst.sh +0 -0
  52. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_nona_nons.sh +0 -0
  53. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/change_keywordtaet_nsessions.sh +0 -0
  54. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/profile.sh +0 -0
  55. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/publish_to_testpypi.sh +0 -0
  56. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/__init__.py +0 -0
  57. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/__main__.py +0 -0
  58. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/README +0 -0
  59. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/env.py +0 -0
  60. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/script.py.mako +0 -0
  61. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/versions/2026_02_21_0453-4087c43f0c7c_initial_migration.py +0 -0
  62. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic.ini +0 -0
  63. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/__init__.py +0 -0
  64. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/add_convenience_data.py +0 -0
  65. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/cft_report.py +0 -0
  66. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/display_client_details.py +0 -0
  67. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/fill_form.py +0 -0
  68. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/flatten_pdf.py +0 -0
  69. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/lgvt.py +0 -0
  70. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/migration.py +0 -0
  71. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/reports.py +0 -0
  72. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/setup_demo.py +0 -0
  73. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/taetigkeitsbericht_from_db.py +0 -0
  74. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/__init__.py +0 -0
  75. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/__main__.py +0 -0
  76. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/create_documentation.py +0 -0
  77. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/delete_client.py +0 -0
  78. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/edit_config.py +0 -0
  79. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/flatten_pdfs.py +0 -0
  80. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/get_clients.py +0 -0
  81. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/info.py +0 -0
  82. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/mk_report.py +0 -0
  83. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/new_client.py +0 -0
  84. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/rotate_key.py +0 -0
  85. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/set_client.py +0 -0
  86. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/setup_demo.py +0 -0
  87. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/taetigkeitsbericht.py +0 -0
  88. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/tui.py +0 -0
  89. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/utils.py +0 -0
  90. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/__init__.py +0 -0
  91. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/config.py +0 -0
  92. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/encrypt.py +0 -0
  93. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/logger.py +0 -0
  94. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/paths.py +0 -0
  95. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/Faecher_BfsEV.md +0 -0
  96. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/Faecher_BfsKi.md +0 -0
  97. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/Faecher_Faks.md +0 -0
  98. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/sampleconfig.yml +0 -0
  99. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/taetigkeitsbericht_categories.csv +0 -0
  100. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/db/__init__.py +0 -0
  101. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/info.py +0 -0
  102. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/__init__.py +0 -0
  103. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/clients_overview_app.py +0 -0
  104. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/dialogs.py +0 -0
  105. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edit_client_app.py +0 -0
  106. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/editconfig.py +0 -0
  107. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/editconfig.tcss +0 -0
  108. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edupsyadmintui.py +0 -0
  109. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edupsyadmintui.tcss +0 -0
  110. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/fill_form_app.py +0 -0
  111. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/fill_form_widget.py +0 -0
  112. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/__init__.py +0 -0
  113. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/academic_year.py +0 -0
  114. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/convert_measures.py +0 -0
  115. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/datediff.py +0 -0
  116. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/int_from_str.py +0 -0
  117. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/path_utils.py +0 -0
  118. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/python_type.py +0 -0
  119. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/taetigkeitsbericht_check_key.py +0 -0
  120. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/.gitignore +0 -0
  121. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_add_convenience_data.py +0 -0
  122. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_decryption_behavior.py +0 -0
  123. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_fill_form.py +0 -0
  124. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_flatten_pdf.py +0 -0
  125. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_managers.py +0 -0
  126. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_migration.py +0 -0
  127. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_taetigkeitsbericht_from_db.py +0 -0
  128. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/benchmark/test_cli_benchmark.py +0 -0
  129. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/benchmark/test_encrypt_benchmark.py +0 -0
  130. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/benchmark/test_key_derivation_benchmark.py +0 -0
  131. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/cli/test_utils.py +0 -0
  132. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/conftest.py +0 -0
  133. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/core/test_config.py +0 -0
  134. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/core/test_encrypt.py +0 -0
  135. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/core/test_logger.py +0 -0
  136. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/data/sample_form_anschreiben.pdf +0 -0
  137. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/data/sample_form_mantelbogen.pdf +0 -0
  138. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/sample_pdf_form.py +0 -0
  139. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/sample_webuntis_export.py +0 -0
  140. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/test_cli.py +0 -0
  141. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_clientsoverview/test_clients_overview.svg +0 -0
  142. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_dialogs/test_yes_no_dialog.svg +0 -0
  143. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_editconfig/test_add_new_school_container.svg +0 -0
  144. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_editconfig/test_edit_new_school_container.svg +0 -0
  145. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_editconfig/test_initial_layout.svg +0 -0
  146. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_fill_form_tui/test_initial_layout.svg +0 -0
  147. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_clientsoverview.py +0 -0
  148. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_dialogs.py +0 -0
  149. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_editconfig.py +0 -0
  150. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_fill_form_tui.py +0 -0
  151. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_academic_year.py +0 -0
  152. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_convert_measures.py +0 -0
  153. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_datediff.py +0 -0
  154. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_int_from_str.py +0 -0
  155. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_path_utils.py +0 -0
  156. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_python_type.py +0 -0
  157. {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_taetigkeitsbericht_check_key.py +0 -0
@@ -7,7 +7,7 @@ repos:
7
7
  - id: end-of-file-fixer
8
8
  - id: trailing-whitespace
9
9
  - repo: https://github.com/astral-sh/ruff-pre-commit
10
- rev: v0.14.11
10
+ rev: v0.15.2
11
11
  hooks:
12
12
  - id: ruff-check
13
13
  args: [ "--config=pyproject.toml", "--fix" ]
@@ -17,7 +17,7 @@ repos:
17
17
  hooks:
18
18
  - id: gitleaks
19
19
  - repo: https://github.com/commitizen-tools/commitizen
20
- rev: v4.11.1
20
+ rev: v4.13.9
21
21
  hooks:
22
22
  - id: commitizen
23
23
  - repo: https://github.com/rstcheck/rstcheck
@@ -30,3 +30,16 @@ repos:
30
30
  hooks:
31
31
  - id: sphinx-lint
32
32
  args: ["--enable=all"]
33
+ - repo: https://github.com/rvben/rumdl-pre-commit
34
+ rev: v0.1.28
35
+ hooks:
36
+ - id: rumdl-fmt # Auto-format and fail if issues remain
37
+ - repo: local
38
+ hooks:
39
+ - id: ty-check
40
+ name: ty-check
41
+ entry: ty check
42
+ language: python
43
+ types: [python]
44
+ args: [--python=.venv/]
45
+ pass_filenames: true
@@ -1,3 +1,16 @@
1
+ ## 8.2.0 (2026-03-08)
2
+
3
+ ### Feat
4
+
5
+ - **db.clients**: add variable case_active to database
6
+
7
+ ## 8.1.5 (2026-03-02)
8
+
9
+ ### Refactor
10
+
11
+ - **api**: improve session management, metadata caching, and ORM consistency
12
+ - **cli**: deprecate migrate-encryption command
13
+
1
14
  ## 8.1.4 (2026-02-27)
2
15
 
3
16
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: edupsyadmin
3
- Version: 8.1.4
3
+ Version: 8.2.0
4
4
  Summary: edupsyadmin provides tools to help school psychologists with their documentation
5
5
  Author: Lukas Liebermann
6
6
  License: MIT
@@ -34,6 +34,19 @@ Description-Content-Type: text/markdown
34
34
  edupsyadmin provides tools to help school psychologists with their
35
35
  documentation
36
36
 
37
+ ## Key Features
38
+
39
+ - **Secure & Encrypted:** Sensitive client data is stored in an encrypted
40
+ SQLite database using `cryptography` and `keyring` for secure credential
41
+ management.
42
+ - **Modern TUI & CLI:** Choose between an intuitive Terminal User Interface
43
+ (TUI) for interactive workflows or a powerful Command Line Interface (CLI) for
44
+ automation.
45
+ - **Automated Documentation:** Automatically fill PDF forms and generate
46
+ reports using stored client data.
47
+ - **Data Interoperability:** Import student data from common school management
48
+ software via CSV exports.
49
+
37
50
  ## Basic Setup
38
51
 
39
52
  You can install the CLI using pip or
@@ -41,7 +54,9 @@ You can install the CLI using pip or
41
54
 
42
55
  Install with uv:
43
56
 
44
- uv tool install edupsyadmin
57
+ ```text
58
+ uv tool install edupsyadmin
59
+ ```
45
60
 
46
61
  You may get a warning that the `bin` directory is not on your environment path.
47
62
  If that is the case, copy the path from the warning and add it directory to
@@ -49,11 +64,37 @@ your **environment path** permanently or just for the current session.
49
64
 
50
65
  Run the application:
51
66
 
52
- edupsyadmin --help
67
+ ```text
68
+ edupsyadmin --help
69
+ ```
70
+
71
+ ## Quick Start
72
+
73
+ The fastest way to get started is by using the interactive **edupsyadmin TUI**:
74
+
75
+ ![Edupsyadmin TUI](test/edupsyadmin/tui/__snapshots__/test_edupsyadmintui/test_edupsyadmintui_initial_layout.svg)
76
+
77
+ ### 1. Configure the app
78
+
79
+ First, you have to update the config file with your data using the config
80
+ editor TUI:
81
+
82
+ ```text
83
+ edupsyadmin edit-config
84
+ ```
85
+
86
+ ### 2. Launch the main interface
87
+
88
+ Once configured, you can view, add, and edit clients, as well as fill PDF forms
89
+ directly from the main TUI:
90
+
91
+ ```text
92
+ edupsyadmin tui
93
+ ```
53
94
 
54
95
  ## Getting started
55
96
 
56
- ### keyring backend
97
+ ### Keyring backend
57
98
 
58
99
  edupsyadmin uses `keyring` to store the encryption credentials. `keyring` has
59
100
  several backends.
@@ -67,13 +108,6 @@ Those default keyring backends unlock when you login to your machine. You may
67
108
  want to install a backend that requires separate unlocking:
68
109
  <https://keyring.readthedocs.io/en/latest/#third-party-backends>
69
110
 
70
- ### Modify the config file
71
-
72
- First, you have to update the config file with your data using the config
73
- editor TUI:
74
-
75
- edupsyadmin edit-config
76
-
77
111
  ## The database
78
112
 
79
113
  The information you enter, is stored in an SQLite database with the fields
@@ -84,23 +118,31 @@ edupsyadmin](https://edupsyadmin.readthedocs.io/en/latest/clients_model.html#)
84
118
 
85
119
  Get information about the path to the config file and the path to the database:
86
120
 
87
- edupsyadmin info
121
+ ```text
122
+ edupsyadmin info
123
+ ```
88
124
 
89
125
  Add a client interactively:
90
126
 
91
- edupsyadmin new-client
127
+ ```text
128
+ edupsyadmin new-client
129
+ ```
92
130
 
93
131
  Add a client to the database from a Webuntis csv export:
94
132
 
95
- edupsyadmin new-client --csv ./path/to/your/file.csv --name "short_name_of_client"
133
+ ```text
134
+ edupsyadmin new-client --csv ./path/to/your/file.csv --name "short_name_of_client"
135
+ ```
96
136
 
97
137
  Change values for the database entry with `client_id=42` interactively:
98
138
 
99
- edupsyadmin set-client 42
139
+ ```text
140
+ edupsyadmin set-client 42
141
+ ```
100
142
 
101
- Change values for the database entry with `client_id=42` from the commandline:
143
+ Change values for the database entry with `client_id=42` from the command line:
102
144
 
103
- ```
145
+ ```text
104
146
  $ edupsyadmin set-client 42 \
105
147
  --key_value_pairs \
106
148
  "nta_font=1" \
@@ -109,33 +151,63 @@ $ edupsyadmin set-client 42 \
109
151
  "lrst_diagnosis_encr=iLst"
110
152
  ```
111
153
 
154
+ Delete the database entry with `client_id=42`:
155
+
156
+ ```text
157
+ edupsyadmin delete-client 42
158
+ ```
159
+
112
160
  See an overview of all clients in the database:
113
161
 
114
- edupsyadmin get-clients
162
+ ```text
163
+ edupsyadmin get-clients
164
+ ```
115
165
 
116
166
  Fill a PDF form for the database entry with `client_id=42`:
117
167
 
118
- edupsyadmin create-documentation 42 --form_paths ./path/to/your/file.pdf
168
+ ```text
169
+ edupsyadmin create-documentation 42 --form_paths ./path/to/your/file.pdf
170
+ ```
119
171
 
120
172
  Fill all files that belong to the form_set `lrst` (as defined in the
121
- config.yml) with the data for `client_id=42`:
173
+ config.yml) for the database entry with `client_id=42`:
122
174
 
123
- edupsyadmin create-documentation 42 --form_set lrst
175
+ ```text
176
+ edupsyadmin create-documentation 42 --form_set lrst
177
+ ```
178
+
179
+ Generate a "Tätigkeitsbericht" PDF with 3 Anrechnungsstunden (experimental):
180
+
181
+ ```text
182
+ edupsyadmin taetigkeitsbericht 3
183
+ ```
184
+
185
+ Flatten filled PDF forms (experimental):
186
+
187
+ ```text
188
+ edupsyadmin flatten-pdfs ./path/to/filled_form.pdf
189
+ ```
124
190
 
125
191
  ## Development
126
192
 
127
- Create the development enviroment:
193
+ Create the development environment:
128
194
 
129
- uv v
130
- uv pip install -e .
195
+ ```text
196
+ uv v
197
+ uv pip install -e .
198
+ ```
131
199
 
132
200
  Run the test suite:
133
201
 
134
- .venv/bin/python -m pytest -v -n auto --cov=src test/
202
+ ```text
203
+ .venv/bin/python -m pytest -v -n auto --cov=src test/
204
+ ```
135
205
 
136
206
  Build documentation:
137
207
 
138
- .venv/bin/python -m sphinx -M html docs docs/_build
208
+ ```text
209
+ .venv/bin/python -m sphinx -M html docs docs/_build
210
+ ```
139
211
 
140
212
  ## License
141
213
 
@@ -3,6 +3,19 @@
3
3
  edupsyadmin provides tools to help school psychologists with their
4
4
  documentation
5
5
 
6
+ ## Key Features
7
+
8
+ - **Secure & Encrypted:** Sensitive client data is stored in an encrypted
9
+ SQLite database using `cryptography` and `keyring` for secure credential
10
+ management.
11
+ - **Modern TUI & CLI:** Choose between an intuitive Terminal User Interface
12
+ (TUI) for interactive workflows or a powerful Command Line Interface (CLI) for
13
+ automation.
14
+ - **Automated Documentation:** Automatically fill PDF forms and generate
15
+ reports using stored client data.
16
+ - **Data Interoperability:** Import student data from common school management
17
+ software via CSV exports.
18
+
6
19
  ## Basic Setup
7
20
 
8
21
  You can install the CLI using pip or
@@ -10,7 +23,9 @@ You can install the CLI using pip or
10
23
 
11
24
  Install with uv:
12
25
 
13
- uv tool install edupsyadmin
26
+ ```text
27
+ uv tool install edupsyadmin
28
+ ```
14
29
 
15
30
  You may get a warning that the `bin` directory is not on your environment path.
16
31
  If that is the case, copy the path from the warning and add it directory to
@@ -18,11 +33,37 @@ your **environment path** permanently or just for the current session.
18
33
 
19
34
  Run the application:
20
35
 
21
- edupsyadmin --help
36
+ ```text
37
+ edupsyadmin --help
38
+ ```
39
+
40
+ ## Quick Start
41
+
42
+ The fastest way to get started is by using the interactive **edupsyadmin TUI**:
43
+
44
+ ![Edupsyadmin TUI](test/edupsyadmin/tui/__snapshots__/test_edupsyadmintui/test_edupsyadmintui_initial_layout.svg)
45
+
46
+ ### 1. Configure the app
47
+
48
+ First, you have to update the config file with your data using the config
49
+ editor TUI:
50
+
51
+ ```text
52
+ edupsyadmin edit-config
53
+ ```
54
+
55
+ ### 2. Launch the main interface
56
+
57
+ Once configured, you can view, add, and edit clients, as well as fill PDF forms
58
+ directly from the main TUI:
59
+
60
+ ```text
61
+ edupsyadmin tui
62
+ ```
22
63
 
23
64
  ## Getting started
24
65
 
25
- ### keyring backend
66
+ ### Keyring backend
26
67
 
27
68
  edupsyadmin uses `keyring` to store the encryption credentials. `keyring` has
28
69
  several backends.
@@ -36,13 +77,6 @@ Those default keyring backends unlock when you login to your machine. You may
36
77
  want to install a backend that requires separate unlocking:
37
78
  <https://keyring.readthedocs.io/en/latest/#third-party-backends>
38
79
 
39
- ### Modify the config file
40
-
41
- First, you have to update the config file with your data using the config
42
- editor TUI:
43
-
44
- edupsyadmin edit-config
45
-
46
80
  ## The database
47
81
 
48
82
  The information you enter, is stored in an SQLite database with the fields
@@ -53,23 +87,31 @@ edupsyadmin](https://edupsyadmin.readthedocs.io/en/latest/clients_model.html#)
53
87
 
54
88
  Get information about the path to the config file and the path to the database:
55
89
 
56
- edupsyadmin info
90
+ ```text
91
+ edupsyadmin info
92
+ ```
57
93
 
58
94
  Add a client interactively:
59
95
 
60
- edupsyadmin new-client
96
+ ```text
97
+ edupsyadmin new-client
98
+ ```
61
99
 
62
100
  Add a client to the database from a Webuntis csv export:
63
101
 
64
- edupsyadmin new-client --csv ./path/to/your/file.csv --name "short_name_of_client"
102
+ ```text
103
+ edupsyadmin new-client --csv ./path/to/your/file.csv --name "short_name_of_client"
104
+ ```
65
105
 
66
106
  Change values for the database entry with `client_id=42` interactively:
67
107
 
68
- edupsyadmin set-client 42
108
+ ```text
109
+ edupsyadmin set-client 42
110
+ ```
69
111
 
70
- Change values for the database entry with `client_id=42` from the commandline:
112
+ Change values for the database entry with `client_id=42` from the command line:
71
113
 
72
- ```
114
+ ```text
73
115
  $ edupsyadmin set-client 42 \
74
116
  --key_value_pairs \
75
117
  "nta_font=1" \
@@ -78,33 +120,63 @@ $ edupsyadmin set-client 42 \
78
120
  "lrst_diagnosis_encr=iLst"
79
121
  ```
80
122
 
123
+ Delete the database entry with `client_id=42`:
124
+
125
+ ```text
126
+ edupsyadmin delete-client 42
127
+ ```
128
+
81
129
  See an overview of all clients in the database:
82
130
 
83
- edupsyadmin get-clients
131
+ ```text
132
+ edupsyadmin get-clients
133
+ ```
84
134
 
85
135
  Fill a PDF form for the database entry with `client_id=42`:
86
136
 
87
- edupsyadmin create-documentation 42 --form_paths ./path/to/your/file.pdf
137
+ ```text
138
+ edupsyadmin create-documentation 42 --form_paths ./path/to/your/file.pdf
139
+ ```
88
140
 
89
141
  Fill all files that belong to the form_set `lrst` (as defined in the
90
- config.yml) with the data for `client_id=42`:
142
+ config.yml) for the database entry with `client_id=42`:
91
143
 
92
- edupsyadmin create-documentation 42 --form_set lrst
144
+ ```text
145
+ edupsyadmin create-documentation 42 --form_set lrst
146
+ ```
147
+
148
+ Generate a "Tätigkeitsbericht" PDF with 3 Anrechnungsstunden (experimental):
149
+
150
+ ```text
151
+ edupsyadmin taetigkeitsbericht 3
152
+ ```
153
+
154
+ Flatten filled PDF forms (experimental):
155
+
156
+ ```text
157
+ edupsyadmin flatten-pdfs ./path/to/filled_form.pdf
158
+ ```
93
159
 
94
160
  ## Development
95
161
 
96
- Create the development enviroment:
162
+ Create the development environment:
97
163
 
98
- uv v
99
- uv pip install -e .
164
+ ```text
165
+ uv v
166
+ uv pip install -e .
167
+ ```
100
168
 
101
169
  Run the test suite:
102
170
 
103
- .venv/bin/python -m pytest -v -n auto --cov=src test/
171
+ ```text
172
+ .venv/bin/python -m pytest -v -n auto --cov=src test/
173
+ ```
104
174
 
105
175
  Build documentation:
106
176
 
107
- .venv/bin/python -m sphinx -M html docs docs/_build
177
+ ```text
178
+ .venv/bin/python -m sphinx -M html docs docs/_build
179
+ ```
108
180
 
109
181
  ## License
110
182
 
@@ -45,7 +45,7 @@ anzeigen. Im Beispiel unten, sind die möglichen Unterbefehle markiert.
45
45
  flatten-pdfs Flatten pdf forms (experimental)
46
46
  get-clients Show clients overview or single client
47
47
  info Get useful information for debugging
48
- migrate-encryption Migrate database to new encryption system
48
+ migrate-encryption [DEPRECATED] Migrate database to new encryption system
49
49
  mk-report Create a report for a given test type. (experimental)
50
50
  new-client Add a new client
51
51
  set-client Change values for one or more clients
@@ -45,6 +45,12 @@ mit ``edupsyadmin version``, ``database_url``, ``config_path`` und
45
45
  die ``database_url`` notieren, damit du das Backup später findest, wenn du es
46
46
  löschen willst.
47
47
 
48
+ .. warning::
49
+
50
+ Der Befehl ``edupsyadmin migrate-encryption`` wird mit Version 9.0.0
51
+ entfernt. Wenn du noch eine Datenbank aus Version 7 nutzt, führe die
52
+ Migration auf das neue Verschlüsselungssystem zeitnah durch.
53
+
48
54
  Update der App
49
55
  --------------
50
56
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "edupsyadmin"
7
- version = "8.1.4"
7
+ version = "8.2.0"
8
8
  authors = [{ name = "Lukas Liebermann" }]
9
9
  description = "edupsyadmin provides tools to help school psychologists with their documentation"
10
10
  readme = "README.md"
@@ -42,7 +42,6 @@ bwbackend = ["bitwarden-keyring>=0.3.1"]
42
42
  [dependency-groups]
43
43
  dev = [
44
44
  "commitizen>=3.31.0",
45
- "mypy>=1.13.0",
46
45
  "pandas-stubs>=2.2.3.241009",
47
46
  "pytest-cov>=6.0.0",
48
47
  "pytest>=8.3.3",
@@ -62,6 +61,8 @@ dev = [
62
61
  "pytest-textual-snapshot>=1.1.0",
63
62
  "pytest-benchmark>=5.2.0",
64
63
  "sphinx-design>=0.6.1",
64
+ "pre-commit>=4.5.1",
65
+ "ty>=0.0.20",
65
66
  ]
66
67
 
67
68
  [tool.hatch.build.targets.wheel]
@@ -124,4 +125,7 @@ omit = [
124
125
  ignore_directives = ["tab-set", "dropdown", "automodule", "autoclass"]
125
126
 
126
127
  [tool.uv]
127
- exclude-newer = "1 week"
128
+ exclude-newer = "3d"
129
+
130
+ [tool.rumdl]
131
+ exclude = ["CHANGELOG.md"]
@@ -18,4 +18,4 @@ and backwards compatibility is not guaranteed for minor versions.
18
18
 
19
19
  __all__ = ["__version__"]
20
20
 
21
- __version__ = "8.1.4"
21
+ __version__ = "8.2.0"
@@ -0,0 +1,30 @@
1
+ """add case_active column to clients
2
+
3
+ Revision ID: 635a9d68fbe8
4
+ Revises: 4087c43f0c7c
5
+ Create Date: 2026-03-02 12:22:07.136023
6
+
7
+ """
8
+
9
+ from collections.abc import Sequence
10
+
11
+ import sqlalchemy as sa
12
+
13
+ from alembic import op
14
+
15
+ # revision identifiers, used by Alembic.
16
+ revision: str = "635a9d68fbe8"
17
+ down_revision: str | None = "4087c43f0c7c"
18
+ branch_labels: str | Sequence[str] | None = None
19
+ depends_on: str | Sequence[str] | None = None
20
+
21
+
22
+ def upgrade() -> None:
23
+ op.add_column(
24
+ "clients",
25
+ sa.Column("case_active", sa.Boolean(), nullable=False, server_default="1"),
26
+ )
27
+
28
+
29
+ def downgrade() -> None:
30
+ op.drop_column("clients", "case_active")
@@ -31,14 +31,22 @@ class ClientsManager:
31
31
  self.engine = create_engine(database_url, echo=False)
32
32
  self.Session = sessionmaker(bind=self.engine)
33
33
 
34
+ # Cache mapper and column metadata
35
+ self._mapper = inspect(clients_db.Client)
36
+ self._colmap = {
37
+ col.key: getattr(clients_db.Client, col.key) for col in self._mapper.columns
38
+ }
39
+ self._valid_keys = {c.key for c in self._mapper.column_attrs}
40
+
34
41
  logger.debug(f"created connection to database at {database_url}")
35
42
 
36
43
  def add_client(self, **client_data: Any) -> int:
37
44
  logger.debug("trying to add client")
38
45
  with self.Session() as session:
39
- new_client = clients_db.Client(**client_data)
40
- session.add(new_client)
41
- session.commit()
46
+ with session.begin():
47
+ new_client = clients_db.Client(**client_data)
48
+ session.add(new_client)
49
+ # Accessing client_id after commit (end of begin block)
42
50
  logger.info(f"added client: {new_client}")
43
51
  return new_client.client_id
44
52
 
@@ -48,9 +56,8 @@ class ClientsManager:
48
56
  client = session.get(clients_db.Client, client_id)
49
57
  if client is None:
50
58
  raise ClientNotFoundError(client_id)
51
- # Create a clean dictionary using the ORM mapper
52
- mapper = inspect(client.__class__)
53
- return {c.key: getattr(client, c.key) for c in mapper.column_attrs}
59
+ # Create a clean dictionary using the cached mapper
60
+ return {c.key: getattr(client, c.key) for c in self._mapper.column_attrs}
54
61
 
55
62
  def get_clients_overview(
56
63
  self,
@@ -78,18 +85,12 @@ class ClientsManager:
78
85
  "keyword_taet_encr",
79
86
  ]
80
87
 
81
- # Map ORM/DB keys to column expressions
82
- mapper = inspect(clients_db.Client)
83
- colmap = {
84
- col.key: getattr(clients_db.Client, col.key) for col in mapper.columns
85
- }
86
-
87
88
  extras = default_extras if columns is None else columns
88
89
 
89
90
  # Validate extras against available columns
90
- invalid = set(extras) - set(colmap.keys())
91
+ invalid = set(extras) - set(self._colmap.keys())
91
92
  if invalid:
92
- allowed = ", ".join(sorted(colmap.keys()))
93
+ allowed = ", ".join(sorted(self._colmap.keys()))
93
94
  raise ValueError(
94
95
  f"Invalid column names: {', '.join(sorted(invalid))}. "
95
96
  f"Allowed: {allowed}"
@@ -99,7 +100,7 @@ class ClientsManager:
99
100
  final_columns = list(dict.fromkeys(required_columns + extras))
100
101
 
101
102
  # Build SELECT
102
- selected_cols = [colmap[name].label(name) for name in final_columns]
103
+ selected_cols = [self._colmap[name].label(name) for name in final_columns]
103
104
  stmt = select(*selected_cols)
104
105
 
105
106
  # Optional filters
@@ -122,23 +123,27 @@ class ClientsManager:
122
123
 
123
124
  def get_all_clients_df(self) -> pd.DataFrame:
124
125
  """
125
- Get the entire database as a pandas DataFrame.
126
- Note: This returns DECRYPTED data.
126
+ Get the entire database as a pandas DataFrame via ORM to ensure decryption.
127
127
  """
128
- logger.debug("trying to query the entire database")
129
- stmt = select(clients_db.Client)
130
- return pd.read_sql_query(stmt, self.engine)
128
+ logger.debug("querying entire database via ORM")
129
+ with self.Session() as session:
130
+ stmt = select(clients_db.Client)
131
+ clients = session.scalars(stmt).all()
132
+ data = [
133
+ {c.key: getattr(client, c.key) for c in self._mapper.column_attrs}
134
+ for client in clients
135
+ ]
136
+ return pd.DataFrame(data)
131
137
 
132
138
  def edit_client(self, client_ids: list[int], new_data: dict[str, Any]) -> None:
133
139
  logger.debug(f"editing clients (ids = {client_ids})")
134
140
 
135
141
  # Validate keys
136
- valid_keys = {c.key for c in inspect(clients_db.Client).column_attrs}
137
- invalid_keys = set(new_data.keys()) - valid_keys
142
+ invalid_keys = set(new_data.keys()) - self._valid_keys
138
143
  if invalid_keys:
139
144
  raise ValueError(f"Invalid keys found: {', '.join(invalid_keys)}")
140
145
 
141
- with self.Session() as session:
146
+ with self.Session() as session, session.begin():
142
147
  stmt = select(clients_db.Client).where(
143
148
  clients_db.Client.client_id.in_(client_ids)
144
149
  )
@@ -160,12 +165,10 @@ class ClientsManager:
160
165
  setattr(client, key, value)
161
166
  client.datetime_lastmodified = datetime.now()
162
167
 
163
- session.commit()
164
-
165
168
  def delete_client(self, client_id: int) -> None:
166
- logger.debug("deleting client")
167
- with self.Session() as session:
169
+ logger.debug(f"deleting client {client_id}")
170
+ with self.Session() as session, session.begin():
168
171
  client = session.get(clients_db.Client, client_id)
169
- if client:
170
- session.delete(client)
171
- session.commit()
172
+ if not client:
173
+ raise ClientNotFoundError(client_id)
174
+ session.delete(client)