Metadata-Version: 2.5
Name: badgr
Version: 2.2.0.post0
Summary: AnteMotion attendance web app on top of ANVIZ CrossChex Standard
Project-URL: Repository, https://gitlab.antemotion.com/matteo.ragni/auto-badge
Author: AnteMotion SRL
License-Expression: MIT
License-File: LICENSE
Classifier: Framework :: Django :: 5.2
Classifier: Operating System :: Microsoft :: Windows
Classifier: Operating System :: POSIX :: Linux
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Requires-Python: <3.14,>=3.12
Requires-Dist: apscheduler<4,>=3.11
Requires-Dist: django<6,>=5.2
Requires-Dist: msal>=1.31
Requires-Dist: mssql-django>=1.6
Requires-Dist: openpyxl>=3.1
Requires-Dist: pyodbc>=5.2
Requires-Dist: waitress>=3.0
Requires-Dist: whitenoise>=6.12.0
Description-Content-Type: text/markdown

# BADGR

AnteMotion web attendance app on top of ANVIZ CrossChex Standard. It reads and writes the CrossChex SQL Server tables without changing their schema: Checks, Leaves, Planned Hours, Balances, reminders, Monthly and Annual Reports, Lock Date, Calendar Sync with Microsoft 365.

The full documentation (user guide, administration, specification, deployment, Microsoft 365, release, code reference) is built with Sphinx from [docs/source](docs/source) and published on GitLab Pages by the pipeline of `master`. Build it locally with `uv run --group docs make -C docs html` (output in `docs/build/html`).

- [Specification](docs/source/spec.md): what the app does
- [Glossary](GLOSSARY.md): domain vocabulary (Check, Leave, Balance, Issue, Lock Date, …)
- [ADR 0001](docs/adr/0001-app-data-in-userinfo-fields.md): why app data lives in `Userinfo` free-text fields
- [ADR 0002](docs/adr/0002-calendar-sync-app-permission-create-only.md): why Calendar Sync uses an application permission and only creates events
- [Deployment](docs/source/deployment.md): Windows service, SQL logins, nginx, test environment, cut-over
- [Backup and restore](docs/source/backup_restore.md)

Contents of this README: [Layout](#layout) · [Development](#development) · [Release and Microsoft 365](#release-and-microsoft-365) · [Useful commands](#useful-commands)

## Layout

```
badgr/                Django project (settings from .env, urls, wsgi, `badgr` command)
attendance/
  domain/             pure rules: days & Issues, Balances, Leaves, holidays, Lock Date, calendar events, formats
  services/           CrossChex access, reports, emails, Microsoft Graph, Calendar Sync
  views/              employee pages, auth, admin pages
  crosschex.py        unmanaged models on the CrossChex tables
  models.py           app-only data (SQLite)
  jobs.py             scheduler: reminders, Monthly Report, Lock Date move
  management/commands serve, run_job, set_password, dedupe_checks
tools/                dump_schema.py, clone_db.py
deploy/windows/       setup.ps1 (service, power, firewall, backup task)
docs/                 Sphinx documentation (source/) and ADRs (adr/)
tests/
.gitlab-ci.yml        test → build → publish
```

## Development

```sh
uv sync
uv run pytest
BADGR_ENV_FILE=.env.test SECRET_KEY=dev DEBUG=1 uv run python manage.py migrate
BADGR_ENV_FILE=.env.test SECRET_KEY=dev DEBUG=1 uv run python manage.py runserver
```

`.env.test` points to the `crosschex_test` clone (see [deployment §8](docs/source/deployment.md#8-test-environment)). On macOS the ODBC driver needs `DYLD_LIBRARY_PATH=/opt/homebrew/opt/openssl@3/lib`.

## Release and Microsoft 365

Step-by-step guides in the documentation: [Release](docs/source/release.md) (versioning, GitLab CI, package registry, upgrading the server, rollback) and [Microsoft 365 configuration](docs/source/microsoft_365.md) (Entra app, Calendar Sync permission, email delivery).

## Useful commands

| Command | Purpose |
|---|---|
| `manage.py serve --port 8000` | production server (waitress) + scheduler |
| `manage.py set_password <email> [--admin] [--invite]` | force a password / grant Admin / email a link |
| `manage.py run_job monthly_report [--today 2026-11-03]` | run a job now (`weekly_reminder`, `month_end_reminder`, `monthly_report`, `lock_advance`) |
| `manage.py dedupe_checks [--apply]` | remove duplicated Checks |
| `manage.py sendtestemail <address>` | test the email configuration |
| `tools/dump_schema.py -s SERVER -u USER -d DB` | read-only schema dump |
| `tools/clone_db.py -s SERVER -u USER` | copy production into `crosschex_test` |
| `manage.py backup_db [--no-sql]` | nightly backup (Task Scheduler / cron) |

On an installed package, `badgr <command>` replaces `manage.py <command>`. `dump_schema.py` and `clone_db.py` use pymssql: install it with `uv sync --group tools`.

## License

[MIT](LICENSE), © AnteMotion SRL. The AnteMotion name and logos are not covered by the license.
