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.
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.pre-commit-config.yaml +15 -2
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/CHANGELOG.md +13 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/PKG-INFO +98 -26
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/README.md +97 -25
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/helpfunction.rst +1 -1
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/update.rst +6 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/pyproject.toml +7 -3
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/__version__.py +1 -1
- edupsyadmin-8.2.0/src/edupsyadmin/alembic/versions/2026_03_02_1222-635a9d68fbe8_add_case_active_column_to_clients.py +30 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/managers.py +33 -30
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/migrate_encryption.py +15 -2
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/db/clients.py +38 -33
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/clients_overview.py +16 -6
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edit_client.py +106 -29
- edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user0].svg +623 -0
- edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user1].svg +625 -0
- edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_new_client.svg +624 -0
- edupsyadmin-8.2.0/test/edupsyadmin/tui/__snapshots__/test_edupsyadmintui/test_edupsyadmintui_initial_layout.svg +228 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_editclient.py +35 -14
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_edupsyadmintui.py +1 -1
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/uv.lock +253 -205
- edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user0].svg +0 -587
- edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_existing_client[client_dict_set_by_user1].svg +0 -589
- edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_editclient/test_initial_layout_new_client.svg +0 -588
- edupsyadmin-8.1.4/test/edupsyadmin/tui/__snapshots__/test_edupsyadmintui/test_edupsyadmintui_initial_layout.svg +0 -162
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.github/workflows/publish.yml +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.gitignore +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.python-version +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/.readthedocs.yaml +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/LICENSE.txt +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/Makefile +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/_static/samplewebuntisfile.csv +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/clients_model.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/conf.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/faq.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/index.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/make.bat +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/requirements.txt +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/taetigkeitsbericht_keywords.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/cli.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/configuration.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/creatingdocumentation.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/editingclients.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/encryption.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/installation.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/taetigkeitsbericht.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/docs/tutorial/tui.rst +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/py.typed +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_iLst.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_iRst.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_lrst.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/add_nona_nons.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/change_keywordtaet_nsessions.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/profile.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/shellscripts/publish_to_testpypi.sh +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/__main__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/README +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/env.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/script.py.mako +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic/versions/2026_02_21_0453-4087c43f0c7c_initial_migration.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/alembic.ini +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/add_convenience_data.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/cft_report.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/display_client_details.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/fill_form.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/flatten_pdf.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/lgvt.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/migration.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/reports.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/setup_demo.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/api/taetigkeitsbericht_from_db.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/__main__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/create_documentation.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/delete_client.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/edit_config.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/flatten_pdfs.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/get_clients.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/info.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/mk_report.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/new_client.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/rotate_key.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/set_client.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/setup_demo.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/taetigkeitsbericht.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/commands/tui.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/cli/utils.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/config.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/encrypt.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/logger.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/core/paths.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/Faecher_BfsEV.md +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/Faecher_BfsKi.md +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/Faecher_Faks.md +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/sampleconfig.yml +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/data/taetigkeitsbericht_categories.csv +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/db/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/info.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/clients_overview_app.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/dialogs.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edit_client_app.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/editconfig.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/editconfig.tcss +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edupsyadmintui.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/edupsyadmintui.tcss +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/fill_form_app.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/tui/fill_form_widget.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/__init__.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/academic_year.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/convert_measures.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/datediff.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/int_from_str.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/path_utils.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/python_type.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/src/edupsyadmin/utils/taetigkeitsbericht_check_key.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/.gitignore +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_add_convenience_data.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_decryption_behavior.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_fill_form.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_flatten_pdf.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_managers.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_migration.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/api/test_taetigkeitsbericht_from_db.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/benchmark/test_cli_benchmark.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/benchmark/test_encrypt_benchmark.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/benchmark/test_key_derivation_benchmark.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/cli/test_utils.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/conftest.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/core/test_config.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/core/test_encrypt.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/core/test_logger.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/data/sample_form_anschreiben.pdf +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/data/sample_form_mantelbogen.pdf +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/sample_pdf_form.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/sample_webuntis_export.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/test_cli.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_clientsoverview/test_clients_overview.svg +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_dialogs/test_yes_no_dialog.svg +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_editconfig/test_add_new_school_container.svg +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_editconfig/test_edit_new_school_container.svg +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_editconfig/test_initial_layout.svg +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/__snapshots__/test_fill_form_tui/test_initial_layout.svg +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_clientsoverview.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_dialogs.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_editconfig.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/tui/test_fill_form_tui.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_academic_year.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_convert_measures.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_datediff.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_int_from_str.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_path_utils.py +0 -0
- {edupsyadmin-8.1.4 → edupsyadmin-8.2.0}/test/edupsyadmin/utils/test_python_type.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+

