{"id":50795463,"url":"https://github.com/leandre000/spring-init-ne","last_synced_at":"2026-06-12T14:02:21.877Z","repository":{"id":362663216,"uuid":"1252092875","full_name":"leandre000/spring-init-ne","owner":"leandre000","description":"Springb  foundation","archived":false,"fork":false,"pushed_at":"2026-06-05T12:16:35.000Z","size":167,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-05T12:17:51.185Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","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/leandre000.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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-28T07:21:12.000Z","updated_at":"2026-06-05T12:16:39.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/leandre000/spring-init-ne","commit_stats":null,"previous_names":["leandre000/spring-init-ne"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/leandre000/spring-init-ne","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandre000%2Fspring-init-ne","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandre000%2Fspring-init-ne/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandre000%2Fspring-init-ne/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandre000%2Fspring-init-ne/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/leandre000","download_url":"https://codeload.github.com/leandre000/spring-init-ne/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/leandre000%2Fspring-init-ne/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34247461,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-12T02:00:06.859Z","response_time":109,"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":[],"created_at":"2026-06-12T14:02:20.044Z","updated_at":"2026-06-12T14:02:21.860Z","avatar_url":"https://github.com/leandre000.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Utility Billing System — Enterprise Spring Boot Backend\n\nA complete production-ready Spring Boot backend system for postpaid utility billing management (water \u0026 electricity). Features dynamic JWT authentication, customer profiles, meter installations, automated meter reading validations, tariff configuration versioning, automated billing engine, payment ledger tracking, and automated system alerts/notifications.\n\n---\n\n## 🛠️ Technology Stack\n\n| Layer | Technology |\n|---|---|\n| **Core Framework** | Spring Boot 3.4.5 |\n| **Language Runtime** | Java 21 |\n| **Security** | Spring Security + JWT (jjwt 0.12.6) |\n| **Database** | PostgreSQL 12+ (tested on v18) |\n| **Database Migrations** | Flyway |\n| **Persistence (ORM)** | Spring Data JPA + Hibernate |\n| **DTO Mappings** | Manual Mapper Pattern (Compile-safe \u0026 high performance) |\n| **Validation Layer** | Jakarta Bean Validation |\n| **API Documentation** | SpringDoc OpenAPI 3 (Swagger UI) |\n| **Mailing** | Spring Boot Starter Mail (JavaMailSender) |\n| **Developer Tools** | Project Lombok |\n\n---\n\n## 🚀 Getting Started\n\n### Prerequisites\n- **Java 21+** installed and set in `PATH`\n- **Maven 3.9+** installed and set in `PATH`\n- **PostgreSQL** instance running locally on port `5432`\n\n### 1. Database Creation\nCreate a new PostgreSQL database called `utility`:\n```sql\nCREATE DATABASE utility;\n```\n\n### 2. Local Configuration Override\nCredentials and local variables are managed in `src/main/resources/application-local.properties` (which is excluded from Git to prevent exposing credentials):\n\nCreate this file if it does not exist, and add:\n```properties\n# DataSource Settings\nspring.datasource.url=jdbc:postgresql://127.0.0.1:5432/utility\nspring.datasource.username=postgres\nspring.datasource.password=your_db_password\n\n# JWT Signing Secret (Base64 encoded, min 256-bit)\napp.jwt.secret=ZXhhbXBsZS1qd3Qtc2VjcmV0LXdyaXR0ZW4td2l0aC1tdWx0aXBsZS1jaGFyYWN0ZXJzLWZvci1oczI1Ng==\n\n# SMTP Mail Settings (Optional)\nspring.mail.username=your-email@gmail.com\nspring.mail.password=your-app-password\napp.mail.from=noreply@yourdomain.com\napp.mail.from-name=UtilityBillingSystem\napp.mail.base-url=http://localhost:8080\n\n# Flyway Settings for Local Dev\nspring.flyway.clean-disabled=false\nspring.flyway.clean-on-validation-error=true\n```\n\n### 3. Build \u0026 Run\nCompile the application and download dependencies:\n```powershell\nmvn clean compile\n```\n\nLaunch the Spring Boot application using the `local` profile:\n```powershell\nmvn spring-boot:run \"-Dspring-boot.run.profiles=local\"\n```\n\nThe database schemas, triggers, functions, and seed data will migrate automatically on boot.\n\n---\n\n## 🔑 Seeded Test Accounts\nAll seeded accounts share the default password: **`Secret@123`**\n\n| Role | Username (Email) | Password | Description |\n|---|---|---|---|\n| **System Admin** | `admin@utility.com` | `Secret@123` | Can create tariffs, delete meters/customers, search records |\n| **Utility Operator** | `operator@utility.com` | `Secret@123` | Responsible for creating customers and uploading meter readings |\n| **Finance Officer** | `finance@utility.com` | `Secret@123` | Approves bills and logs customer payments |\n| **Customer Support User** | `customer@utility.com` | `Secret@123` | Normal customer role accessing their own bills and payments |\n\n---\n\n## 📐 System Flows \u0026 Database Model\n\n### 1. Database Entity-Relationship Diagram (ERD)\n\nThe relational schema is structured as follows, separating authentication credentials and roles from the physical customer asset register, readings ledger, tariffs, billing schedules, payment history, and system notifications:\n\n```mermaid\nerDiagram\n    roles {\n        bigint id PK\n        varchar name UK\n    }\n    users {\n        bigint id PK\n        varchar full_name\n        varchar email UK\n        varchar phone_number\n        varchar password\n        varchar status\n        bigint role_id FK\n        timestamptz created_at\n        timestamptz updated_at\n        boolean deleted\n    }\n    customers {\n        bigint id PK\n        varchar customer_code UK\n        varchar full_name\n        varchar national_id UK\n        varchar email UK\n        varchar phone_number\n        text address\n        varchar status\n        date registration_date\n    }\n    meters {\n        bigint id PK\n        varchar meter_number UK\n        varchar meter_type\n        date installation_date\n        varchar status\n        bigint customer_id FK\n    }\n    meter_readings {\n        bigint id PK\n        bigint meter_id FK\n        decimal previous_reading\n        decimal current_reading\n        decimal consumption\n        date reading_date\n        int month\n        int year\n        bigint captured_by FK\n    }\n    tariffs {\n        bigint id PK\n        varchar tariff_name\n        varchar meter_type\n        varchar tariff_type\n        decimal rate_per_unit\n        decimal fixed_charge\n        decimal vat_percentage\n        decimal penalty_percentage\n        int version\n        date effective_from\n        date effective_to\n        varchar status\n    }\n    bills {\n        bigint id PK\n        varchar bill_number UK\n        bigint customer_id FK\n        bigint meter_id FK\n        bigint meter_reading_id FK\n        bigint tariff_id FK\n        int billing_month\n        int billing_year\n        decimal consumption\n        decimal amount_before_tax\n        decimal tax_amount\n        decimal penalty_amount\n        decimal total_amount\n        decimal paid_amount\n        decimal balance\n        varchar status\n        timestamptz generated_date\n    }\n    payments {\n        bigint id PK\n        varchar payment_reference UK\n        bigint bill_id FK\n        decimal amount_paid\n        varchar payment_method\n        timestamptz payment_date\n        bigint received_by FK\n    }\n    notifications {\n        bigint id PK\n        bigint customer_id FK\n        text message\n        varchar status\n        timestamptz created_at\n    }\n    email_verification_tokens {\n        bigint id PK\n        varchar token UK\n        bigint user_id FK\n        timestamptz expiry_date\n    }\n    password_reset_tokens {\n        bigint id PK\n        varchar token UK\n        bigint user_id FK\n        timestamptz expiry_date\n    }\n\n    users ||--|| roles : \"has\"\n    users ||--o| email_verification_tokens : \"has\"\n    users ||--o| password_reset_tokens : \"has\"\n    customers ||--o{ meters : \"owns\"\n    customers ||--o{ bills : \"receives\"\n    customers ||--o{ notifications : \"receives\"\n    meters ||--o{ meter_readings : \"logs\"\n    meters ||--o{ bills : \"tracks\"\n    meter_readings ||--|| users : \"captured by\"\n    meter_readings ||--|| bills : \"billed in\"\n    tariffs ||--o{ bills : \"applies to\"\n    bills ||--o{ payments : \"has\"\n    payments ||--|| users : \"received by\"\n```\n\n---\n\n### 2. Operational System Lifecycle Flows\n\nThe sequence diagram below visualizes the three primary system pipelines: Onboarding/Verification, Meter Readings/Billing calculations, and Finance Payment/Ledger settlement.\n\n```mermaid\nsequenceDiagram\n    autonumber\n    actor Customer as Customer / User\n    actor Operator as Utility Operator\n    actor Admin as System Admin\n    actor Finance as Finance Officer\n    participant DB as PostgreSQL Database\n    participant Email as Asynchronous Email Service\n\n    Note over Customer, DB: 1. Onboarding \u0026 Registration Flow\n    Operator-\u003e\u003eDB: Onboard Customer Profile (Email, National ID, Code)\n    Customer-\u003e\u003eDB: Public Register Account (Same Email, status='PENDING')\n    DB--\u003e\u003eEmail: Generate \u0026 Save EmailVerificationToken\n    Email-\u003e\u003eCustomer: Send Verification HTML Email (Async)\n    Customer-\u003e\u003eDB: Call /verify-email?token=\u003ctoken\u003e\n    DB-\u003e\u003eDB: Delete token \u0026 Set User status to 'ACTIVE'\n\n    Note over Customer, DB: 2. Reading \u0026 Billing Engine Flow\n    Operator-\u003e\u003eDB: Input Meter Reading (currentReading, month, year)\n    Admin-\u003e\u003eDB: Generate Bill for Meter Reading\n    DB-\u003e\u003eDB: Trigger: Create PENDING Notification record\n    DB--\u003e\u003eEmail: Fetch Customer details \u0026 Bill info\n    Email-\u003e\u003eCustomer: Send HTML Bill Notification (Async)\n\n    Note over Customer, DB: 3. Ledger Posting \u0026 Payment Flow\n    Finance-\u003e\u003eDB: Record Payment for Bill (amountPaid, method)\n    DB-\u003e\u003eDB: Trigger: Update Bill paidAmount, balance, and status (PAID/PARTIAL)\n    DB-\u003e\u003eDB: Trigger: Create PENDING Payment Receipt Notification\n    DB--\u003e\u003eEmail: Fetch Customer details \u0026 Payment info\n    Email-\u003e\u003eCustomer: Send HTML Payment Receipt (Async)\n```\n\n---\n\n## 📖 API Documentation \u0026 Verification\n\nOnce the application is running, you can access documentation and verify endpoints using the following resources:\n\n*   **Swagger UI (Interactive API docs)**: [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html)\n*   **OpenAPI 3 JSON Specification**: [http://localhost:8080/v3/api-docs](http://localhost:8080/v3/api-docs)\n*   **Postman Collection**: Locate the [UtilityBillingSystem.postman_collection.json](UtilityBillingSystem.postman_collection.json) file at the root of the workspace. Import it into Postman to run pre-configured flows (Login, Create Customer, Log Reading, Generate Bill, Post Payment, and view Notifications).\n\n---\n\n## 🏗️ Core Architecture \u0026 Logic\n\n### 1. Database-Level Automated Triggers\nTo enforce high integrity and speed up billing operations, the PostgreSQL database contains triggers defined in Flyway migration `V2__triggers_and_routines.sql`:\n*   **Bill Alert trigger** (`bill_created_trigger`): Whenever a new bill is inserted, a pending notification is automatically inserted into `notifications` for the customer.\n*   **Payment \u0026 Bill Sync trigger** (`payment_received_trigger`): Whenever a payment is registered, the target bill's `paid_amount` is incremented and its `balance` is updated. If the balance falls to `0`, the bill status is marked as `PAID` (or `PARTIAL` if partially paid). A transaction notification receipt is also logged automatically.\n\n### 2. Billing Engine\nBills are calculated inside `BillingServiceImpl` according to the following formulas:\n$$\\text{Consumption Cost} = \\text{Consumption (Units)} \\times \\text{Tariff Rate}$$\n$$\\text{Subtotal} = \\text{Consumption Cost} + \\text{Fixed Charge}$$\n$$\\text{Tax Amount} = \\text{Subtotal} \\times \\text{VAT Percentage}$$\n$$\\text{Penalty Amount} = \\text{Subtotal} \\times \\text{Penalty Percentage} \\text{ (If Overdue)}$$\n$$\\text{Total Bill Amount} = \\text{Subtotal} + \\text{Tax Amount} + \\text{Penalty Amount}$$\n\n### 3. Email Verification \u0026 Password Reset Lifecycle\n*   **Account Registration**: Newly registered users are assigned a status of `PENDING` and are blocked from logging in (returning a `403 Forbidden` response). An activation link is sent to the registered email address containing a registration token (valid for 24 hours).\n*   **Verification**: Invoking `GET /api/v1/auth/verify-email?token=\u003ctoken\u003e` activates the user status to `ACTIVE`. A helper endpoint `POST /api/v1/auth/resend-verification?email=\u003cemail\u003e` exists to request a new token if needed.\n*   **Password Reset**: Requesting a reset via `POST /api/v1/auth/forgot-password` (with body `{\"email\": \"...\"}`) sends a reset link to the email. The password can then be reset via `POST /api/v1/auth/reset-password` (with body `{\"token\": \"...\", \"password\": \"...\"}`) containing the 15-minute token.\n\n### 4. Asynchronous HTML Email System\n*   Emails are compiled using Thymeleaf HTML templates: `verification.html` (for registrations), `password-reset.html` (for password resets), and `notification.html` (for bill and payment transactions).\n*   All email operations run asynchronously under a configured executor pool (`async-email-` thread prefix) to prevent blocking the REST API request threads.\n\n### 5. Strict Payload Validations\n*   **National ID**: Validated using `^\\d{16}$` to ensure it is exactly 16 digits.\n*   **Phone Numbers**: Validated using `^\\+?[0-9]{10,15}$` (optional `+` followed by 10 to 15 digits).\n*   **Meter Numbers**: Validated using `^[A-Z0-9\\-]{5,20}$` (alphanumeric with optional hyphens, 5-20 characters long).\n*   **Reading Dates \u0026 Months**: Months must be integers between 1 and 12, years must be after 2000, and current reading values must be positive.\n\n---\n\n## 🧪 Step-by-Step Swagger Testing Guide (All 6 Tasks)\n\nOnce the application is running locally on port `8080`, navigate to the **Swagger UI** at [http://localhost:8080/swagger-ui/index.html](http://localhost:8080/swagger-ui/index.html) to interact with and test all 6 core tasks:\n\n### Task 1: User Registration \u0026 Email Verification Flow\n\n#### 1. Public Customer Registration\n*   **Endpoint**: `POST /api/v1/auth/register`\n*   **Action**: Click **Try it out** and supply a registration body:\n    ```json\n    {\n      \"fullName\": \"Jane Doe\",\n      \"email\": \"janedoe@example.com\",\n      \"phoneNumber\": \"+250780000020\",\n      \"password\": \"SecretPassword@123\",\n      \"roleName\": \"ROLE_CUSTOMER\"\n    }\n    ```\n*   **Expected Response**: `201 Created` with `\"status\": \"PENDING\"`.\n*   *Security Check*: If a public caller requests a staff role (e.g., `ROLE_OPERATOR` or `ROLE_ADMIN`), the system will reject the request with `403 Forbidden` (\"Registration of staff roles is restricted to administrators\").\n\n#### 2. Verify Login Blocking (Unverified User)\n*   **Endpoint**: `POST /api/v1/auth/login`\n*   **Action**: Try logging in with the newly registered user:\n    ```json\n    {\n      \"email\": \"janedoe@example.com\",\n      \"password\": \"SecretPassword@123\"\n    }\n    ```\n*   **Expected Response**: `403 Forbidden` with `\"message\": \"Email address is not verified\"`.\n\n#### 3. Retrieve Token \u0026 Verify Email\n*   **Action**: Query the verification token from your database:\n    ```powershell\n    $env:PGPASSWORD='leandre'; \u0026 'C:\\Program Files\\PostgreSQL\\18\\bin\\psql.exe' -h 127.0.0.1 -U postgres -d utility -c \"SELECT token FROM email_verification_tokens;\"\n    ```\n*   **Endpoint**: `GET /api/v1/auth/verify-email`\n*   **Action**: Pass the UUID token value into the `token` parameter and execute.\n*   **Expected Response**: `200 OK` (\"Email verified successfully. You can now log in.\").\n*   **Login Success**: Call `POST /api/v1/auth/login` again. It will now return `200 OK` along with the `\"accessToken\"`.\n\n---\n\n### Task 2: Customer \u0026 Meter Management\n\n*Authentication Pre-requisite*: All subsequent operations require authentication. Log in as the seeded Admin (`admin@utility.com` / `Secret@123`), copy the `\"accessToken\"` value, and click **Authorize** at the top of Swagger to paste it.\n\n#### 1. Create a Customer Profile\n*   **Endpoint**: `POST /api/v1/customers`\n*   **Action**: Submit a customer profile payload:\n    ```json\n    {\n      \"customerCode\": \"CUST-9999\",\n      \"fullName\": \"Elizabeth Vance\",\n      \"nationalId\": \"1199580000000021\",\n      \"email\": \"elizabeth.vance@example.com\",\n      \"phoneNumber\": \"+250780000099\",\n      \"address\": \"Kigali, Sector 3\",\n      \"status\": \"ACTIVE\"\n    }\n    ```\n*   **Expected Response**: `201 Created` returning the customer's database ID (e.g., `id: 5`).\n*   *Validation Check*: Clicking execute again will trigger a `409 Conflict` (duplicates are rejected).\n\n#### 2. Register a Meter\n*   **Endpoint**: `POST /api/v1/meters`\n*   **Action**: Register a meter for the customer ID returned above:\n    ```json\n    {\n      \"meterNumber\": \"ELE-99882\",\n      \"meterType\": \"ELECTRICITY\",\n      \"status\": \"ACTIVE\",\n      \"customerId\": 5\n    }\n    ```\n*   **Expected Response**: `201 Created`.\n*   *Validation Check*: Re-executing with the same `meterNumber` will fail with a `409 Conflict`.\n\n---\n\n### Task 3: Meter Reading Management\n\n#### 1. Log a Meter Reading\n*   **Endpoint**: `POST /api/v1/meter-readings`\n*   **Action**: Log a reading for June 2026 for the meter ID returned above:\n    ```json\n    {\n      \"meterId\": 5,\n      \"currentReading\": 150.00,\n      \"month\": 6,\n      \"year\": 2026\n    }\n    ```\n*   **Expected Response**: `201 Created`.\n*   *Validation Checks*:\n    *   **Uniqueness**: Re-executing with same month/year fails with `409 Conflict`.\n    *   **Reading Value**: Logging a reading lower than previous reading (e.g., `120.00` in month 7) fails with `400 Bad Request`.\n\n---\n\n### Task 4: Tariff, Tax, and Penalty Configuration\n\n#### 1. Publish a New Tariff\n*   **Endpoint**: `POST /api/v1/tariffs`\n*   **Action**: Publish a tariff rates config:\n    ```json\n    {\n      \"tariffName\": \"Electricity High Tier Flat\",\n      \"meterType\": \"ELECTRICITY\",\n      \"tariffType\": \"FLAT\",\n      \"ratePerUnit\": 150.00,\n      \"fixedCharge\": 2000.00,\n      \"vatPercentage\": 18.00,\n      \"penaltyPercentage\": 10.00,\n      \"effectiveFrom\": \"2026-06-01\",\n      \"status\": \"ACTIVE\"\n    }\n    ```\n*   **Expected Response**: `201 Created` with automated incremental version (e.g., `version: 2`). Future tariff updates will automatically apply only to cycles whose billing date is equal to or after the `effectiveFrom` date.\n\n---\n\n### Task 5: Payment Processing\n\n#### 1. Generate the Bill\n*   **Endpoint**: `POST /api/v1/bills`\n*   **Action**: Calculate bill from the logged meter reading:\n    ```json\n    {\n      \"meterReadingId\": 5\n    }\n    ```\n*   **Expected Response**: `201 Created` returning the bill ID (e.g., `id: 1`) and calculated `totalAmount` (e.g., `57820.00 FRW`).\n\n#### 2. Partial Payment\n*   **Endpoint**: `POST /api/v1/payments`\n*   **Action**: Pay `20000.00` towards the generated bill:\n    ```json\n    {\n      \"billId\": 1,\n      \"amountPaid\": 20000.00,\n      \"paymentMethod\": \"MOBILE_MONEY\"\n    }\n    ```\n*   **Expected Response**: `201 Created`. The target bill's status automatically updates to `PARTIAL`, its balance updates to `37820.00`.\n\n#### 3. Full Payment\n*   **Endpoint**: `POST /api/v1/payments`\n*   **Action**: Clear the outstanding balance:\n    ```json\n    {\n      \"billId\": 1,\n      \"amountPaid\": 37820.00,\n      \"paymentMethod\": \"CASH\"\n    }\n    ```\n*   **Expected Response**: `201 Created`. The target bill's status automatically updates to `PAID`, and its balance drops to `0.00`.\n\n---\n\n### Task 6: Database Routines and Messaging\n\n#### 1. Verify Trigger Logged Notifications\n*   **Endpoint**: `GET /api/v1/notifications`\n*   **Action**: List all notifications.\n*   **Expected Response**: `200 OK` listing the notification records. Check `\"message\"` fields to confirm the exact trigger-generated outputs:\n    *   *Bill Alert Trigger*: `\"Dear Elizabeth Vance, Your 6/2026 utility bill of 57820.00 FRW has been successfully processed.\"`\n    *   *Payment Receipt Trigger*: `\"Dear Elizabeth Vance, Your payment of 20000.00 FRW has been received successfully.\"`\n\n---\n\n## 📂 Directory Layout\n\n```\nsrc/main/java/com/utility/billing/\n├── audit/                  # AuditAware context for BaseEntity tracing\n├── common/                 # Pagination, Specs, validation constraints, and envelopes\n├── config/                 # Security configs, Thread pools (Async), and OpenAPI/Swagger Config\n├── controller/             # REST Endpoints (Auth, Customer, Meter, Bill, Payment, Notification)\n├── dto/                    # Request bodies and API response models\n├── entity/                 # Hibernate models (User, Role, Customer, Meter, Bill, Payment, etc.)\n├── enums/                  # System-wide Enums (BillStatus, MeterType, CustomerStatus, etc.)\n├── exception/              # ControllerAdvice translating logic faults into JSON responses\n├── mapper/                 # Compile-safe DTO/Entity mappings\n├── repository/             # JPA/Hibernate query interfaces\n├── security/               # JWT validation filters and token issuance engines\n└── service/                # Core business layer implementation\n```\n\n---\n\n## 📜 License\nThis project is licensed under the MIT License - see the LICENSE file for details.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandre000%2Fspring-init-ne","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fleandre000%2Fspring-init-ne","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fleandre000%2Fspring-init-ne/lists"}