Skip to content

Architecture

IONFLOW Frontend follows a modular architecture designed for scalability, maintainability, and developer experience.

graph TB
subgraph "Frontend Application"
Router[Vue Router]
Views[Views/Pages]
Components[Components]
Composables[Composables]
Stores[Pinia Stores]
Services[API Services]
end
subgraph "External"
API[Backend API]
Keycloak[Keycloak SSO]
Gateway[Gateway]
end
Router --> Views
Views --> Components
Views --> Composables
Components --> Composables
Composables --> Stores
Composables --> Services
Stores --> Services
Services --> API
Router --> Keycloak
Services --> Gateway

The application is organized into the following main modules:

ModuleDescription
AdminAdministrative features and tenant management
TenantTenant-specific features and flows
WorkspaceWorkspace management and collaboration
sequenceDiagram
participant C as Component
participant H as Composable/Hook
participant S as Pinia Store
participant A as API Service
participant B as Backend API
C->>H: Request data
H->>S: Check cache
alt Data in store
S-->>H: Return cached data
else Data not cached
H->>A: Fetch from API
A->>B: HTTP Request
B-->>A: Response
A-->>H: Parsed data
H->>S: Update store
end
H-->>C: Return data
sequenceDiagram
participant U as User
participant A as App
participant K as Keycloak
participant B as Backend
U->>A: Access protected route
A->>K: Redirect to login
U->>K: Enter credentials
K-->>A: Return tokens
A->>A: Store tokens
A->>B: API request + token
B-->>A: Protected data

The application uses a hierarchical routing structure:

  • /admin/* - Admin routes (protected, requires admin role)
  • /tenant/* - Tenant routes (protected, requires authentication)
  • /workspace/* - Workspace routes (protected, requires authentication)
  • /login - Authentication page
  • /sso-callback - SSO callback handler
GuardPurpose
auth.guard.tsValidates user authentication
keycloak.guard.tsHandles Keycloak SSO flow

The application uses Vite’s dynamic imports for code splitting:

// Lazy loaded routes
{
path: '/admin',
component: () => import('@/layouts/AdminLayout.vue'),
children: [...]
}

Pinia stores are organized by domain:

  • auth.ts - Authentication state and user info
  • counter.ts - Example/utility store

All components use Vue 3 Composition API with <script setup>:

<script setup lang="ts">
import { ref, computed } from 'vue';
const props = defineProps<{ title: string }>();
const emit = defineEmits<{ select: [item: Item] }>();
</script>

Services extend abstract classes for consistency:

class FlowService extends FlowsAbstractService {
// Implementation
}

Data fetching uses TanStack Query for caching and state management:

const { data, isLoading } = useQuery({
queryKey: ['flows', tenantId],
queryFn: () => flowsService.getAll(tenantId)
});