Introduction
This page will guide you on how to set up Fluxend locally. We assume you’re interested in modifying functionality or fixing bugs in either the Frontend or the Backend parts of the application. If you follow to end, you’ll fully understand how to make changes in either part.
Prerequisites
Before installing Fluxend, ensure you have the following tools installed and available via your command line interface:
Docker : Container platform for running applications
Docker Compose : Tool for defining multi-container applications
Make : Build automation tool for making your life easier
Git : Version control system
Golang: ^1.23.x
installed and accessible by running go version
Node: ^20.16.x
installed and accessible by running node --version
Yarn: Build tool responsible for frontend app
Goose: Database migration tool, must be accessible at goose version
You can verify these tools are installed by running docker --version
, docker-compose --version
, make --version
, and git --version
in your terminal.
Setup
Once you have all requirements satisfied, follow the Quickstart guide for initial setup. The basic installation process. The next steps will be different.
If you’re only interested in backend
, you can ignore frontend
and vice versa.
Please ensure to set URL_SCEHEME
to http
to avoid SSL issues when running application locally
Backend
Our backend app runs a compiled binary inside fluxend_api
container. If you’re interested in changing/developing a feature in this area, you should run this without a container to see realtime changes without having to re-compile each time.
You can following command inside fluxend
directory to initiate a real-time Golang Echo server
go run cmd/main.go server
You’ll now be able to see all logs and errors as they happen. If you’re also working on frontend, you’ll need to modify ENV
for frontend app by modifiying web/.env
file and point it to http://api.localhost:8080/
Frontend
Our frontend app runs on React and using container fluxend_frontend
In order to see changes realtime, you should first install dependencies by running:
Once this command has finished, you can don’t need to worry about dependencies anymore. You can begin running following:
Architecture
This section dives deep into architecture. It will give you an overview of directory structure, design principals, and other related topics.
File structure
├── bin/ # Backend compiled binaries and executables
├── cmd/ # Application entry points and main functions
├── docs/ # Project docs including swagger and openapi
├── internal/ # Private application code (not importable)
│ ├── adapters/ # External service integrations
│ │ ├── client/ # HTTP client implementations
│ │ ├── email/ # Email service providers (SES, Mailgun etc)
│ │ ├── postgrest/ # PostgREST API adapter
│ │ ├── sqlx/ # Database driver implementations
│ │ └── storage/ # File storage providers (S3, local, etc.)
│ ├── api/ # HTTP layer and web framework
│ │ ├── dto/ # Data Transfer Objects for API
│ │ ├── handlers/ # HTTP request handlers
│ │ ├── mapper/ # Data mapping between layers
│ │ ├── middlewares/ # HTTP middlewares (auth, logging, etc.)
│ │ ├── response/ # Response formatting utilities
│ │ └── routes/ # Route definitions and registration
│ ├── app/ # Application layer orchestration
│ │ └── commands/ # CLI commands
│ ├── config/ # Application configuration
│ │ └── constants/ # Application-wide constants
│ ├── database/ # Database layer
│ │ ├── factories/ # Test data factories
│ │ ├── migrations/ # Database schema migrations
│ │ ├── repositories/ # Data access implementations
│ │ └── seeders/ # Database seeding scripts
│ └── domain/ # Core business logic (Hexagonal Architecture)
│ ├── admin/ # Administrative operations domain
│ ├── auth/ # Authentication and authorization domain
│ ├── backup/ # Data backup operations domain
│ ├── database/ # Database management domain
│ ├── form/ # Form handling and validation domain
│ ├── health/ # Health checks and monitoring domain
│ ├── logging/ # Logging services domain
│ ├── openapi/ # Client documentation generation domain
│ ├── organization/ # Multi-tenancy and organization domain
│ ├── project/ # Project management domain
│ ├── setting/ # Configuration management domain
│ ├── shared/ # Common domain utilities
│ ├── stats/ # Analytics and statistics domain
│ ├── storage/ # File storage operations domain
│ └── user/ # User management domain
├── pkg/ # Public library code (importable)
│ ├── auth/ # Authentication utilities
│ ├── errors/ # Error handling utilities
│ └── message/ # Message formatting and i18n
├── tests/ # Test files and test utilities
└── web/ # React frontend application
├── app/ # Main React application code
│ ├── components/ # Reusable UI components
│ ├── contexts/ # React context providers
│ ├── hooks/ # Custom React hooks
│ ├── lib/ # Utility libraries and configurations
│ ├── routes/ # Route definitions and page components
│ ├── services/ # API service layer
│ ├── tools/ # Development and build tools
│ └── types/ # TypeScript type definitions
├── public/ # Static assets (images, favicon, etc.)
└── test/ # Frontend test files
Clean Architecture Foundation
Our BaaS follows Uncle Bob’s Clean Architecture principles with four distinct layers:
Domain Layer (innermost) - Pure business logic, no external dependencies
Application Layer - Use cases and application services
Infrastructure Layer - External concerns (database, web, file system)
Interface Layer - Controllers, presenters, and gateways
Dependency Rule
Source code dependencies must point only toward higher-level policies:
Domain layer has no dependencies on other layers
Application layer depends only on domain
Infrastructure layer depends on application and domain
Interface layer depends on all inner layers
Debugging
You can use pkg.DumpJSON
to print debug info when dealing with go related issues. We also use Zerolog so you can use it for printing information. Also, try looking into other files under pkg
directory.
When it comes to frontend, console.log
is your friend.
We’ll be updating this section with more helpful resources.
Go Conventions
When writing code, please ensure to follow best practices and write consistent code.
Naming Conventions
Variables & Functions : Use camelCase
for all variables, functions, and methods
Constants : Use PascalCase
for constants
Types & Structs : Use PascalCase
for exported types, camelCase
for unexported
Interfaces : Use PascalCase
with descriptive names (e.g., UserRepository
, EmailSender
)
var userName string
var maxRetryCount int
const DatabaseTimeout = 30
type UserService struct {}
type emailProvider struct {}
func getUserById ( id int ) ( * User , error ) {}
func ( s * UserService ) CreateUser ( user * User ) error {}
File Names : Use snake_case
for all Go files
Test Files : Append _test.go
to the corresponding file name
// ✅ Good
user_service . go
user_service_test . go
email_sender . go
database_connection . go
jwt_token_validator . go
// ❌ Bad
UserService . go
user - service . go
userService . go
Database Management
Always Close Connections : Database connections must be closed properly
Use defer : Close connections immediately after opening
Context Handling : Use context for timeout management
Error Handling : Always check connection errors
Error Handling
Same-Line if Statements : Use inline error checking for cleaner code
Wrap Errors : Use fmt.Errorf
with %w
verb for error wrapping
Early Returns : Return errors early to reduce nesting
// ✅ Good - Same-line error handling
func ( s * UserService ) CreateUser ( user * User ) error {
if err := s . validator . Validate ( user ); err != nil {
return fmt . Errorf ( "validation failed: %w " , err )
}
if err := s . repository . Save ( user ); err != nil {
return fmt . Errorf ( "failed to save user: %w " , err )
}
if err := s . emailSender . SendWelcomeEmail ( user . Email ); err != nil {
// Log error but don't fail the operation
log . Printf ( "failed to send welcome email: %v " , err )
}
return nil
}
Responses are generated using AI and may contain mistakes.