PlatePal

A cookbook and recipe management app — Spring Boot backend, React Native frontend, full CI/CD, and a deeply normalised recipe database schema.

PlatePal

PlatePal is a dream project of mine that I turned into a university ICW (Independent Coursework) during my Master’s. The idea is simple: I have never found a cookbook app I actually like. They’re either missing features I care about, bury everything behind a paywall, or both. So I decided to build one myself — starting with a solid foundation and MVP scope I could complete in a semester.

The goal for this first phase was to build a mobile recipe database application and a backend REST API to support it, with proper security, a production deployment, and a fully automated CI/CD pipeline.

The full development process is documented in a five-part devlog on my blog .

Architecture

The backend is a Spring Boot 3 / Java 17 application exposing a secured REST API, backed by a PostgreSQL database managed with Liquibase migrations. The frontend is a React Native app with both Android and web targets.

The architecture follows a layered Spring Boot pattern — controllers → services → JPA repositories — with all data exchange happening through dedicated DTOs mapped by Mapstruct. Entities never leave the persistence layer. The user/auth concern is partially separated from the recipe API, laying groundwork for a microservice split later.

What was built

CI/CD & Deployment

One of the first things I tackled was automating the deployment pipeline. The backend runs as a Docker Compose stack on a Debian VPS — a Spring Boot container alongside a PostgreSQL container, communicating by container name, with secrets stored in a secured file outside the image. A GitHub Actions workflow triggers on every push to main: it SSH-connects to the VPS, pulls changes, rebuilds with Maven, and re-deploys the containers. Tests run in CI against an embedded H2 database.

Security

The REST API is protected with Spring Security + JWT. I implemented UserDetailsManager myself rather than relying on the rigid built-in JdbcUserDetailsManager, which gave me full control over the account schema. The migration from my previous Spring Boot 2 JWT setup to Spring Boot 3 involved updating deprecated security configuration patterns and the javaxjakarta package rename.

Recipe Database Schema

The most involved part of the project was designing the recipe data model. After researching existing recipe schemas — including schema.org/Recipe — I landed on a fully normalised PostgreSQL schema with separate tables for ingredients, units, tags, steps, notes, and ingredient lists. Custom unit_type enum types, composite primary keys with @IdClass, and careful cascade configuration across @OneToMany / @ManyToMany relationships were all part of the final design.

I also consulted with a UX designer friend, Sabine Freese , who created wireframes for the mobile frontend on the basis of the planned feature set.

Recipe REST API

With the schema in place, I built the full CRUD API for recipes and collections. Entity classes were generated from the live database using JPA Buddy — saving several hundred lines of boilerplate — and then manually reviewed and corrected. The trickiest part was handling deeply nested entities on creation: a single recipe create request touches six or seven tables. CascadeType.ALL on parent-side relationships handles the persistence, while @AfterMapping hooks in the Mapstruct mapper ensure child entities are correctly linked back to their parent before saving.

Project Proposal

The full scope, backlog breakdown, architecture diagram, and work programme from the original university proposal are available here:

Read the Project Proposal →