A member directory for the intranet
Java · Spring Boot · intermediate · modification
Adds the first read endpoints of the employee directory: a list of active members and a lookup by id. The controller reads straight from `MemberRepository` and returns the members. `Member` gains a `jobTitle` field for the new directory page. Reads the directory from the existing member table.
Intranet backend on Spring Boot 3.3 (Java 21) with Spring Web, Spring Data JPA and Spring Security. `MemberRepository` (existing, unchanged) extends `JpaRepository<Member, Long>` and declares `List<Member> findByActiveTrueOrderByDisplayNameAsc()`. `Member` is an existing JPA entity mapped to `members`; the password reset flow (existing) stores the emailed single-use token in `passwordResetToken` with an expiry in `passwordResetExpiresAt`, and compares it as stored. The application has no custom Jackson configuration and no mixins, so Spring Boot's default `ObjectMapper` serialises whatever the controller returns. Security configuration (existing) requires an authenticated user for every `/api/**` request.
Requirements
- `GET /api/members` returns the active members as a JSON array ordered by display name; `GET /api/members/{id}` returns one active member, or 404 when the id is unknown or the member is inactive. The endpoints are open to any signed-in employee (the existing security configuration already requires authentication for `/api/**`).
- Each member in a response carries exactly four fields: `id`, `displayName`, `email` and the new `jobTitle` (may be `null`). Nothing else about a member is part of the directory.
- A member's `passwordResetToken` is a single-use credential that is emailed to them by the existing reset flow. It must never appear in any API response; any signed-in employee can call the directory.
- `Member` gets a nullable `jobTitle` column (the schema migration ships separately and is already applied).
Files touched
- src/main/java/com/acme/people/directory/Member.java
- src/main/java/com/acme/people/directory/MemberController.java
--- src/main/java/com/acme/people/directory/Member.java
private boolean active = true;
+ private String jobTitle;
+
private String passwordResetToken;
public String getDisplayName() { return displayName; }
public String getEmail() { return email; }
+ public String getJobTitle() { return jobTitle; }
+ public void setJobTitle(String jobTitle) { this.jobTitle = jobTitle; }
public boolean isActive() { return active; }
public void setActive(boolean active) { this.active = active; }
--- src/main/java/com/acme/people/directory/MemberController.java
+package com.acme.people.directory;
+
+import java.util.List;
+import org.springframework.http.HttpStatus;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestMapping;
+import org.springframework.web.bind.annotation.RestController;
+import org.springframework.web.server.ResponseStatusException;
+
+@RestController
+@RequestMapping("/api/members")
+public class MemberController {
+
+ private final MemberRepository members;
+