Teambalance allows groups of people that meet regularly (such as sports team) to plan their events' attendance, and have a shared wallet, or 'pot' in Dutch to pay for expenses around those events. go out together often to have a kind of shared wallet or 'pot' in Dutch. With everybody being able to chip in and see what transactions went out, it allows the bills to be paid from a single bank account.
As it is becoming more uncommon to use cash, and bars and clubs allow card payments more often, the need for a digital money pool is becoming more and more apparent.
Team balance started off a hobby project and technology explorer (see setup).
Tovo is a Utrecht based Volleybal club, consisting of many. The teams have a training on a weekly basis, and play a competion is a poule of 11, meaning they'll play 20 matches per year. What's more, there are some other (obligatory) events for the team to meet. During events (most notably the matches), members meet in the canteen of the sports hall before and after the match for some drinks.
As everybody in the team has a role, e.g. outside hitter, libero and setter. For each event, each position should be filled, and keeping track of attendance beforehand makes it easy to spot when substitutes from other teams are needed.
Oftentimes, canteen allow teams to have a tab, which they can pay at once afterwards. To not have one member having to pay the whole bill it would be nice to have a money pool everyone can contribute towards. As a cashless option is preferred, and payments are often done with a debit card (in the Netherlands), a dedicated bank account for the team would be a good way to solve it, if and only if all members would be able to send money at any point in time to the account, and, of course, there is a basis of trust towards the owner of said account.
(this list is probably never complete)
As far as I am aware, there are currently (2022) no solutions that offer both event planning / attendance tracking as well as money pool solutions.
The event and attendance planning aspect:
- Datumprikker
- Allows you to, in great detail plan (recursive) events and keep track of attendance.
- It does not seem to have grouping functionality (grouping members to a 'hitters' or 'keepers' pool or something)
- It does not seem to offer an API to allow it to be integrated into other solutions
- voetbal.nl
- Limited to, well, football
- more...
The money pool aspect:
- Paypal's money pools:
- More targeted towards reaching a certain goals (in terms of $), to be able to buy something.
- Tikkie
- Tikkie allows you to pay people upon request. Unfortunately there's no way of creating a money pool up front that allows to centralize spending. Decentralised spending is a nice, but different approach, teambalance doesn't aim for.
- Tikkie's concept of payment requests is used by teambalance. bunq.me is a similar concept where one can own a page a allow people to pay whatever they want, and include a message.
- more...
Team balance has 2 main functional parts:
- A money pool
- (calendar)Event creation and moderation
There is an integration available with Bunq, through their sdk_java
.
This shows everything you'd expect from a money pool:
- Current balance
- Transaction history
- most / least contributors to the money pool
They money pool is build an a basis of mutual trust, where there is a single bank account connected to the money pool, owned by one of the team members. All team member are expected to contribute fairly. There is no concept of keeping track of individual consumption
The Events api allows team members to register availability for upcoming events in three categories:
- trainings
- matches, and
- other, miscellaneous events
Through admin screen, events can be created, modified, deleted at any point in time.
Teambalance is composed of a Kotlin JVM backend, and a React frontend. Through REST APIs they are connected. The frontend includes an authentication flow as well to prevent nosy neighbours from peeking.
Backend app
- Spring boot
- Spring data (with JOOQ)
- Spring security
- Kotlin
Frontend application
- React
- Typescript
- Mui
Persistence
- PostgreSQL
Infra
- Jib, GCP container registry
- Google cloud run
Build everything
./mvnw clean install
To be able to run this locally there are two options:
- by using the 'dev' application profile, teambalance tries to fetch the properties from GCP, which are stored in GCP secret manager. One should make sure to be connected to gcloud, and having credentials for a service account for a service account
- by using the 'local' application profile, teambalances assumes one has a local postgres instance running, exposed on
port
54321
(note the trailing1
), with a database namedteambalance
- Hint:
docker compose up -d
- Hint:
⚠️ Attention Because of the multitenant setup of teambalance, it is necessary to access teambalance through a recognised domain. The ones that are set up are:
- 4.teambalance.local
- 5.teambalance.local
Make sure configure your local
/etc/hosts
file to map these domains to127.0.0.1
in order to work with teambalance locally. (Both port 3000 and 8080 work for the local setup)
Any commit to master, use the gcp workflow to build and push a docker image to GCR.
Through google cloud console, deployments can be managed
Teambalance makes use of a PostgreSQL database that sits in the cloud
Using JOOQ (used to be Spring data jpa )and Postgres dependency:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jooq</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
</dependencies>
Which is configured through the spring.datasource
config properties
spring:
datasource:
username: <username>
password: <password>
url: <jdbc-url>>
As with most projects, it's hardly ever considered finished.
Dec 2019 Ability to contribute to team balanceDec 2019 View latest contribution to team balanceJune 2020 Training overview including player availabilityAug 2020 Match overview including player availabilityAug 2020 Training admin screen (add/change/remove trainings)- Allow to remove trainings
Aug 2020 Match admin screen (add/change/remove matches)- Allow to remove trainings
Use polling mechanism when back-end is still down.- Handle back-end being down better in the front-end (500's should result in a 'whoops' screen?)
Aug 2020 Ensure training endpoint are also protected- Use 'proper' authentication mechanism.
- Decouple front-end and back-end to seperate deployables
Try google run
Jan 2020 Debounce was introduced to ensure every API call takes at least 500 ms (for UX purposes). This only works if a call is successful. Should also work for unsuccessful ones.October 2020 Github actions, used to deploy to Google cloud on every merge to masterApril 2020Stg env for testing purposes (use a different application version, but don't take all traffic ?)
Oct 2020 Availabilities and agenda for non training/match events (like team uitje)- Upload receipts and tie them to payments
- Stats on team balanc contributors
- Link to Nevobo site with competition
- Integration with Nevobo: Link to Nevobo team 'API': https://api.nevobo.nl/export/team/CKL7W0D/heren/1/programma.rss
- A setup that makes it reusable for different teams as well.
- Integration with CMS systems for customisation purposes
Let Intellij understand the shaded artifact from shaded-bunq-sdk.
Unfortunately, Intellij doesn't understand shaded artifacts (read up on it here)
A better workaround seems to be:
- Right-click on shade-bug-repackaged -> pom.xml in the project view in IntelliJ,
- choose "Maven" -> "Ignore Projects".
- Then do a "Maven" -> "Reload" on the top-level pom.xml. .