Skip to content

System Overview

Architecture Diagram

Module Responsibilities

platform-api

Shared Dubbo interface definitions that all modules depend on:

  • BlockChainService - Blockchain operations
  • DistributedStorageService - Storage operations
  • Common DTOs and response types

platform-backend

Multi-module backend service (Dubbo Consumer):

SubmoduleResponsibility
backend-webREST controllers, JWT filters, rate limiting, CORS
backend-serviceBusiness logic, Saga orchestration, Outbox publishing
backend-daoMyBatis Plus mappers, entities, VOs
backend-apiInternal API interfaces
backend-commonUtilities, constants, annotations

platform-fisco

Blockchain integration service (Dubbo Provider):

  • Smart contract interaction (Storage.sol, Sharing.sol)
  • Multi-chain adapters (Local FISCO, BSN FISCO, Besu)
  • Certificate management

platform-storage

Distributed storage service (Dubbo Provider):

  • Multi-node S3 client management
  • Fault domain management
  • Consistent hashing and rebalancing
  • File encryption/decryption

Core Business Flow

File Upload & Attestation

Saga Compensation Flow

StepForward ActionCompensation
PENDINGInitialize-
S3_UPLOADINGStore chunksClean stored chunks
S3_UPLOADEDChunks storedDelete S3 files
CHAIN_STORINGBlockchain attestationMark chain record deleted
COMPLETEDCommit-

Compensation Strategy: Exponential backoff (initial 1s, max 5 retries), then manual queue.

Saga State Machine

The FileSagaOrchestrator manages the complete state machine:

Transactional Outbox Pattern

RecordPlatform uses the Outbox pattern for reliable event publishing to RabbitMQ.

How It Works

Components

ComponentResponsibility
OutboxServiceAppends events within business transaction
OutboxPublisherBackground polling and publishing (30s interval)
outbox_event tablePersistent event store with tenant isolation

Guarantees

  • At-least-once delivery: Events survive broker unavailability
  • Transactional consistency: Event created in same DB transaction as business data
  • Tenant-aware polling: Each tenant's events processed independently

Configuration

yaml
outbox:
  enabled: true
  poll-interval: 30s
  batch-size: 100
  retention-days: 7  # Auto-cleanup after 7 days

CQRS Architecture

File module uses Command Query Responsibility Segregation:

Virtual Thread Async Methods

Query service provides async methods using Java 21 Virtual Threads:

  • getUserFilesListAsync()
  • getFileAddressAsync()
  • getFileDecryptInfoAsync()

Multi-tenancy

Isolation Strategy

LayerIsolation Method
Databasetenant_id field, MyBatis auto-inject
RedisKey prefix tenant:{tenantId}:
S3 StoragePath /{tenantId}/{userId}/
DubboContext propagation TenantContext

Tenant Context Control

@TenantScope annotation for declarative tenant isolation:

java
// Cross-tenant query (scheduled tasks)
@TenantScope(ignoreIsolation = true)
@Scheduled(cron = "0 0 3 * * ?")
public void cleanupDeletedFiles() { ... }

// Switch to specific tenant
@TenantScope(tenantId = 1)
public void migrateDataForTenant() { ... }

Real-time Notifications (SSE)

Server-Sent Events provide real-time updates to connected clients.

Multi-Connection Architecture

The system supports multiple simultaneous connections per user:

Connection Configuration

ParameterDefaultDescription
Max connections per user5Oldest connection closed when exceeded
Heartbeat interval30sKeep-alive signal
Connection timeout30mAuto-close after inactivity
Reconnect delay1sClient reconnect backoff

Event Types

EventPayloadDescription
connected{ connectionId }Initial connection confirmation
notification{ title, content }General notification
message-received{ conversationId, preview }New message in conversation
file-processed{ fileId, status }File upload/processing complete
announcement-published{ id, title }System announcement
ticket-updated{ ticketId, status }Ticket status change
badge-update{ unreadMessages, tickets }UI badge count update

Frontend Leader Election

For multi-tab scenarios, frontend uses BroadcastChannel for leader election:

  • Leader tab: Maintains single SSE connection
  • Follower tabs: Receive events via BroadcastChannel
  • Failover: Auto-elect new leader when leader tab closes

This prevents multiple SSE connections from same browser, reducing server load.

Released under the Apache 2.0 License.