savvy Svelte Themes

Savvy

Digital management of customer cards, vouchers, and gift cards with sharing functionality - Progressive Web App with Go + SvelteKit

🎁 Savvy

Digital management system for loyalty cards, vouchers, and gift cards with sharing functionality

A modern web-based system for managing loyalty cards, discount vouchers, and prepaid gift cards. Features integrated barcode scanner, transaction history, and flexible sharing with other users.

✨ Features

🎴 Loyalty Cards

  • Digital storage of loyalty cards and membership cards
  • Barcode support (CODE128, QR, EAN13, EAN8)
  • Barcode scanning via smartphone/webcam (html5-qrcode)
  • Server-side barcode generation (bwip-js)
  • Status tracking (Active, Inactive)
  • Merchant management with colors and logos
  • Merchant filter for quick merchant-based filtering
  • Share with other users (with edit permissions)

🎟️ Vouchers

  • Discount vouchers (percentage, fixed amount, points multiplier)
  • Multiple usage models:
    • Single-Use (one-time)
    • One-per-Customer (once per customer)
    • Multiple-Use (multiple times with/without card tracking)
    • Unlimited
  • Validity period and minimum order value
  • Barcode scanning for quick capture
  • Merchant filter for targeted searching
  • Sharing (always read-only for shared users)

πŸ’³ Gift Cards

  • Prepaid balance with automatic calculation
  • Transaction history (expenses and recharges)
  • Optional PIN protection
  • Barcode scanning for card numbers
  • Merchant filter for organized overview
  • Expiration date management
  • Share with granular permissions:
    • Edit (modify details)
    • Delete (remove card)
    • Manage transactions (record expenses)

πŸ‘₯ Sharing & Permissions

  • All three resource types can be shared
  • Flexible permissions per share
  • Edit/Delete/View permissions for Cards
  • Transaction management for Gift Cards
  • Overview of shared items in dashboard
  • User-specific favorites (shared items can be favorited individually)
  • Owner display for shared items ("from [Name]")

πŸ”„ Ownership Transfer

  • Complete ownership transfer for Cards, Vouchers & Gift Cards
  • Email-based recipient selection with autocomplete
  • Only owner can transfer (Authorization via AuthzService)
  • Clean slate approach: All shares are deleted on transfer
  • Audit logging for all ownership transfers
  • Inline form with warnings before transfer
  • Reactive SvelteKit UI without page reload

πŸ“Š Dashboard

  • Statistics (number of Cards/Vouchers/Gift Cards)
  • Total balance of all Gift Cards
  • ⭐ Favorites system (pinning) - Quick access to frequently used items
  • Recently added items (when no favorites available)
  • Quick access to create new items
  • Mobile-optimized view (favorites before statistics)

πŸ” Search & Filter

  • Full-text search by merchant/code
  • Filter by owner (Mine / All)
  • Filter by status (Active / Expired)
  • Sort by merchant or date
  • Client-side filtering (Svelte reactive statements) for fast results

πŸ“± Progressive Web App (PWA)

  • βœ… Installable: Can be installed as app on iOS/Android/Desktop
  • βœ… Offline-first: Automatic warmup cache for instant offline support
  • βœ… Custom Service Worker: NetworkFirst strategy with Workbox Recipes
  • βœ… Offline detection: Visual feedback for network issues
  • βœ… Automatic updates: Service worker updates transparently in background
  • βœ… Zero 500 errors: Cache fallback prevents offline errors

Offline features:

  • βœ… View cards/vouchers/gift cards (automatically cached on Service Worker install)
  • βœ… Display barcode details
  • βœ… Filter & sort (client-side)
  • βœ… Browse favorites
  • βœ… Dashboard statistics (automatically cached)
  • ❌ Create/edit/delete items (online only)
  • ❌ Share management (online only)

πŸ”” Notifications

  • In-app notification system for shares and transfers
  • Real-time notifications when items are shared with you
  • Permission change alerts for shared resources
  • Ownership transfer notifications
  • Mark as read/unread functionality
  • Delete individual or all notifications
  • Automatic notification generation via service layer

🌍 Internationalization

  • Multi-language support: German (DE), English (EN), French (FR)
  • Language switcher in navigation
  • Fully translated UI including forms, buttons, and messages
  • SvelteKit i18n store with reactive language switching
  • Persistent language preference (localStorage)
  • Date and number localization per language

