SW360 Frontend Architecture

Architecture documentation for the SW360 React Frontend (Next.js).

SW360 Frontend Architecture Documentation

Version: 1.0
Date: May 2026
Classification: Public
Repository: eclipse-sw360/sw360-frontend


Document Information

AttributeValue
Document TitleSW360 Frontend Architecture Documentation
Version1.0
StatusReleased
Last UpdatedMay 2026
LicenseEPL-2.0

Table of Contents

  1. Introduction and Goals
  2. Technology Stack
  3. Architecture Constraints
  4. System Context
  5. Building Block View
  6. Runtime View
  7. Deployment View
  8. Cross-cutting Concepts
  9. Quality Requirements
  10. Risks and Technical Debt

1. Introduction and Goals

1.1 Purpose

The SW360 Frontend is a modern web application that replaces the legacy Liferay Portal UI. Built with Next.js and React, it provides a responsive, internationalized user interface for managing software components, licenses, projects, and compliance workflows.

1.2 Goals

  • Modern UX: Responsive, accessible interface using React Bootstrap
  • Performance: Server-side rendering (SSR) and Turbopack for fast builds
  • Internationalization: 10 language support out of the box
  • Security: OAuth2/OIDC authentication, CSP headers, RBAC middleware
  • Separation of Concerns: Standalone frontend communicating exclusively via REST API
  • Developer Experience: TypeScript, Biome linting, Playwright E2E testing

1.3 Stakeholders

RoleConcerns
Frontend DevelopersComponent structure, TypeScript types, build tooling
UX DesignersDesign system consistency, accessibility, responsive layout
Backend DevelopersREST API contract, HAL+JSON parsing, auth token flow
System AdministratorsContainer deployment, environment configuration
Translatorsi18n message files, locale coverage

2. Technology Stack

LayerTechnologyVersion
FrameworkNext.js16.x
UI LibraryReact19.x
LanguageTypeScript6.x
StylingBootstrap 5 + React Bootstrap5.3.x / 2.10.x
AuthenticationNextAuth.js4.x
Internationalizationnext-intl4.x
Data Tables@tanstack/react-table8.x
Reactive StreamsRxJS7.x
Linting/FormattingBiome2.x
E2E TestingPlaywrightLatest
Package Managerpnpm10.x
RuntimeNode.js24.x (slim)
BundlerTurbopack (Next.js native)Built-in
Git HooksHusky + lint-staged + commitlintLatest

3. Architecture Constraints

3.1 Technical Constraints

ConstraintDescriptionRationale
REST API onlyFrontend communicates exclusively via SW360 REST API (HAL+JSON)Clean separation, independent deployment
No direct DB accessAll data flows through backend REST endpointsSecurity, single source of truth
Next.js App RouterUses src/app/ directory with [locale] dynamic segmentsNext.js 16 convention, built-in i18n routing
Standalone outputoutput: 'standalone' in next.config.tsOptimized Docker images, no node_modules in production
CSP enforcedContent Security Policy headers on all routesXSS prevention, security compliance

3.2 Organizational Constraints

ConstraintImpact
Eclipse FoundationEPL-2.0 license, DCO sign-off required
Conventional CommitsEnforced via commitlint (@commitlint/config-conventional)
BiomeReplaces ESLint + Prettier for unified linting/formatting
pnpm onlypreinstall script enforces pnpm (only-allow pnpm)

4. System Context

4.1 Context Diagram

Frontend System Context

4.2 External Interfaces

