Skip to content

BananaOps/Offly

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

5 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

🌴 Offly β€” Time Off Manager

Modern absence & time off management. Simple, fast, self-hosted.

Release License Go Test Protobuf Lint Docker Pulls Docker Image Size Go Version Node Version Vite GitHub Stars GitHub Issues


πŸ“– New here? Check out the Quick Start Guide to get up and running in 5 minutes!

✨ Features

Feature Description
πŸ“… Calendar Grid Visual month-by-month absence grid per user & team
πŸ‘₯ Team Management Organize users into teams with availability tracking
πŸ–οΈ Absence Types Full day, morning only, afternoon only
🌍 Public Holidays Per-country holiday management
πŸ” Quick Search Instant search across users and teams
πŸŒ™ Dark Mode Full light/dark theme support
πŸ“Š Presence View Real-time daily attendance overview
πŸ“€ Export CSV and PDF export of absence reports
πŸ” SSO / OIDC Optional SSO authentication via Dex (PKCE flow)
πŸ›‘οΈ RBAC Role-based access control (admin / user)
πŸš€ Self-hosted Single Docker image β€” no external services required

πŸ“Έ Screenshots

Calendar View Teams
Calendar Teams
Users Holidays
Users Holidays

πŸ—οΈ Architecture

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                     Browser (React)                      β”‚
β”‚         TypeScript Β· Tailwind CSS Β· Vite 8              β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                        β”‚ HTTP / REST
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β–Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                    Go Backend                            β”‚
β”‚   gRPC Β· gRPC-Gateway Β· Protocol Buffers                β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚   SQLite (default)    β”‚   MongoDB (optional)            β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The single Docker image embeds both the Go binary and the compiled React SPA. The backend serves the frontend static files and provides the REST/gRPC API.

πŸ› οΈ Tech Stack

Layer Technology
Backend Go 1.26, gRPC, gRPC-Gateway, Protocol Buffers
Frontend React 18, TypeScript 5, Tailwind CSS 3, Vite 8
Database SQLite (default) Β· MongoDB (optional)
Auth Dex (OIDC/PKCE), JWT, JWKS
Container Docker (multi-stage, Alpine)
Orchestration Kubernetes Β· Helm Β· Skaffold
CI/CD GitHub Actions (SHA-pinned)

πŸ“‹ Prerequisites

Tool Version Purpose
Go 1.26+ Backend
Node.js 24+ Frontend
Task latest Task runner
Buf latest Protobuf tooling
Docker latest Containers

πŸš€ Quick Start

Option 1 β€” Docker Compose (recommended)

docker-compose up -d

The application is available at http://localhost:8080

Option 2 β€” Local development

# Clone
git clone https://github.com/BananaOps/offly.git && cd offly

# Install all dependencies and generate protobuf code
task setup

# Start the app (backend + frontend with hot reload)
task dev
Service URL
Web UI http://localhost:3000
REST API http://localhost:8080/api/v1
Swagger UI http://localhost:8080/docs
gRPC localhost:50051

Seed test data

# Requires k6 β€” see k6-README.md
k6 run k6-seed-data.js

Creates 5 departments, 10 teams, 12 users, 29 public holidays, and random absences.

🐳 Docker

# Pull & run (in-memory storage β€” no DB required)
docker run -p 8080:8080 bananaops/offly:latest

# With persistent SQLite
docker run -p 8080:8080 \
  -v $(pwd)/data:/app/data \
  bananaops/offly:latest

# With MongoDB
docker run -p 8080:8080 \
  -e STORAGE_TYPE=mongodb \
  -e MONGO_URI=mongodb://host.docker.internal:27017 \
  bananaops/offly:latest

See DOCKER.md for the full deployment guide.

☸️ Kubernetes (Helm)

# Add the chart repository
helm repo add offly https://bananaops.github.io/offly
helm repo update

# Install
helm install offly offly/offly

# Install a specific version
helm install offly offly/offly --version 0.1.0

# Upgrade
helm upgrade offly offly/offly

βš™οΈ Environment Variables

Variable Description Default
STORAGE_TYPE sqlite or mongodb sqlite
SQLITE_DB_PATH SQLite database path /app/data/offly.db
MONGO_URI MongoDB connection string mongodb://localhost:27017
HTTP_PORT HTTP server port 8080
GRPC_PORT gRPC server port 50051
AUTH_ENABLED Enable SSO authentication false
AUTH_ISSUER_URL OIDC issuer URL β€”
AUTH_CLIENT_ID OIDC client ID β€”

