PhotoFlow Documentation Help

System Architecture

High-Level Architecture

PhotoFlow follows a microservices architecture with each service owning its domain and database. Services communicate through internal events and REST APIs.

Infrastructure

External

Supporting Services

Core Services

API Gateway

Client Layer

Angular Frontend

Public Portal

AppGateway

Photoflow Service

Storage Service

Identity Service

Organization Service

Provider Service

Sender Service

Google Drive

SMTP Server

PostgreSQL

Redis

SignalR Hub

Microservices Overview

Core Services

Service

Responsibility

Database

Photoflow

Album workflow, photos, feedback, state machine

pfl-dev

Storage

Cloud provider integration, file sync

pfl-dev

Identity

User authentication, token management

pfl-dev

Organization

Multi-tenant organization management

pfl-dev

Supporting Services

Service

Responsibility

Provider

External provider configurations

Sender

Email/SMS notification delivery

AppGateway

API routing, authentication middleware

Service Architecture Pattern

Each service follows Clean Architecture with four layers:

Service/ ├── Service.API/ # Controllers, DTOs, Middleware ├── Service.Application/ # Use Cases, Commands, Queries, Handlers ├── Service.Domain/ # Entities, Value Objects, Domain Events └── Service.Infrastructure/ # Repositories, External Services, EF Context

Layer Responsibilities

Infrastructure Layer

Repositories

EF Context

External APIs

Domain Layer

Entities

Value Objects

Domain Events

State Machine

Application Layer

Use Cases

Commands

Queries

Handlers

API Layer

Controllers

DTOs

Middleware

API Layer

Application Layer

Domain Layer

Infrastructure Layer

Communication Patterns

Synchronous Communication (REST APIs)

Services expose REST APIs for synchronous operations:

Frontend → AppGateway → Service API → Application Layer → Domain/Infrastructure

Asynchronous Communication (Internal Events)

Services publish and subscribe to internal events using IInServiceEventBus:

// Publishing an event await eventBus.Publish(new AlbumStateMachineTriggeredEvent { AlbumId = album.Id, FromState = previousState, ToState = newState }, cancellationToken); // Subscribing to events (via MediatR) public class AlbumStateMachineTriggeredEventHandler : INotificationHandler<AlbumStateMachineTriggeredEvent> { public async Task Handle(AlbumStateMachineTriggeredEvent notification, ...) { // Handle the event } }

Real-time Communication (SignalR)

SignalR is used for pushing real-time updates to connected clients:

Photoflow ServiceSignalR HubFrontendPhotoflow ServiceSignalR HubFrontendConnect with Auth TokenConnection EstablishedPublish AlbumStateChangedPush NotificationUpdate UI

Data Flow

Album Sync Flow

Google DriveStoragePhotoflowFrontendGoogle DriveStoragePhotoflowFrontendTrigger SyncRawTagValidate State MachineSyncFolderToStorage(folderId)Fetch PhotosPhotos DataProcess & StoreStorageFolderSyncProgressEventSignalR: PhotoSyncProgressStorageFolderSyncCompletedEventCreate PhotoProc RecordsSignalR: PhotoSyncCompleted

BuildingBlocks (Shared Libraries)

The BuildingBlocks directory contains shared libraries used across all services:

Library

Purpose

BuildingBlocks.Authentication

JWT authentication, authorization policies

BuildingBlocks.Caching

Redis caching abstractions

BuildingBlocks.Cloud

Cloud provider integrations (Google, AWS)

BuildingBlocks.Core

Base classes, common utilities

BuildingBlocks.Domain

Shared domain primitives

BuildingBlocks.Exception

Custom exception types

BuildingBlocks.Interceptor

Cross-cutting concerns

BuildingBlocks.Library

Helper utilities

BuildingBlocks.Messaging

Event bus abstractions

BuildingBlocks.Persistence

EF Core configurations

BuildingBlocks.SignalR

SignalR hub and notification service

BuildingBlocks.StateMachine

State machine abstractions

Security Architecture

Authentication Flow

Google OAuthIdentity ServiceGatewayFrontendUserGoogle OAuthIdentity ServiceGatewayFrontendUserClick LoginRedirect to Google OAuthAuth CodeExchange CodeHandleOAuthCallbackExchange for TokensGoogle TokensGenerate App JWTApp TokensAccess + Refresh TokenStore Tokens

Authorization Policies

Policy

Roles Allowed

Use Case

Photographer

photographer, org_admin

Album management operations

Admin

org_admin

Organization-level operations

SuperAdmin

supper_admin

System-wide operations

Anonymous

anonymous

Public client operations

PhotographerOrAnonymous

photographer, org_admin, anonymous

Shared operations (transitions)

Infrastructure Architecture

Kubernetes Deployment

Kubernetes Cluster

Infrastructure Namespace

photoflow-dev Namespace

PostgreSQL

Ingress Controller

Gateway Pod

Photoflow Pod

Storage Pod

Identity Pod

Redis

Helm Chart Structure

shin-helm-chart/ ├── Chart.yaml ├── values.yaml ├── templates/ │ ├── deployment.yaml │ ├── service.yaml │ ├── ingress.yaml │ ├── configmap.yaml │ ├── component-deployments.yaml │ └── component-services.yaml
  • Modules Overview

  • API Documentation

  • Deployment Guide

Last modified: 25 February 2026