Angular client and Spring Boot API for managing monthly expenses/income with a MySQL backend. Full-text search across incomes, expenses, and credit-card details is served by the Spring Boot API using MySQL FULLTEXT indexes (no separate search service).
-
Docker — used to run MySQL, the Spring Boot API, and the nginx-served client
-
Java 17 JDK — required to build the Spring Boot 4.x API
-
Node.js (current LTS) — required to build the AngularJS client
-
MySQL 8 — provided via the Docker container; required for the
FULLTEXTindexes that the API auto-creates on startup -
Make sure the user that will run docker is in the docker group. In this example, the username is
vmuser
sudo usermod vmuser -a -G dockercurl -fsSL https://deb.nodesource.com/setup_20.x | sudo -E bash -
sudo apt-get install -y nodejs- Test that mysql docker will work with
mysql/docker-mysql.sh- After making sure the container runs you can stop the container with
docker stop mysql- Run the export script
./mysql/db-backup.shbillDb.sql.gzwill be located in the directory abovebill-manager
-
Make sure
billDb.sql.gzis located in the directory abovebill-manager -
Run the restore script
./mysql/db-restore.sh- Inside the springboot-api directory, build a container with
./docker-build.sh- Verify the container runs with
./docker-springboot.shOn first startup against a populated database, the API creates three FULLTEXT indexes — on income.description, expense.name, and detail.description. Creation is idempotent; subsequent startups are no-ops.
- Use the following script to run locally against a mysql docker container
./local-run.shThe /search endpoint uses MySQL boolean-mode MATCH ... AGAINST. MySQL's default innodb_ft_min_token_size is 3, so single- and two-character search terms are ignored. If you need to search short vendor abbreviations (e.g. "TJ", "BJ"), lower that variable in MySQL config and rebuild the indexes.
Credit-card CSV parsing happens in the API at POST /detail/parse using Apache Commons CSV (handles RFC 4180 quoted fields with embedded newlines). The client uploads the file as multipart; no parsing logic runs in the browser. Sample Amex CSVs for manual testing live in springboot-api/test-data/.
- Build client project
npm install
npx bower install
npx grunt build- Build the nginx container from the client build output in
./client/dist
client/docker-build.sh- Make sure the client runs with
client/docker-nginx.sh- The application will be running on http://localhost
- Inside the
clientdirectory run
npx grunt serve- A livereload development server will be available at http://localhost:9000
- After configuring and verifying the containers run, use the following scripts to run and stop all the containers
./docker-run-all.sh
./docker-stop-all.sh