Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
8828357
update sse plan
calebbourg Nov 15, 2025
c2db7d9
add integration testing tool design to sse plan
calebbourg Nov 15, 2025
e400a70
add sse-test-client initial implementation
calebbourg Nov 16, 2025
9bfa12d
Add SSE infrastructure configuration (Phase 1 & 2)
calebbourg Nov 18, 2025
8235a20
feat: add SSE crate for real-time server-sent events
calebbourg Nov 18, 2025
636ab32
feat: integrate SSE manager into AppState
calebbourg Nov 18, 2025
7ffd60b
feat: add SSE HTTP endpoint for real-time events
calebbourg Nov 18, 2025
2852d07
feat: initialize SSE manager in application entry points
calebbourg Nov 18, 2025
666b15c
test: update auth middleware tests for SSE manager
calebbourg Nov 18, 2025
c9a256e
docs: update architecture documentation for SSE infrastructure
calebbourg Nov 18, 2025
5f81a94
fix(sse-test-client): correct authentication endpoint and cookie hand…
calebbourg Nov 26, 2025
b63cfa9
feat(sse-test-client): add API version header and fix endpoint structure
calebbourg Nov 26, 2025
9f3f260
feat(sse-test-client): add connection test scenario
calebbourg Nov 26, 2025
57ea759
feat(sse-test-client): add ConnectionTest and ForceLogoutTest scenarios
calebbourg Nov 26, 2025
035f613
refactor(sse-test-client): remove test environment dependency from Fo…
calebbourg Nov 26, 2025
981f979
cargo fmt
calebbourg Dec 1, 2025
e931a5e
docs(sse-test-client): update README examples to use seeded user cred…
calebbourg Dec 16, 2025
54303f0
refactor(sse-test-client): use existing coaching data or create if ne…
calebbourg Dec 16, 2025
dcccc2a
refactor: move sse-test-client into testing-tools crate
calebbourg Dec 16, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
638 changes: 560 additions & 78 deletions Cargo.lock

Large diffs are not rendered by default.

6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,16 @@ edition = "2021"
default-run = "refactor_platform_rs"

[workspace]
members = [".", "entity_api", "entity", "migration", "service", "web", "domain"]
members = [".", "entity_api", "entity", "migration", "service", "web", "domain", "sse", "testing-tools"]
# Exclude testing-tools from default builds - it's a development/testing tool only
# and should not be built or deployed in production environments
default-members = [".", "entity_api", "entity", "migration", "service", "web", "domain", "sse"]

[dependencies]
service = { path = "service" }
entity_api = { path = "entity_api" }
web = { path = "web" }
sse = { path = "sse" }

