How ntrefftz/iw works
1. Overall shape
- Frenemy is a Spring Boot application with a classic server-side architecture: controllers for HTTP endpoints, services for business logic, JPA-style domain models/repositories for persistence, and Thymeleaf templates + static JS/CSS for the UI.
- The app is centered on three roles described in the README: admin, host, and player.
2. Main entry and configuration
- IwApplication is the application bootstrap.
- AppConfig, StartupConfig, SecurityConfig, WebSocketConfig, and WebSocketSecurityConfig define the main runtime boundaries: startup behavior, authentication/authorization, and real-time messaging.
- LoginSuccessHandler and IwUserDetailsService plug the user model into Spring Security.
3. Presentation layer
- There are two UI styles in the repo:
- Server-rendered pages in src/main/resources/templates (index, login, register, profile, lobby, game, admin, etc.).
- Client-side behavior in src/main/resources/static/js and css.
- Thymeleaf fragments (head, nav, footer, chat) indicate a shared page layout with reusable UI components.
4. HTTP controllers and page/API split
- Controllers are split by responsibility:
- RootController, UserController, LobbyController, AdminController likely serve pages and user flows.
- ApiController, LobbyApiController, UnoApiController expose JSON endpoints for dynamic interactions.
- This suggests a mixed model: full-page navigation for core flows plus AJAX-driven endpoints for interactive features.
5. Core service layer
- LobbyService and UnoService are the main business-logic boundaries.
- LobbyService likely manages lobby creation/joining, player order, lobby state, and game selection.
- UnoService manages the card game state and player actions.
- LobbyException indicates domain-specific validation and workflow errors are handled in the service layer rather than in controllers.
6. Domain model
- The model package contains the main entities and transfer objects:
- Social/user data: User, Friendship, FriendRequest, Message, Topic.
- Game data: Game, GameMessage, Card, UnoState, UnoActionRequest.
- Utility/base abstractions: Transferable, Lorem.
- UnoStateConverter shows that UNO game state is persisted/transformed as a structured value, not just held in memory.
7. Persistence and seed data
- GameRepository is the main repository visible in the tree, implying persistent storage for available games and related metadata.
- LocalData and src/main/resources/import.sql indicate bootstrap/seed data is loaded at startup.
- The README confirms initial data includes users (a, b, c, d), friendships, friendship scores, and match rankings so profile pages are not empty on first run.
8. Authentication and authorization boundaries
- The app uses role-based access control around the three user types, with admin features separated from normal user flows.
- Security is integrated both for standard HTTP sessions and for WebSocket traffic, which matters because the app has real-time lobby/chat/game updates.
- credentials.json.template suggests there is some environment-specific credential/config injection for deployment or external integration.
9. Real-time communication
- WebSocketConfig and WebSocketSecurityConfig indicate a dedicated real-time channel for lobby/chat/game updates.
- Static JS files such as stomp.js, chat.js, lobby.js, and game.js support this front-end messaging model.
- This is likely the main path for live state synchronization while users are inside lobbies or active games.
10. Frontend behavior
- The browser-side code is organized by feature: admin.js, friend-requests.js, profile.js, game.js, lobby.js, chat.js, plus shared helpers like util.js and iw.js.
- This means most interactive UI behavior is feature-scoped rather than centralized, which helps keep the lobby/game/admin flows separate.
11. Administrative and social subsystems
- AdminController and admin.html form the management plane for games and users.
- UserController plus the profile/friend-request scripts support the social layer: friendships, friend requests, affinity/rankings, and profile viewing.
- The README explicitly positions the app as a friendship-testing social game platform, so the social graph is a first-class feature, not just auxiliary data.
12. Testing and delivery
- Tests are split into:
- internal tests under src/test/java/internal/...
- external/behavioral tests using feature files and ExternalRunner
- a focused unit test for UnoStateConverter
- The presence of karate-config.js and .feature files suggests end-to-end API/UI behavior tests.
- deploy.py is a repo-level deployment helper, while Maven (pom.xml) is the main build/runtime toolchain.
13. Architecture summary for a diagram
- A good diagram would show:
- Browser/UI on the left
- HTTP controllers and WebSocket endpoints in the middle
- services underneath as the business layer
- domain models/repository + database on the right/bottom
- The key special-case flows are:
- login/security through Spring Security
- lobby/chat/game live updates through WebSockets
- admin/user management through dedicated controllers/pages
- UNO state handling through UnoService and UnoStateConverter.
Main entry points: iw.js Client JS · WebSocketConfig.java WebSocket · index.html Templates · IwApplication.java Boot app
Components 27
Presentation
Server-rendered pages and browser-side behavior
Web layer
HTTP controllers and real-time endpoints
- Root · Landing pages and shared navigation
src/main/java/es/ucm/fdi/iw/controller/RootController.java - Users · Profile and social flows
src/main/java/es/ucm/fdi/iw/controller/UserController.java - Lobby pages · Lobby and game entry pages
src/main/java/es/ucm/fdi/iw/controller/LobbyController.java - Admin · Administrative pages and management
src/main/java/es/ucm/fdi/iw/controller/AdminController.java - API · Shared JSON endpoints
src/main/java/es/ucm/fdi/iw/controller/ApiController.java - Lobby API · Lobby state and join/leave actions
src/main/java/es/ucm/fdi/iw/controller/LobbyApiController.java - UNO API · UNO actions and game-state endpoints
src/main/java/es/ucm/fdi/iw/controller/UnoApiController.java
Core logic
Business services and security/runtime wiring
- Boot app · Application entry point
src/main/java/es/ucm/fdi/iw/IwApplication.java - Config · Core application configuration
src/main/java/es/ucm/fdi/iw/AppConfig.java - Startup · Startup-time initialization and wiring
src/main/java/es/ucm/fdi/iw/StartupConfig.java - Security · HTTP authentication and authorization
src/main/java/es/ucm/fdi/iw/SecurityConfig.java - WebSocket · Real-time messaging configuration
src/main/java/es/ucm/fdi/iw/WebSocketConfig.java - WS security · Security rules for WebSocket traffic
src/main/java/es/ucm/fdi/iw/WebSocketSecurityConfig.java - Login success · Post-login routing and session setup
src/main/java/es/ucm/fdi/iw/LoginSuccessHandler.java - User details · Spring Security user lookup
src/main/java/es/ucm/fdi/iw/IwUserDetailsService.java - Lobby service · Lobby lifecycle and match coordination
src/main/java/es/ucm/fdi/iw/LobbyService.java - UNO service · UNO rules and state transitions
src/main/java/es/ucm/fdi/iw/UnoService.java - Lobby error · Lobby workflow validation errors
src/main/java/es/ucm/fdi/iw/LobbyException.java
Domain data
Entities, state, repository, and bootstrapped data
- User · Application user and role model
src/main/java/es/ucm/fdi/iw/model/User.java - Game · Game metadata and ownership
src/main/java/es/ucm/fdi/iw/model/Game.java - UNO state · Serialized game state
src/main/java/es/ucm/fdi/iw/model/UnoState.java - State converter · Persists UNO state values
src/main/java/es/ucm/fdi/iw/model/converters/UnoStateConverter.java - Game repo · Persistence access for games
src/main/java/es/ucm/fdi/iw/GameRepository.java - Seed data · Initial in-memory/bootstrap data
src/main/java/es/ucm/fdi/iw/LocalData.java
Connections 31
- Boot app → Config: loads · Bootstraps application configuration
- Boot app → Startup: initializes · Runs startup setup
- Boot app → Security: enables · Activates HTTP security
- Boot app → WebSocket: enables · Activates WebSocket runtime
- Security → User details: uses · Loads users for authentication
- Security → Login success: delegates · Handles post-login routing
- WebSocket → WS security: protects · Secures real-time channels
- Root → Templates: renders · Serves shared pages
- Users → Templates: renders · Serves profile/social pages
- Lobby pages → Templates: renders · Serves lobby/game pages
- Admin → Templates: renders · Serves admin pages
- Root → Client JS: drives · Page scripts support interactions
- Users → Client JS: drives · Social UI scripts support interactions
- Lobby pages → Client JS: drives · Lobby/game scripts support interactions
- Admin → Client JS: drives · Admin scripts support interactions
- API → Lobby service: uses · Shared API logic
- Lobby API → Lobby service: uses · Lobby operations
- UNO API → UNO service: uses · UNO actions and rules
- Lobby service → Lobby error: throws · Reports workflow errors
- Lobby service → Game repo: reads/writes · Persists lobby/game metadata
- UNO service → UNO state: manages · Updates game state
- UNO service → State converter: persists via · Stores UNO state as a value
- State converter → UNO state: converts · Maps state to storage
- Game repo → Game: stores · Game persistence model
- Seed data → User: seeds · Initial users and social graph
- Seed data → Game: seeds · Initial game data
- Seed data → Game repo: loads into · Bootstrap repository content
- Client JS → WebSocket: connects to · Browser scripts consume realtime updates
- Styles → Templates: styles · Presentation assets for pages
- Lobby API → WebSocket: broadcasts · Lobby updates over realtime channel
- UNO API → WebSocket: broadcasts · Game updates over realtime channel