This document provides a comprehensive overview of the class architecture for the Hexagon Feed System, a location-based social feed application using hexagonal spatial indexing (H3) with Spring Boot.
┌─────────────────────────────────────────────────────────────────┐
│ PRESENTATION LAYER │
├─────────────────────────────────────────────────────────────────┤
│ Controllers (REST API Endpoints) │
│ • AuthController • FeedController │
│ • PostController • WebSocket Controllers │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ SERVICE LAYER │
├─────────────────────────────────────────────────────────────────┤
│ Business Logic Services │
│ • FeedAggregationService • LocationService │
│ • PostIngestionService • RateLimiterService │
│ • UserService • AuthenticationService │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ REPOSITORY LAYER │
├─────────────────────────────────────────────────────────────────┤
│ Data Access Layer (JPA Repositories) │
│ • UserRepository • PostRepository │
│ • UserSessionRepository • CacheRepository │
└─────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────┐
│ DATA LAYER │
├─────────────────────────────────────────────────────────────────┤
│ • PostgreSQL (Primary) • Redis (Cache) │
│ • Kafka (Messaging) • H3 Spatial Index │
└─────────────────────────────────────────────────────────────────┘
@RestController
@RequestMapping("/api/v1/auth")
public class AuthController {
// Endpoints: /register, /login, /refresh, /verify, /logout
// Dependencies: UserRepository, PasswordEncoder, JwtUtil
}@RestController
@RequestMapping("/api/v1/feed")
public class FeedController {
// Endpoints: GET /feed, GET /health
// Dependencies: FeedAggregationService, LocationService
}@RestController
@RequestMapping("/api/v1/posts")
public class PostController {
// Endpoints: POST /posts, GET /posts/{id}, DELETE /posts/{id}
// Dependencies: PostIngestionService, RateLimiterService
}@Service
public class FeedAggregationService {
// Core Algorithm: K-way merge of 7 hexagons
// Methods: aggregateFeed(), mergeHexagonFeeds()
// Dependencies: PostRepository, LocationService, CacheRepository
}@Service
public class LocationService {
// H3 Spatial Indexing Operations
// Methods: getHexIdForLocation(), getNeighborHexagons()
// Dependencies: H3Core library
}@Service
public class PostIngestionService {
// Post Creation and Management
// Methods: createPost(), updatePost(), deletePost()
// Dependencies: PostRepository, LocationService, KafkaProducer
}@Service
public class RateLimiterService {
// Token Bucket Rate Limiting
// Methods: checkRateLimit(), consumeToken()
// Dependencies: RedisTemplate
}@Repository
public interface UserRepository extends JpaRepository<User, UUID> {
// Methods: findByUsername(), findByEmail(), existsByUsername()
// Custom Queries: findActiveUsers(), findByLocation()
}@Repository
public interface PostRepository extends JpaRepository<Post, UUID> {
// Methods: findByHexId(), findByUserIdOrderByTimestampDesc()
// Custom Queries: findPostsInHexagons(), softDeletePost()
}@Repository
public interface UserSessionRepository extends JpaRepository<UserSession, UUID> {
// Methods: findByUser_UserId(), findByRefreshTokenHash()
// Custom Queries: findActiveSessions(), updateLastAccessedTime()
}@Entity
@Table(name = "users")
public class User {
@Id @GeneratedValue private UUID userId;
private String username, email, passwordHash;
private String firstName, lastName, bio, location;
private Boolean isActive, isVerified, isPrivate;
private Integer followersCount, followingCount, postsCount;
@CreatedDate private LocalDateTime createdAt;
@LastModifiedDate private LocalDateTime updatedAt;
private String preferences; // JSONB
}@Entity
@Table(name = "posts")
public class Post {
@Id @GeneratedValue private UUID postId;
@ManyToOne private User user;
private String content, hexId;
private Double latitude, longitude;
private Integer likesCount, repliesCount, viewsCount;
private Boolean isDeleted;
@CreatedDate private LocalDateTime createdAt;
private LocalDateTime deletedAt;
}@Entity
@Table(name = "user_sessions")
public class UserSession {
@Id @GeneratedValue private UUID sessionId;
@ManyToOne private User user;
private String refreshTokenHash, deviceType, ipAddress;
private Boolean isActive;
private LocalDateTime expiresAt, lastAccessedAt;
}// Request DTOs
public class RegisterRequest {
private String username, email, password, confirmPassword;
private String fullName;
private Boolean acceptTerms, acceptPrivacy;
}
public class LoginRequest {
private String usernameOrEmail, password;
private Boolean rememberMe;
}
// Response DTOs
public class AuthResponse {
private String access_token, refresh_token;
private UserDTO user;
private AuthMetadata auth_metadata;
}public class FeedRequest {
private Double latitude, longitude;
private Integer page, limit;
private String cursor;
}
public class FeedResponse {
private List<PostDTO> posts;
private PaginationInfo pagination;
private LocationInfo location;
}@Configuration
@EnableWebSecurity
public class SecurityConfig {
// JWT Authentication Configuration
// Security Filter Chain
// CORS and CSRF Configuration
}@Configuration
public class RedisConfig {
// RedisTemplate Configuration
// JSON Serialization Setup
// Connection Factory
}@Configuration
public class KafkaConfig {
// Producer Configuration
// Consumer Configuration
// Topic Configuration
}@Component
public class H3Util {
// H3 Library Wrapper
// Methods: latLngToH3(), h3ToLatLng(), getNeighbors()
}@Component
public class JwtUtil {
// JWT Token Operations
// Methods: generateToken(), validateToken(), extractClaims()
}@Component
public class ValidationUtil {
// Input Validation
// Methods: validateEmail(), validatePassword(), validateLocation()
}@RestControllerAdvice
public class GlobalExceptionHandler {
// Centralized Exception Handling
// Custom Exception Types:
// - ValidationException (400)
// - UnauthorizedException (401)
// - ResourceNotFoundException (404)
// - RateLimitException (429)
// - InternalServerException (500)
}public class ValidationException extends RuntimeException
public class UnauthorizedException extends RuntimeException
public class ResourceNotFoundException extends RuntimeException
public class RateLimitException extends RuntimeException@Component
public class PostEventProducer {
// Kafka Message Producer
// Methods: publishPostCreated(), publishPostDeleted()
}@Component
public class PostEventConsumer {
// Kafka Message Consumer
// Methods: handlePostCreated(), handlePostDeleted()
// WebSocket Notification Broadcasting
}@Configuration
@EnableWebSocketMessageBroker
public class WebSocketConfig {
// WebSocket Configuration
// STOMP Protocol Setup
}@Controller
public class FeedWebSocketController {
// WebSocket Message Handling
// Real-time Feed Updates
// User Subscription Management
}- Clean separation between data access and business logic
- JPA repositories with custom query methods
- Consistent data access interface
- Business logic encapsulation
- Transaction management
- Service composition
- Data transfer between layers
- Input validation
- Response formatting
- Constructor-based injection
- Loose coupling between components
- Testability
- Rate limiting algorithms
- Authentication strategies
- Caching strategies
AuthController → UserRepository → PostgreSQL
↓
JwtUtil → AuthResponse → Client
FeedController → FeedAggregationService → LocationService
↓ ↓
PostRepository ← K-way Merge Algorithm
↓
CacheRepository (Redis) → FeedResponse → Client
PostController → RateLimiterService (Redis Check)
↓
PostIngestionService → PostRepository → PostgreSQL
↓
PostEventProducer → Kafka → PostEventConsumer
↓
WebSocket Broadcasting → Connected Clients
- Stateless service design
- Database partitioning by hex_id
- Load balancer compatible
- Multi-layer caching (Redis)
- Cache-aside pattern
- TTL-based invalidation
- Asynchronous processing
- Event-driven architecture
- Kafka partitioning
- Composite indexes
- Connection pooling (HikariCP)
- Query optimization
- Service layer testing
- Repository testing
- Utility class testing
- API endpoint testing
- Database integration
- Message queue integration
- TestContainers for database testing
- MockMvc for API testing
- Custom test data builders
- Structured logging with correlation IDs
- Different log levels per environment
- Centralized log aggregation ready
- Spring Boot Actuator endpoints
- Custom business metrics
- Performance monitoring
- Database connectivity
- Redis connectivity
- Kafka connectivity
- Custom health indicators
This architecture provides a robust, scalable, and maintainable foundation for the Hexagon Feed System, following Spring Boot best practices and supporting the requirements for a location-based social feed application.