This diagram and documentation outline how the core backend authentication module of the Resume Builder application is currently designed, focusing on component responsibilities and data flow.
This block diagram represents the basic structure of the application. It follows a classic layered architecture pattern which promotes separation of concerns.
flowchart TD
%% Define Nodes
Client("Client / Browser")
Controller("<b>AuthController</b><br/><small>Handles HTTP Endpoints</small>")
AuthSvc("<b>AuthService</b><br/><small>Business Logic</small>")
EmailSvc("<b>EmailService</b><br/><small>SMTP Email Dispatcher</small>")
Repo("<b>UserRepository</b><br/><small>Spring Data Mongo</small>")
DB[("<b>MongoDB Database</b>")]
%% Define Edges
Client -- "HTTP Requests" --> Controller
Controller -- "Delegates Processing" --> AuthSvc
AuthSvc -- "1. Sends User Entity" --> Repo
AuthSvc -- "2. Calls to send HTML email" --> EmailSvc
Repo -- "Persists Data" --> DB
EmailSvc -. "Sends Verification Link via SMTP" .-> Client
The registration flow happens in two major phases: first, the user submits their data, and an unverified account is created in the database. Second, the user clicks the link in their email which marks their account as verified.
sequenceDiagram
autonumber
actor User as User / Client
participant AuthController
participant AuthService
participant EmailService
participant UserRepository
participant MongoDB
%% Phase 1: Registration
rect rgba(0, 123, 255, 0.1)
Note over User, MongoDB: Phase 1: Registration Request
User->>AuthController: POST /api/auth/register (RegisterRequest)
AuthController->>AuthService: register(registerRequest)
AuthService->>UserRepository: existsByEmail(email)
UserRepository-->>AuthService: Returns boolean
alt If User Exists
AuthService-->>AuthController: Throws ResourceException
AuthController-->>User: Returns 400 Bad Request
else If New User
AuthService->>AuthService: Generate UUID Token & Construct User
AuthService->>UserRepository: save(User)
UserRepository->>MongoDB: Insert Document
MongoDB-->>UserRepository: Acknowledge
UserRepository-->>AuthService: Returns saved User
AuthService->>EmailService: sendHtmlEmail(to, subject, htmlContent)
EmailService-->>User: Dispatches Email with Verification Link
AuthService-->>AuthController: Returns AuthResponse (User details)
AuthController-->>User: Returns 201 Created (AuthResponse)
end
end
%% Phase 2: Email Verification
rect rgba(40, 167, 69, 0.1)
Note over User, MongoDB: Phase 2: Email Verification
User->>AuthController: GET /api/auth/verify-email?token=uuid...
AuthController->>AuthService: verifyemail(token)
AuthService->>UserRepository: findByVericationToken(token)
UserRepository->>MongoDB: Query by token
MongoDB-->>UserRepository: Returns Document
UserRepository-->>AuthService: Returns Optional<User>
alt Token expired or Invalid
AuthService-->>AuthController: Throws ResourceException
AuthController-->>User: Returns error
else Token valid
AuthService->>AuthService: Set emailverifed = true, clear token
AuthService->>UserRepository: save(User)
UserRepository->>MongoDB: Update Document
MongoDB-->>UserRepository: Acknowledge
AuthService-->>AuthController: Success
AuthController-->>User: Returns 200 OK (Verification Successful)
end
end
AuthController)
Your controllers are the gatekeepers. Their only job is to receive the HTTP request (like parsing the JSON body into a RegisterRequest DTO) and route the information to the Service layer securely. They then format the outcome into an HTTP Response with corresponding status codes (e.g., 201 Created or 400 Bad Request).AuthService and EmailService)
This is the brain of the application. It doesn’t care about HTTP Requests directly. Instead, AuthService handles crucial business rules such as verifying if a user already exists, creating standard UUID tokens for emails, deciding when tokens expire, mapping data models (RegisterRequest to User), formatting the actual text of the HTML email, and ensuring ResourceExceptions are thrown for violations. EmailService acts as a specialized utility to isolate mail logic, using Spring’s JavaMailSender to dispatch real emails safely.UserRepository)
This is the translator between the Java API and the Database. Through Spring Data interfaces (MongoRepository), you can define methods like .existsByEmail() and .findByVericationToken(), and Spring automatically writes the complicated MongoDB driver queries for you behind the scenes.MongoDB)
The underlying NoSQL data store capturing JSON-like documents, holding the definitive state around users, their passwords, and whether they’ve clicked the email verification link yet!