πŸ” SSO Authentication

Offly supports optional SSO via Dex (OIDC/PKCE flow).

Browser ──PKCE──▢ Dex ──ID Token──▢ Backend ──JWT verify──▢ SQLite
Role Permissions
admin Full access β€” users, teams, holidays, absences
user Read all Β· Edit own profile & absences only

See SSO-README.md for the full configuration guide.

πŸ”Œ API

REST (port 8080)

Interactive documentation available at http://localhost:8080/docs

Method Endpoint Description
GET /api/v1/health Health check
GET/POST /api/v1/users List / create users
GET/PUT/DELETE /api/v1/users/{id} Get / update / delete user
GET/POST /api/v1/teams List / create teams
GET/POST /api/v1/absences List / create absences
PUT/DELETE /api/v1/absences/{id} Update / delete absence
GET/POST /api/v1/holidays List / create public holidays
GET /api/v1/auth/config SSO configuration
POST /api/v1/auth/ensure-user Auto-provision SSO user

gRPC (port 50051)

Services: AbsenceService Β· UserService Β· OrganizationService Β· HolidayService

🧰 Task Commands

task setup            # Install deps + generate protobuf code
task dev              # Start backend + frontend (hot reload)
task build            # Build the full application
task test             # Run all tests
task lint             # Lint backend + frontend
task format           # Format backend + frontend
task proto            # Regenerate protobuf code
task proto:lint       # Lint protobuf definitions
task mongo:start      # Start MongoDB in Docker
task mongo:stop       # Stop MongoDB
task pre-commit       # Format + lint + test (run before committing)
task clean            # Remove generated files

πŸ“ Project Structure

offly/
β”œβ”€β”€ backend/
β”‚   β”œβ”€β”€ cmd/server/          # Server entry point
β”‚   β”œβ”€β”€ internal/
β”‚   β”‚   β”œβ”€β”€ auth/            # OIDC, JWT, RBAC middleware
β”‚   β”‚   β”œβ”€β”€ service/         # gRPC service implementations
β”‚   β”‚   └── storage/         # SQLite + MongoDB adapters
β”‚   └── proto/               # Protocol Buffer definitions
β”œβ”€β”€ frontend/
β”‚   └── src/
β”‚       β”œβ”€β”€ components/      # React components
β”‚       β”‚   β”œβ”€β”€ AbsenceGrid  # Main calendar grid
β”‚       β”‚   β”œβ”€β”€ PresenceView # Daily attendance view
β”‚       β”‚   β”œβ”€β”€ UserManagement
β”‚       β”‚   β”œβ”€β”€ TeamManagement
β”‚       β”‚   └── HolidayManagement
β”‚       β”œβ”€β”€ api.ts           # REST API client
β”‚       β”œβ”€β”€ auth.ts          # PKCE / JWT helpers
β”‚       └── types.ts         # TypeScript types
β”œβ”€β”€ helm/offly/              # Helm chart for Kubernetes
β”œβ”€β”€ dex/                     # Dex OIDC provider (dev/test)
β”œβ”€β”€ Dockerfile               # Multi-stage build (frontend + backend)
β”œβ”€β”€ docker-compose.yml       # Local stack
β”œβ”€β”€ Taskfile.yml             # Task automation
└── k6-seed-data.js          # Test data generator

🀝 Contributing

Contributions are welcome! We follow Conventional Commits:

git commit -m "feat: add new absence type filter"
git commit -m "fix: correct date calculation in calendar"
git commit -m "docs: update API reference"

Types: feat Β· fix Β· docs Β· chore Β· ci Β· refactor Β· perf Β· test

Releases are automated via Release Please.

πŸ› Troubleshooting

MongoDB won't start
task mongo:stop && task mongo:start
Protobuf compilation errors
task install:backend
task proto:lint   # Check for syntax errors
task proto        # Regenerate
Frontend dependency issues
cd frontend && rm -rf node_modules package-lock.json && npm install
SSO / Dex issues

See SSO-README.md for detailed troubleshooting steps.

πŸ“„ License

Released under the MIT License β€” Β© BananaOps


Documentation Β· Issues Β· Discussions Β· Docker Hub

Made with ❀️ by BananaOps