InterfaceProtocolDirectionDescription
SW360 REST APIHTTPS (HAL+JSON)Frontend → BackendAll CRUD operations
KeycloakOAuth2/OIDCFrontend ↔ KeycloakUser login, token refresh
NextAuth API RoutesInternal HTTPBrowser → Next.js serverSession management (/api/auth/*)
GravatarHTTPSFrontend → ExternalUser avatar images

4.3 Authentication Providers

The frontend supports three authentication modes configured via NEXT_PUBLIC_SW360_AUTH_PROVIDER:

ProviderValueUse Case
KeycloakkeycloakProduction (OAuth2/OIDC SSO via Keycloak)
SW360 OAuthsw360oauthProduction (OAuth2 via SW360 backend directly)
SW360 Basicsw360basicDevelopment/testing (username + password)

5. Building Block View

5.1 Project Structure

Frontend Project Structure

5.2 Layer Architecture

Frontend Layer Architecture

5.3 Key Modules

5.3.1 Pages (src/app/[locale]/)

Pages follow the SW360 domain model. Each page directory maps to a backend resource:

Page RouteBackend ResourceKey Functionality
/homeDashboardMy components, my projects, recent activity
/componentsComponentControllerList, create, edit, detail components
/components/[id]/releasesReleaseControllerRelease management within components
/projectsProjectControllerProject lifecycle, linked releases
/licensesLicenseControllerLicense database, obligations
/packagesPackageControllerPackage (pURL) management
/vulnerabilitiesVulnerabilityControllerCVE tracking, risk assessment
/requestsModerationServiceModeration + clearing requests
/eccECC endpointsExport Control Classification
/adminAdmin endpointsSystem administration (ADMIN only)
/searchSearch endpointsGlobal cross-entity search
/preferencesUser endpointsUser preferences, API tokens

5.3.2 Components (src/components/)

Shared UI components organized by domain concern:

Component ModuleDescription
sw360/Core SW360 widgets (tables, modals, nav sidebar)
AccessControl/Role-based UI visibility guards
Attachments/File upload, attachment listing, type management
ChangeLog/Diff view for audit trail records
LinkedReleases/Release linking with version selection
LinkedObligations/Obligation display and management
ComponentVulnerabilities/CVE display per component/release
ProjectAddSummary/Project creation wizard
ReleaseSummary/Release detail summary card
ExternalIds/External ID management (SWID, CPE, etc.)

5.3.3 Object Types (src/object-types/)

TypeScript interfaces mirroring the backend Thrift/REST data model:

Type FileBackend Entity
Component.tsComponent
Release.ts, ReleaseDetail.tsRelease
Project.ts, ProjectPayload.tsProject
LicenseDetail.ts, LicensePayload.tsLicense
Vulnerability.ts, LinkedVulnerability.tsVulnerability
Package.ts, LinkedPackage.tsPackage
Obligation.tsObligation
User.tsUser
Attachment.tsAttachment
ClearingRequest.tsClearingRequest
ModerationRequest.tsModerationRequest
Embedded.ts, Links.ts, Pageable.tsHAL+JSON response envelope

5.3.4 Services (src/services/)

ServiceResponsibility
auth.service.tsToken extraction, session helpers
async.storage.service.tsAsync key-value storage abstraction
download.service.tsFile download with auth headers
message.service.tsToast notification via RxJS Observable

5.3.5 Custom Hooks (src/hooks/)

HookPurpose
useLocalStorageTyped localStorage read/write with SSR safety
useSW360BackendConfigFetch and cache backend configuration
useUiConfigUI configuration (feature flags, display settings)

6. Runtime View

6.1 Authentication Flow

Frontend Authentication Flow

6.2 Middleware Pipeline

Middleware Pipeline

Route Protection Configuration:

Route PrefixAuth RequiredRoles
/adminADMIN, SW360_ADMIN only
/home, /projects, /components, etc.Any authenticated user
/ (login)Public

6.3 API Communication Pattern

The frontend uses a consistent pattern for data fetching:

  1. Page renders and calls a custom hook
  2. Hook invokes API utility with auth headers from session
  3. API Utils makes fetch request to SW360 REST API
  4. Response returns HAL+JSON with _embedded, _links, and page metadata
  5. Data is rendered using @tanstack/react-table for list views

6.4 Notification Flow (RxJS)

Toast notifications use an RxJS Subject-based pattern:

  • Action triggers message.service.ts which emits on an RxJS Subject
  • Toast Component subscribes to the Observable stream and displays notifications
  • This decouples business logic from UI rendering of notifications

7. Deployment View

7.1 Docker Architecture

Frontend Deployment Architecture

7.2 Dockerfile (Multi-stage Build)

StageBase ImagePurpose
buildnode:24-slimInstall pnpm, build Next.js with Turbopack
runtimenode:24-slimCopy standalone output, run node server.js

Build-time Environment Variables:

VariableDescriptionDefault
NEXT_PUBLIC_SW360_API_URLSW360 REST API base URL
NEXT_PUBLIC_SW360_AUTH_PROVIDERkeycloak, sw360oauth, or sw360basicsw360basic

Runtime Environment Variables:

VariableDescription
SW360_REST_CLIENT_IDOAuth2 client ID for REST API
SW360_REST_CLIENT_SECRETOAuth2 client secret
SW360_KEYCLOAK_CLIENT_IDKeycloak client ID
SW360_KEYCLOAK_CLIENT_SECRETKeycloak client secret
AUTH_ISSUERKeycloak issuer URL
AUTH_SECRETNextAuth.js session encryption secret

7.3 Docker Compose

services:
  sw360-frontend:
    build:
      context: .
      args:
        - NEXT_PUBLIC_SW360_API_URL=http://sw360:8080
        - NEXT_PUBLIC_SW360_AUTH_PROVIDER=keycloak
    ports:
      - "3000:3000"
    environment:
      - SW360_KEYCLOAK_CLIENT_ID=sw360-frontend
      - SW360_KEYCLOAK_CLIENT_SECRET=${KC_SECRET}
      - AUTH_ISSUER=http://keycloak:8083/realms/sw360
      - AUTH_SECRET=${AUTH_SECRET}
    depends_on:
      - sw360
      - keycloak

7.4 Production Considerations

ConcernApproach
Reverse Proxynginx/Traefik in front of Next.js for TLS termination
ScalingHorizontal (stateless — session in JWT cookie)
CDNStatic assets served from /_next/static/ — CDN-friendly
Health CheckNext.js built-in health endpoint
Source MapsproductionBrowserSourceMaps: true for debugging

8. Cross-cutting Concepts

8.1 Internationalization (i18n)

SW360 Frontend supports 10 locales using next-intl:

LocaleLanguage
enEnglish
deGerman
frFrench
esSpanish
jaJapanese
koKorean
viVietnamese
pt-BRBrazilian Portuguese
zh-CNSimplified Chinese
zh-TWTraditional Chinese

Architecture:

  • URL-based locale: /{locale}/components (e.g., /en/components, /de/components)
  • Message files: messages/{locale}.json
  • Middleware detects locale from URL, cookie, or Accept-Language header
  • All UI strings externalized — no hardcoded text in components

8.2 Security

8.2.1 Content Security Policy

The next.config.ts enforces strict CSP headers:

default-src 'self';
script-src 'self' 'unsafe-inline';
style-src 'self' 'unsafe-inline';
img-src 'self' data: https://secure.gravatar.com;
connect-src 'self';
object-src 'none';
frame-ancestors 'self';
require-trusted-types-for 'script';

8.2.2 Additional Security Headers

HeaderValue
Strict-Transport-Securitymax-age=31536000; includeSubDomains; preload
X-Content-Type-Optionsnosniff
X-XSS-Protection0 (modern browsers handle XSS internally)
Referrer-Policystrict-origin-when-cross-origin
X-Frame-OptionsSAMEORIGIN
Permissions-Policycamera=(), microphone=(), geolocation=()

8.2.3 Role-Based Access Control (Three-Layer Defense)

SW360 Frontend implements a comprehensive RBAC system with three layers of defense:

LayerMechanismScopeImplementation
Layer 1: Route Blockingproxy.ts middlewareServer-side redirectBlocks entire routes for restricted roles
Layer 2: Page AccessAccessControl HOCPage-level blockingRenders “Access Denied” for unauthorized pages
Layer 3: Element UIViewerGate / CapabilityGateButton/field hidingHides specific UI elements per role
Blacklist-Based Route Protection

The middleware uses a blockedRoles configuration with longest-prefix matching:

const roleBasedAccessControl = {
    '/admin': { roles: [ADMIN, SW360_ADMIN], authRequired: true },
    '/projects/add': { blockedRoles: [UserGroupType.VIEWER], authRequired: true },
    '/components/add': { blockedRoles: [UserGroupType.VIEWER], authRequired: true },
    '/vulnerabilities': { blockedRoles: [UserGroupType.VIEWER], authRequired: true },
    '/ecc': { blockedRoles: [UserGroupType.VIEWER], authRequired: true },
    // ... all authenticated routes
}
Capability-Based Permission System

Beyond role-based blocking, granular capabilities provide fine-grained UI control:

CapabilityAffected UIRestricted For
canEditClearingRequestDetailsPriority, Clearing Type, Requesting User fieldsUSER role
canCreateVulnerabilities“Add Vulnerability” buttonSECURITY_USER role
canExportSpreadsheetExport Spreadsheet buttonsVIEWER role
canTriggerFossologyFOSSology process iconsVIEWER role
Component Patterns
// Layer 2: Page-level blocking via HOC
export default AccessControl(MyPage, [UserGroupType.VIEWER])

// Layer 3a: Element hiding for VIEWER
<ViewerGate>
  <Button>Edit</Button>  {/* Hidden for VIEWER */}
