A lightweight, full-stack business management platform built with Spring Boot & PrimeFaces.
Customer Management System (CMS) is a self-hosted, multi-entity business management tool designed for small to medium organizations. It ships a ready-to-use web UI and a JSON REST API to manage clients, contacts, and custom analytics dashboards β all from a single deployable JAR.
Key capabilities:
- π Entity management β full CRUD for clients, persons, industries, types, and countries
- π Custom dashboards β define SQL-backed bar, horizontal-bar, and pie charts through the admin UI; no code changes required
- π Built-in authentication β Spring Security login with BCrypt-hashed passwords
- π Dual interface β every feature is accessible via both the PrimeFaces web UI and the REST API simultaneously
- π€ Data export β one-click XLS, CSV, and XML export on every list view
- Architecture
- Getting Started
- REST API Examples
- Built With
- Contributing
- Versioning
- Authors
- License
- Donation
The application exposes two parallel interaction layers backed by the same Spring beans:
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Client Layer β
β Browser (JSF / PrimeFaces UI) β REST client / cURL β
βββββββββββββββββ¬βββββββββββββββββββ΄βββββββββββββββ¬βββββββββββββ
β Facelets / EL β JSON HTTP
βββββββββββββββββΌββββββββββββββββββββββββββββββββββΌβββββββββββββ
β Controller Layer (@RestController + @ManagedBean) β
β PersonController Β· UnitController Β· DashboardController β
β AbstractController<T> (CRUD base) β
ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ
β Service Layer (AbstractService<T>) β
β JPQL findByName Β· CrudRepository delegation β
ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
ββββββββββββββββββββββββββββββΌββββββββββββββββββββββββββββββββββ
β Repository Layer (Spring Data CrudRepository) β
ββββββββββββββββββββββββββββββ¬ββββββββββββββββββββββββββββββββββ
β
PostgreSQL / MySQL
Key design constraint:
AbstractControllerderives entity class names at runtime viaParameterizedTypereflection. The Java entity class name must match the.xhtmlfile prefix β e.g.PersonβpersonList.xhtml,personView.xhtml. Violating this breaks both JSF navigation and JPQL queries.
| Requirement | Version |
|---|---|
| Java (JDK) | 1.8 |
| Maven | 3.x |
| PostgreSQL or MySQL | 9.6+ / 5.7+ |
git clone https://github.com/your-org/customer-management-system.git
cd customer-management-systemCREATE DATABASE cms;Seed reference data by running all .sql files in src/main/resources/:
# PostgreSQL example
psql -U postgres -d cms -f src/main/resources/chart_type.sql
psql -U postgres -d cms -f src/main/resources/country.sql
psql -U postgres -d cms -f src/main/resources/data.sql
psql -U postgres -d cms -f src/main/resources/first_name.sql
psql -U postgres -d cms -f src/main/resources/last_name.sql
psql -U postgres -d cms -f src/main/resources/unit_industry.sql
psql -U postgres -d cms -f src/main/resources/unit_type.sqlMySQL 8.0.4+ only:
ALTER USER '${USER}'@'localhost' IDENTIFIED WITH mysql_native_password BY '${PASSWORD}';To switch to MySQL, edit
src/main/resources/application.propertiesβ comment out the PostgreSQL block and uncomment the MySQL block.
mvn clean compile package
java -jar target/customer-management-system-0.0.2-SNAPSHOT.jarThe application starts at http://localhost:8081/cms
| Credential | Value |
|---|---|
| Username | admin |
| Password | 123 |
All entity endpoints follow the same convention: /{entityName} maps to full CRUD. The surface is identical for every entity (/unit, /dashboard, /country, etc.).
Request
POST http://localhost:8081/cms/person
Content-Type: application/json
{
"name": "John Doe",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "+1-555-0100",
"notes": "Key contact for Acme Corp"
}Response 200 OK
{
"id": 42,
"name": "John Doe",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "+1-555-0100",
"notes": "Key contact for Acme Corp",
"createdDate": "2026-03-29T10:00:00.000+0000",
"endDate": null
}Request
GET http://localhost:8081/cms/personResponse 200 OK
[
{
"id": 42,
"name": "John Doe",
"firstName": "John",
"lastName": "Doe",
"email": "john.doe@example.com",
"phone": "+1-555-0100",
"createdDate": "2026-03-29T10:00:00.000+0000",
"endDate": null
}
]POST http://localhost:8081/cms/api/user/register
Content-Type: application/json
{
"username": "alice",
"password": "s3cur3p@ss"
}The password is automatically BCrypt-hashed before storage. To generate a hash manually, run
SecurityConfig.main()insrc/main/java/com/cms/configs/SecurityConfig.java.
| Method | Path | Description |
|---|---|---|
GET |
/{entity} |
List all records |
GET |
/{entity}/{id} |
Fetch a single record |
POST |
/{entity} |
Create a new record |
PUT |
/{entity} |
Update an existing record |
DELETE |
/{entity}/{id} |
Delete a record |
| Technology | Purpose |
|---|---|
| Spring Boot 1.5.x | Application framework & embedded Tomcat |
| JoinFaces / PrimeFaces | JSF component library & UI widgets |
| Spring Data JPA | Repository abstraction over JPA / Hibernate |
| Spring Security | Authentication & authorization |
| PostgreSQL / MySQL | Relational database (switchable via config) |
| Apache POI | XLS / XLSX data export |
| iText | PDF generation |
| Lombok | Boilerplate reduction (security models & DTOs) |
| Maven | Build & dependency management |
Please read CONTRIBUTING.md for details on the code of conduct and the process for submitting pull requests.
This project uses SemVer for versioning. For available releases, see the tags on this repository.
- Sergiu Drahnea β Initial work β LinkedIn
This project is licensed under the MIT License β see the LICENSE.md file for details.
If this project saved you time, consider a β donation via PayPal. Any contribution is warmly appreciated!