clap = { version = "4.5.20", features = ["cargo", "derive", "env"] }
log = "0.4.22"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,8 @@ _For additional commands, database utilities, and debugging tips, check the [Con

`service` - CLI flags, environment variables, config handling and backend daemon setup

`sse` - Server-Sent Events infrastructure for real-time notifications. In-memory connection management (single-instance only)

`src` - contains a main function that initializes logging and calls all sub-services

`web` - API endpoint definition, routing, handling of request/responses, controllers
Expand Down
17 changes: 17 additions & 0 deletions docker-compose.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,23 @@ services:
networks:
- backend_network

######################################################
# CRITICAL: SSE Connection Management Limitation
#
# The rust-app service MUST run as a single instance (replicas: 1)
# because SSE connections are tracked in-memory using DashMap.
#
# ⚠️ DO NOT SCALE HORIZONTALLY WITHOUT REDIS PUB/SUB ⚠️
#
# If you need to scale beyond 1 replica:
# 1. Add Redis service to docker-compose.yaml
# 2. Update SseManager to use Redis Pub/Sub
# 3. See docs/implementation-plans/sse-communication.md
# "Multi-Instance Architecture" section
#
# Symptom if misconfigured: SSE events randomly fail
# (~50% with 2 replicas, ~67% with 3 replicas, etc.)
######################################################
rust-app:
image: ${BACKEND_IMAGE_NAME}
build:
Expand Down
4 changes: 4 additions & 0 deletions docs/architecture/crate_dependency_graph.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@

This diagram represents the dependency structure of the crates in this project. Each arrow indicates a dependency relationship between the crates. For example, the `web` crate depends on both the `domain` and `service` crates, while the `entity_api` crate depends on the `entity` and `service` crates.

The `sse` crate is standalone with no domain dependencies, using generic types to avoid circular dependencies.

```mermaid
graph TD;
web-->domain;
web-->service;
web-->sse;
service-->sse;
domain-->entity_api;
entity_api-->entity;
entity_api-->service;
Expand Down
5 changes: 4 additions & 1 deletion docs/architecture/network_flow_diagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ flowchart TB
4. **API Forwarding**: NextJS forwards API calls to Axum backend on port 4000
5. **Backend Processing**: Axum backend handles API endpoints like `/api/login` with secure caching
6. **Database Operations**: Backend connects to Digital Ocean Managed PostgreSQL
7. **SSE Connections**: Long-lived `/api/sse` connections for real-time events (24h timeout, no buffering)

## Infrastructure Notes

Expand All @@ -48,4 +49,6 @@ flowchart TB
- Axum: Internal port 4000
- **Managed PostgreSQL**: Separate Digital Ocean managed database service, accessed over the internet with SSL
- **SSL/TLS**: HTTPS encryption from client to Nginx using Let's Encrypt certificates managed by `certbot`, then unencrypted internal traffic within the container network
- **Database Connection**: Axum connects to managed PostgreSQL over SSL outside the container network
- **Database Connection**: Axum connects to managed PostgreSQL over SSL outside the container network
- **SSE Configuration**: Nginx configured for long-lived connections (24h timeout, proxy buffering disabled) at `/api/sse` endpoint
- **Scaling Limitation**: SSE uses in-memory connection tracking - **single backend instance only** until Redis pub/sub is implemented
18 changes: 15 additions & 3 deletions docs/architecture/system_architecture_diagram.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,10 @@ The Refactor Platform is a coaching management system built with Rust (Axum back
- **Migration**: Database schema versioning and migrations
- **Database**: PostgreSQL with `refactor_platform` schema

### Real-Time Communication
- **SSE (Server-Sent Events)**: Unidirectional push notifications from server to client
- **Connection Management**: In-memory registry for active user connections (single-instance only)

### External Integrations
- **TipTap**: Collaborative document editing service
- **JWT**: Token generation and validation service
Expand Down Expand Up @@ -71,11 +75,13 @@ graph TB
Router[Router<br/>Route Definitions & Middleware]
Controllers[Controllers<br/>HTTP Request Handlers]
Auth[Authentication Layer<br/>Session Management]

SSE[SSE Handler<br/>Real-Time Events]

%% Business Logic Layer
Domain[Domain Layer<br/>Business Logic & Models]
EntityAPI[Entity API<br/>Database Operations]
Service[Service Layer<br/>Configuration & Utilities]
SSEManager[SSE Manager<br/>Connection Registry]

%% Data Layer
Entity[Entity Layer<br/>Database Models]
Expand All @@ -96,6 +102,7 @@ graph TB
%% Router to Controllers
Router --> Controllers
Router --> Auth
Router --> SSE

%% Controllers breakdown
Controllers --> ActionCtrl[Action Controller]
Expand Down Expand Up @@ -123,6 +130,11 @@ graph TB
%% Domain to Data Access
Domain --> EntityAPI
Domain --> Service

%% SSE Integration
SSE --> SSEManager
Service --> SSEManager
Domain -.->|send events| SSEManager

%% Data Access Layer
EntityAPI --> Entity
Expand All @@ -147,8 +159,8 @@ graph TB
classDef database fill:#ffebee

class Client,Nginx external
class Web,Router,Controllers,Auth,ActionCtrl,AgreementCtrl,CoachingCtrl,NoteCtrl,OrgCtrl,UserCtrl,GoalCtrl,SessionCtrl,JWTCtrl,HealthCtrl web
class Domain,EntityAPI,Service business
class Web,Router,Controllers,Auth,SSE,ActionCtrl,AgreementCtrl,CoachingCtrl,NoteCtrl,OrgCtrl,UserCtrl,GoalCtrl,SessionCtrl,JWTCtrl,HealthCtrl web
class Domain,EntityAPI,Service,SSEManager business
class Entity,Migration data
class DB database
```
Loading