diff --git a/frontend/src/router/index.ts b/frontend/src/router/index.ts
index 279a411..ad4b558 100644
--- a/frontend/src/router/index.ts
+++ b/frontend/src/router/index.ts
@@ -1,14 +1,17 @@
import { createRouter, createWebHistory } from 'vue-router'
import Login from '../views/auth/Login.vue'
import Setup from '../views/auth/Setup.vue'
+import Register from '../views/auth/Register.vue'
import Dashboard from '../views/Dashboard.vue'
import Users from '../views/Users.vue'
import Restaurants from '../views/Restaurants.vue'
+import AdminSettings from '../views/AdminSettings.vue'
import NotFound from '../views/NotFound.vue'
const routes = [
{ path: '/login', component: Login, meta: { title: 'Login' } },
{ path: '/setup', component: Setup, meta: { title: 'Setup' } },
+ { path: '/register', component: Register, meta: { title: 'Register' } },
{
path: '/',
redirect: '/dashboard'
@@ -18,14 +21,21 @@ const routes = [
component: Dashboard,
meta: { requiresAuth: true, title: 'Dashboard' }
},
- { path: '/users',
+ {
+ path: '/users',
component: Users,
meta: { requiresAuth: true, title: 'Users' }
},
- { path: '/restaurants',
+ {
+ path: '/restaurants',
component: Restaurants,
meta: { requiresAuth: true, title: 'Restaurants' }
},
+ {
+ path: '/settings',
+ component: AdminSettings,
+ meta: { requiresAuth: true, title: 'Settings' }
+ },
{
path: '/:pathMatch(.*)*',
name: 'NotFound',
diff --git a/frontend/src/views/AdminSettings.vue b/frontend/src/views/AdminSettings.vue
new file mode 100644
index 0000000..1f065e8
--- /dev/null
+++ b/frontend/src/views/AdminSettings.vue
@@ -0,0 +1,37 @@
+
+
+
+
Application Settings
+
+
+
+
+
+
diff --git a/frontend/src/views/Dashboard.vue b/frontend/src/views/Dashboard.vue
index 38efb93..398179a 100644
--- a/frontend/src/views/Dashboard.vue
+++ b/frontend/src/views/Dashboard.vue
@@ -118,11 +118,32 @@
import { ref, onMounted, onUnmounted } from 'vue'
import AppLayout from '../components/Layout/AppLayout.vue'
-const stats = ref({
- totalUsers: 0,
- activeSessions: 0,
- systemHealth: 98,
- uptime: '99.9%'
+const stats = ref({ totalUsers: 0, activeSessions: 0, systemHealth: 100, uptime: '99.9%' })
+
+async function loadStats() {
+ try {
+ const [usersRes, sessionsRes, healthRes] = await Promise.all([
+ fetch('/api/admin/users'),
+ fetch('/api/admin/active-sessions'),
+ fetch('/api/health')
+ ])
+ const users = await usersRes.json()
+ const sessions = await sessionsRes.json()
+ const health = await healthRes.json()
+
+ stats.value.totalUsers = users.length
+ stats.value.activeSessions = sessions.count || 0
+
+ const upCount = health.checks?.filter(c => c.status === 'UP').length || 0
+ const total = health.checks?.length || 1
+ stats.value.systemHealth = Math.round((upCount / total) * 100)
+ } catch (e) { console.error(e) }
+}
+
+onMounted(() => {
+ loadStats()
+ const interval = setInterval(loadStats, 5000)
+ onUnmounted(() => clearInterval(interval))
})
const recentUsers = ref([])
diff --git a/frontend/src/views/Users.vue b/frontend/src/views/Users.vue
index 98f2236..df3d728 100644
--- a/frontend/src/views/Users.vue
+++ b/frontend/src/views/Users.vue
@@ -11,20 +11,28 @@
@@ -133,21 +153,24 @@ import { ref, computed, watch } from 'vue'
import { useRouter } from 'vue-router'
const router = useRouter()
-const form = ref({ login: '', password: '' })
+const form = ref({ login: '', email: '', password: '' });
const loading = ref(false)
const error = ref('')
const showPassword = ref(false)
const validation = computed(() => {
- const errors: any = {}
+ const errors: any = {};
if (form.value.login && form.value.login.length < 3) {
- errors.login = 'Username must be at least 3 characters'
+ errors.login = 'Username must be at least 3 characters';
+ }
+ if (form.value.email && !/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(form.value.email)) {
+ errors.email = 'Please enter a valid email address';
}
if (form.value.password && form.value.password.length < 6) {
- errors.password = 'Password must be at least 6 characters'
+ errors.password = 'Password must be at least 6 characters';
}
- return errors
-})
+ return errors;
+});
const passwordStrength = computed(() => {
const pwd = form.value.password
@@ -178,29 +201,33 @@ const strengthBarColor = computed(() => {
})
async function handleSetup() {
- if (Object.keys(validation.value).length > 0) return
+ if (Object.keys(validation.value).length > 0) return;
- loading.value = true
- error.value = ''
+ loading.value = true;
+ error.value = '';
try {
const res = await fetch('/api/setup', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
- body: JSON.stringify(form.value)
- })
+ body: JSON.stringify({
+ login: form.value.login,
+ email: form.value.email,
+ password: form.value.password
+ })
+ });
- const data = await res.json()
+ const data = await res.json();
if (res.ok) {
- router.push('/login')
+ router.push('/login');
} else {
- error.value = data.error || 'Failed to create account'
+ error.value = data.error || 'Failed to create account';
}
} catch (e) {
- error.value = 'Network error. Please try again.'
+ error.value = 'Network error. Please try again.';
} finally {
- loading.value = false
+ loading.value = false;
}
}
diff --git a/src/main/java/su/xserver/iikocon/MainVerticle.java b/src/main/java/su/xserver/iikocon/MainVerticle.java
index d4ee32f..82d731c 100644
--- a/src/main/java/su/xserver/iikocon/MainVerticle.java
+++ b/src/main/java/su/xserver/iikocon/MainVerticle.java
@@ -4,6 +4,7 @@ import io.vertx.config.ConfigRetriever;
import io.vertx.config.ConfigRetrieverOptions;
import io.vertx.config.ConfigStoreOptions;
import io.vertx.core.AbstractVerticle;
+import io.vertx.core.Future;
import io.vertx.core.Promise;
import io.vertx.core.http.HttpServer;
import io.vertx.core.json.JsonObject;
@@ -14,6 +15,7 @@ import io.vertx.ext.web.handler.StaticHandler;
import io.vertx.ext.web.sstore.LocalSessionStore;
import io.vertx.ext.web.sstore.SessionStore;
+import io.vertx.ext.web.sstore.redis.RedisSessionStore;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import su.xserver.iikocon.config.AppConfig;
@@ -21,6 +23,10 @@ import su.xserver.iikocon.service.DataBaseService;
import su.xserver.iikocon.service.HealthCheckService;
import su.xserver.iikocon.service.RedisService;
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.List;
+
public class MainVerticle extends AbstractVerticle {
private final Logger log = LoggerFactory.getLogger("[MainVerticle]");
@@ -32,6 +38,7 @@ public class MainVerticle extends AbstractVerticle {
private UserService userService;
private RestaurantService restaurantService;
+ private SettingsService settingsService;
@Override
public void start(Promise startPromise) {
@@ -57,21 +64,21 @@ public class MainVerticle extends AbstractVerticle {
// Инициализация сервисов
userService = new UserService(db.getPool());
restaurantService = new RestaurantService(db.getPool());
+ settingsService = new SettingsService(db.getPool());
// Инициализация БД (создание таблицы users)
- userService.initDatabase()
- .onSuccess(v -> log.info("Database initialized successfully"))
- .onFailure(err -> {
- log.error("Failed to initialize database", err);
- startPromise.fail(err);
- });
-
- restaurantService.initDatabase()
- .onSuccess(v -> log.info("Database initialized successfully"))
- .onFailure(err -> {
- log.error("Failed to initialize database", err);
- startPromise.fail(err);
- });
+ userService.initDatabase().onFailure(err -> {
+ log.error("Failed to initialize database", err);
+ startPromise.fail(err);
+ });
+ restaurantService.initDatabase().onFailure(err -> {
+ log.error("Failed to initialize database", err);
+ startPromise.fail(err);
+ });
+ settingsService.initDatabase().onFailure(err -> {
+ log.error("Failed to initialize database", err);
+ startPromise.fail(err);
+ });
Router router = initRouter();
@@ -90,7 +97,7 @@ public class MainVerticle extends AbstractVerticle {
.setSessionCookieName("admin.session")
.setCookieHttpOnlyFlag(true)
.setCookieSecureFlag(false)
- .setSessionTimeout(3600000); // 1 час
+ .setSessionTimeout(3600000);
// Роутер
Router router = Router.router(vertx);
@@ -144,6 +151,21 @@ public class MainVerticle extends AbstractVerticle {
router.post("/api/logout").handler(authHandler::handleLogout);
+ router.post("/api/register").handler(rc -> {
+ JsonObject body = rc.body().asJsonObject();
+ String login = body.getString("login");
+ String email = body.getString("email");
+ String password = body.getString("password");
+ String ip = rc.request().remoteAddress().host();
+ if (login == null || email == null || password == null) {
+ rc.response().setStatusCode(400).end("Missing fields");
+ return;
+ }
+ userService.createUser(login, email, password, ip)
+ .onSuccess(v -> rc.response().setStatusCode(201).end(new JsonObject().put("success", true).encode()))
+ .onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
+ });
+
router.route("/api/admin/*").handler(authHandler::requireAuth);
router.get("/api/admin/users").handler(rc -> userService.getAllUsers().onComplete(ar -> {
@@ -159,13 +181,14 @@ public class MainVerticle extends AbstractVerticle {
router.post("/api/admin/users").handler(rc -> {
JsonObject body = rc.body().asJsonObject();
String login = body.getString("login");
+ String email = body.getString("email");
String password = body.getString("password");
String ip = rc.request().remoteAddress().host();
- if (login == null || password == null) {
- rc.response().setStatusCode(400).end("Missing login or password");
+ if (login == null || email == null || password == null) {
+ rc.response().setStatusCode(400).end("Missing login, email or password");
return;
}
- userService.createUser(login, password, ip)
+ userService.createUser(login, email, password, ip, true)
.onSuccess(v -> rc.response().setStatusCode(201).end())
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
@@ -174,13 +197,14 @@ public class MainVerticle extends AbstractVerticle {
int id = Integer.parseInt(rc.pathParam("id"));
JsonObject body = rc.body().asJsonObject();
String login = body.getString("login");
+ String email = body.getString("email");
String password = body.getString("password");
String ip = rc.request().remoteAddress().host();
- if (login == null) {
- rc.response().setStatusCode(400).end("Missing login");
+ if (login == null || email == null) {
+ rc.response().setStatusCode(400).end("Missing login or email");
return;
}
- userService.updateUser(id, login, password, ip)
+ userService.updateUser(id, login, email, password, ip)
.onSuccess(v -> rc.response().end())
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
@@ -192,6 +216,14 @@ public class MainVerticle extends AbstractVerticle {
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
+ router.put("/api/admin/users/:id/activate").handler(rc -> {
+ int id = Integer.parseInt(rc.pathParam("id"));
+ boolean active = Boolean.parseBoolean(rc.queryParam("active").get(0));
+ userService.setActive(id, active)
+ .onSuccess(v -> rc.response().end())
+ .onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
+ });
+
// Получение текущего пользователя
router.get("/api/admin/me").handler(rc -> {
Integer userId = rc.session().get("userId");
@@ -265,6 +297,29 @@ public class MainVerticle extends AbstractVerticle {
.onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
});
+ // Получение всех настроек
+ router.get("/api/settings").handler(rc -> {
+ settingsService.getAll()
+ .onSuccess(settings -> rc.response().putHeader("Content-Type", "application/json").end(settings.encode()))
+ .onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
+ });
+
+// Обновление настроек (админ)
+ router.put("/api/admin/settings").handler(rc -> {
+ JsonObject body = rc.body().asJsonObject();
+ List> futures = new ArrayList<>(); // явно указываем тип Future
+ body.forEach(entry -> futures.add(settingsService.set(entry.getKey(), entry.getValue().toString())));
+ Future.all(futures)
+ .onSuccess(v -> rc.response().end())
+ .onFailure(err -> rc.response().setStatusCode(500).end(err.getMessage()));
+ });
+
+// Количество активных сессий (на основе Redis)
+ router.get("/api/admin/active-sessions").handler(rc -> {
+ // TODO: реализовать подсчёт активных сессий через Redis или другой механизм
+ rc.response().end(new JsonObject().put("count", 0).encode());
+ });
+
return router;
}
diff --git a/src/main/java/su/xserver/iikocon/RestaurantService.java b/src/main/java/su/xserver/iikocon/RestaurantService.java
index 72c975b..63b031e 100644
--- a/src/main/java/su/xserver/iikocon/RestaurantService.java
+++ b/src/main/java/su/xserver/iikocon/RestaurantService.java
@@ -23,7 +23,7 @@ public class RestaurantService {
CREATE TABLE IF NOT EXISTS restaurants (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(255) UNIQUE NOT NULL,
- login VARCHAR(255) UNIQUE NOT NULL,
+ login VARCHAR(255) NOT NULL,
password VARCHAR(255) NOT NULL,
host VARCHAR(255) NOT NULL,
created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
diff --git a/src/main/java/su/xserver/iikocon/SettingsService.java b/src/main/java/su/xserver/iikocon/SettingsService.java
new file mode 100644
index 0000000..d48c3b2
--- /dev/null
+++ b/src/main/java/su/xserver/iikocon/SettingsService.java
@@ -0,0 +1,67 @@
+package su.xserver.iikocon;
+
+import io.vertx.core.Future;
+import io.vertx.core.json.JsonObject;
+import io.vertx.sqlclient.Pool;
+import io.vertx.sqlclient.templates.SqlTemplate;
+
+import java.util.Map;
+
+public class SettingsService {
+ private final Pool pool;
+
+ public SettingsService(Pool pool) { this.pool = pool; }
+
+ public Future initDatabase() {
+ String createTable = """
+ CREATE TABLE IF NOT EXISTS app_settings (
+ setting_key VARCHAR(255) PRIMARY KEY,
+ setting_value TEXT
+ )
+ """;
+ return pool.query(createTable).execute()
+ .compose(v -> setIfAbsent("site_name", "Admin Panel"))
+ .compose(v -> setIfAbsent("site_description", "Powerful administration dashboard"))
+ .compose(v -> setIfAbsent("theme", "light"))
+ .compose(v -> setIfAbsent("items_per_page", "20"))
+ .compose(v -> setIfAbsent("enable_registration", "true"))
+ .compose(v -> setIfAbsent("maintenance_mode", "false"))
+ .compose(v -> setIfAbsent("default_language", "en"))
+ .compose(v -> setIfAbsent("session_timeout_minutes", "60"))
+ .compose(v -> setIfAbsent("logo_url", "/assets/logo.png"))
+ .mapEmpty();
+ }
+
+ private Future setIfAbsent(String key, String defaultValue) {
+ return get(key).compose(existing -> {
+ if (existing == null) {
+ return set(key, defaultValue);
+ }
+ return Future.succeededFuture();
+ });
+ }
+
+ public Future get(String key) {
+ return SqlTemplate.forQuery(pool, "SELECT setting_value FROM app_settings WHERE setting_key = #{key}")
+ .execute(Map.of("key", key))
+ .map(rows -> rows.iterator().hasNext() ? rows.iterator().next().getString("setting_value") : null);
+ }
+
+ public Future set(String key, String value) {
+ return SqlTemplate.forUpdate(pool,
+ "INSERT INTO app_settings (setting_key, setting_value) VALUES (#{key}, #{value}) " +
+ "ON DUPLICATE KEY UPDATE setting_value = #{value}")
+ .execute(Map.of("key", key, "value", value))
+ .mapEmpty();
+ }
+
+ public Future getAll() {
+ return pool.query("SELECT setting_key, setting_value FROM app_settings")
+ .execute()
+ .map(rows -> {
+ JsonObject json = new JsonObject();
+ rows.forEach(row -> json.put(row.getString("setting_key"), row.getString("setting_value")));
+ return json;
+ });
+ }
+}
diff --git a/src/main/java/su/xserver/iikocon/SetupHandler.java b/src/main/java/su/xserver/iikocon/SetupHandler.java
index 8e2209a..f7c3826 100644
--- a/src/main/java/su/xserver/iikocon/SetupHandler.java
+++ b/src/main/java/su/xserver/iikocon/SetupHandler.java
@@ -37,6 +37,11 @@ public class SetupHandler {
String login = body.getString("login");
String password = body.getString("password");
+ String email = body.getString("email");
+
+ if (email == null || email.isBlank()) {
+ email = login + "@admin.local"; // значение по умолчанию
+ }
if (login == null || password == null || login.length() < 3 || password.length() < 6) {
ctx.response().setStatusCode(400)
@@ -47,7 +52,7 @@ public class SetupHandler {
}
String ip = ctx.request().remoteAddress().host();
- userService.createUser(login, password, ip).onComplete(cr -> {
+ userService.createUser(login, email, password, ip, true).onComplete(cr -> {
if (cr.succeeded()) {
ctx.response().setStatusCode(201)
.end(new JsonObject().put("success", true).encode());
diff --git a/src/main/java/su/xserver/iikocon/UserService.java b/src/main/java/su/xserver/iikocon/UserService.java
index fcb7535..1e41a86 100644
--- a/src/main/java/su/xserver/iikocon/UserService.java
+++ b/src/main/java/su/xserver/iikocon/UserService.java
@@ -21,16 +21,17 @@ public class UserService {
public Future initDatabase() {
String createTable = """
- CREATE TABLE IF NOT EXISTS users (
- id INT AUTO_INCREMENT PRIMARY KEY,
- login VARCHAR(255) UNIQUE NOT NULL,
- password VARCHAR(255) NOT NULL,
- created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
- updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
- ip VARCHAR(45)
- )
- """;
-
+ CREATE TABLE IF NOT EXISTS users (
+ id INT AUTO_INCREMENT PRIMARY KEY,
+ login VARCHAR(255) UNIQUE NOT NULL,
+ email VARCHAR(255) UNIQUE NOT NULL,
+ password VARCHAR(255) NOT NULL,
+ active BOOLEAN DEFAULT FALSE,
+ ip VARCHAR(45),
+ created TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
+ updated TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+ )
+ """;
return pool.query(createTable).execute().mapEmpty();
}
@@ -40,20 +41,38 @@ public class UserService {
.map(rows -> rows.iterator().next().getLong("cnt"));
}
- public Future createUser(String login, String password, String ip) {
+ public Future createUser(String login, String email, String password, String ip, boolean active) {
String hash = BCrypt.hashpw(password, BCrypt.gensalt());
-
- Map params = new HashMap<>();
- params.put("login", login);
- params.put("password", hash);
- params.put("ip", ip);
-
+ Map params = Map.of(
+ "login", login,
+ "email", email,
+ "password", hash,
+ "ip", ip,
+ "active", active
+ );
return SqlTemplate.forUpdate(pool,
- "INSERT INTO users (login, password, ip) VALUES (#{login}, #{password}, #{ip})")
+ "INSERT INTO users (login, email, password, ip, active) VALUES (#{login}, #{email}, #{password}, #{ip}, #{active})")
.execute(params)
.mapEmpty();
}
+ // Существующий метод оставляем, но он будет создавать неактивного пользователя (active = false)
+ public Future createUser(String login, String email, String password, String ip) {
+ return createUser(login, email, password, ip, false);
+ }
+
+ public Future setActive(int id, boolean active) {
+ return SqlTemplate.forUpdate(pool, "UPDATE users SET active = #{active} WHERE id = #{id}")
+ .execute(Map.of("id", id, "active", active)).mapEmpty();
+ }
+
+ public Future findByEmail(String email) {
+ return SqlTemplate.forQuery(pool, "SELECT id, login, email, password, active, ip, created, updated FROM users WHERE email = #{email}")
+ .mapTo(this::toJson)
+ .execute(Map.of("email", email))
+ .map(rows -> rows.iterator().hasNext() ? rows.iterator().next() : null);
+ }
+
public Future findByLogin(String login) {
return SqlTemplate.forQuery(pool,
"SELECT id, login, password, created, updated, ip FROM users WHERE login = #{login}")
@@ -71,42 +90,30 @@ public class UserService {
}
public Future getAllUsers() {
- return pool.query("SELECT id, login, created, updated, ip FROM users ORDER BY id")
+ return pool.query("SELECT id, login, email, active, ip, created, updated FROM users ORDER BY id")
.execute()
.map(rows -> {
JsonArray array = new JsonArray();
- for (Row row : rows) {
- array.add(new JsonObject()
- .put("id", row.getInteger("id"))
- .put("login", row.getString("login"))
- .put("created", row.getLocalDateTime("created") != null ?
- row.getLocalDateTime("created").toString() : null)
- .put("updated", row.getLocalDateTime("updated") != null ?
- row.getLocalDateTime("updated").toString() : null)
- .put("ip", row.getString("ip")));
- }
+ rows.forEach(row -> array.add(toJson(row)));
return array;
});
}
- public Future updateUser(int id, String login, String password, String ip) {
+ public Future updateUser(int id, String login, String email, String password, String ip) {
Map params = new HashMap<>();
params.put("id", id);
params.put("login", login);
+ params.put("email", email);
params.put("ip", ip);
-
String sql;
if (password != null && !password.isEmpty()) {
String hash = BCrypt.hashpw(password, BCrypt.gensalt());
params.put("password", hash);
- sql = "UPDATE users SET login = #{login}, password = #{password}, ip = #{ip} WHERE id = #{id}";
+ sql = "UPDATE users SET login = #{login}, email = #{email}, password = #{password}, ip = #{ip} WHERE id = #{id}";
} else {
- sql = "UPDATE users SET login = #{login}, ip = #{ip} WHERE id = #{id}";
+ sql = "UPDATE users SET login = #{login}, email = #{email}, ip = #{ip} WHERE id = #{id}";
}
-
- return SqlTemplate.forUpdate(pool, sql)
- .execute(params)
- .mapEmpty();
+ return SqlTemplate.forUpdate(pool, sql).execute(params).mapEmpty();
}
public Future deleteUser(int id) {
@@ -122,4 +129,15 @@ public class UserService {
return false;
}
}
+
+ private JsonObject toJson(Row row) {
+ return new JsonObject()
+ .put("id", row.getInteger("id"))
+ .put("login", row.getString("login"))
+ .put("email", row.getString("email"))
+ .put("active", row.getBoolean("active"))
+ .put("ip", row.getString("ip"))
+ .put("created", row.getLocalDateTime("created") != null ? row.getLocalDateTime("created").toString() : null)
+ .put("updated", row.getLocalDateTime("updated") != null ? row.getLocalDateTime("updated").toString() : null);
+ }
}
diff --git a/src/main/java/su/xserver/iikocon/service/HealthCheckService.java b/src/main/java/su/xserver/iikocon/service/HealthCheckService.java
index 99b0afc..66abc35 100644
--- a/src/main/java/su/xserver/iikocon/service/HealthCheckService.java
+++ b/src/main/java/su/xserver/iikocon/service/HealthCheckService.java
@@ -31,7 +31,7 @@ public class HealthCheckService {
long time = System.currentTimeMillis() - start;
if ("PONG".equalsIgnoreCase(response.toString())) {
JsonObject data = new JsonObject()
- .put("name", "redis")
+ .put("name", "Redis")
.put("latency_ms", time);
future.complete(Status.OK(data));
} else {
@@ -42,7 +42,7 @@ public class HealthCheckService {
});
// Database check
- healthCheckHandler.register("database", future -> {
+ healthCheckHandler.register("DataBase", future -> {
long start = System.currentTimeMillis();
dbService.getPool().query("SELECT 1").execute()
.onSuccess(rs -> {