πŸ” Authentication & Authorization

  • OAuth/OIDC: Provider-agnostic authentication (Google, Microsoft, etc.)
  • Local Authentication: Email/Password with bcrypt hashing
  • Session-based authentication with Gorilla Sessions
  • AuthzService: Centralized authorization logic for all resources
  • Granular permission checks (view, edit, delete, manage transactions)
  • User impersonation for admin debugging
  • Secure session management with CSRF protection

πŸŽ›οΈ Feature Toggles

  • Environment-based feature flags for flexible deployment:
    • ENABLE_CARDS - Enable/disable loyalty cards feature
    • ENABLE_VOUCHERS - Enable/disable vouchers feature
    • ENABLE_GIFT_CARDS - Enable/disable gift cards feature
    • ENABLE_LOCAL_LOGIN - Enable/disable email/password authentication
    • ENABLE_REGISTRATION - Enable/disable user self-registration
  • Runtime configuration via /api/v1/config endpoint
  • Client-side feature detection (SvelteKit reads config on startup)
  • Middleware-based feature enforcement

πŸ“ Audit Logging

  • Automatic logging of all delete operations
  • Comprehensive audit trail with:
    • User ID, action type, resource type/ID
    • JSONB snapshot of deleted resource
    • IP address and user agent
    • Timestamp with timezone
  • Admin panel access to audit logs
  • Retention policy support
  • Compliance-ready audit trail

πŸ“Š Observability & Monitoring

  • Prometheus Metrics (/metrics endpoint):
    • HTTP request duration and counts
    • Resource counts (cards, vouchers, gift cards, users)
    • Active sessions and database connections
  • Health Checks:
    • /health - Liveness probe (server running)
    • /ready - Readiness probe (database connectivity)
  • Structured Logging: JSON logs with slog
  • OpenTelemetry: Optional distributed tracing (OTEL_ENABLED)
  • Performance monitoring (N+1 query prevention, database triggers)

πŸ‘¨β€πŸ’Ό Admin Panel

  • User Management: View and manage all users
  • Resource Overview: Access to all cards/vouchers/gift cards
  • Audit Log Viewer: Review deletion history
  • Resource Restoration: Recover soft-deleted items
  • User Impersonation: Debug user-specific issues
  • Statistics Dashboard: System-wide metrics
  • Role-based access control (admin-only features)

πŸš€ Quick Start

Prerequisites

  • Docker & Docker Compose
  • Make (optional, for Makefile shortcuts)

Installation & Start

# 1. Clone repository
git clone <repository-url>
cd savvy

# 2. Configure environment variables
cp .env.example .env
# Edit .env with your settings

# 3. Start Docker containers (automatically builds everything)
make dev

# 4. Load test data (optional, in another terminal)
make seed

Application URL: http://localhost:8080

Note: Local development without Docker is not supported due to Vite proxy requirements. The Vite dev server requires access to http://api:8080 which only works in the Docker network. See DEVELOPMENT.md for details.

Test Users

After seeding, the following test accounts are available (password: test123):

Email Role Description
[email protected] Admin Has admin rights + own items
[email protected] User Has access to shared items
[email protected] User Has access to shared items
[email protected] User Has own items

πŸ’» Development

Local Development Environment

IMPORTANT: Always use Docker for development!

# βœ… RECOMMENDED: Start with Makefile (includes Hot Reload)
make dev

# This starts:
# - PostgreSQL (port 5432)
# - Go API with Air Hot Reload (port 8080)
# - Vite Dev Server with HMR (port 5173)

