Backend (Spring Boot):
Backend (NestJS):
Frontend (Angular):
Frontend (Next.js):
A hands-on project demonstrating full-stack development skills, originally built as a home assignment and later expanded.
This app manages content trees. You can add, delete, edit tree nodes and their contents, move nodes to another parent, as well as search nodes by name or content.
The repository holds four applications: two backends (Spring Boot and NestJS) and two frontends (Angular and Next.js).
The frontends and backends are deployed as two independent stacks (each with its own database), mapped as follows, with published ports indicated where applicable:
flowchart LR
subgraph Frontends["Frontends"]
FE1["Angular<br/>:8080 (nginx)<br/>:4200 (dev)"]
FE2["Next.js<br/>:3000"]
end
subgraph Backends["Backends"]
BE1["Spring Boot<br/>:8081"]
BE2["NestJS<br/>:3001"]
end
subgraph Databases["Databases"]
DB1["PostgreSQL<br/>:5432 (dev only)"]
DB2["PostgreSQL<br/>:5432 (dev only)"]
end
FE1 -->|"API calls"| BE1
FE2 -->|"API calls"| BE2
BE1 -->|"queries"| DB1
BE2 -->|"queries"| DB2
Configurable backend targets per frontend are planned but not yet implemented.
| Main Dependencies | Quality & Testing | |
|---|---|---|
| Backend (Spring Boot) |
|
|
| Backend (NestJS) |
|
|
| Frontend (Angular) |
|
|
| Frontend (Next.js) |
|
|
| Common |
|
|
- Backend (Spring Boot):
- Java Development Kit 25 or later
- Docker and Docker Compose
- (Optional) GNG (provides the
gwcommand)
- Backend (NestJS) and Frontend (Angular and Next.js):
You can install Java and Node.js using a version manager of your choice. This project was developed with jenv and nvs.
The Spring Boot backend (when using the dev profile), the NestJS backend, and the integration
tests automatically pull the PostgreSQL database image. To enable this, ensure that you are logged
in to
the Docker Hardened Images distribution registry:
docker login dhi.ioNavigate to the contenttree-backend-springboot folder and start the Spring Boot application. This
command also triggers Docker Compose to start the PostgreSQL database defined in compose.yaml.
cd contenttree-backend-springboot
gw bootRunThe bootRun task defaults to the dev profile if no other profile is explicitly set via
environment variable (SPRING_PROFILES_ACTIVE) or command-line arguments
(--spring.profiles.active=prod). You can override this default in your IDE's Run Configuration.
Once the backend is running, the API documentation is available at
http://localhost:8081/swagger-ui.html. The Actuator can be
accessed at http://localhost:8082/actuator/<endpoint>, e.g.,
http://localhost:8082/actuator/health.
If you do not have IntelliJ IDEA Ultimate edition and you need a database manager tool, you can view
and manage the contenttree database content via the DbGate UI
at http://localhost:5433/ after running the bootRun task the following
way:
cd contenttree-backend-springboot
gw bootRun --args='--spring.docker.compose.profiles.active=debug'Navigate to the contenttree-backend-nestjs folder and start the NestJS application. This command
also triggers Docker Compose to start the PostgreSQL database defined in compose.yaml.
cd contenttree-backend-nestjs
npm startOnce the backend is running, the API documentation is available at http://localhost:3000/api.
If you need a database manager tool, you can view and manage the contenttree database content via
the DbGate UI at http://localhost:5433/ after running the backend the
following way:
cd contenttree-backend-nestjs
COMPOSE_PROFILES=debug npm startNavigate to the contenttree-frontend-angular folder and start the Angular development server.
cd contenttree-frontend-angular
npm ci
npm startThis runs the development web server. Once the frontend is running, the application will be available at http://localhost:4200/tree.
Navigate to the contenttree-frontend-nextjs folder and start the Next.js development server.
cd contenttree-frontend-nextjs
npm ci
npm startNote
In this project, npm start is alias for npm run dev, matching the Angular & NestJS stacks,
and because a standalone output is built for Docker.
This runs the development web server. Once the frontend is running, the application will be available at http://localhost:3000/tree.
For test users with different roles, see the following files:
- Backend (Spring Boot):
002_test-data.sql - Backend (NestJS):
002_test-data.ts
The passwords for these users were generated using BCrypt:
- Backend (Spring Boot):
BCryptPasswordEncoder - Backend (NestJS): bcrypt
To test the application in a production-like deployment, it is possible to create a deployment on the local machine by executing the following commands:
(cd contenttree-backend-springboot && gw bootBuildImage)
(cd contenttree-backend-nestjs && npm run build:docker)
(cd contenttree-frontend-angular && npm run build:docker)
(cd contenttree-frontend-nextjs && npm run build:docker)
(cd contenttree-deploy && docker compose up)The files in contenttree-deploy/etc contain default credentials for local development convenience
only.
Execute backend tests (including integration tests) using Gradle:
cd contenttree-backend-springboot
gw checkThe check task depends on the integrationTest suite.
Execute unit and integration tests using npm:
cd contenttree-backend-nestjs
npm test
npm run test:intExecute unit and integration tests using npm:
cd contenttree-frontend-angular
npm testComponent tests are executed separately because they require a browser (this project uses Chromium):
cd contenttree-frontend-angular
npm run install:chromium
npm run test:ctExecute unit and integration tests using npm:
cd contenttree-frontend-nextjs
npm testComponent tests are executed separately because they require a browser (this project uses Chromium):
cd contenttree-frontend-nextjs
npm run install:chromium
npm run test:ctTo run E2E tests, be sure that you have executed the aforementioned production-like deployment.
cd contenttree-deploy/e2e
npm ci
npm run install:chromium
npm testNote
This repository serves as a demonstration of my skills and a personal learning exercise. It is not set up to accept external contributions. The following guidelines are provided for informational purposes only.
The following IDEs are recommended for use:
- Backend (Spring Boot):
- IntelliJ IDEA (with or without the Ultimate subscription)
- Backend (NestJS), Frontend (Angular & Next.js):
You can change dependencies (e.g., update dependency versions) by running the following commands:
cd contenttree-backend-springboot
gw build --write-verification-metadata pgp,sha256 --export-keys --write-locks
git diff gradle/verification-*Then review the changes in the verification metadata and the lock file. Once done, update the
origin and reason fields of trusted-keys and checksums with your own verification info, and
delete unused versions in verification-metadata.xml.
To generate TypeScript types, run the following commands:
(cd contenttree-backend-springboot && gw generateOpenApiDocs)
(cd contenttree-frontend-angular && npm run generate:openapi)
(cd contenttree-backend-nestjs && npm run generate:openapi)
(cd contenttree-frontend-nextjs && npm run generate:openapi)
(cd contenttree-deploy/e2e && npm run generate:openapi)Note: generateOpenApiDocs is a standalone task because it is incompatible with Gradle's
configuration cache.
In this project, I strive not to rely on LLMs heavily. I intend to write code that I understand as
much as possible, reducing the chance of introducing technical debts and security vulnerabilities
unknowingly. I have also had relatively bad experience with using LLMs for code generation so far
(e.g., outdated knowledge, context window limitations, etc.). For this reason, this project no
longer uses AGENT.md and related files.