Member & subscription management system for our cooperative WirGarten Lüneburg e.G.
  • Python 73.3%
  • TypeScript 17.7%
  • HTML 4%
  • CSS 3.2%
  • FreeMarker 0.9%
  • Other 0.8%
Find a file
2026-06-15 17:04:49 +02:00
.github/workflows chore: updated github action pnpm/action-setup to v6 because the runner was giving a deprecation warning. 2026-06-08 13:15:36 +02:00
.vite/deps Merge branch 'refs/heads/biotop-dev' 2026-04-01 16:48:21 +02:00
docker/keycloak chore: removed unused nginx files. Added all django migrations to files excluded by SonarQube. Misc recommendations from SonarQube implemented. 2026-04-01 17:46:37 +02:00
scripts dev: added --remove-orphans to the script that resets dev contains. 2026-04-24 09:07:52 +02:00
src_frontend feat: #986 don't show association memberships in the Step3ProductTypesChoice.tsx 2026-06-15 17:04:49 +02:00
tapir feat: #986 don't show association memberships in the Step3ProductTypesChoice.tsx 2026-06-15 17:04:49 +02:00
.gitattributes Use hash to avoid changes in generated API classes and auto-format generated files with prettier (#1077) 2026-04-08 10:45:42 +02:00
.gitignore feat: US 4.3.: Konfiguration der Mitgliedsnummer (#1084) 2026-04-28 11:03:53 +02:00
.pre-commit-config.yaml chore: updated python packages, removed a few unused packages. 2026-05-22 10:40:57 +02:00
.prettierrc.json misc: Added a prettier plugin so that it also organizes imports (#1079) 2026-04-08 11:49:47 +02:00
.schema.hash feat: #986 don't show association memberships in the Step3ProductTypesChoice.tsx 2026-06-15 17:04:49 +02:00
.sonarcloud.properties Added a config file for SonarCloud. 2022-02-21 19:59:10 +01:00
CONTRIBUTING.md #5: Require Pipeline before PR Merge (#8) 2022-09-21 12:26:11 +02:00
docker-compose.yml dev: use a solo pool for celery like the prod containers. 2026-04-15 16:32:21 +02:00
Dockerfile Revert "chore: updated the dockerfile so that dev dependencies are not installed on prod images." 2026-04-14 09:35:05 +02:00
LICENSE Added LICENSE file (AGPLv3) 2025-07-31 16:52:23 +02:00
Makefile tests: Keycloak is now mocked on all integration tests. (#1064) 2026-04-02 09:51:00 +02:00
manage.py misc: fixed black formatting for new version 2026-01-27 12:28:38 +01:00
models.png chore: updated the model graph. 2026-04-10 09:54:01 +02:00
openapitools.json Added a Vite docker container that runs NPM and vite. Configured vite to allow React in django templates. 2025-03-06 10:56:09 +01:00
package.json chore: switched from vitejs/plugin-react-swc to vitejs/plugin-react as recommended in the vite doc. 2026-05-11 18:07:54 +02:00
pnpm-lock.yaml chore: switched from vitejs/plugin-react-swc to vitejs/plugin-react as recommended in the vite doc. 2026-05-11 18:07:54 +02:00
pnpm-workspace.yaml fix: #1189 vite container could not build because build scripts were not allowed. 2026-05-11 12:34:32 +02:00
poetry.lock infra#69 wunsch hinterlegung von vorname und nachname bei zusaetzlichen mailadressen (#1198) 2026-06-11 18:37:30 +02:00
pyproject.toml infra#69 wunsch hinterlegung von vorname und nachname bei zusaetzlichen mailadressen (#1198) 2026-06-11 18:37:30 +02:00
README.md Fixed typo in README.md 2026-05-13 10:09:26 +02:00
schema.yml feat: #986 don't show association memberships in the Step3ProductTypesChoice.tsx 2026-06-15 17:04:49 +02:00
sonar-project.properties fix: infra#87, fix payments after updating solidarity contributions 2026-06-10 16:10:55 +02:00
tsconfig.app.json feat: in the bestellwizard, product types with only 2 products are shown on the same page instead of inside a carousel 2026-01-07 13:23:26 +01:00
tsconfig.app.tsbuildinfo fix: infra#113, Clicking on "Bestellung anpassen" from the order wizard overlay would lead to an empty page if the product type was not selected. 2026-06-15 16:11:45 +02:00
tsconfig.json feat: in the bestellwizard, product types with only 2 products are shown on the same page instead of inside a carousel 2026-01-07 13:23:26 +01:00
tsconfig.node.json US 5.8 #742: More modern ts version in tsconfig. 2025-12-19 16:49:35 +01:00
tsconfig.node.tsbuildinfo feat: #1112, added a summary step to the bestell wizard single product type from the member profile, always show the banking data step in that wizard, show the cancellation policy in that wizard. 2026-04-24 13:16:29 +02:00
vite.config.ts fix: missing entry in vite config for the new payment transactions UI. 2026-06-08 15:16:24 +02:00
vite.Dockerfile fix: #1189 vite container could not build because build scripts were not allowed. 2026-05-11 12:34:32 +02:00

Tapir

Python code test coverage

Tapir is a management system for community supported agriculture. It is currently used productively by several organizations, including WirGarten Lüneburg eG, Möllers Morgen, Gemüsekollektiv Hebenshausen e.V., and more.

Its features include:

  • Member & membership management including cooperative shares
  • Contract management: yearly commitment, weekly deliveries, solidarity contributions, renewal...
  • Communication with the members with customizable automated mails
  • Delivery locations and capacity management
  • And more

The development is lead mainly by Théo for FoodCoopX.

The backend code is written with Python and Django, the frontend code is a mix of Django templates and React.

Don't hesitate to contact us if you are interested in using or contributing to Tapir.

Getting started

Use docker to quickly get a development server running on your machine. Run the following commands:

docker compose up -d
# Create tables
docker compose exec web poetry run python manage.py migrate
# Define the configuration parameters
docker compose exec web poetry run python manage.py parameter_definitions    
# Generate test data
docker compose exec web poetry run python manage.py populate --reset_all

You should now have a local instance accessible at http://localhost:8000/. You can log in as admin with username roberto.cortes@example.com and password roberto.cortes.

You can log in as any user using the same pattern: [name]@example.come as username and [name] as password

Contributing & GitHub issues

You are very welcome to try Tapir locally with the "Getting started" instructions above and do your own thing. The current documentation being basically just this README, you may need extra guidance to get started. Don't hesitate to contact us so that we can give you an introduction.

If you're looking for something to work on, filter the issues using the Ready to be worked on label. Those issues should have a good enough description to get you started. Don't hesitate to ask more questions on the issue directly if needed. If you do, also assign either Theo (for technical questions) or Marcus (for requirements questions) to the issue, so that they know they have to react. They'll assign the issue back to you when the answer is there.

You're of course free to check the other issues and ask questions about them, but be aware that they may not make sense if you're not involved in the daily Tapir-development life. We don't have an internal tool to track tasks yet, so we use the GitHub issues as our todo-list. Hopefully the labels will be enough to let you sort through the mess.

Tests

Tests are run with pytest:

docker compose exec web poetry run pytest --reuse-db -n auto

If you run into troubles while running the tests, try running them without --reuse-db -n auto.

You can run unit tests outside the Docker container with just by simple running pytest, assuming you have the poetry environment installed and activated. That should be a bit faster. Integration tests must be run from inside Docker.

Keycloak during tests

User authentication is handled by keycloak through django-allauth. During integration tests, this connection is mocked via tapir.wirgarten.tests.test_utils.mock_keycloak, called in TapirIntegrationTest. The mocking happen during setUp and setUpTestData happens before setUp, that means we can't create users inside setUpTestData.

Formatting

Python files are formatted with Black.

JavaScript and React files are formatted with Prettier.

Django template files are formatted with DjHTML

Install the pre-commit hooks to make sure that the files you commit are properly formatted: poetry run pre-commit install. It should be possible to configure your IDE of choice to run the formatting automatically on save, at least for Black and Prettier. Look in their respective documentation.

Frontend API clients

API Requests made from the React frontend use API clients. Here are the steps to get updated API clients:

  • Annotate your API view with Spectacular (search for @extend_schema( for examples)
  • Generate the API schema file with python ./manage.py spectacular --file schema.yml
  • Generate the TypeScript API clients using OpenAPI Generator with ./scripts/generate_api_clients.sh

There are help scripts in the /scripts folder. You can do a full update with the following command:

docker compose exec web ./scripts/generate_api_schema.sh && docker compose exec vite ./scripts/generate_api_clients.sh

Style and conventions

Models

Models should inherit from tapir.core.models.TapirModel:

  • It uses nanoid instead of integer IDs, that makes sure we never use an ID from a model when getting another model, for example in tests.
  • It has created_at and updated_at fields that help unterstand the state of production databases.

As much as possible, model classes should contain only their own fields. Helper methods are OK if they only reference the fields of the given object.

Cache

Many functions, especially service functions, take a cache parameter which is a normal python dictionary. The goal of this cache is to avoid redundant database requests within one http request: in most of our views, DB requests are the most time-consuming part. The cache dictionary should be created at the origin point: for example in the view's __init__ function or the first lines or the command. Since this cache only lives for the duration of the request, in most cases it is not necessary to invalidate it. If you do need to invalidate, look at tapir.utils.services.tapir_cache_manager.TapirCacheManager Some functions have the cache parameter optional. This is only because they are called in legacy code, all new functions should have the cache parameter required if possible. For examples, see usages of tapir.utils.services.tapir_cache.TapirCache.

Service classes

Most of the business logic code should be in service classes. You can find examples in tapir/*/services/.

Commits

Use conventional commits for your commit messages. When applicable, add the ID of the related GitHub issue in the commit message.

Legacy code

Everything that is under tapir/wirgarten should be considered legacy code. It doesn't respect the conventions above. If you need to change anything in there, consider rewriting the part that you are changing and moving it to one of the other apps.

Class diagram

models.png

If this graph is outdated, you can re-generate it with:

docker compose exec web sh -c "apt update && apt install -y graphviz graphviz-dev && poetry run pip install pygraphviz && poetry run python manage.py graph_models -a -g -o models.png"

The other Tapir

This Tapir started as a fork of another project: Tapir for cooperative supermarkets. They are now completely separate but have kept the same name. Sorry for the confusion!