</ViewerGate>

// Layer 3b: Capability-based control
const { hasCapability } = usePermissionContext()
const canEdit = hasCapability('canEditClearingRequestDetails')
<input disabled={!canEdit} />
Key Infrastructure Files
FilePurpose
src/contexts/PermissionContext.tsxReact context providing isViewer, isAdmin, hasCapability()
src/components/AccessControl/RoleGate.tsxViewerGate component for element-level hiding
src/components/AccessControl/CapabilityGate.tsxCapability-based conditional rendering
src/config/permissions/capabilities.config.tsRole-to-capability mapping matrix
src/utils/permission.utils.tsUtility functions mirroring backend permission logic
src/proxy.tsServer-side route blocking with longest-prefix matching

8.3 State Management

SW360 Frontend uses no global state library (no Redux, Zustand, etc.). Instead:

PatternUsage
React ContextUiConfigContext, SW360BackendConfigContext, PermissionContext — app-wide config & RBAC
Custom HooksuseSW360BackendConfig, useUiConfig, useLocalStorage
NextAuth SessionUser identity, tokens, roles (JWT cookie)
RxJS SubjectsCross-component notifications (toast messages)
URL StatePagination, filters via query parameters
Local Component StateForm state, UI toggles via useState

8.4 Data Table Pattern

