diff --git a/.rustfmt.toml b/.rustfmt.toml
index 26673e7..ae02153 100644
--- a/.rustfmt.toml
+++ b/.rustfmt.toml
@@ -1,2 +1,9 @@
+unstable_features = true
 newline_style = "Unix"
 hard_tabs = true
+
+# unstable
+group_imports = "StdExternalCrate"
+reorder_impl_items = true
+imports_granularity = "Module"
+blank_lines_upper_bound = 2
\ No newline at end of file
diff --git a/Cargo.lock b/Cargo.lock
index 5505180..7e276a2 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -733,6 +733,7 @@ dependencies = [
  "serde",
  "serde_derive",
  "serde_json",
+ "sqlx",
  "uuid",
 ]
 
diff --git a/Makefile b/Makefile
index 98b1e63..d847842 100644
--- a/Makefile
+++ b/Makefile
@@ -16,3 +16,6 @@ clean-db:
 	rm ./emgauwa-core.sqlite || true
 	rm ./emgauwa-controller.sqlite || true
 	$(MAKE) sqlx
+
+fmt:
+	cargo +nightly fmt
diff --git a/emgauwa-controller/src/main.rs b/emgauwa-controller/src/main.rs
index 6ab7430..3759a11 100644
--- a/emgauwa-controller/src/main.rs
+++ b/emgauwa-controller/src/main.rs
@@ -1,21 +1,20 @@
-use std::time::Duration;
-
-use crate::relay_loop::run_relay_loop;
-use crate::settings::Settings;
 use emgauwa_lib::constants::WEBSOCKET_RETRY_TIMEOUT;
 use emgauwa_lib::db::{DbController, DbRelay};
-use emgauwa_lib::handlers::v1::ws::controllers::ControllerWsAction;
 use emgauwa_lib::models::{Controller, FromDbModel};
-use emgauwa_lib::types::ControllerUid;
+use emgauwa_lib::types::{ControllerUid, ControllerWsAction};
 use emgauwa_lib::{db, utils};
 use futures::{SinkExt, StreamExt};
 use sqlx::pool::PoolConnection;
 use sqlx::Sqlite;
 use tokio::time;
+use tokio_tungstenite::connect_async;
+use tokio_tungstenite::tungstenite::protocol::Message;
 use tokio_tungstenite::tungstenite::Error;
-use tokio_tungstenite::{connect_async, tungstenite::protocol::Message};
 use utils::init_logging;
 
+use crate::relay_loop::run_relay_loop;
+use crate::settings::Settings;
+
 mod driver;
 mod relay_loop;
 mod settings;
@@ -123,7 +122,7 @@ async fn main() {
 	}
 }
 