Why Docker?

  • βœ… Consistent development environment
  • βœ… Vite proxy only works in Docker network (http://api:8080)
  • βœ… Air and Vite HMR work automatically
  • βœ… No manual port configurations
  • βœ… All dependencies bundled (PostgreSQL, Go, Node.js)

See DEVELOPMENT.md for details.

Makefile Commands

# Development (Docker-based)
make dev         # Start Docker development (alias for make up)
make up          # Start Docker containers with hot reload
make down        # Stop Docker containers
make restart     # Restart containers
make rebuild     # Rebuild containers
make logs        # View API logs
make logs-all    # View all container logs

# Database (runs in Docker)
make migrate-up     # Apply migrations
make migrate-down   # Rollback migration
make migrate-status # Check migration status
make seed           # Seed test data
make db-shell       # PostgreSQL shell

# Testing & Build
make test        # Run all tests
make test-core   # Run core tests (services + models)
make build       # Build binary with embedded client

# Container Access
make shell       # Application shell

Code Changes

All changes are automatically detected in Docker containers:

# Start Docker development environment
make dev  # or: make up

# This provides automatic hot reload for:
# - SvelteKit Frontend: Vite HMR detects changes in client/src/
# - Go Backend: Air reloads on changes in internal/
# - Database: GORM AutoMigrate runs on server start

File locations:

  • Frontend: client/src/ - SvelteKit components, stores, API clients
  • Backend: internal/ - Go handlers, services, repositories
  • Database Models: internal/models/ - GORM models
  • API Endpoints: internal/handlers/api/ - JSON API handlers

Important: Always use Docker (make dev) - local npm/air commands won't work due to network requirements.

πŸ“ Project Structure

savvy/
β”œβ”€β”€ cmd/                  # Application entrypoints
β”‚   β”œβ”€β”€ server/           # Main application server
β”‚   β”œβ”€β”€ seed/             # Database seeding script
β”‚   β”œβ”€β”€ migrate/          # Database migration tool
β”‚   β”œβ”€β”€ release-tool/     # Release version synchronization
β”‚   └── e2e/              # E2E test server setup
β”‚
β”œβ”€β”€ internal/
β”‚   β”œβ”€β”€ setup/            # Server initializationβ”‚   β”‚   β”œβ”€β”€ dependencies.go # DI container, database, telemetry
β”‚   β”‚   β”œβ”€β”€ routes.go     # Route registration
β”‚   β”‚   └── server.go     # Echo configuration
β”‚   β”œβ”€β”€ config/           # Configuration management
β”‚   β”œβ”€β”€ database/         # Database connection & utilities
β”‚   β”œβ”€β”€ handlers/         # HTTP handlers (Controllers)
β”‚   β”‚   β”œβ”€β”€ api/          # JSON API handlersβ”‚   β”‚   β”‚   β”œβ”€β”€ cards.go    # Cards API
β”‚   β”‚   β”‚   β”œβ”€β”€ vouchers.go # Vouchers API
β”‚   β”‚   β”‚   β”œβ”€β”€ gift_cards.go # Gift Cards API
β”‚   β”‚   β”‚   β”œβ”€β”€ notifications.go # Notifications API
β”‚   β”‚   β”‚   β”œβ”€β”€ dto.go      # Data Transfer Objects
β”‚   β”‚   β”‚   └── mappers.go  # Model ↔ DTO mapping
β”‚   β”‚   β”œβ”€β”€ shares/       # Share handler abstraction
β”‚   β”‚   β”œβ”€β”€ health.go     # Health checks
β”‚   β”‚   β”œβ”€β”€ oauth.go      # OAuth/OIDC handlers
β”‚   β”‚   └── spa.go        # SvelteKit SPA fallback
β”‚   β”œβ”€β”€ services/         # Business logic layer
β”‚   β”‚   β”œβ”€β”€ card_service.go
β”‚   β”‚   β”œβ”€β”€ voucher_service.go
β”‚   β”‚   β”œβ”€β”€ gift_card_service.go
β”‚   β”‚   β”œβ”€β”€ notification_service.go
β”‚   β”‚   β”œβ”€β”€ transfer_service.go
β”‚   β”‚   β”œβ”€β”€ authz_service.go
β”‚   β”‚   └── container.go  # Service DI container
β”‚   β”œβ”€β”€ repository/       # Data access layer (GORM)
β”‚   β”œβ”€β”€ models/           # GORM models
β”‚   β”‚   β”œβ”€β”€ user.go
β”‚   β”‚   β”œβ”€β”€ merchant.go
β”‚   β”‚   β”œβ”€β”€ notification.goβ”‚   β”‚   β”œβ”€β”€ card.go / voucher.go / gift_card.go
β”‚   β”‚   └── *_share.go    # Sharing models
β”‚   β”œβ”€β”€ middleware/       # HTTP middleware
β”‚   β”‚   β”œβ”€β”€ auth.go       # Authentication
β”‚   β”‚   β”œβ”€β”€ cors.go       # CORS configuration
β”‚   β”‚   β”œβ”€β”€ csrf*.go      # CSRF protection
β”‚   β”‚   β”œβ”€β”€ security.go   # Security headers
β”‚   β”‚   └── ...           # Other middleware
β”‚   β”œβ”€β”€ migrations/       # Database migrations (embedded)
β”‚   β”œβ”€β”€ mocks/            # Generated mocks for testing (mockery)
β”‚   β”œβ”€β”€ audit/            # Audit logging
β”‚   β”œβ”€β”€ metrics/          # Prometheus metrics
β”‚   β”œβ”€β”€ telemetry/        # OpenTelemetry integration
β”‚   β”œβ”€β”€ oauth/            # OAuth/OIDC implementation
β”‚   β”œβ”€β”€ security/         # Security utilities
β”‚   β”œβ”€β”€ i18n/             # Internationalization
β”‚   β”œβ”€β”€ validation/       # Input validation
β”‚   β”œβ”€β”€ debug/            # Debug utilities
β”‚   └── assets/           # Embedded client build
β”‚       └── client/       # SvelteKit build output
β”‚
β”œβ”€β”€ client/               # SvelteKit Frontendβ”‚   β”œβ”€β”€ src/
β”‚   β”‚   β”œβ”€β”€ routes/       # SvelteKit pages
β”‚   β”‚   β”‚   β”œβ”€β”€ +page.svelte       # Dashboard
β”‚   β”‚   β”‚   β”œβ”€β”€ cards/             # Cards routes
β”‚   β”‚   β”‚   β”œβ”€β”€ vouchers/          # Vouchers routes
β”‚   β”‚   β”‚   β”œβ”€β”€ gift-cards/        # Gift cards routes
β”‚   β”‚   β”‚   └── admin/             # Admin panel
β”‚   β”‚   β”œβ”€β”€ lib/
β”‚   β”‚   β”‚   β”œβ”€β”€ components/        # Reusable Svelte components
β”‚   β”‚   β”‚   β”œβ”€β”€ api/               # API client modules
β”‚   β”‚   β”‚   β”œβ”€β”€ stores/            # Svelte stores (auth, offline, i18n)
β”‚   β”‚   β”‚   β”œβ”€β”€ utils/             # Helper functions
β”‚   β”‚   β”‚   β”œβ”€β”€ i18n/              # Translations (DE, EN, FR)
β”‚   β”‚   β”‚   └── types/             # TypeScript types
β”‚   β”‚   β”œβ”€β”€ tests/        # E2E tests (Playwright)
β”‚   β”‚   β”œβ”€β”€ hooks.client.ts # SvelteKit client hooks
β”‚   β”‚   └── app.html      # HTML template
β”‚   β”œβ”€β”€ static/           # Static assets (favicon, etc.)
β”‚   β”œβ”€β”€ vite.config.ts    # Vite configuration
β”‚   β”œβ”€β”€ playwright.config.ts # Playwright E2E test config
β”‚   β”œβ”€β”€ package.json      # Node.js dependencies
β”‚   └── tsconfig.json     # TypeScript config
β”‚
β”œβ”€β”€ deploy/               # Deployment configurations
β”‚   β”œβ”€β”€ helm/             # Helm charts for Kubernetes
β”‚   β”œβ”€β”€ kustomize/        # Kustomize overlays
β”‚   β”œβ”€β”€ grafana/          # Grafana dashboards
β”‚   └── observability/    # Observability stack (Prometheus, Loki)
β”‚
β”œβ”€β”€ .air.toml            # Hot reload config (Air)
β”œβ”€β”€ .golangci.yml        # Go linter configuration
β”œβ”€β”€ .revive.toml         # Revive linter configuration
β”œβ”€β”€ .mockery.yaml        # Mock generation config
β”œβ”€β”€ .goreleaser.yaml     # Release automation config
β”œβ”€β”€ docker-compose.yml   # Docker services (dev)
β”œβ”€β”€ Dockerfile           # Multi-stage build
β”œβ”€β”€ Makefile             # Development commands
β”œβ”€β”€ go.mod / go.sum      # Go dependencies
β”œβ”€β”€ CODE_OF_CONDUCT.md   # Community guidelines
β”œβ”€β”€ OBSERVABILITY.md     # Observability guide
└── README.md            # This file

πŸ› οΈ Tech Stack

Core Stack

Component Technology Version Purpose
Backend Framework Echo v4.15 HTTP Router & Middleware
ORM GORM v1.31 PostgreSQL Abstraction
Frontend SvelteKit + TypeScript 2.51 Modern SPA Framework
Build Tool Vite 7.3 Fast Build & Dev Server
Styling TailwindCSS 4.1 Utility-First CSS
Database PostgreSQL 16 Primary Data Store
Language Go 1.26 Backend Language
Language TypeScript 5.9 Frontend Language

Features & Libraries

Feature Technology Purpose
Auth (Sessions) Gorilla Sessions Session-based Authentication
Auth (OAuth/OIDC) go-oidc OpenID Connect Provider
Barcode Scanning @undecaf/zbar-wasm WebAssembly Barcode Scanner
Barcode Generation bwip-js Server-side Barcode Rendering
Validation go-playground/validator Input Validation
i18n go-i18n Internationalization
Metrics Prometheus Application Metrics
Tracing OpenTelemetry Distributed Tracing
PWA @vite-pwa/sveltekit Service Worker & Offline
Service Worker Workbox Caching & Offline Strategies

Development & Testing

Tool Technology Purpose
Hot Reload (Go) Air Go Auto-Reload
Hot Reload (Vite) Vite HMR Frontend Hot Module Replace
Unit Testing (Go) testify Go Test Assertions
Unit Testing (JS) Vitest Frontend Unit Tests
E2E Testing Playwright End-to-End Browser Tests
Mocking Mockery Mock Generation for Tests
Linting (Go) golangci-lint + revive Go Code Quality
Linting (TS) svelte-check TypeScript/Svelte Validation

πŸ—„οΈ Database

The application uses PostgreSQL with 12 main tables for users, merchants, cards, vouchers, gift cards, sharing, favorites, notifications, and audit logs.

For detailed database schema, ERD diagram, and table descriptions, see:

πŸ“– ARCHITECTURE.md - Database Schema

πŸ” Security

  • βœ… Bcrypt password hashing
  • βœ… Session-based authentication
  • βœ… CSRF protection (Echo middleware)
  • βœ… SQL injection protection (GORM parameterized queries)
  • βœ… XSS protection (SvelteKit auto-escaping)
  • βœ… UUID instead of integer IDs
  • βœ… Granular permissions for sharing

See SECURITY.md for complete security policy and vulnerability reporting.

πŸš€ Deployment

The application is designed for containerized deployment with Traefik reverse proxy for production use. Supports Docker Compose and Kubernetes (K3s/K8s).

Production Architecture:

Client (HTTPS) β†’ Traefik (TLS) β†’ Savvy (HTTP:8080) β†’ PostgreSQL

For detailed deployment instructions, environment variables, Traefik configuration, and Kubernetes manifests, see:

πŸ“– OPERATIONS.md - Deployment Guide

πŸ§ͺ Testing

Backend Tests (Go)

# Run all tests
make test

# Run core tests (services + models)
make test-core

# Run tests with coverage report
make test-coverage

# Run specific test (direct go test)
go test ./internal/models -run TestCard_GetColor

# Run tests with race detection
go test -race ./...

Coverage: 57.8% (Services), 54.1% (Handlers/API), 100.0% (Models), 97.2% (Repositories)

Frontend Tests (Vitest)

cd client

# Run unit tests
npm test

# Run tests with UI
npm run test:ui

# Run tests with coverage
npm run test:coverage

Coverage: 32.8% unit test coverage (19 tests, stores and utils)

E2E Tests (Playwright)

cd client

# Install Playwright browsers
npm run playwright:install

# Run all E2E tests
npm run test:e2e

# Run tests in UI mode (interactive)
npm run test:e2e:ui

# Run tests with visible browser
npm run test:e2e:headed

# Run on specific browser
npm run test:e2e:chromium

# View test report
npm run playwright:report

Coverage: 75 E2E tests across 13 test suites covering authentication, CRUD operations, sharing, favorites, notifications, and admin panel.

🀝 Contributing

We welcome contributions! Please see CONTRIBUTING.md for:

  • Contribution guidelines
  • Development setup
  • Code style requirements
  • Pull request process
  • Testing requirements

πŸ“ Changelog

See CHANGELOG.md for full release history and breaking changes.

πŸ“š Documentation

For Users

For Developers

  • CONTRIBUTING.md - Contribution guidelines, code style, PR process
  • AGENTS.md - AI agent documentation, offline architecture, cache validation
  • ARCHITECTURE.md - System design, database schema, clean architecture, PWA
  • OPERATIONS.md - Deployment (Traefik/K8s), monitoring, audit logging
  • OBSERVABILITY.md - Observability stack, Prometheus, Grafana, Loki
  • DEVELOPMENT.md - Docker development, Air hot reload, best practices
  • RELEASE.md - Release process and versioning

Project Management

Technical Details

πŸ“§ Support

Need help? We have various support channels:

  • SUPPORT.md - Complete support guide with FAQ and troubleshooting
  • GitHub Discussions - Community Q&A and discussions
  • GitHub Issues - Bug reports and feature requests (use templates!)
  • Security Issues - security@sbaerlo.ch (NEVER report publicly!)

See also: CONTRIBUTING.md for contribution guidelines

πŸ“„ License

MIT License - see LICENSE file for details.


Built with Go + Echo + SvelteKit + TypeScript + TailwindCSS

Deployed with Docker + PostgreSQL (Traefik recommended for production)

Top categories

Loading Svelte Themes