Hemma system för att tända och släcka lampor
  • C# 44.5%
  • TypeScript 19.3%
  • HTML 16%
  • CSS 11.2%
  • Shell 5.5%
  • Other 3.5%
Find a file
2026-06-19 17:42:59 +00:00
.claude fix: Temporarily disable OpenTelemetry tracing 2026-02-06 18:38:42 +01:00
.github Fix formatting in dependabot.yml 2025-10-31 15:13:29 +01:00
.vscode fix: Temporarily disable OpenTelemetry tracing 2026-02-06 18:38:42 +01:00
docs fix: Fix broken Docusaurus links, rebuild docs-site with updated content 2026-02-12 19:56:59 +01:00
infrastructure/kubernetes feat: Redesign frontend as IBM CICS 3270 terminal simulation 2026-06-19 19:25:32 +02:00
k8s Fix light control issues: sorting and toggle functionality 2025-11-27 21:25:24 +01:00
scripts Add Hue Bridge integration, services, controllers, and browser-based control panel 2025-10-26 19:46:11 +01:00
src Merge pull request 'main' (#1) from main into frontend-mainframe-style 2026-06-19 17:42:04 +00:00
.env.example Dockerized application frontend and backend. 2025-10-30 17:51:42 +01:00
.gitignore Add Java/Maven/Spring Boot entries to .gitignore 2025-11-27 21:25:24 +01:00
9F87846C-179A-42F9-8165-4024AD57B360_1_102_o.jpeg fix: Temporarily disable OpenTelemetry tracing 2026-02-06 18:38:42 +01:00
CLAUDE.md feat: Embed docs-site in frontend via iframe with /docs route 2026-02-12 19:43:00 +01:00
deploy.sh feat: Switch backend from Java Spring Boot to .NET 8, remove ArgoCD 2026-02-12 18:53:31 +01:00
DEPLOYMENT.md feat: Switch backend from Java Spring Boot to .NET 8, remove ArgoCD 2026-02-12 18:53:31 +01:00
LICENSE Initial commit 2025-10-26 18:09:53 +01:00
MACOS_SETUP.md Port backend to Java, fix Node.js v23 issue, add Docker/K8s deployment 2025-11-27 21:25:18 +01:00
README.md docs: add private docs site (#15) 2026-01-27 18:10:33 +01:00
SECURITY.md Create SECURITY.md for security policy 2025-10-30 10:12:17 +01:00
Task.md feat: Switch backend from Java Spring Boot to .NET 8, remove ArgoCD 2026-02-12 18:53:31 +01:00

Fredrics Hem - Smart Home Automation

A production-ready home automation system for controlling Philips Hue lights with role-based authentication, admin user management, and enterprise-grade deployment on Kubernetes.

🌐 Live at: https://adellen.se

📋 Table of Contents

🏗️ Architecture Overview

Fredrics Hem is a modern full-stack application built with Java Spring Boot backend and React frontend, deployed on a 3-node Kubernetes cluster with PostgreSQL database and integrated with Philips Hue Bridge.

graph TB
    subgraph "Client Layer"
        Browser[Web Browser]
    end
    
    subgraph "Kubernetes Cluster"
        subgraph "Ingress Layer"
            Ingress[Nginx Ingress Controller]
            Cert[cert-manager + Let's Encrypt]
        end
        
        subgraph "Application Layer"
            Frontend[React Frontend<br/>Node.js + Vite]
            Backend[Spring Boot API<br/>Java 21]
        end
        
        subgraph "Data Layer"
            PostgreSQL[(PostgreSQL 16<br/>ASP.NET Identity Schema)]
        end
    end
    
    subgraph "External"
        HueBridge[Philips Hue Bridge]
        LetsEncrypt[Let's Encrypt CA]
    end
    
    Browser -->|HTTPS| Ingress
    Ingress -->|TLS Termination| Frontend
    Ingress -->|/api/*| Backend
    Frontend -->|API Calls| Backend
    Backend -->|JPA/Hibernate| PostgreSQL
    Backend -->|REST API| HueBridge
    Cert -.->|ACME Protocol| LetsEncrypt
    
    style Frontend fill:#61dafb,stroke:#333,stroke-width:2px
    style Backend fill:#6db33f,stroke:#333,stroke-width:2px
    style PostgreSQL fill:#336791,stroke:#333,stroke-width:2px
    style Ingress fill:#009639,stroke:#333,stroke-width:2px

🛠️ Technology Stack

Backend

  • Java 21 with Spring Boot 3.4.0
  • Spring Security with JWT authentication
  • JPA/Hibernate with PostgreSQL
  • ASP.NET Core Identity password compatibility (PBKDF2 HMACSHA512)
  • Maven for dependency management
  • Docker multi-stage builds with layered JARs

Frontend

  • React 19 with TypeScript
  • Vite 7 for build tooling
  • React Router for navigation
  • Axios for HTTP client
  • Lucide React for icons
  • TanStack Query for data fetching

Infrastructure

  • Kubernetes 1.31 on 3-node cluster (Intel NUC)
  • PostgreSQL 16 with persistent volumes
  • Nginx Ingress Controller for routing
  • cert-manager for TLS certificate management
  • GitHub Container Registry (ghcr.io) for image hosting

DevOps

  • Docker containerization
  • GitHub Actions for CI/CD (future)
  • kubectl for deployments
  • Semantic versioning with timestamped tags

Features

Authentication & Authorization

  • JWT-based authentication with role-based access control
  • ASP.NET Identity compatibility - seamlessly migrated from .NET to Java
  • Admin user management with approval workflow
  • Secure password hashing using PBKDF2 with HMACSHA512 (100k iterations)
  • Role hierarchy: Administrator, User

Smart Home Control

  • Philips Hue integration via Bridge REST API
  • Light discovery and automatic synchronization
  • Individual light control (on/off, brightness)
  • Bulk operations (all on, all off)
  • Real-time status updates with polling

Admin Features

  • User approval system for new registrations
  • User management dashboard with pending/approved tabs
  • Role assignment and revocation
  • User deletion and access control

Production Ready

  • HTTPS/TLS with Let's Encrypt certificates
  • Health checks and readiness probes
  • Resource limits and requests
  • Persistent storage for database
  • High availability with pod replicas
  • Rolling updates with zero downtime

🔐 Authentication Flow

sequenceDiagram
    participant U as User/Browser
    participant F as React Frontend
    participant B as Spring Boot API
    participant DB as PostgreSQL
    participant Hue as Hue Bridge

    Note over U,DB: Registration & Approval Flow
    U->>F: Register (username, email, password)
    F->>B: POST /api/auth/register
    B->>DB: Create user (IsApproved=false)
    B-->>F: Registration successful
    F-->>U: "Wait for admin approval"
    
    Note over U,DB: Admin Approval
    U->>F: Admin logs in
    F->>B: POST /api/auth/login
    B->>DB: Verify credentials + load roles
    B->>B: Generate JWT with ROLE_Administrator
    B-->>F: Return JWT token
    F->>B: GET /api/admin/pending-users
    B->>DB: Query unapproved users
    B-->>F: List of pending users
    F->>B: POST /api/admin/approve-user/:id
    B->>DB: Set IsApproved=true
    B-->>F: User approved
    
    Note over U,Hue: Authentication & Light Control
    U->>F: Login (username, password)
    F->>B: POST /api/auth/login
    B->>DB: Verify credentials (PBKDF2 hash)
    B->>DB: Load user roles from AspNetUserRoles
    B->>B: Generate JWT with roles claim
    B-->>F: JWT token + user info
    F->>F: Store JWT in localStorage
    
    U->>F: View Dashboard
    F->>B: GET /api/lights (Authorization: Bearer JWT)
    B->>B: Validate JWT signature
    B->>DB: Query lights table
    B-->>F: Light list
    
    U->>F: Turn on light
    F->>B: PUT /api/lights/:id (state: on)
    B->>B: Validate JWT & permissions
    B->>Hue: PUT /api/{username}/lights/:id/state
    Hue-->>B: Success
    B->>DB: Update light state
    B-->>F: Updated light info
    F-->>U: UI updates

🚀 Getting Started

Prerequisites

  • Java 21 or higher (download)
  • Node.js 20+ and npm (download)
  • PostgreSQL 16 (download)
  • Docker Desktop (for containerization)
  • kubectl (for Kubernetes deployment)
  • Philips Hue Bridge on your network

Quick Start - Local Development

  1. Clone the repository

    git clone https://github.com/fredricadell/fredrics-hem.git
    cd fredrics-hem
    
  2. Setup PostgreSQL Database

    # Create database
    createdb huelights
    
    # Run migrations (ASP.NET Identity schema)
    psql huelights < archive/identity-migration.sql
    
  3. Configure Backend

    cd src/backend-java/huelights
    
    # Edit application.properties
    # Set database connection string, JWT secret, Hue Bridge IP
    
    # Build and run
    ./mvnw spring-boot:run
    
  4. Configure Frontend

    cd src/frontend
    
    # Install dependencies
    npm install
    
    # Start dev server
    npm run dev
    
  5. Access the application

Initial Setup

  1. Register a user at http://localhost:5173
  2. Approve the user manually in the database:
    UPDATE "AspNetUsers" SET "IsApproved" = true WHERE "UserName" = 'your-username';
    
  3. Assign admin role:
    INSERT INTO "AspNetUserRoles" ("UserId", "RoleId")
    SELECT u."Id", r."Id"
    FROM "AspNetUsers" u, "AspNetRoles" r
    WHERE u."UserName" = 'your-username' AND r."Name" = 'Administrator';
    
  4. Login and access admin panel

💻 Development

Backend Development

cd src/backend-java/huelights

# Build
./mvnw clean package

# Run tests
./mvnw test

# Build Docker image
docker build -t fredrics-hem-backend:local .

# Run with Docker
docker run -p 8080:8080 \
  -e SPRING_DATASOURCE_URL=jdbc:postgresql://host.docker.internal:5432/huelights \
  fredrics-hem-backend:local

Frontend Development

cd src/frontend

# Install dependencies
npm install

# Start dev server with HMR
npm run dev

# Build for production
npm run build

# Preview production build
npm run preview

# Type checking
npm run type-check

# Linting
npm run lint

Project Structure

fredrics-hem/
├── src/
│   ├── backend-java/huelights/          # Spring Boot API
│   │   ├── src/main/java/se/adellen/huelights/
│   │   │   ├── controller/              # REST controllers
│   │   │   ├── model/                   # JPA entities
│   │   │   ├── repository/              # Data repositories
│   │   │   ├── security/                # JWT & authentication
│   │   │   ├── service/                 # Business logic
│   │   │   └── config/                  # Configuration
│   │   ├── pom.xml                      # Maven dependencies
│   │   └── Dockerfile                   # Multi-stage build
│   │
│   └── frontend/                        # React app
│       ├── src/
│       │   ├── components/              # React components
│       │   ├── contexts/                # Auth context
│       │   ├── hooks/                   # Custom hooks
│       │   ├── pages/                   # Page components
│       │   └── main.tsx                 # Entry point
│       ├── package.json
│       ├── vite.config.ts
│       └── Dockerfile                   # Node serve build
│
├── infrastructure/
│   └── kubernetes/base/                 # K8s manifests
│       ├── backend-deployment.yaml
│       ├── frontend-deployment.yaml
│       ├── postgres-deployment.yaml
│       ├── ingress.yaml
│       └── secrets.yaml
│
├── docs/                                # Documentation
├── archive/                             # Legacy .NET code
└── scripts/                             # Setup scripts

🚢 Deployment

Docker Images

Build and push images to GitHub Container Registry:

# Backend
cd src/backend-java/huelights
./mvnw clean package
docker buildx build --platform linux/amd64 \
  -t ghcr.io/fredricadell/fredrics-hem-backend:v1.0.24-amd64 .
docker push ghcr.io/fredricadell/fredrics-hem-backend:v1.0.24-amd64

# Frontend
cd src/frontend
npm run build
docker buildx build --platform linux/amd64 \
  -t ghcr.io/fredricadell/fredrics-hem-frontend:v$(date +%s)-amd64 .
docker push ghcr.io/fredricadell/fredrics-hem-frontend:v$(date +%s)-amd64

Kubernetes Deployment

# Create namespace
kubectl create namespace fredrics-hem

# Create secrets (GitHub Container Registry)
kubectl create secret docker-registry ghcr-secret \
  --docker-server=ghcr.io \
  --docker-username=YOUR_GITHUB_USERNAME \
  --docker-password=YOUR_GITHUB_TOKEN \
  -n fredrics-hem

# Deploy PostgreSQL
kubectl apply -f infrastructure/kubernetes/base/postgres-deployment.yaml

# Deploy backend
kubectl apply -f infrastructure/kubernetes/base/backend-deployment.yaml

# Deploy frontend
kubectl apply -f infrastructure/kubernetes/base/frontend-deployment.yaml

# Deploy ingress
kubectl apply -f infrastructure/kubernetes/base/ingress.yaml

# Check status
kubectl get pods -n fredrics-hem
kubectl get services -n fredrics-hem
kubectl get ingress -n fredrics-hem

Deployment Architecture

graph TB
    subgraph "Internet"
        Users[Users]
        DNS[DNS: adellen.se]
    end
    
    subgraph "Kubernetes Cluster - fredrics-hem namespace"
        subgraph "Node 1 - k8s-master"
            Ingress[Ingress Controller<br/>cert-manager]
        end
        
        subgraph "Node 2 - k8s-w1"
            Backend[Backend Pod<br/>Java Spring Boot<br/>Port 8080]
            Postgres[PostgreSQL Pod<br/>Port 5432<br/>PVC: 10Gi]
        end
        
        subgraph "Node 3 - k8s-w2"
            Frontend[Frontend Pod<br/>Node.js serve<br/>Port 8080]
        end
        
        BackendSvc[backend-service<br/>ClusterIP:8080]
        FrontendSvc[frontend-service<br/>ClusterIP:80]
        PostgresSvc[postgres-service<br/>ClusterIP:5432]
    end
    
    subgraph "Home Network"
        HueBridge[Hue Bridge<br/>192.168.x.x]
    end
    
    Users -->|HTTPS| DNS
    DNS -->|TLS| Ingress
    Ingress -->|/| FrontendSvc
    Ingress -->|/api/*| BackendSvc
    FrontendSvc --> Frontend
    BackendSvc --> Backend
    Backend --> PostgresSvc
    PostgresSvc --> Postgres
    Backend -->|REST API| HueBridge
    
    style Frontend fill:#61dafb
    style Backend fill:#6db33f
    style Postgres fill:#336791
    style Ingress fill:#009639

📚 Documentation

Detailed documentation is available in the /docs directory:

🔑 Environment Variables

Backend (Spring Boot)

# Database
SPRING_DATASOURCE_URL=jdbc:postgresql://postgres-service:5432/huelights
SPRING_DATASOURCE_USERNAME=huelights_user
SPRING_DATASOURCE_PASSWORD=your_secure_password

# JWT
JWT_SECRET=your_jwt_secret_key_min_256_bits
JWT_EXPIRATION_MS=3600000

# Hue Bridge
HUE_BRIDGE_IP=192.168.x.x
HUE_BRIDGE_USERNAME=your_hue_username

Frontend (React)

# API endpoint
VITE_API_BASE_URL=/api

# Backend service (for Node.js serve)
BACKEND_HOST=backend-service
BACKEND_PORT=8080
PORT=8080

🧪 Testing

# Backend unit tests
cd src/backend-java/huelights
./mvnw test

# Frontend tests (if configured)
cd src/frontend
npm run test

# Integration tests
curl -X POST https://adellen.se/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{"username":"testuser","password":"TestPass123!"}'

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit changes (git commit -m 'Add amazing feature')
  4. Push to branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

📝 License

This project is licensed under the MIT License - see the LICENSE file for details.

🙏 Acknowledgments

  • Philips Hue for the excellent smart home platform
  • Spring Boot and React communities
  • Kubernetes project and ecosystem
  • Let's Encrypt for free TLS certificates

📞 Contact

Fredric Adell - fredric@adell.me

Project Link: https://github.com/fredricadell/fredrics-hem


Current Version: Backend v1.0.24, Frontend v1764363391
Last Updated: December 3, 2025
Status: Production - Running at https://adellen.se