---
title: Project structure
---
classDiagram
direction TB
namespace server {
class src
class web
class ui
class operation
class service
class model
class data
class common
}
integration ..> client
client ..> operation
integration ..> data
web ..> operation
web ..> service
ui ..> service
service ..> data
operation ..> model
model ..> common
data ..> common
service ..> model
src ..> web
src ..> ui
Note: client can only access operation, model, common. No business code
Note: integration can only access client (with everything mentioned above) and data. No business code
Download sdkman to manage java and gradle versions.
git clone git@github.com:BSStudio/bss-web-admin-backend.git
cd bss-web-admin-backend
sdk env install./gradlew spotlessCheck./gradlew spotlessApply./gradlew testdocker compose up -d
./gradlew integrationTest
docker compose downDocker:
docker build -t bss-web-admin-backend .Gradle:
./gradlew buildDocker:
docker run bss-web-admin-backendDocker compose:
docker compose upThis will start the app, database, and 3rd party mocks.
If you want to look at metrics
# Set your git not to commit changes to the default Grafana config
git update-index --skip-worktree docker/grafana/grafana.db
docker compose -profile metrics up
# If you want to commit changes to the default Grafana config
git update-index --no-skip-worktree docker/grafana/grafana.db
git add docker/grafana/grafana.db
git commit -m "Update Grafana config"
# Ignore logs again
git update-index --skip-worktree docker/grafana/grafana.dbGradle:
./gradlew bootRunThe mock-oidc WireMock fakes the API's token check, and it also fakes an OAuth2 login for browser logins
(the admin UI). Its stubs in docker/wiremock/stubs/oidc/login.json give it a login form where any username logs
in. They load every time mock-oidc starts; they cost nothing when unused, and keeping them there needs no extra
compose configuration. The login is plain OAuth2 (scope profile), because the mock has no ID tokens to sign.
| Stub | Does |
|---|---|
GET /login/authorize |
Shows the login form, carrying the app's redirect_uri and state along |
GET /login/approve |
Redirects back to the app with the typed username as the authorization code |
POST /login/token |
Returns the code (the username) as the access token |
GET /login/userinfo |
Returns the token (the username) as sub, preferred_username and name |
Nothing is checked and there is no password, so this is for local use only.
Please read the documentation for each module to understand the codebase.