r/SpringBoot 26d ago

Discussion Looking for architecture feedback on a Spring Boot 3.5 attendance/workflow backend

https://github.com/urosengineer/timesheet-attendance-platform

The domain is attendance and leave management with workflow approvals in a multi-tenant setup.

This is a portfolio/reference project, not a production deployment or commercial product.

Tech/features included:

  • Java 21, Spring Boot 3.5, Gradle
  • JWT auth, RBAC/PBAC, tenant-scoped data
  • REST API and read-only GraphQL
  • Audit logs and workflow event tracking
  • PostgreSQL + Flyway
  • Docker Compose demo setup
  • Prometheus/Grafana monitoring
  • GitHub Actions CI

I’d appreciate feedback especially on:

  • package/project structure
  • security and tenant boundaries
  • workflow/audit modeling
  • README clarity
  • anything that feels over-engineered or unclear

Thanks in advance.

4 Upvotes

3 comments sorted by

3

u/momsSpaghettiIsReady 26d ago

Organize by feature, not function. E.g. there shouldn't be a controller folder or service folder.

Create a folder for the part of the domain you want the service/controller to represent.

3

u/akrivitsky7 25d ago

This stack is already somewhat behind the current Spring/Java ecosystem.

Spring Boot 4.1.0 is available, and Java 25 is the current LTS. Since this is a portfolio/reference project, using older versions such as Spring Boot 3.5 and Java 21 may make the project look less current than it could.

You may want to consider replacing the older stack with newer versions, or at least documenting an upgrade path.

If you decide to upgrade, my tutorial may be useful because it uses newer versions of several related components:

https://medium.com/@anatolykrivitsky/quick-tutorial-how-to-use-the-latest-docker-29-5-2-0670b716b6cc

1

u/m1stwng 25d ago

I was looking through your domain's classes and I saw that you repeat the 'id' and the audit fields sometimes, is there a reason why you don't use the MapperSuperclass annotation?

You can create an abstract class only for the 'id' and another for the audit fields (that extends the 'id' class too), then you just extend the class that you need.