diff --git a/Makefile b/Makefile index 654cf0e2..d29cb5cb 100644 --- a/Makefile +++ b/Makefile @@ -56,29 +56,29 @@ help: @printf " $(BOLD)$(GREEN)format$(NC) : Automatically format code.\n\n" @printf "$(BOLD)$(BLUE)Build Commands:$(NC)\n" - @printf " $(BOLD)$(GREEN)build:app$(NC) : Build the main application executable.\n" + @printf " $(BOLD)$(GREEN)build:app$(NC) : Build the main application executable.\n" @printf " $(BOLD)$(GREEN)build:app:linux$(NC) : Build the application specifically for Linux.\n" - @printf " $(BOLD)$(GREEN)build:release$(NC) : Build a release version of the application.\n" - @printf " $(BOLD)$(GREEN)build:run$(NC) : Build and run the application.\n" - @printf " $(BOLD)$(GREEN)build:fresh$(NC) : Build and run a freshly instance of the application.\n" - @printf " $(BOLD)$(GREEN)build:flush$(NC) : Clean build artifacts and then build the application.\n\n" + @printf " $(BOLD)$(GREEN)build:release$(NC) : Build a release version of the application.\n" + @printf " $(BOLD)$(GREEN)build:run$(NC) : Build and run the application.\n" + @printf " $(BOLD)$(GREEN)build:fresh$(NC) : Build and run a freshly instance of the application.\n" + @printf " $(BOLD)$(GREEN)build:flush$(NC) : Clean build artifacts and then build the application.\n\n" @printf "$(BOLD)$(BLUE)Database Commands:$(NC)\n" - @printf " $(BOLD)$(GREEN)db:local$(NC) : Set up or manage the local database environment.\n" - @printf " $(BOLD)$(GREEN)db:up$(NC) : Start the database service or container.\n" - @printf " $(BOLD)$(GREEN)db:ping$(NC) : Check the database connection.\n" - @printf " $(BOLD)$(GREEN)db:bash$(NC) : Access the database environment via bash.\n" - @printf " $(BOLD)$(GREEN)db:fresh$(NC) : Reset and re-seed the database.\n" - @printf " $(BOLD)$(GREEN)db:logs$(NC) : View database logs.\n" - @printf " $(BOLD)$(GREEN)db:delete$(NC) : Delete the database.\n" - @printf " $(BOLD)$(GREEN)db:secure$(NC) : Apply database security configurations.\n" - @printf " $(BOLD)$(GREEN)db:secure:show$(NC): Display database security configurations.\n" - @printf " $(BOLD)$(GREEN)db:chmod$(NC) : Adjust database file or directory permissions.\n" - @printf " $(BOLD)$(GREEN)db:seed$(NC) : Run database seeders to populate data.\n" - @printf " $(BOLD)$(GREEN)db:migrate$(NC) : Run database migrations.\n" - @printf " $(BOLD)$(GREEN)db:rollback$(NC) : Rollback database migrations (usually the last batch).\n" + @printf " $(BOLD)$(GREEN)db:local$(NC) : Set up or manage the local database environment.\n" + @printf " $(BOLD)$(GREEN)db:up$(NC) : Start the database service or container.\n" + @printf " $(BOLD)$(GREEN)db:ping$(NC) : Check the database connection.\n" + @printf " $(BOLD)$(GREEN)db:bash$(NC) : Access the database environment via bash.\n" + @printf " $(BOLD)$(GREEN)db:fresh$(NC) : Reset and re-seed the database.\n" + @printf " $(BOLD)$(GREEN)db:logs$(NC) : View database logs.\n" + @printf " $(BOLD)$(GREEN)db:delete$(NC) : Delete the database.\n" + @printf " $(BOLD)$(GREEN)db:secure$(NC) : Apply database security configurations.\n" + @printf " $(BOLD)$(GREEN)db:secure:show$(NC) : Display database security configurations.\n" + @printf " $(BOLD)$(GREEN)db:chmod$(NC) : Adjust database file or directory permissions.\n" + @printf " $(BOLD)$(GREEN)db:seed$(NC) : Run database seeders to populate data.\n" + @printf " $(BOLD)$(GREEN)db:migrate$(NC) : Run database migrations.\n" + @printf " $(BOLD)$(GREEN)db:rollback$(NC) : Rollback database migrations (usually the last batch).\n" @printf " $(BOLD)$(GREEN)db:migrate:create$(NC): Create a new database migration file.\n" - @printf " $(BOLD)$(GREEN)db:migrate:force$(NC): Force database migrations to run.\n\n" + @printf " $(BOLD)$(GREEN)db:migrate:force$(NC) : Force database migrations to run.\n\n" @printf "$(BOLD)$(BLUE)Environment Commands:$(NC)\n" @printf " $(BOLD)$(GREEN)env:check$(NC) : Verify environment configuration.\n" diff --git a/config/makefile/db.mk b/config/makefile/db.mk index 8a09534e..5674e85a 100644 --- a/config/makefile/db.mk +++ b/config/makefile/db.mk @@ -52,12 +52,11 @@ db\:delete: docker ps db\:secure: - make fresh && \ rm -rf $(DB_INFRA_SERVER_CRT) && rm -rf $(DB_INFRA_SERVER_CSR) && rm -rf $(DB_INFRA_SERVER_KEY) && \ openssl genpkey -algorithm RSA -out $(DB_INFRA_SERVER_KEY) && \ openssl req -new -key $(DB_INFRA_SERVER_KEY) -out $(DB_INFRA_SERVER_CSR) && \ openssl x509 -req -days 365 -in $(DB_INFRA_SERVER_CSR) -signkey $(DB_INFRA_SERVER_KEY) -out $(DB_INFRA_SERVER_CRT) && \ - make db:secure:permissions + make db:chmod db\:chmod: chmod 600 $(DB_INFRA_SERVER_KEY) && chmod 600 $(DB_INFRA_SERVER_CRT) @@ -76,6 +75,7 @@ db\:rollback: @docker run -v $(DB_MIGRATE_VOL_MAP) --network $(ROOT_NETWORK) migrate/migrate -verbose -path=$(DB_MIGRATE_PATH) -database $(ENV_DB_URL) down 1 @printf "$(GREEN)[DB]$(NC) Migration rollback has finished.\n\n" +# --- Migrations db\:migrate\:create: docker run -v $(DB_MIGRATE_VOL_MAP) --network $(ROOT_NETWORK) migrate/migrate create -ext sql -dir $(DB_MIGRATE_PATH) -seq $(name) diff --git a/config/makefile/env.mk b/config/makefile/env.mk index 97ddd84f..5c4406a7 100644 --- a/config/makefile/env.mk +++ b/config/makefile/env.mk @@ -31,6 +31,11 @@ env\:fresh: fi env\:print: - @echo "APP NAME ... : $(ENV_APP_NAME)" - @echo "APP TYPE ... : $(ENV_APP_ENV_TYPE)" - @echo "APP ENV .... : $(ENV_APP_ENV)" + @echo "APP NAME ........ : $(ENV_APP_NAME) " + @echo "APP TYPE ........ : $(ENV_APP_ENV_TYPE) " + @echo "APP ENV ......... : $(ENV_APP_ENV) " + @echo "ROOT_NETWORK .... : $(ROOT_NETWORK) " + @echo " --------------------------------------- " + @echo "ENV_DB_URL ...... : $(ENV_DB_URL) " + @echo "DB_MIGRATE_PATH . : $(DB_MIGRATE_PATH) " + @echo "DB_MIGRATE_VOL_MAP: $(DB_MIGRATE_VOL_MAP)" diff --git a/database/infra/ssl/server.crt b/database/infra/ssl/server.crt index 5a9d47ba..9b02911d 100644 --- a/database/infra/ssl/server.crt +++ b/database/infra/ssl/server.crt @@ -1,21 +1,19 @@ -----BEGIN CERTIFICATE----- -MIIDXzCCAkegAwIBAgIUR4BGSsQUqTMoxQjJa2qz2kADzXwwDQYJKoZIhvcNAQEL -BQAwWDELMAkGA1UEBhMCU0cxEjAQBgNVBAgMCVNpbmdhcG9yZTESMBAGA1UEBwwJ -U2luZ2Fwb3JlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwHhcN -MjUwNDA4MDk0NDI2WhcNMjYwNDA4MDk0NDI2WjBYMQswCQYDVQQGEwJTRzESMBAG -A1UECAwJU2luZ2Fwb3JlMRIwEAYDVQQHDAlTaW5nYXBvcmUxITAfBgNVBAoMGElu -dGVybmV0IFdpZGdpdHMgUHR5IEx0ZDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC -AQoCggEBALPNWCKN/atF0XXGA4XqghQ/6WdEnsi9nUFgbUUziY/5+BktDEiAyBR0 -kSg27aCtPy+6TGvrAVOSQz0zMw/StU/D6xKFCCEVpQJUbvOMZtJnmMHZZDJIZIrn -F4GUZlViH99TdTr1Ic2WrbTkdbp09Px3oLWXltzhQc88WpZyTasidOfe8DvqkCMq -PPuUJOqI7UAChkf81E7XDaHCuAnBZnb73CJbKYWnSYUewS8IGsSVjercJtn2t/jP -r/MOlEKON1p4iLDupeh5PTYIir/lG2r119n6IZeSq0e9rBC4uV0EEoyvbtKG1tb2 -1fyjEteRwrEN+0DDOeJeRtu17Y4G4bcCAwEAAaMhMB8wHQYDVR0OBBYEFFJSEIMF -zpnjWdwUn1Kh2lYdEDInMA0GCSqGSIb3DQEBCwUAA4IBAQAY1tYH5eateT6DYNwo -rrT8C/9YZHIEBtgfv8Ayhbrtx8YLsS6igyXhN6f+iu9Bj64m3bI/fAWb40f4ev1f -tE6lkSEVU9G2qzFxh843jpCnrF7+NZ+8GjDJ+okcGQQUQ7yZwd732d5h1odIMJ2h -/RgP3b6MRQrGq+CGeibc+1qHjIEVDgFDd5qZl4Uj+tjBlLLYzew3C6U8nHgSTFcE -YR0ck0Kt2IkMB1MqBzvJw3WEy690k3KS+i1fqLsZr0ZiaoP0JBlzdx7b8Ea08sem -ywtniMOX2TxPvd4Tj5kkI+MF40sK/3bs+EKS1qqnhmzXyprjp4L3EaeG1dgcDKX0 -6vCE +MIIDITCCAgmgAwIBAgIUUVXiUem90E7ghf5dL/svbBXsshgwDQYJKoZIhvcNAQEL +BQAwOTELMAkGA1UEBhMCU0cxCzAJBgNVBAgMAlNHMQswCQYDVQQHDAJTRzEQMA4G +A1UECgwHZ29jYW50bzAeFw0yNTA2MDQwNTQ5MzVaFw0yNjA2MDQwNTQ5MzVaMDkx +CzAJBgNVBAYTAlNHMQswCQYDVQQIDAJTRzELMAkGA1UEBwwCU0cxEDAOBgNVBAoM +B2dvY2FudG8wggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCKV716RAFp +PlbbYHPwAYmb1XqOUoznnlJ0HsW7k5vXiiSoHV90huPuP3vyBRX0l/wUoYvyjRka +t1ITTF0eahTjm8UQ6whqu8VsUhB5ktjanAVeO6PsXgksvZ1FrIM2YfXkzMUmVlDs +qsSmGSDwaZMfHpDUeXhmMJkstO1h+Pk3tmGez4zxHEhDRHHEpHlKPGRIjbb36EZL +LEtMJAMANzeSZZl8HDRKTWP/L4NFpY7PBbIo5ucHXGJHkmqrvUPoROGl1NxKDZgF +yvMkj5FeLR+akxCKpY22QI0f7JdchEwU5HuuTAAVQScM5Um9kpo6CKck3Dfv5oRE +R7aE8nqrUMvTAgMBAAGjITAfMB0GA1UdDgQWBBTUEft1y+FcQH2XgbD4zzuvGfnl +KzANBgkqhkiG9w0BAQsFAAOCAQEANPaRIQROVkxPqcucgH61SXL5BNIDz0A/qJeL +WAeko94Bp+yEzoxFUJd2ZlWLHuYykvi1A2XuQAbElzrqfNm0+AoS7GwTcZmK0je3 +qLuVSvyim8LFNL/WRQO/ScaPsbSX7fyCMDnNxNVA+IhZVuSnCvijEGWaRQPzcaqf +mcK7QOUERpbUghaYcYZJTfpMcHYi7bEht0+oCBrBZaZyCeRBzrSFKiwsQP2c2GdM +2f2rzJQVHjPXDH15UAsCpe14eJcfzuRSRX6V79PJYxPZTPdOqxZtMgnCo0bQrV/q +TARcz6GlIYQraM0rqIXvwyL3NpGq7ccWNW4a6xFeGa/2+mh/Bg== -----END CERTIFICATE----- diff --git a/database/infra/ssl/server.csr b/database/infra/ssl/server.csr index f27d682c..88390087 100644 --- a/database/infra/ssl/server.csr +++ b/database/infra/ssl/server.csr @@ -1,17 +1,16 @@ -----BEGIN CERTIFICATE REQUEST----- -MIICnTCCAYUCAQAwWDELMAkGA1UEBhMCU0cxEjAQBgNVBAgMCVNpbmdhcG9yZTES -MBAGA1UEBwwJU2luZ2Fwb3JlMSEwHwYDVQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0 -eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCzzVgijf2rRdF1 -xgOF6oIUP+lnRJ7IvZ1BYG1FM4mP+fgZLQxIgMgUdJEoNu2grT8vukxr6wFTkkM9 -MzMP0rVPw+sShQghFaUCVG7zjGbSZ5jB2WQySGSK5xeBlGZVYh/fU3U69SHNlq20 -5HW6dPT8d6C1l5bc4UHPPFqWck2rInTn3vA76pAjKjz7lCTqiO1AAoZH/NRO1w2h -wrgJwWZ2+9wiWymFp0mFHsEvCBrElY3q3CbZ9rf4z6/zDpRCjjdaeIiw7qXoeT02 -CIq/5Rtq9dfZ+iGXkqtHvawQuLldBBKMr27ShtbW9tX8oxLXkcKxDftAwzniXkbb -te2OBuG3AgMBAAGgADANBgkqhkiG9w0BAQsFAAOCAQEAQaVIqnIg8A3323PI0ttc -meE9as7Vx8qclBlILaDgNvSDNUYoqLja6gEap9anCCmvUNNuV7FUPsqpJLQQlSOr -+LYtdo6JX1EfPO6ZFMjzyjlGDPQLnw9OrPlVIoY38XfrKU+il1nFQd7Jv1dm5WvP -DdMPtL5tS2hh6zYaOwESQMj9qkW7FgOwpKyxba82B80+qDk3WiMFH+29krrdtSfQ -QyzPWIJ9Fy/HXtP3A9RC9ZF/S4j1Dqd1oQ2g9kq9a3rEOOb2eCDxUjADniw1qkVX -N3Kt5j+37sbxSESfhM4iNMo/O0YpqN3ccD1+exyxHZcqTxmDtUgY7XrujdIk7fLH -Qg== +MIICfjCCAWYCAQAwOTELMAkGA1UEBhMCU0cxCzAJBgNVBAgMAlNHMQswCQYDVQQH +DAJTRzEQMA4GA1UECgwHZ29jYW50bzCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC +AQoCggEBAIpXvXpEAWk+Vttgc/ABiZvVeo5SjOeeUnQexbuTm9eKJKgdX3SG4+4/ +e/IFFfSX/BShi/KNGRq3UhNMXR5qFOObxRDrCGq7xWxSEHmS2NqcBV47o+xeCSy9 +nUWsgzZh9eTMxSZWUOyqxKYZIPBpkx8ekNR5eGYwmSy07WH4+Te2YZ7PjPEcSENE +ccSkeUo8ZEiNtvfoRkssS0wkAwA3N5JlmXwcNEpNY/8vg0Wljs8Fsijm5wdcYkeS +aqu9Q+hE4aXU3EoNmAXK8ySPkV4tH5qTEIqljbZAjR/sl1yETBTke65MABVBJwzl +Sb2SmjoIpyTcN+/mhERHtoTyeqtQy9MCAwEAAaAAMA0GCSqGSIb3DQEBCwUAA4IB +AQBIUSHGl4Cnj4bjSc8cb4iQ+eKSuY22ndeEz9Bnd9/BFnf+1kh0yGPK6P8zmtcy +0Jw5Vuoxd+AXjR54of7WWtbF0Ik/SV62Ke+XkH1XUmEMl5Ch71v6rnWSYqYmKhIK +2jlg5Tx8bPCjtBvXhAtgk4dDbENvNpcM9+AOwGRfOzuS/kYfil5RvzO84bTjw+Z2 +7A5BJ/qPyLhpof4dfjrkTIFjSI6gCljei7tZEuUSD9YxEXBBBFEq7PdypTcnZ46S +kTCx1WTGrVGA3kBTnbyHlBbfg+hPXIT13px2PyK0qq4JiiKPrDiUmVCqbzuOOymU +5us5erd07C7BAHmbup+BMAtZ -----END CERTIFICATE REQUEST----- diff --git a/database/infra/ssl/server.key b/database/infra/ssl/server.key index bd3105f1..31699d54 100644 --- a/database/infra/ssl/server.key +++ b/database/infra/ssl/server.key @@ -1,28 +1,28 @@ -----BEGIN PRIVATE KEY----- -MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCzzVgijf2rRdF1 -xgOF6oIUP+lnRJ7IvZ1BYG1FM4mP+fgZLQxIgMgUdJEoNu2grT8vukxr6wFTkkM9 -MzMP0rVPw+sShQghFaUCVG7zjGbSZ5jB2WQySGSK5xeBlGZVYh/fU3U69SHNlq20 -5HW6dPT8d6C1l5bc4UHPPFqWck2rInTn3vA76pAjKjz7lCTqiO1AAoZH/NRO1w2h -wrgJwWZ2+9wiWymFp0mFHsEvCBrElY3q3CbZ9rf4z6/zDpRCjjdaeIiw7qXoeT02 -CIq/5Rtq9dfZ+iGXkqtHvawQuLldBBKMr27ShtbW9tX8oxLXkcKxDftAwzniXkbb -te2OBuG3AgMBAAECggEASIM7lK/8Cltddqh1mkfxzvXZjS7E9MNXzNp1Jw/6Xgjb -UFf1GLZrOqiqM/Q3EHJeRcLV+D3uKoSVvnRMFwkM207xmmXxWdpvUkm391v7ycZC -+obQXGEKv2QkfDtbq/qnTPtND4p16AJpKsdqXVi2xqz+MM4iZxEnZ8r446zUevv8 -kTgrWzYworCot+qQIlML4nG27OI2Mx6jdLMBMVj54GJi+uhfZdAxfPEKhoiAQScB -5Khu1FiglaiOo5xXEblkrkuG3+diPD/A3jLjqFJZ7OYH3QnAixno+uXzJkqvT3Gd -EgHTJ4UBnVTrZNdOZNKaEAno63neg1oBx5CYmErgsQKBgQDkjrY+LxmglVKELjsr -3/2oiyGtVRrPsenH8bWBwIzY/mcYGH57RzhA6tIlYDK5u/ISwjzBjyThCSxxnqIW -9KO5gThHViWcGJHONwqNBo2gkx1Ge1Qj/wlqd8Ql4DT/P2e7MllxgmmVu6exhIxV -QcWpZsAdWcniFSFlehZ1JaFQ0QKBgQDJZAOx8dYB+4CQtkN8A22Vk/wEb9ys7eRP -6GOrGkzd2Y12yWeTnGx0SvK+iRw0GZTSO3QXNmXLns26LiLXhtqs9poLsPUKGzOO -zfwFfWznBDAZvW/qAzr1F0DG832sI0mNSDl5FsrSe2u6VG2+4vp68h2Le3HLob5e -Sdh1vY3sBwKBgHExQI5xcya1bSVrZACpsQ1swmP+lwWvnhFY4sR84QSCkfo7/z/8 -mJ6F7Ud3agfUTeH+cmqGAwS0L1+h6bKmvAMePQoPXxb8kBFp7v7C9RdGZKRIZfZh -0374C5uae4TCGRR7rhJqPPJb+oQPGhULOuJXseOXWUVvo5eHLGIeHdNRAoGBAJ77 -LU+UMfVurZePysZjjma+Y/y8seByDAJo2gWAxZ182IglhnaozZUgdXCknHckmq87 -7/FDKCkOPCn1sduiwY45PnJsR4Sq5JCfW4yZ7xaP38jyGx8JXcmNib2FCniRgsbd -dUF6FLMEa460h85hMItOBrTNxo+SJ84XTaHk+dyRAoGBAMH8+qyhtRRCLSfcfUAE -pe8a/aZg2dTv7LDbC0Bh9CnAhCmoXSfK81q1lNXe+0BERvzqG7tBlduJgdr0RNk9 -3slTUH1KFTLgcATc3AuVM3M0/JIHQQqEOw6GpI6BDoy0K9ryYD3sPA2o2Y5t7gLI -4iYJitAWbdXmNsuTNgBSt1C9 +MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQCKV716RAFpPlbb +YHPwAYmb1XqOUoznnlJ0HsW7k5vXiiSoHV90huPuP3vyBRX0l/wUoYvyjRkat1IT +TF0eahTjm8UQ6whqu8VsUhB5ktjanAVeO6PsXgksvZ1FrIM2YfXkzMUmVlDsqsSm +GSDwaZMfHpDUeXhmMJkstO1h+Pk3tmGez4zxHEhDRHHEpHlKPGRIjbb36EZLLEtM +JAMANzeSZZl8HDRKTWP/L4NFpY7PBbIo5ucHXGJHkmqrvUPoROGl1NxKDZgFyvMk +j5FeLR+akxCKpY22QI0f7JdchEwU5HuuTAAVQScM5Um9kpo6CKck3Dfv5oRER7aE +8nqrUMvTAgMBAAECggEAJEHKjvizxflomiY1PHmqrwTMEfDgrPN5eKV3/Sk6dsrl +wImyMsAHjLFmso9SqcALePy9yNvh8HaLNDOXVBlJUD3K8BwpIJAFtdXsK3CpFOI/ +JetLku8ySF+JkHEeEmqqH0TrhpiorN40m7OKRnfk7wr7ujP7sgyamHTyofK2njrz +uho5pEQA2dogO1DNvAWwWpVn0CLX9HQyDP2N87W5bJf3nfKsPeW/WOh6CrQPSJ5E +5Trt3v2ou51rHFAM+avQfaEcMEzZoZGxTAjbmIj+UVpNvkUm4Da1M8f7uMZiIdCS +iuZjKIhGLPEJoI6zgX/iX9BoANQrOZqyBTHmopIbgQKBgQDCCam/b5xUd3Prarkl +LLr6eZ8bXeM6jUPkqeRyLs9xGNWsxRsqTvHFhAOZ0Ir1sQVtD49TCjyQCPe+H+YT +2k+dSQjOsxdM1oL3GR0zmEM3sp+KKHygvFPezIOw1ynQFpHoF/2NlmXL6X3wGkHY +ZgHjyhsxt8NvuiHXgotxurJQ+wKBgQC2hRTQv2shBMPazv5kBV5pclGoRv3j7WvS +SU3UhnhkTxfpDLNiNUbpvTshVPA9WtkUCnCw0LdBWohzKvlFIjdpL1gg4orVSKEC +4AM+ZKr3Xy2bPb/r0rtbD9hGQZiQJDMIgYuk8tKNQkwvhhkDZ7Wf8iR4T1Nt//v3 +GMKroW9pCQKBgQC2CnTL2n1TLYJ+kfDDdLSy+1mPRkVBkHjq1Y0ypsINvBvzbDSx +O8FN6i2qp+FG4d5SVG/Fm2v4QcGUCL9FTuK0kGmH6rNobjQOeOxRlH8ziQxuhM9v +yV/yPfMq/KIIzLP0iFVj+X7lkNiLY0b1K7aIK/vZaCsd7gWD98C1YU+b8wKBgHV8 +0NtWfFUyxgfxOluUASQLTHjvybqQN9mTCiCFtrWLHC8N1+KdvNn0zz0zeblk41s9 +JTEMCQpuhmrr/Kz9y4FP0oDIkumb6Nj67duZ3VuCzs6hPwtECQoi9uqyiswuIROW +oBc7n0ECrhvhS/SfK5Cbw9IV7fRe1QhHzffA4QBRAoGBAL2yIRoY4JG9LaiBM3kH +bPFqBPb62bT1Kmw/mSVeO8bLOvQO4VCq036U8Mk+7vU9dAai/M6rFc31osKxYeCH +zlSyCCbYJURJ7ukr+akFc8DGEWQo1ds6D+MbtOZUa7hCkyNrvmBOvm+xgdQmwOUz +guoQfzDluD0WYO5zk3MXgun1 -----END PRIVATE KEY----- diff --git a/database/schema.go b/database/schema.go index 7888c05c..59c2089b 100644 --- a/database/schema.go +++ b/database/schema.go @@ -10,7 +10,7 @@ var schemaTables = []string{ "users", "posts", "categories", "post_categories", "tags", "post_tags", "post_views", "post_views", "comments", - "likes", + "likes", "newsletters", } func GetSchemaTables() []string { diff --git a/database/seeder/main.go b/database/seeder/main.go index 7a404c7e..4d0a420c 100644 --- a/database/seeder/main.go +++ b/database/seeder/main.go @@ -1,115 +1,131 @@ package main import ( - "github.com/gocanto/blog/boost" - "github.com/gocanto/blog/database" - "github.com/gocanto/blog/database/seeder/seeds" - "github.com/gocanto/blog/env" - "github.com/gocanto/blog/pkg/cli" - "sync" - "time" + "fmt" + "github.com/gocanto/blog/boost" + "github.com/gocanto/blog/database" + "github.com/gocanto/blog/database/seeder/seeds" + "github.com/gocanto/blog/env" + "github.com/gocanto/blog/pkg/cli" + "os" + "os/exec" + "sync" + "time" ) var environment *env.Environment func init() { - secrets, _ := boost.Spark("./.env") + secrets, _ := boost.Spark("./.env") - environment = secrets + environment = secrets } func main() { - dbConnection := boost.MakeDbConnection(environment) - logs := boost.MakeLogs(environment) + clearScreen() + dbConnection := boost.MakeDbConnection(environment) + logs := boost.MakeLogs(environment) - defer (*logs).Close() - defer (*dbConnection).Close() + defer (*logs).Close() + defer (*dbConnection).Close() - // [1] --- Create the Seeder Runner. - seeder := seeds.MakeSeeder(dbConnection, environment) + // [1] --- Create the Seeder Runner. + seeder := seeds.MakeSeeder(dbConnection, environment) - // [2] --- Truncate the DB. - if err := seeder.TruncateDB(); err != nil { - panic(err) - } else { - cli.MakeTextColour("DB Truncated successfully ...", cli.Green).Println() - time.Sleep(2 * time.Second) - } + // [2] --- Truncate the DB. + if err := seeder.TruncateDB(); err != nil { + panic(err) + } else { + cli.MakeTextColour("DB Truncated successfully ...", cli.Green).Print() + time.Sleep(2 * time.Second) + } - // [3] --- Seed users and posts sequentially because the below seeders depend on them. - UserA, UserB := seeder.SeedUsers() - posts := seeder.SeedPosts(UserA, UserB) + // [3] --- Seed users and posts sequentially because the below seeders depend on them. + UserA, UserB := seeder.SeedUsers() + posts := seeder.SeedPosts(UserA, UserB) - categoriesChan := make(chan []database.Category) - tagsChan := make(chan []database.Tag) + categoriesChan := make(chan []database.Category) + tagsChan := make(chan []database.Tag) - go func() { - defer close(categoriesChan) + go func() { + defer close(categoriesChan) - cli.MakeTextColour("Seeding categories ...", cli.Yellow).Println() - categoriesChan <- seeder.SeedCategories() - }() + cli.MakeTextColour("Seeding categories ...", cli.Yellow).Print() + categoriesChan <- seeder.SeedCategories() + }() - go func() { - defer close(tagsChan) + go func() { + defer close(tagsChan) - cli.MakeTextColour("Seeding tags ...", cli.Magenta).Println() - tagsChan <- seeder.SeedTags() - }() + cli.MakeTextColour("Seeding tags ...", cli.Magenta).Print() + tagsChan <- seeder.SeedTags() + }() - // [4] Use channels to concurrently seed categories and tags since they are main dependencies. - categories := <-categoriesChan - tags := <-tagsChan + // [4] Use channels to concurrently seed categories and tags since they are main dependencies. + categories := <-categoriesChan + tags := <-tagsChan - // [5] Use a WaitGroup to run independent seeding tasks concurrently. - var wg sync.WaitGroup - wg.Add(6) + // [5] Use a WaitGroup to run independent seeding tasks concurrently. + var wg sync.WaitGroup + wg.Add(6) - go func() { - defer wg.Done() + go func() { + defer wg.Done() - cli.MakeTextColour("Seeding comments ...", cli.Blue).Println() - seeder.SeedComments(posts...) - }() + cli.MakeTextColour("Seeding comments ...", cli.Blue).Print() + seeder.SeedComments(posts...) + }() - go func() { - defer wg.Done() + go func() { + defer wg.Done() - cli.MakeTextColour("Seeding likes ...", cli.Cyan).Println() - seeder.SeedLikes(posts...) - }() + cli.MakeTextColour("Seeding likes ...", cli.Cyan).Print() + seeder.SeedLikes(posts...) + }() - go func() { - defer wg.Done() + go func() { + defer wg.Done() - cli.MakeTextColour("Seeding posts-categories ...", cli.Gray).Println() - seeder.SeedPostsCategories(categories, posts) - }() + cli.MakeTextColour("Seeding posts-categories ...", cli.Gray).Print() + seeder.SeedPostsCategories(categories, posts) + }() - go func() { - defer wg.Done() + go func() { + defer wg.Done() - cli.MakeTextColour("Seeding posts-tags ...", cli.Magenta).Println() - seeder.SeedPostTags(tags, posts) - }() + cli.MakeTextColour("Seeding posts-tags ...", cli.Magenta).Print() + seeder.SeedPostTags(tags, posts) + }() - go func() { - defer wg.Done() + go func() { + defer wg.Done() - cli.MakeTextColour("Seeding views ...", cli.Yellow).Println() - seeder.SeedPostViews(posts, UserA, UserB) - }() + cli.MakeTextColour("Seeding views ...", cli.Yellow).Print() + seeder.SeedPostViews(posts, UserA, UserB) + }() - go func() { - defer wg.Done() + go func() { + defer wg.Done() - cli.MakeTextColour("Seeding Newsletters ...", cli.Green).Println() - if err := seeder.SeedNewsLetters(); err != nil { - cli.MakeTextColour(err.Error(), cli.Red).Println() - } - }() + cli.MakeTextColour("Seeding Newsletters ...", cli.Green).Print() + if err := seeder.SeedNewsLetters(); err != nil { + cli.MakeTextColour(err.Error(), cli.Red).Print() + } + }() - wg.Wait() + wg.Wait() - cli.MakeTextColour("DB seeded as expected.", cli.Green).Println() + cli.MakeTextColour("DB seeded as expected.", cli.Green).Print() +} + +func clearScreen() { + cmd := exec.Command("clear") + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Run(); err != nil { + message := fmt.Sprintf("Could not clear screen. Error: %s", err.Error()) + + cli.MakeTextColour(message, cli.Red).Print() + } } diff --git a/pkg/cli/colour.go b/pkg/cli/colour.go index 32eb7bec..d554793d 100644 --- a/pkg/cli/colour.go +++ b/pkg/cli/colour.go @@ -36,14 +36,22 @@ func MakeTextColour(text string, colour string) TextColour { } } -func (t TextColour) Print() string { - return fmt.Sprintf("%s > %s %s\n", t.colour, t.text, Reset) +func (t TextColour) Print() { + _, err := fmt.Print(t.String()) + + if err != nil { + _, _ = fmt.Fprintf(os.Stderr, "%v\n", err) + } } func (t TextColour) Println() { - _, err := fmt.Println(fmt.Sprintf("%s > %s %s\n", t.colour, t.text, Reset)) + _, err := fmt.Println(t.String()) if err != nil { _, _ = fmt.Fprintf(os.Stderr, "%v\n", err) } } + +func (t TextColour) String() string { + return fmt.Sprintf("%s > %s %s\n", t.colour, t.text, Reset) +} diff --git a/web/index.html b/web/index.html index 63a0147d..0027af26 100644 --- a/web/index.html +++ b/web/index.html @@ -4,14 +4,9 @@ -
-
- I am a dedicated engineering leader passionate about building seamless, high-quality experiences for organizations and
- open source. With over twenty years of
-
+ I am an engineering leader who’s passionate about building reliable and smooth software that strive to make a difference. With over twenty years in + software development and architecture, I’ve worked extensively with + GO, + Node.js, + TypeScript, and + PHP. I’m also comfortable with frameworks/libraries such as + Laravel, + Vue, + Symfony, and + Next.js.
-- Beyond technical expertise, I have a strong leadership background in managing - cross-functional teams, optimizing workflows, and implementing best practices that drive productivity and innovation. I thrive in fast-paced - environments that demand strategic thinking, problem-solving, and a commitment to delivering high-quality results. +
+ I’ve led teams in designing and delivering scalable, high-performance systems that run efficiently even in complex environments. Beyond writing code, I + focus on helping teams work better together by improving workflows and encouraging innovation. +
++ I thrive in fast-paced settings where clear thinking and problem-solving are key, and I’m always committed to delivering high-quality results. +
++ For me, software has always been more than just a job—it’s a way to turn ideas into real solutions. Over the years, I’ve enjoyed tackling challenges, + learning new technologies, and guiding talented teams to create tools that users and businesses rely on. +
++ Today, I combine deep technical skills with thoughtful leadership to help teams push boundaries and build software that grows and scales with purpose.
- I’m excited to connect by email or - X to chat about projects and ideas. I’m always open to freelance or long-term projects, - so please feel free to reach out. +
+ I’m happy to connect by email to discuss projects and ideas. While I’m + not always available for freelance or long-term work, please don’t hesitate to reach out anytime.
-Tell me about your vision, and if it seems like a good fit, we can explore collaborating down the road.
Writer, Speaker, Developer, Founder, and Leadership.
-+
I'm a full-stack Software Engineer leader with over two decades of building complex web systems and products, specialising in areas like e-commerce, banking, cross-payment solutions, cyber security, and customer success.
diff --git a/web/src/partials/WidgetSocialPartial.vue b/web/src/partials/WidgetSocialPartial.vue new file mode 100644 index 00000000..c8630270 --- /dev/null +++ b/web/src/partials/WidgetSocialPartial.vue @@ -0,0 +1,63 @@ + +