Resume Builder Architecture Overview

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.

High-Level Component Diagram

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

User Registration & Verification Sequence

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

Layer Explanations

  1. Controller Layer (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).
  2. Service Layer (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.
  3. Repository Layer (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.
  4. Database (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!