|
|
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
|
-
###
|
|
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
|
-
|
|
121
|
+
```text
|
|
122
|
+
edupsyadmin info
|
|
123
|
+
```
|
|
88
124
|
|
|
89
125
|
Add a client interactively:
|
|
90
126
|
|
|
91
|
-
|
|
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
|
-
|
|
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
|
-
|
|
139
|
+
```text
|
|
140
|
+
edupsyadmin set-client 42
|
|
141
|
+
```
|
|
100
142
|
|
|
101
|
-
Change values for the database entry with `client_id=42` from the
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
173
|
+
config.yml) for the database entry with `client_id=42`:
|
|
122
174
|
|
|
123
|
-
|
|
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
|
|
193
|
+
Create the development environment:
|
|
128
194
|
|
|
129
|
-
|
|
130
|
-
|
|
195
|
+
```text
|
|
196
|
+
uv v
|
|
197
|
+
uv pip install -e .
|
|
198
|
+
```
|
|
131
199
|
|
|
132
200
|
Run the test suite:
|
|
133
201
|
|
|
134
|
-
|
|
202
|
+
```text
|
|
203
|
+
.venv/bin/python -m pytest -v -n auto --cov=src test/
|
|
204
|
+
```
|
|
135
205
|
|
|
136
206
|
Build documentation:
|
|
137
207
|
|
|
138
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
+

|
|
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
|
-
###
|
|
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
|
-
|
|
90
|
+
```text
|
|
91
|
+
edupsyadmin info
|
|
92
|
+
```
|
|
57
93
|
|
|
58
94
|
Add a client interactively:
|
|
59
95
|
|
|
60
|
-
|
|
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
|
-
|
|
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
|
-
|
|
108
|
+
```text
|
|
109
|
+
edupsyadmin set-client 42
|
|
110
|
+
```
|
|
69
111
|
|
|
70
|
-
Change values for the database entry with `client_id=42` from the
|
|
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
|
-
|
|
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
|
-
|
|
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)
|
|
142
|
+
config.yml) for the database entry with `client_id=42`:
|
|
91
143
|
|
|
92
|
-
|
|
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
|
|
162
|
+
Create the development environment:
|
|
97
163
|
|
|
98
|
-
|
|
99
|
-
|
|
164
|
+
```text
|
|
165
|
+
uv v
|
|
166
|
+
uv pip install -e .
|
|
167
|
+
```
|
|
100
168
|
|
|
101
169
|
Run the test suite:
|
|
102
170
|
|
|
103
|
-
|
|
171
|
+
```text
|
|
172
|
+
.venv/bin/python -m pytest -v -n auto --cov=src test/
|
|
173
|
+
```
|
|
104
174
|
|
|
105
175
|
Build documentation:
|
|
106
176
|
|
|
107
|
-
|
|
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.
|
|
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 = "
|
|
128
|
+
exclude-newer = "3d"
|
|
129
|
+
|
|
130
|
+
[tool.rumdl]
|
|
131
|
+
exclude = ["CHANGELOG.md"]
|
|
@@ -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
|
-
|
|
40
|
-
|
|
41
|
-
|
|
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
|
|
52
|
-
|
|
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(
|
|
91
|
+
invalid = set(extras) - set(self._colmap.keys())
|
|
91
92
|
if invalid:
|
|
92
|
-
allowed = ", ".join(sorted(
|
|
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 = [
|
|
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("
|
|
129
|
-
|
|
130
|
-
|
|
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
|
-
|
|
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
|
-
|
|
171
|
-
|
|
172
|
+
if not client:
|
|
173
|
+
raise ClientNotFoundError(client_id)
|
|
174
|
+
session.delete(client)
|