Metadata-Version: 2.4
Name: marinerg_test_access
Version: 7.1.0
Summary: A web app for project access applications.
Author-email: Irish Centre for High End Computing <james.grogan@ichec.ie>
License: MIT
Project-URL: Repository, https://git.ichec.ie/marinerg-i/test-access-service
Project-URL: Homepage, https://git.ichec.ie/marinerg-i/test-access-service
Keywords: Web Application,Django
Classifier: Development Status :: 3 - Alpha
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.14
Classifier: Operating System :: OS Independent
Requires-Python: >=3.14
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: marinerg_facility==3.2.0
Requires-Dist: ichec_django_core[workflows]==6.1.0
Requires-Dist: django>=6.0
Requires-Dist: djangorestframework>=3.17
Requires-Dist: drf-spectacular
Requires-Dist: pydantic>=2
Requires-Dist: pyyaml
Requires-Dist: requests
Requires-Dist: python-keycloak
Requires-Dist: django-fsm-2
Requires-Dist: django-simple-history
Provides-Extra: container
Requires-Dist: psycopg2-binary; extra == "container"
Requires-Dist: gunicorn; extra == "container"
Provides-Extra: types
Requires-Dist: types-requests; extra == "types"
Requires-Dist: types-PyYAML; extra == "types"
Provides-Extra: async
Requires-Dist: celery>=5.3; extra == "async"
Requires-Dist: redis>=5.0; extra == "async"
Provides-Extra: keycloak
Requires-Dist: ichec_django_core[keycloak]==6.1.0; extra == "keycloak"
Dynamic: license-file

# Marinerg-i Test Access Service

This is the backend for the Marinerg-i Test Access Portal. Researchers apply
for time at marine renewable energy test facilities. A review board evaluates
each application, the board chair decides, and accepted applications lead to a
facility test report.

It is a Django app with a REST API, built for the
[Marinerg-i project](https://www.marinerg-i.eu). The Angular frontend is in
[`marinerg-i/frontend`](https://git.ichec.ie/marinerg-i/frontend). Run it
separately and point it at this backend.

## Try it locally

Read `infra/quick_start.sh`, then run it:

```sh
./infra/quick_start.sh
```

It creates a virtual environment, installs the dependencies, sets up a local
database with an admin user, and starts the server. Browse to
[localhost:8000/api](http://localhost:8000/api).

## Develop

The app reads its settings from the environment. `infra/dev.txt` has working
values for local development. Keep real deployment settings out of the repo.

```sh
uv sync --group dev
source infra/set_dev_environment.sh
uv run python manage.py migrate
uv run python manage.py sync_roles
uv run python manage.py runserver
```

If the server says the secret key is missing, the settings didn't load into
your shell.

`uv run tox` runs every check CI runs: format, lint, types, the tests, the
Celery tests, the schema check and the e2e collection. After you change a model
or serializer, regenerate the schema and client, and commit them:

```sh
uv run python manage.py generate_client marinerg_test_access.client
```

After you change an access policy, rewrite the deployed sweep's declaration:

```sh
WRITE_DECLARATION=1 uv run pytest tests/test_policies.py
```

## PDF summaries

Each submitted application gets a PDF summary, built by
[Gotenberg](https://gotenberg.dev). Without Gotenberg the summary is a zip of
the HTML and the attachments instead, so you don't need it for most work. The
tests in `tests/integration/` need it and are skipped without it.

To run Gotenberg locally and include those tests:

```sh
podman run -d --rm -p 3000:3000 gotenberg/gotenberg:8.34.0
GOTENBERG_URL=http://localhost:3000 uv run python runtests.py
```

These settings control it:

| Variable | Default | Purpose |
|---|---|---|
| `GOTENBERG_URL` | unset | The Gotenberg service. Unset gives a zip instead of a PDF. |
| `GOTENBERG_TIMEOUT_SECONDS` | `120` | How long to wait for one conversion. |
| `GOTENBERG_RETRY_ATTEMPTS` | `3` | Attempts per request, including the first. |
| `GOTENBERG_RETRY_BACKOFF_MS` | `500` | Delay before the first retry. It doubles each time. |

Gotenberg runs all requests through one Chromium process. When that process
restarts, every request in progress fails with a 500, which is why the client
retries.

## The review flow

Each call runs its applications through a review flow, from ichec-django-core's
workflows app. [`flows/access_review.yaml`](src/marinerg_test_access/flows/access_review.yaml)
is the template. Every migrate loads it, and each new call gets its own copy:

1. Facility review. Each facility the applicant chose confirms it discussed
   the application. The step ends when the call closes.
2. Board review. Each board member reviews.
3. Decision. The chair accepts or rejects.
4. Test report. After acceptance, the chosen facility reports on the test.

Reviews, decisions and reports are tasks at `/api/tasks/`, and their answers
are forms at `/api/populated_forms/`. Each assignee gets a notification.

Until a call opens, its coordinator can change its copy at `/api/steps/`, such
as to drop the facility review, to have one review suffice, or to pick the
reviewers instead of assigning the whole board. They set each step's template
file at `/api/forms/`.

Some things are left to people:

- A call closes at `closes_at`. The coordinator or chair can reopen it with a
  new date.
- The coordinator or chair can reopen one application with `reopen`, to let the
  applicant change or submit it after the close.
- When a board member declines, the chair either assigns someone else, or runs
  `proceed` to move on with the reviews in hand.
- With several facilities on an application, the chair sets `chosen_facility`
  before accepting.
- An admin corrects an application's place with `move`, such as after a mistaken
  withdrawal.

`available_actions` on each resource lists what the caller may do now. Each
model's `Access` policy says who may do what, and `tests/test_policies.py`
holds each policy in words.

## Release

Each pipeline on `main` has `release patch`, `release minor` and
`release major` buttons. Press one to publish that release. Then pin the new
version in `marinerg-deploy` and release its image. The deployment runs
`migrate` and `sync_roles`.

## Licence

Copyright of the Irish Centre for High End Computing (ICHEC), released under the
MIT Licence. See [`LICENSE`](LICENSE).