All list pages use @tanstack/react-table with:

  • Server-side pagination (via HAL page metadata)
  • Column sorting
  • Row selection
  • Custom cell renderers for links, badges, status icons

8.5 Error Handling

LevelMechanism
Page-levelerror.tsx boundary in src/app/[locale]/
API errorsHTTP status codes → toast notifications via message.service.ts
Auth errorsNextAuth error handling → redirect to login
Type safetyTypeScript strict mode catches errors at compile time

8.6 Code Quality

ToolPurposeConfiguration
BiomeLint + format (replaces ESLint + Prettier)biome.json
TypeScriptType checking (strict: true)tsconfig.json
HuskyPre-commit hooks.husky/
lint-stagedRun Biome on staged files onlypackage.json
commitlintEnforce conventional commitspackage.json
PlaywrightE2E testingplaywright.config.ts

9. Quality Requirements

9.1 Performance

ScenarioTarget
First Contentful Paint< 1.5s
Page navigation (client-side)< 500ms
Component list load (100 items)< 1s
Build time (production)< 3 min

Optimization strategies:

  • Next.js SSR for initial load
  • Turbopack for fast development builds
  • Standalone output (minimal production footprint)
  • react: 19.x with concurrent features

9.2 Accessibility

RequirementApproach
Keyboard navigationReact Bootstrap components are keyboard-accessible
Screen readersSemantic HTML, ARIA attributes
Color contrastBootstrap 5 default theme meets WCAG AA
Focus managementManaged by React Bootstrap modals/dialogs

9.3 Browser Support

BrowserVersion
ChromeLatest 2 versions
FirefoxLatest 2 versions
EdgeLatest 2 versions
SafariLatest 2 versions

10. Risks and Technical Debt

10.1 Risks

IDRiskMitigation
R1NextAuth.js v4 → v5 migrationNextAuth v5 (Auth.js) has breaking changes; plan migration path
R2Preact aliasingpreact in dependencies — may cause React compatibility issues; monitor
R3Large i18n files100KB+ per locale; consider lazy-loading or splitting
R4No unit test frameworkOnly Playwright E2E; add Vitest for component unit tests

10.2 Technical Debt

IDDescriptionImpactProposed Solution
D1No component unit testsRegression riskAdd Vitest + React Testing Library
D2Mixed service patternsSome API calls in components, some in servicesConsolidate all API calls into service layer
D3TypeScript any usageReduced type safetyStrict noImplicitAny enforcement
D4No StorybookNo component catalogAdd Storybook for design system documentation

Appendix A: Revision History

VersionDateAuthorChanges
1.0May 2026SW360 Architecture TeamInitial document

Appendix B: References

  1. SW360 Frontend Repository: https://github.com/eclipse-sw360/sw360-frontend
  2. Next.js Documentation: https://nextjs.org/docs
  3. NextAuth.js: https://next-auth.js.org/
  4. React Bootstrap: https://react-bootstrap.github.io/
  5. next-intl: https://next-intl.dev/
  6. TanStack Table: https://tanstack.com/table
  7. Biome: https://biomejs.dev/
  8. Playwright: https://playwright.dev/

This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0 which is available at https://www.eclipse.org/legal/epl-2.0/