Skip to content
Back to the galaxy

Case study · 2026

Completed

Avelon Crypto

A crypto portfolio tracker with one Spring Boot 3 backend and two front ends — a server-rendered Thymeleaf app and a Vue 3 single-page app — secured with sessions and JWT.

Role
Full-stack development · University project
Year
2026
Stack
Spring Boot 3, Spring Security + JWT, Thymeleaf, Vue 3 + Pinia, PostgreSQL / H2, Docker
Avelon Crypto — Portfolio dashboard

01

Project Overview

Avelon Crypto is a crypto portfolio tracker built as a university full-stack project. One Spring Boot 3 backend serves two complete front ends: a server-rendered Thymeleaf web app with form login, and a REST API with JWT consumed by a separate Vue 3 single-page app. Users browse a coin catalogue, build portfolios and follow their profit and loss; administrators manage coins, categories and users.

02

Problem

The brief asked for two different architectures — a classic server-rendered app and a token-based API for a modern front end — with real authentication, role-based access, validation, database migrations and Docker. Building them as two separate projects would duplicate every entity, rule and query.

03

Solution

One shared domain, service and repository layer with two security filter chains on top: a stateless JWT chain for /api/** and a session-based form-login chain for the Thymeleaf app. Both front ends run on the same business rules, so every permission and validation lives in exactly one place.

04

My Role

Full-stack development · University project

  • Domain model and relational schema with versioned Flyway migrations
  • Spring Security with two filter chains: JWT for the API, form login for the web app
  • REST API with centralised error handling and per-user ownership checks
  • Thymeleaf app with layouts, fragments, validation and an AJAX live filter
  • Vue 3 single-page app with Pinia stores, protected routes and axios interceptors
  • Integration tests and a Docker Compose setup with PostgreSQL

05

Tech Stack

  • Spring Boot 3
  • Spring Security + JWT
  • Thymeleaf
  • Vue 3 + Pinia
  • PostgreSQL / H2
  • Docker

Connected planets

06

Key Features

  • 01

    Two front ends, one backend

    Thymeleaf pages and a Vue 3 SPA share the same entities, services and repositories — separated only at the security layer.

  • 02

    Roles and ownership

    USER and ADMIN rules on every URL, @PreAuthorize on service methods, and ownership checks so users only ever see their own portfolios.

  • 03

    Portfolio analytics

    Value, cost basis, profit and loss and allocation for every portfolio, plus market movers and the top 24-hour gainer.

  • 04

    Dynamic search

    Catalogue filtering across five criteria built with JPA Specifications, and a live filter over AJAX in the Thymeleaf app.

  • 05

    Custom validation

    Repository-backed @UniqueSymbol and @ValidTicker validators, with field-level errors shown in both Thymeleaf forms and the Vue app.

  • 06

    Admin panel

    Manage users, roles and account status, review every portfolio, and maintain the coin catalogue and its categories.

07

Screenshots

Avelon Crypto — Market catalogue
Market catalogueThe Vue app's catalogue with market stats, search, sorting and an active-only filter.
Avelon Crypto — Portfolio detail
Portfolio detailHoldings with buy price, current value and profit or loss, next to the allocation breakdown.
Avelon Crypto — Admin panel
Admin panelOnly administrators reach this view: user roles, account status and every portfolio on the platform.
Avelon Crypto — Server-rendered catalogue
Server-rendered catalogueThe same data in the Thymeleaf app — full CRUD, five-criteria search and role-gated actions, rendered on the server.

08

Challenges

  1. 01

    Sessions and tokens in one app

    A stateless JWT API and a session-based login cannot share a filter chain. Two ordered chains solve it — with /api/ui/** carved out so the Thymeleaf page's AJAX calls use the browser session.

  2. 02

    Keeping the schema honest

    Hibernate only validates; every table and change comes from versioned Flyway migrations, including one that alters an existing table.

  3. 03

    One error shape everywhere

    A global exception handler, the JWT entry point and the access-denied handler all return the same JSON, so the Vue app shows field-level messages consistently.

09

What I Learned

  • How Spring Security's filter chains decide who gets in — and in which order.
  • Why schema changes belong in versioned migrations, not in auto-generated DDL.
  • How to design one domain layer that serves two very different clients.
  • Security rules deserve integration tests, not just manual clicking.

10

Result

A complete, tested full-stack application: integration tests cover authentication, role-based access and portfolio ownership, and the whole stack starts with a single Docker Compose command.

Integration tests
15
Front ends
2
Security chains
2

Next mission

Chrome Hearts Concept

An e-commerce concept for the luxury brand Chrome Hearts — five desktop pages and a clickable Figma prototype with hover states and a colour-shifting best-seller carousel. Unofficial, not affiliated with the brand.

Read case study
Chrome Hearts Concept — Home page