Architecture
Introduction
Fenice is a framework for creating custom applications, designed to support multiple tenants (clients) with their own configurations and customizations. The architecture allows generating specific applications for each tenant while maintaining a common and reusable codebase.
Fenice contains three main projects:
- Desktop: A desktop application developed with Electron and React.
- Mobile: A mobile application developed with React Native.
- Fenice: A shared module containing common logic, components, and resources used by both applications.
Fenice Objective
The objective of this structure is twofold:
- Centralize the development of applications that share common logic, design, and functionalities, simplifying maintenance and team collaboration.
- Provide a flexible framework that allows rapid creation of custom applications for different tenants, maintaining consistency in user experience and reusing base components while allowing client-specific customization.
Project Structure
root/
├── desktop/
│ ├── public/ # Static resources for desktop app and Electron-specific code
│ ├── src/ # React-specific source code
│ ├── node_scripts/ # Desktop-specific node scripts
│ └── package.json # Desktop project configuration
├── env/ # Environment variables
│ ├── default/ # Basic project environment variables
│ └── staging/ # Environment variables cloned from external repository (see [docs](https://engineering.publica.la/docs/Fenice/Environment))
├── fenice/
│ ├── config/ # Project configuration
│ ├── src/ # Shared source code between platforms
│ ├── tenant/ # Tenant repository submodule
│ └── package.json # Shared module dependencies and configuration
├── mobile/
│ ├── android/ # Android configuration
│ ├── tests/ # Automated test files
│ ├── ios/ # iOS configuration
│ ├── node_scripts/ # Mobile-specific node scripts
│ ├── src/ # React Native app source code
│ ├── app.json # Mobile project configuration
│ └── package.json # Mobile project dependencies and scripts
├── node_scripts/ # [Custom Node scripts](https://engineering.publica.la/docs/Fenice/Scripts)
├── .env # Environment variables created by script
├── processedTenants.json # List of tenants processed by build script
└── version.json # Version file for all apps
Description of Each Folder
1. Desktop (see docs)
The desktop folder contains the desktop application implementation with Electron as the main framework for window creation and React for UI rendering.
- Main Code: Located in
public/. Includes:- electron.js: Main Electron process (handles window creation and system logic).
- React Code: Located in
src/. Includes:- index.js: Contains React code that runs inside the window.
- navigation: Contains navigation definition using react-router-dom.
- Packaging Configuration: Defined in
electron-builder.yml.
Basic Flow
- Electron initializes the main process (
public/electron.js). - The main process launches a window that loads the React application from the renderer.
- Logic and UI are generated using React components, many of which are shared from
fenice. - Communication between the main process and renderer(React) is done through IPC (Inter-Process Communication).
2. Mobile (see docs)
The mobile folder contains the mobile application implementation with React Native. It's structured to support both Android and iOS.
- Main Code: In
src/you'll find the application's components, screens, and services. - Platform-specific configurations:
- Android: Configuration in the
android/folder. Contains Android native configuration, including application resources, project configuration files, custom native modules, and platform-specific native dependencies. - iOS: Configuration in the
ios/folder. Contains iOS native configuration, including Xcode project, CocoaPods dependency management, custom native modules, and platform-specific resources.
- Android: Configuration in the
Basic Flow
- React Native initializes the native app on its respective platform.
- Logic and UI are generated using React components, many of which are shared from
fenice.
3. Fenice (see docs)
The fenice folder contains shared resources between desktop and mobile applications. Includes:
- Components: Reusable elements like buttons, forms, layouts, etc.
- Hooks: Reusable logic like state management or API integration.
- Services: Definition of platform-specific singletons and plugins.
- Tenant: Git submodule with app resources and specifications.
- Platform Definitions: Both components and services are defined separately for each platform (desktop and mobile), adding the
nativeprefix to the file extension. E.g.,handleFiles.native.js.
Usage in Projects
desktopandmobileimport modules fromfeniceto use common components or logic.- This is achieved through symlinks (in a Yarn-configured environment) defined in each platform's
package.jsonfile.
Best Practices
• Keep code modular and well-documented in fenice. • Ensure changes in shared modules don't break dependent applications. • Use defined scripts for running and packaging projects.