Skip to main content

Project E: Contact Form

Scenario​

A company wants to collect contact details from visitors to its website. When someone fills out the contact form, their information must be saved in a PostgreSQL database and an email must be sent.


What You Need to Create​

A Spring Boot REST API with:

  1. A public contact form - anyone can submit their contact details
  2. A protected admin panel - to view and manage received contacts
  3. An email system - automatic notifications

The Flow​


Form Preview (Frontend)​

Here is what the form should look like on the webpage:

┌─────────────────────────────────────────────────────────┐
│ CONTACT US │
├─────────────────────────────────────────────────────────┤
│ │
│ Full Name * Company │
│ ┌─────────────────────────┐ ┌─────────────────────┐│
│ │ Your name │ │ Your company name ││
│ └─────────────────────────┘ └─────────────────────┘│
│ │
│ Email * Phone │
│ ┌─────────────────────────┐ ┌─────────────────────┐│
│ │ your@company.com │ │ Your phone number ││
│ └─────────────────────────┘ └─────────────────────┘│
│ │
│ Request Type * │
│ ┌─────────────────────────────────────────────────┬──┐│
│ │ Select request type │ v││
│ ├─────────────────────────────────────────────────┴──┤│
│ │ > Select request type ││
│ │ Information request ││
│ │ Quote request ││
│ │ Technical support ││
│ │ Partnership ││
│ │ Other ││
│ └────────────────────────────────────────────────────┘│
│ │
│ Message * │
│ ┌────────────────────────────────────────────────────┐│
│ │ Describe your request, your budget, ││
│ │ and your deadlines... ││
│ │ ││
│ │ ││
│ └────────────────────────────────────────────────────┘│
│ │
│ ┌─────────────────────┐ │
│ │ SEND │ │
│ └─────────────────────┘ │
│ │
│ * Required fields │
└─────────────────────────────────────────────────────────┘

Form Fields:

FieldHTML TypeValidation
Full Name<input type="text">Required
Company<input type="text">Optional
Email<input type="email">Required, email format
Phone<input type="tel">Optional
Request Type<select>Required
Message<textarea>Required, min 10 characters

Options for "Request Type" field:

ValueDisplay
INFOInformation request
QUOTEQuote request
SUPPORTTechnical support
PARTNERSHIPPartnership
OTHEROther

Endpoints to Create​

Public Endpoint (no authentication)​

MethodURLDescription
POST/api/contactSubmit the form

Form Data:

  • fullName (required)
  • company (optional)
  • email (required)
  • phone (optional)
  • requestType (required) - selection list
  • message (required)

Admin Endpoints (with JWT)​

MethodURLDescription
GET/api/admin/leadsList of contacts
GET/api/admin/leads/\{id\}Contact details
PUT/api/admin/leads/\{id\}/statusChange status
DELETE/api/admin/leads/\{id\}Delete

Class Diagram​

Here is a proposed structure. You can modify, add, or simplify as needed.

Design Freedom

This diagram is a suggestion. You are free to:

  • Add classes (e.g., LeadNote for internal notes)
  • Add fields (e.g., company, source)
  • Modify relationships
  • Simplify if you find it too complex

The important thing is that your solution works and is well-structured.


Database​

Create these tables in PostgreSQL:

Table leads

  • id (primary key)
  • full_name
  • company
  • email (unique)
  • phone
  • request_type (INFO, QUOTE, SUPPORT, PARTNERSHIP, OTHER)
  • message
  • status (NEW, CONTACTED, CONVERTED, LOST)
  • created_at

Table users (for admins)

  • id
  • email
  • password
  • role

Emails to Send​

  1. When someone submits the form:

    • Email to admin: "New contact received"
    • Email to visitor: "Thank you, we have received your message"
  2. Use @Async to avoid blocking the request


Configuration​

# application.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/contactdb
username: postgres
password: postgres

mail:
host: localhost
port: 1025 # MailHog for testing

To test emails locally:

docker run -d -p 1025:1025 -p 8025:8025 mailhog/mailhog

View emails at http://localhost:8025


Tests to Write​

  • POST /api/contact with valid data → returns 200
  • POST /api/contact with invalid email → returns 400
  • GET /api/admin/leads without token → returns 401
  • GET /api/admin/leads with token → returns the list

Evaluation​

CriteriaPoints
Endpoint POST /api/contact works20
Data saved in PostgreSQL20
Emails sent15
Admin endpoints protected by JWT20
Tests15
Clean code10
Total100

Getting Started​

  1. Create the project on start.spring.io with:

    • Spring Web
    • Spring Data JPA
    • Spring Security
    • Spring Mail
    • Validation
    • PostgreSQL Driver
    • Lombok
  2. Create the Lead entity

  3. Create the LeadRepository

  4. Create the ContactController with POST /api/contact

  5. Test with curl or Postman


Deliverables​

  • Code on GitHub
  • README with instructions
  • Postman collection for testing

Back to Final Project