-pub async fn handle_message(message_result: Result<Message, Error>) {
+async fn handle_message(message_result: Result<Message, Error>) {
 	match message_result {
 		Ok(message) => {
 			if let Message::Text(msg_text) = message {
diff --git a/emgauwa-controller/src/relay_loop.rs b/emgauwa-controller/src/relay_loop.rs
index c3e1c29..612fd6a 100644
--- a/emgauwa-controller/src/relay_loop.rs
+++ b/emgauwa-controller/src/relay_loop.rs
@@ -1,8 +1,10 @@
-use crate::settings::Settings;
-use chrono::Local;
 use std::time::Duration;
+
+use chrono::Local;
 use tokio::time;
 
+use crate::settings::Settings;
+
 #[allow(unused_variables)]
 pub async fn run_relay_loop(settings: Settings) {
 	let default_duration = Duration::from_millis(1000);
diff --git a/emgauwa-core/Cargo.toml b/emgauwa-core/Cargo.toml
index cfdfe77..731bff4 100644
--- a/emgauwa-core/Cargo.toml
+++ b/emgauwa-core/Cargo.toml
@@ -21,5 +21,7 @@ serde = "1.0"
 serde_json = "1.0"
 serde_derive = "1.0"
 
+sqlx = { version = "0.7", features = ["sqlite", "runtime-tokio", "macros", "chrono"] }
+
 futures = "0.3.29"
 libc = "0.2"
diff --git a/emgauwa-lib/src/handlers/errors.rs b/emgauwa-core/src/handlers/errors.rs
similarity index 97%
rename from emgauwa-lib/src/handlers/errors.rs
rename to emgauwa-core/src/handlers/errors.rs
index ab783e1..367ac42 100644
--- a/emgauwa-lib/src/handlers/errors.rs
+++ b/emgauwa-core/src/handlers/errors.rs
@@ -1,9 +1,10 @@
-use crate::db::errors::DatabaseError;
+use std::fmt::{Display, Formatter};
+
 use actix_web::http::StatusCode;
 use actix_web::HttpResponse;
+use emgauwa_lib::db::errors::DatabaseError;
 use serde::ser::SerializeStruct;
 use serde::{Serialize, Serializer};
-use std::fmt::{Display, Formatter};
 
 #[derive(Debug)]
 pub enum ApiError {
diff --git a/emgauwa-lib/src/handlers/mod.rs b/emgauwa-core/src/handlers/mod.rs
similarity index 100%
rename from emgauwa-lib/src/handlers/mod.rs
rename to emgauwa-core/src/handlers/mod.rs
diff --git a/emgauwa-lib/src/handlers/v1/controllers.rs b/emgauwa-core/src/handlers/v1/controllers.rs
similarity index 78%
rename from emgauwa-lib/src/handlers/v1/controllers.rs
rename to emgauwa-core/src/handlers/v1/controllers.rs
index 013251a..f3fed61 100644
--- a/emgauwa-lib/src/handlers/v1/controllers.rs
+++ b/emgauwa-core/src/handlers/v1/controllers.rs
@@ -1,12 +1,9 @@
 use actix_web::{get, web, HttpResponse};
-
+use emgauwa_lib::db::DbController;
+use emgauwa_lib::models::{convert_db_list, Controller};
 use sqlx::{Pool, Sqlite};
 
-use crate::db::DbController;
-
 use crate::handlers::errors::ApiError;
-use crate::models::{convert_db_list, Controller};
-use crate::types::ConnectedControllersType;
 
 #[get("/api/v1/controllers")]
 pub async fn index(pool: web::Data<Pool<Sqlite>>) -> Result<HttpResponse, ApiError> {
diff --git a/emgauwa-lib/src/handlers/v1/mod.rs b/emgauwa-core/src/handlers/v1/mod.rs
similarity index 100%
rename from emgauwa-lib/src/handlers/v1/mod.rs
rename to emgauwa-core/src/handlers/v1/mod.rs
diff --git a/emgauwa-lib/src/handlers/v1/relays.rs b/emgauwa-core/src/handlers/v1/relays.rs
similarity index 87%
rename from emgauwa-lib/src/handlers/v1/relays.rs
rename to emgauwa-core/src/handlers/v1/relays.rs
index 2319ce1..61b5141 100644
--- a/emgauwa-lib/src/handlers/v1/relays.rs
+++ b/emgauwa-core/src/handlers/v1/relays.rs
@@ -1,12 +1,10 @@
 use actix_web::{get, web, HttpResponse};
+use emgauwa_lib::db::DbRelay;
+use emgauwa_lib::models::{convert_db_list, Relay};
 use serde::{Deserialize, Serialize};
-
 use sqlx::{Pool, Sqlite};
 
-use crate::db::DbRelay;
-
 use crate::handlers::errors::ApiError;
-use crate::models::{convert_db_list, Relay};
 
 #[derive(Debug, Serialize, Deserialize)]
 pub struct RequestRelay {
diff --git a/emgauwa-lib/src/handlers/v1/schedules.rs b/emgauwa-core/src/handlers/v1/schedules.rs
similarity index 95%
rename from emgauwa-lib/src/handlers/v1/schedules.rs
rename to emgauwa-core/src/handlers/v1/schedules.rs
index bf754a0..bd521aa 100644
--- a/emgauwa-lib/src/handlers/v1/schedules.rs
+++ b/emgauwa-core/src/handlers/v1/schedules.rs
@@ -1,14 +1,13 @@
 use actix_web::{delete, get, post, put, web, HttpResponse};
+use emgauwa_lib::db::errors::DatabaseError;
+use emgauwa_lib::db::{DbPeriods, DbSchedule, DbTag};
+use emgauwa_lib::models::{convert_db_list, FromDbModel, Schedule};
+use emgauwa_lib::types::ScheduleUid;
 use serde::{Deserialize, Serialize};
 use sqlx::pool::PoolConnection;
 use sqlx::{Pool, Sqlite};
 
-use crate::db::errors::DatabaseError;
-use crate::db::DbTag;
-use crate::db::{DbPeriods, DbSchedule};
 use crate::handlers::errors::ApiError;
-use crate::models::{convert_db_list, FromDbModel, Schedule};
-use crate::types::ScheduleUid;
 
 #[derive(Debug, Serialize, Deserialize)]
 pub struct RequestSchedule {
diff --git a/emgauwa-lib/src/handlers/v1/ws/controllers.rs b/emgauwa-core/src/handlers/v1/ws/controllers.rs
similarity index 90%
rename from emgauwa-lib/src/handlers/v1/ws/controllers.rs
rename to emgauwa-core/src/handlers/v1/ws/controllers.rs
index bb5d7c6..d4e6bf7 100644
--- a/emgauwa-lib/src/handlers/v1/ws/controllers.rs
+++ b/emgauwa-core/src/handlers/v1/ws/controllers.rs
@@ -1,22 +1,17 @@
-use crate::constants::{HEARTBEAT_INTERVAL, HEARTBEAT_TIMEOUT};
-use crate::db::errors::DatabaseError;
-use crate::db::{DbController, DbRelay};
-use crate::models::{Controller, FromDbModel};
-use crate::types::{ConnectedControllersType, ControllerUid};
+use std::time::Instant;
+
 use actix::{Actor, ActorContext, AsyncContext, StreamHandler};
 use actix_web_actors::ws;
 use actix_web_actors::ws::ProtocolError;
-use serde_derive::{Deserialize, Serialize};
+use emgauwa_lib::constants::{HEARTBEAT_INTERVAL, HEARTBEAT_TIMEOUT};
+use emgauwa_lib::db::errors::DatabaseError;
+use emgauwa_lib::db::{DbController, DbRelay};
+use emgauwa_lib::models::{Controller, FromDbModel};
+use emgauwa_lib::types::{ConnectedControllersType, ControllerUid, ControllerWsAction};
 use sqlx::pool::PoolConnection;
 use sqlx::{Pool, Sqlite};
-use std::time::Instant;
 use ws::Message;
 
-#[derive(Debug, Serialize, Deserialize)]
-pub enum ControllerWsAction {
-	Register(Controller),
-}
-
 pub struct ControllerWs {
 	pub pool: Pool<Sqlite>,
 	pub controller_uid: Option<ControllerUid>,
diff --git a/emgauwa-lib/src/handlers/v1/ws/mod.rs b/emgauwa-core/src/handlers/v1/ws/mod.rs
similarity index 93%
rename from emgauwa-lib/src/handlers/v1/ws/mod.rs
rename to emgauwa-core/src/handlers/v1/ws/mod.rs
index f1d194e..e3ebdd0 100644
--- a/emgauwa-lib/src/handlers/v1/ws/mod.rs
+++ b/emgauwa-core/src/handlers/v1/ws/mod.rs
@@ -1,10 +1,12 @@
-use crate::handlers::errors::ApiError;
-use crate::handlers::v1::ws::controllers::ControllerWs;
-use crate::types::ConnectedControllersType;
+use std::time::Instant;
+
 use actix_web::{get, web, HttpRequest, HttpResponse};
 use actix_web_actors::ws;
+use emgauwa_lib::types::ConnectedControllersType;
 use sqlx::{Pool, Sqlite};
-use std::time::Instant;
+
+use crate::handlers::errors::ApiError;
+use crate::handlers::v1::ws::controllers::ControllerWs;
 
 pub mod controllers;
 
diff --git a/emgauwa-core/src/main.rs b/emgauwa-core/src/main.rs
index 145bdad..b38aa25 100644
--- a/emgauwa-core/src/main.rs
+++ b/emgauwa-core/src/main.rs
@@ -1,17 +1,17 @@
-use actix_cors::Cors;
 use std::collections::HashMap;
 use std::net::TcpListener;
-use std::str::FromStr;
 use std::sync::{Arc, Mutex};
 
-use crate::utils::drop_privileges;
+use actix_cors::Cors;
 use actix_web::middleware::TrailingSlash;
 use actix_web::{middleware, web, App, HttpServer};
 use emgauwa_lib::db::DbController;
-use emgauwa_lib::handlers;
 use emgauwa_lib::types::ConnectedControllersType;
 use emgauwa_lib::utils::init_logging;
 
+use crate::utils::drop_privileges;
+
+mod handlers;
 mod settings;
 mod utils;
 
diff --git a/emgauwa-core/src/utils.rs b/emgauwa-core/src/utils.rs
index 9fafd27..dea14c5 100644
--- a/emgauwa-core/src/utils.rs
+++ b/emgauwa-core/src/utils.rs
@@ -1,8 +1,8 @@
-use crate::settings::Settings;
-use log::log;
 use std::ffi::CString;
 use std::io::{Error, ErrorKind};
 
+use crate::settings::Settings;
+
 // https://blog.lxsang.me/post/id/28.0
 pub fn drop_privileges(settings: &Settings) -> Result<(), Error> {
 	log::info!(
diff --git a/emgauwa-lib/src/db/controllers.rs b/emgauwa-lib/src/db/controllers.rs
index 38325d5..b154323 100644
--- a/emgauwa-lib/src/db/controllers.rs
+++ b/emgauwa-lib/src/db/controllers.rs
@@ -1,6 +1,6 @@
-use serde_derive::{Deserialize, Serialize};
 use std::ops::DerefMut;
 
+use serde_derive::{Deserialize, Serialize};
 use sqlx::pool::PoolConnection;
 use sqlx::Sqlite;
 
diff --git a/emgauwa-lib/src/db/mod.rs b/emgauwa-lib/src/db/mod.rs
index 031449b..91b4787 100644
--- a/emgauwa-lib/src/db/mod.rs
+++ b/emgauwa-lib/src/db/mod.rs
@@ -1,8 +1,9 @@
+use std::str::FromStr;
+
 use log::{info, trace};
 use sqlx::migrate::Migrator;
 use sqlx::sqlite::{SqliteConnectOptions, SqlitePoolOptions};
 use sqlx::{Pool, Sqlite};
-use std::str::FromStr;
 
 use crate::db::errors::DatabaseError;
 use crate::db::model_utils::Period;
diff --git a/emgauwa-lib/src/db/model_utils.rs b/emgauwa-lib/src/db/model_utils.rs
index 73d9f10..e1b5835 100644
--- a/emgauwa-lib/src/db/model_utils.rs
+++ b/emgauwa-lib/src/db/model_utils.rs
@@ -1,4 +1,3 @@
-use crate::db::DbPeriods;
 use chrono::{NaiveTime, Timelike};
 use serde::{Deserialize, Serialize};
 use sqlx::database::HasArguments;
@@ -7,6 +6,8 @@ use sqlx::error::BoxDynError;
 use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef};
 use sqlx::{Decode, Encode, Sqlite, Type};
 
+use crate::db::DbPeriods;
+
 #[derive(Debug, Serialize, Deserialize, PartialEq, Clone)]
 pub struct Period {
 	#[serde(with = "period_format")]
diff --git a/emgauwa-lib/src/db/relays.rs b/emgauwa-lib/src/db/relays.rs
index 310d020..65a5f4b 100644
--- a/emgauwa-lib/src/db/relays.rs
+++ b/emgauwa-lib/src/db/relays.rs
@@ -1,12 +1,11 @@
-use serde_derive::{Deserialize, Serialize};
 use std::ops::DerefMut;
 
-use crate::db::DbController;
+use serde_derive::{Deserialize, Serialize};
 use sqlx::pool::PoolConnection;
 use sqlx::Sqlite;
 
 use crate::db::errors::DatabaseError;
-use crate::db::DbTag;
+use crate::db::{DbController, DbTag};
 
 #[derive(Debug, Clone, Serialize, Deserialize)]
 pub struct DbRelay {
diff --git a/emgauwa-lib/src/db/schedules.rs b/emgauwa-lib/src/db/schedules.rs
index 00b294b..988bb30 100644
--- a/emgauwa-lib/src/db/schedules.rs
+++ b/emgauwa-lib/src/db/schedules.rs
@@ -1,7 +1,7 @@
-use serde_derive::{Deserialize, Serialize};
 use std::borrow::Borrow;
 use std::ops::DerefMut;
 
+use serde_derive::{Deserialize, Serialize};
 use sqlx::pool::PoolConnection;
 use sqlx::Sqlite;
 
diff --git a/emgauwa-lib/src/db/tag.rs b/emgauwa-lib/src/db/tag.rs
index 4f89432..2cb9551 100644
--- a/emgauwa-lib/src/db/tag.rs
+++ b/emgauwa-lib/src/db/tag.rs
@@ -1,6 +1,6 @@
-use serde_derive::Serialize;
 use std::ops::DerefMut;
 
+use serde_derive::Serialize;
 use sqlx::pool::PoolConnection;
 use sqlx::Sqlite;
 
diff --git a/emgauwa-lib/src/lib.rs b/emgauwa-lib/src/lib.rs
index acdab58..dc3750e 100644
--- a/emgauwa-lib/src/lib.rs
+++ b/emgauwa-lib/src/lib.rs
@@ -1,6 +1,5 @@
 pub mod constants;
 pub mod db;
-pub mod handlers;
 pub mod models;
 pub mod types;
 pub mod utils;
diff --git a/emgauwa-lib/src/models/mod.rs b/emgauwa-lib/src/models/mod.rs
index 8e55dc6..1c3f8e1 100644
--- a/emgauwa-lib/src/models/mod.rs
+++ b/emgauwa-lib/src/models/mod.rs
@@ -1,11 +1,12 @@
-use crate::db::errors::DatabaseError;
-use crate::db::{DbController, DbRelay, DbSchedule};
-use crate::types::ControllerUid;
 use futures::executor;
 use serde_derive::{Deserialize, Serialize};
 use sqlx::pool::PoolConnection;
 use sqlx::Sqlite;
 
+use crate::db::errors::DatabaseError;
+use crate::db::{DbController, DbRelay, DbSchedule};
+use crate::types::ControllerUid;
+
 pub trait FromDbModel {
 	type DbModel: Clone;
 
diff --git a/emgauwa-lib/src/types/controller_uid.rs b/emgauwa-lib/src/types/controller_uid.rs
index a4e709a..85d8ffd 100644
--- a/emgauwa-lib/src/types/controller_uid.rs
+++ b/emgauwa-lib/src/types/controller_uid.rs
@@ -1,10 +1,11 @@
+use std::str::FromStr;
+
 use serde::{Deserialize, Deserializer, Serialize, Serializer};
 use sqlx::database::HasArguments;
 use sqlx::encode::IsNull;
 use sqlx::error::BoxDynError;
 use sqlx::sqlite::{SqliteTypeInfo, SqliteValueRef};
 use sqlx::{Decode, Encode, Sqlite, Type};
-use std::str::FromStr;
 use uuid::Uuid;
 
 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
diff --git a/emgauwa-lib/src/types/mod.rs b/emgauwa-lib/src/types/mod.rs
index e163fae..4c0cc95 100644
--- a/emgauwa-lib/src/types/mod.rs
+++ b/emgauwa-lib/src/types/mod.rs
@@ -1,12 +1,18 @@
 mod controller_uid;
 mod schedule_uid;
 
-use crate::models::Controller;
-
-pub use controller_uid::ControllerUid;
-pub use schedule_uid::ScheduleUid;
-
 use std::collections::HashMap;
 use std::sync::{Arc, Mutex};
 
+pub use controller_uid::ControllerUid;
+pub use schedule_uid::ScheduleUid;
+use serde_derive::{Deserialize, Serialize};
+
+use crate::models::Controller;
+
 pub type ConnectedControllersType = Arc<Mutex<HashMap<ControllerUid, Controller>>>;
+
+#[derive(Debug, Serialize, Deserialize)]
+pub enum ControllerWsAction {
+	Register(Controller),
+}
diff --git a/emgauwa-lib/src/types/schedule_uid.rs b/emgauwa-lib/src/types/schedule_uid.rs
index f903d17..d04df24 100644
--- a/emgauwa-lib/src/types/schedule_uid.rs
+++ b/emgauwa-lib/src/types/schedule_uid.rs
@@ -19,11 +19,11 @@ pub enum ScheduleUid {
 
 impl ScheduleUid {
 	const OFF_STR: &'static str = "off";
-	const ON_STR: &'static str = "on";
-	const OFF_U8: u8 = 0;
-	const ON_U8: u8 = 1;
 	const OFF_U128: u128 = 0;
+	const OFF_U8: u8 = 0;
+	const ON_STR: &'static str = "on";
 	const ON_U128: u128 = 1;
+	const ON_U8: u8 = 1;
 }
 
 impl Default for ScheduleUid {
diff --git a/emgauwa-lib/src/utils.rs b/emgauwa-lib/src/utils.rs
index b6e7889..0d8e6ab 100644
--- a/emgauwa-lib/src/utils.rs
+++ b/emgauwa-lib/src/utils.rs
@@ -1,6 +1,7 @@
+use std::str::FromStr;
+
 use log::LevelFilter;
 use simple_logger::SimpleLogger;
-use std::str::FromStr;
 
 pub fn load_settings<T>(config_name: &str, env_prefix: &str) -> T
 where