{"id":28202331,"url":"https://github.com/jessfreak/servicestation","last_synced_at":"2026-04-20T10:32:26.653Z","repository":{"id":267536406,"uuid":"901531560","full_name":"JessFreak/ServiceStation","owner":"JessFreak","description":"Repository for coursework on the topic Web application for service station support","archived":false,"fork":false,"pushed_at":"2025-05-13T16:21:41.000Z","size":13613,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-05-13T17:27:35.083Z","etag":null,"topics":["client-server","coursework","full-stack","google-auth","imagebb","nest","react","service"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","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/JessFreak.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,"zenodo":null}},"created_at":"2024-12-10T20:41:46.000Z","updated_at":"2025-05-13T16:24:42.000Z","dependencies_parsed_at":"2025-05-13T17:35:37.512Z","dependency_job_id":null,"html_url":"https://github.com/JessFreak/ServiceStation","commit_stats":null,"previous_names":["jessfreak/service_station","jessfreak/servicestation"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/JessFreak/ServiceStation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JessFreak%2FServiceStation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JessFreak%2FServiceStation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JessFreak%2FServiceStation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JessFreak%2FServiceStation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/JessFreak","download_url":"https://codeload.github.com/JessFreak/ServiceStation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/JessFreak%2FServiceStation/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":259567066,"owners_count":22877634,"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","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":["client-server","coursework","full-stack","google-auth","imagebb","nest","react","service"],"created_at":"2025-05-17T00:12:54.747Z","updated_at":"2026-04-20T10:32:26.648Z","avatar_url":"https://github.com/JessFreak.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🚗 ServiceStation\n\n**ServiceStation** is a web application designed to support the operations of car service stations. The system provides an intuitive interface for users, mechanics, and administrators to manage profiles, vehicles, services, and orders.\n\n## 🛠️ Key Features\n\n- 🔐 User authentication and authorization (including Google OAuth)\n- 👤 Profile management\n- 🚙 Vehicle management (add, view, edit)\n- 🧾 View service history\n- 📅 Online service booking\n- 🧰 Service management (create, update, delete)\n- 📦 Order management (status updates, filtering, assignment)\n- 👥 Role-based user management\n\n## 🧑‍💻 Technologies Used\n\n- **Frontend:** React\n- **Backend:** NestJS\n- **Database:** PostgreSQL\n- **OAuth Integration:** Google\n- **Image Hosting:** ImgBB\n- **Architecture:** Client-Server, REST API\n\n## 📊 Diagrams\n\nFor a detailed overview of the system's structure and components, please refer to the `docs/diagrams/` folder.\n\n## 📄 Additional document\nAlso you can check explanatory note to course work (Ukrainian): Курсова робота.pdf.\n\n## 🚀 Running the Project Locally\n\n1. Clone the repository:\n\n```bash\ngit clone https://github.com/JessFreak/ServiceStation.git\ncd ServiceStation\n```\n\n2. Fill all env variables.\n3. Install all dependencies:\n\n```bash\nnpn istall\n```\n\n3. Run the project:\n\n```bash\nnpn start\n```\n\n## Infrastructure \u0026 Production-Grade Features (Lab 0)\n\nThis section documents the implementation of the \"Level 2\" requirements for the project infrastructure.\n\n### Environment Variables\n\nThe application requires the following environment variables to be configured.\n\n#### Backend (`back/.env`)\n| Variable | Description | Example |\n| :--- | :--- | :--- |\n| `DB_USER` | Database username | `postgres` |\n| `DB_PASSWORD` | Database password | `1234` |\n| `DB_HOST` | Database host (Docker service name or localhost) | `db` |\n| `DB_PORT` | Database port | `5432` |\n| `DB_NAME` | Database name | `service_station` |\n| `DATABASE_URL` | Full Prisma connection string | `postgresql://user:pass@host:port/db?schema=public` |\n| `PORT` | Backend server port | `8080` |\n| `JWT_SECRET` | Secret for JWT signing | `your_secret_key` |\n| `JWT_EXPIRE` | JWT expiration time | `1d` |\n| `GOOGLE_CLIENT_ID` | OAuth2 Client ID | `your_id.apps.googleusercontent.com` |\n| `GOOGLE_CLIENT_SECRET` | OAuth2 Client Secret | `your_secret` |\n| `GOOGLE_CALLBACK_URL` | OAuth2 Redirect URI | `http://localhost:8080/auth/google/callback` |\n| `CLIENT_URL` | Frontend URL for CORS | `http://localhost:3000` |\n\n#### Frontend (`front/.env`)\n| Variable | Description | Example |\n| :--- | :--- | :--- |\n| `REACT_APP_API_URL` | Backend API base URL | `http://localhost:8080` |\n| `REACT_APP_IMGBB_API_KEY` | API Key for image hosting | `your_imgbb_key` |\n\n---\n\n### 🩺 Health Checks\nThe application provides a deep health check endpoint at `/health` to verify system integrity.\n\n* **Status 200 (OK):** Returned when both the HTTP server and the PostgreSQL database connection are healthy.\n    ![img.png](docs/images/healthSuccess.png)\n* **Status 503 (Service Unavailable):** Returned when the database connection is lost or the service is degraded.\n    ![img.png](docs/images/healthUnavailable.png)\n\n---\n\n### 📝 Structured Logging (JSON)\nLogs are output to `STDOUT` in structured JSON format, enabling machine-readability for log aggregators (ELK, Prometheus). Each log contains mandatory `timestamp`, `level`, and `message` fields.\n\n**Example Logs:**\n```json\n[0] {\"level\":\"INFO\",\"timestamp\":\"2026-03-11T08:35:16.202Z\",\"context\":\"NestApplication\",\"message\":\"Nest application successfully started\"}\n[0] {\"level\":\"INFO\",\"timestamp\":\"2026-03-11T08:35:16.203Z\",\"message\":\"Started server on port 8080\"}\n[0] {\"level\":\"INFO\",\"timestamp\":\"2026-03-11T08:35:29.736Z\",\"req\":{\"method\":\"GET\",\"url\":\"/health\"},\"res\":{\"statusCode\":200},\"responseTime\":8,\"message\":\"request completed\"}\n[0] {\"level\":\"ERROR\",\"timestamp\":\"2026-03-11T08:35:48.008Z\",\"req\":{\"method\":\"GET\",\"url\":\"/health\"},\"message\":\"Health Check has failed! {\\\"database\\\":{\\\"message\\\":\\\"timeout of 1000ms exceeded\\\",\\\"status\\\":\\\"down\\\"}}\"}\n[0] {\"level\":\"INFO\",\"timestamp\":\"2026-03-11T08:35:48.009Z\",\"req\":{\"method\":\"GET\",\"url\":\"/health\"},\"res\":{\"statusCode\":503},\"err\":{\"type\":\"Error\",\"message\":\"failed with status code 503\",\"stack\":\"Error: failed with status code 503\\n    at onResFinished (C:\\\\Users\\\\Jess\\\\WebstormProjects\\\\ServiceStation\\\\node_modules\\\\pino-http\\\\logger.js:115:39)\\n    at ServerResponse.onResponseComplete (C:\\\\Users\\\\Jess\\\\WebstormProjects\\\\ServiceStation\\\\node_modules\\\\pino-http\\\\logger.js:178:14)\\n    at ServerResponse.emit (node:events:520:35)\\n    at onFinish (node:_http_outgoing:1026:10)\\n    at callback (node:internal/streams/writable:764:21)\\n    at afterWrite (node:internal/streams/writable:708:5)\\n    at afterWriteTick (node:internal/streams/writable:694:10)\\n    at process.processTicksAndRejections (node:internal/process/task_queues:89:21)\"},\"responseTime\":1013,\"message\":\"request errored\"}\n```\n\n### 🛑 Graceful Shutdown\nThe backend application is configured to handle `SIGTERM` (sent by Docker/Kubernetes) and `SIGINT` (sent via CTRL+C) signals to ensure no data loss or interrupted requests during deployment or scaling.\n\n* **Shutdown Process:**\n1. **Signal Interception:** The app catches the termination signal.\n2. **Logging:** A JSON-structured log is emitted: `\"message\": \"SIGINT/SIGTERM received. Starting graceful shutdown...\"`.\n3. **Request Draining:** NestJS stops accepting new connections and finishes processing in-flight HTTP requests.\n4. **Database Cleanup:** All active PostgreSQL connections are closed via Prisma's `onModuleDestroy` hook.\n5. **Clean Exit:** The process exits with code 0.\n\n**Verification Screenshot:**\n![img.png](docs/images/Shutdown.png)\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjessfreak%2Fservicestation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjessfreak%2Fservicestation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjessfreak%2Fservicestation/lists"}