{"id":20415825,"url":"https://github.com/rbkgh/billablehoursapi","last_synced_at":"2026-04-09T18:41:27.349Z","repository":{"id":90539291,"uuid":"269854913","full_name":"RbkGh/billableHoursAPI","owner":"RbkGh","description":null,"archived":false,"fork":false,"pushed_at":"2020-06-09T06:01:35.000Z","size":1439,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-03-05T03:41:34.743Z","etag":null,"topics":["docker","docker-compose","gradle","hibernate","integration-testing","java","k8s","kotlin","kubernetes","spring-boot","unit-testing"],"latest_commit_sha":null,"homepage":null,"language":"Kotlin","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/RbkGh.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-06-06T03:26:38.000Z","updated_at":"2020-06-09T06:13:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"facba0d4-4aeb-487f-ac04-cbc1096bc35c","html_url":"https://github.com/RbkGh/billableHoursAPI","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/RbkGh/billableHoursAPI","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RbkGh%2FbillableHoursAPI","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RbkGh%2FbillableHoursAPI/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RbkGh%2FbillableHoursAPI/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RbkGh%2FbillableHoursAPI/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/RbkGh","download_url":"https://codeload.github.com/RbkGh/billableHoursAPI/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/RbkGh%2FbillableHoursAPI/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":274902237,"owners_count":25371074,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-09-12T02:00:09.324Z","response_time":60,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["docker","docker-compose","gradle","hibernate","integration-testing","java","k8s","kotlin","kubernetes","spring-boot","unit-testing"],"created_at":"2024-11-15T06:17:41.932Z","updated_at":"2026-04-09T18:41:22.301Z","avatar_url":"https://github.com/RbkGh.png","language":"Kotlin","readme":"# billableHours API - compute billable hours that lawyers have worked on projects\n### Shot For 100% Code Coverage\n![alt text](https://github.com/RbkGh/billableHoursAPI/blob/master/demo_test.png)\n### Requirements\n\u003e Kotlin V1.3.72+ \u003cbr\u003e\n\u003e docker V18.09.2+ \u003cbr\u003e\n\u003e docker-compose v1.23.2+\n### For a quick introduction to the project design decisions,architecture,trade-offs and others, listen to this audio \n:point_down: :point_down: :point_down:\n\u003e [Right Here](https://bit.ly/BillableAPI)  :point_left: :point_left: \u003cbr\u003e\n:point_up: :point_up: :point_up: \n\n### Run All Tests\n\u003e just type code below in your root directory,no need to have gradle installed on your machine as we are using the wrapper\n```$xslt\n./gradlew test\n```\n### Quick Run(Gradle)\n```$xslt\n./gradlew bootRun\n```\n### Quick Start - Run With Docker [If you are running with docker instead,then change the active profile property in application.properties to \"prod\"]\n```$xslt\n\n 1. docker-compose build\n 2. docker-compose up [Make sure nothing is running on port 8080] \n \n```\n\u003e Once you use the docker ,You can now access API on http://localhost:8080/billablehours-api , not http://localhost:8080/ \u003cbr\u003e\n\u003e Note, you should be able to run all the sample responses below and get the same result.\n### View Documentation About All Endpoints\n[http://localhost:8080/swagger-ui.html](http://localhost:8080/swagger-ui.html)\n\n\n### Default Credentials \n```$xslt\nusername = lawyer1@gmail.com\npassword = pass1234\nRole =\u003e Lawyer \n\nusername = finance1@gmail.com\npassword = pass1234\nRole =\u003e Finance Administrator\n\n```\n\n### Sample Requests And Responses \n#### Authentication or signin \n\u003e Request\n```$xslt\nPOST http://localhost:8080/api/v1/auth/signin\nAccept: */*\nCache-Control: no-cache\nContent-Type: application/json\n\n{\n  \"username\": \"lawyer1@gmail.com\",\n  \"password\": \"pass1234\"\n}\n\n```\n\n\u003e Response\n```$xslt\n{\n  \"token\": \"eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsYXd5ZXIxQGdtYWlsLmNvbSIsImlhdCI6MTU5MTU5MDg5NCwiZXhwIjoxNTkyMTk1Njk0fQ.pavyfoIoZW-f-R07UG2aJjszP2ttycQZuFQiJeSJ-N1YMjK18M2_ciS2-sFaA_4OAK-UkySni_gTvAG77wtgJg\",\n  \"id\": 1,\n  \"firstName\": \"rodney\",\n  \"roleName\": \"ROLE_LAWYER\",\n  \"surName\": \"boachie\"\n}\n```\n\n### Create Lawyer Billable Work Log\n\u003eRequest\n```$xslt\nPOST http://localhost:8080/api/v1/lawyer/1/bill\nAccept: */*\nCache-Control: no-cache\nContent-Type: application/json\nAuthorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsYXd5ZXIxQGdtYWlsLmNvbSIsImlhdCI6MTU5MTU1ODg4MywiZXhwIjoxNTkyMTYzNjgzfQ.OKY-SJjgzmKAfKd0HbJyMIxWnJqsgnUayo2M2CDVWdSNzSzldOG8x3rGrrVBBl9K6Rjp_hGQWYFXLNOd2tqtpg\n\n{\n  \"billableRate\": 300,\n  \"companyID\": 1,\n  \"dateOfDay\": \"2020-06-07T19:39:52.193+00:00\",\n  \"startTime\": \"2023-03-07T07:39:52.000+00:00\",\n  \"endTime\": \"2023-03-07T09:39:52.000+00:00\",\n  \"userID\": 1\n}\n\n```\n\u003eResponse\n```$xslt\nHTTP/1.1 201 \nVary: Origin\nVary: Access-Control-Request-Method\nVary: Access-Control-Request-Headers\nX-Content-Type-Options: nosniff\nX-XSS-Protection: 1; mode=block\nCache-Control: no-cache, no-store, max-age=0, must-revalidate\nPragma: no-cache\nExpires: 0\nTransfer-Encoding: chunked\nDate: Mon, 08 Jun 2020 04:41:02 GMT\n\n\u003cResponse body is empty\u003e\n\nResponse code: 201; Time: 229ms; Content length: 0 bytes\n```\n\n### Get Lawyer Billable Work Period Within Time Range (Week,Month or Whatever)\n\u003e Request \n```$xslt\nGET http://localhost:8080/api/v1/lawyer/1/timesheet?startDate=2023-03-07\u0026endDate=2023-03-07\nAccept: */*\nCache-Control: no-cache\nContent-Type: application/json\nAuthorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJsYXd5ZXIxQGdtYWlsLmNvbSIsImlhdCI6MTU5MTU1ODg4MywiZXhwIjoxNTkyMTYzNjgzfQ.OKY-SJjgzmKAfKd0HbJyMIxWnJqsgnUayo2M2CDVWdSNzSzldOG8x3rGrrVBBl9K6Rjp_hGQWYFXLNOd2tqtpg\n\n```\n\u003e Response \n```$xslt\nGET http://localhost:8080/api/v1/lawyer/1/timesheet?startDate=2023-03-07\u0026endDate=2023-03-07\n\nHTTP/1.1 200 \nVary: Origin\nVary: Access-Control-Request-Method\nVary: Access-Control-Request-Headers\nX-Content-Type-Options: nosniff\nX-XSS-Protection: 1; mode=block\nCache-Control: no-cache, no-store, max-age=0, must-revalidate\nPragma: no-cache\nExpires: 0\nContent-Type: application/json\nTransfer-Encoding: chunked\nDate: Mon, 08 Jun 2020 16:56:40 GMT\nKeep-Alive: timeout=60\nConnection: keep-alive\n\n[\n  {\n    \"id\": 1,\n    \"user\": {\n      \"id\": 1,\n      \"email\": \"lawyer1@gmail.com\",\n      \"dateCreated\": 1591592050000,\n      \"firstName\": \"rodney\",\n      \"surName\": \"boachie\",\n      \"dateOfBirth\": 1591574400000,\n      \"accountActive\": true,\n      \"roleList\": [\n        {\n          \"id\": 1,\n          \"roleName\": {\n            \"roleDescription\": \"ROLE_LAWYER\"\n          },\n          \"privilegeList\": []\n        }\n      ]\n    },\n    \"billableRate\": 300.00,\n    \"company\": {\n      \"id\": 1,\n      \"companyName\": \"MTN\"\n    },\n    \"dateOfDay\": 1591558792193,\n    \"startTime\": 1678174792000,\n    \"endTime\": 1678181992000,\n    \"noOfHours\": 2,\n    \"durationCost\": 600.00\n  }\n]\n```\n\n### Get All Lawyer Billable Work Period - Implemented Role Authorization Security such that Only Accessible By Finance Administrator Users\n\n\u003e Request \n```$xslt\nGET http://localhost:8080/api/v1/lawyer/timesheet\nAccept: */*\nCache-Control: no-cache\nContent-Type: application/json\nAuthorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmaW5hbmNlMUBnbWFpbC5jb20iLCJpYXQiOjE1OTE2Mzg1MzEsImV4cCI6MTU5MjI0MzMzMX0.FolHgdDGWDD3nYsbRhYBffpHcHfLegefBEZSMhQWgqElKwRV4M2bENZhmqQvkNU7qdhkW4MmGSz6jMx2hOqp8w\n\n```\n\u003e Response \n```$xslt\nGET http://localhost:8080/api/v1/lawyer/timesheet\n\nHTTP/1.1 200 \nVary: Origin\nVary: Access-Control-Request-Method\nVary: Access-Control-Request-Headers\nX-Content-Type-Options: nosniff\nX-XSS-Protection: 1; mode=block\nCache-Control: no-cache, no-store, max-age=0, must-revalidate\nPragma: no-cache\nExpires: 0\nContent-Type: application/json\nTransfer-Encoding: chunked\nDate: Mon, 08 Jun 2020 16:56:40 GMT\nKeep-Alive: timeout=60\nConnection: keep-alive\n\n[\n  {\n    \"id\": 1,\n    \"user\": {\n      \"id\": 1,\n      \"email\": \"lawyer1@gmail.com\",\n      \"dateCreated\": 1591592050000,\n      \"firstName\": \"rodney\",\n      \"surName\": \"boachie\",\n      \"dateOfBirth\": 1591574400000,\n      \"accountActive\": true,\n      \"roleList\": [\n        {\n          \"id\": 1,\n          \"roleName\": {\n            \"roleDescription\": \"ROLE_LAWYER\"\n          },\n          \"privilegeList\": []\n        }\n      ]\n    },\n    \"billableRate\": 300.00,\n    \"company\": {\n      \"id\": 1,\n      \"companyName\": \"MTN\"\n    },\n    \"dateOfDay\": 1591558792193,\n    \"startTime\": 1678174792000,\n    \"endTime\": 1678181992000,\n    \"noOfHours\": 2,\n    \"durationCost\": 600.00\n  },\n     {\n       \"id\": 2,\n       \"user\": {\n         \"id\": 1,\n         \"email\": \"lawyer1@gmail.com\",\n         \"dateCreated\": 1591592050000,\n         \"firstName\": \"rodney\",\n         \"surName\": \"boachie\",\n         \"dateOfBirth\": 1591574400000,\n         \"accountActive\": true,\n         \"roleList\": [\n           {\n             \"id\": 1,\n             \"roleName\": {\n               \"roleDescription\": \"ROLE_LAWYER\"\n             },\n             \"privilegeList\": []\n           }\n         ]\n       },\n       \"billableRate\": 300.00,\n       \"company\": {\n         \"id\": 1,\n         \"companyName\": \"MTN\"\n       },\n       \"dateOfDay\": 1591558792193,\n       \"startTime\": 1678174792000,\n       \"endTime\": 1678181992000,\n       \"noOfHours\": 2,\n       \"durationCost\": 600.00\n     }\n]\n```\n\n### \n\u003e Request : \n```$xslt\nGET http://localhost:8080/api/v1/finance/company/1/invoice?startDate=2020-06-07\u0026endDate=2020-06-07\nAccept: */*\nCache-Control: no-cache\nContent-Type: application/json\nAuthorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJzdWIiOiJmaW5hbmNlMUBnbWFpbC5jb20iLCJpYXQiOjE1OTE2Mzg1MzEsImV4cCI6MTU5MjI0MzMzMX0.FolHgdDGWDD3nYsbRhYBffpHcHfLegefBEZSMhQWgqElKwRV4M2bENZhmqQvkNU7qdhkW4MmGSz6jMx2hOqp8w\n\n```\n\n\u003e Response Sample: \n```$xslt\n\nHTTP/1.1 200 \nVary: Origin\nVary: Access-Control-Request-Method\nVary: Access-Control-Request-Headers\nX-Content-Type-Options: nosniff\nX-XSS-Protection: 1; mode=block\nCache-Control: no-cache, no-store, max-age=0, must-revalidate\nPragma: no-cache\nExpires: 0\nContent-Type: application/json\nTransfer-Encoding: chunked\nDate: Tue, 09 Jun 2020 05:39:47 GMT\nKeep-Alive: timeout=60\nConnection: keep-alive\n\n{\n  \"company\": {\n    \"id\": 1,\n    \"companyName\": \"MTN\"\n  },\n  \"employeeBillRecords\": [\n    {\n      \"employeeID\": 1,\n      \"totalNoOfHours\": 2,\n      \"unitPrice\": 300.00,\n      \"totalCostOfWork\": 600.00\n    }\n  ],\n  \"totalCompanyBillCost\": 600.0\n}\n\nResponse code: 200; Time: 237ms; Content length: 173 bytes\n\n```\n\n\u003e As you can see, everything has already been logically calculated on the backend.\n\u003e meaning that any frontend engineer can pick the API and implement in a shortwhile\n\n# Kubernetes(k8s) deployment \n```\n// first, set active profile to prod for google kubernetes or prod for amazon eks in application.properties\ndocker build -t dockerrodneykb2/bha-api-server-backend:latest -t dockerrodneykb2/bha-api-server-backend:latest . --file=Dockerfile \ndocker push dockerrodneykb2/bha-api-server-backend:latest\nkubect rollout restart deploy bha-api-server-backend-deployment\n\n// if a different id is logged in you can do \ndocker logout // this will log the account out\n// then you can do \ndocker login // this will request new username and password to authenticate,that's all.\n```\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frbkgh%2Fbillablehoursapi","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frbkgh%2Fbillablehoursapi","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frbkgh%2Fbillablehoursapi/lists"}