User.java

package com.stocks.stockease.model;

import jakarta.persistence.Column;
import jakarta.persistence.Entity;
import jakarta.persistence.GeneratedValue;
import jakarta.persistence.GenerationType;
import jakarta.persistence.Id;
import jakarta.persistence.Table;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

/**
 * Domain entity representing a User account in the system.
 * 
 * Persisted to the "app_user" table with auto-increment ID. Stores authentication
 * credentials (hashed password) and authorization role. Username is unique,
 * enforced at database level.
 * 
 * @author Team StockEase
 * @version 1.0
 * @since 2025-01-01
 */
@Data
@Entity
@Table(name = "app_user")
@NoArgsConstructor
@AllArgsConstructor
public class User {

    /**
     * Unique user identifier. Auto-generated by database (auto-increment).
     * Used as primary key for database relationships and audit trails.
     */
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    /**
     * Unique login identifier. Required, enforced unique at database level.
     * Used for authentication and displayed in API responses.
     * Cannot be changed after initial creation.
     */
    @Column(nullable = false, unique = true)
    private String username;

    /**
     * Hashed user password. Never stored in plaintext (BCrypt hash).
     * Used by Spring Security for authentication during login.
     * Never exposed in API responses or logs.
     */
    @Column(nullable = false)
    private String password;

    /**
     * User authorization role. Determines API endpoint access permissions.
     * Valid values: "ADMIN" (full access) or "USER" (read-only access).
     * Used in @PreAuthorize("hasRole('ADMIN')") security annotations.
     */
    @Column(nullable = false)
    private String role;

    /**
     * Constructs user entity for creation (without auto-generated ID).
     * 
     * Used for new user registration. ID is omitted; database generates it via auto-increment.
     * Password must already be hashed before passing to constructor (hashing done in service layer).
     * 
     * @param username unique login name (required)
     * @param password BCrypt-hashed password (required, never plaintext)
     * @param role authorization role (required, ADMIN or USER)
     */
    public User(String username, String password, String role) {
        this.username = username;
        this.password = password;
        this.role = role;
    }
}