{"id":43562559,"url":"https://github.com/sbaerlocher/savvy","last_synced_at":"2026-03-02T23:04:03.227Z","repository":{"id":335529771,"uuid":"1144642431","full_name":"sbaerlocher/savvy","owner":"sbaerlocher","description":"Digital management of customer cards, vouchers, and gift cards with sharing functionality - Progressive Web App with Go + SvelteKit","archived":false,"fork":false,"pushed_at":"2026-02-18T22:54:39.000Z","size":21798,"stargazers_count":0,"open_issues_count":2,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-19T00:54:49.682Z","etag":null,"topics":["barcode","docker","echo","echo-framework","gift-cards","go","golang","gorm","helm","kubernetes","loyalty-cards","offline-first","postgresql","progressive-web-app","pwa","svelte","sveltekit","typescript","voucher-management","vouchers"],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/sbaerlocher.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":"GOVERNANCE.md","roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-01-28T22:09:30.000Z","updated_at":"2026-02-18T22:52:48.000Z","dependencies_parsed_at":"2026-02-10T22:01:18.486Z","dependency_job_id":null,"html_url":"https://github.com/sbaerlocher/savvy","commit_stats":null,"previous_names":["sbaerlocher/savvy"],"tags_count":138,"template":false,"template_full_name":null,"purl":"pkg:github/sbaerlocher/savvy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbaerlocher%2Fsavvy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbaerlocher%2Fsavvy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbaerlocher%2Fsavvy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbaerlocher%2Fsavvy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/sbaerlocher","download_url":"https://codeload.github.com/sbaerlocher/savvy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/sbaerlocher%2Fsavvy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29668615,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-20T23:24:07.480Z","status":"ssl_error","status_checked_at":"2026-02-20T23:24:06.202Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["barcode","docker","echo","echo-framework","gift-cards","go","golang","gorm","helm","kubernetes","loyalty-cards","offline-first","postgresql","progressive-web-app","pwa","svelte","sveltekit","typescript","voucher-management","vouchers"],"created_at":"2026-02-03T21:05:41.799Z","updated_at":"2026-02-27T00:14:28.115Z","avatar_url":"https://github.com/sbaerlocher.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 🎁 Savvy\n\n[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)\n[![Go Version](https://img.shields.io/badge/Go-1.23%2B-blue.svg)](https://golang.org/dl/)\n[![Node Version](https://img.shields.io/badge/Node-18%2B-green.svg)](https://nodejs.org/)\n[![CI Status](https://github.com/sbaerlocher/savvy/workflows/Continuous%20Integration/badge.svg)](https://github.com/sbaerlocher/savvy/actions/workflows/ci.yml)\n[![Security Scan](https://github.com/sbaerlocher/savvy/workflows/Security%20Scan/badge.svg)](https://github.com/sbaerlocher/savvy/actions/workflows/security.yml)\n[![E2E Tests](https://github.com/sbaerlocher/savvy/workflows/E2E%20Tests/badge.svg)](https://github.com/sbaerlocher/savvy/actions/workflows/e2e.yml)\n[![Go Report Card](https://goreportcard.com/badge/github.com/sbaerlocher/savvy)](https://goreportcard.com/report/github.com/sbaerlocher/savvy)\n[![codecov](https://codecov.io/gh/sbaerlocher/savvy/branch/main/graph/badge.svg)](https://codecov.io/gh/sbaerlocher/savvy)\n\n\u003e Digital management system for loyalty cards, vouchers, and gift cards with sharing functionality\n\nA modern web-based system for managing loyalty cards, discount vouchers, and prepaid gift cards. Features integrated\nbarcode scanner, transaction history, and flexible sharing with other users.\n\n## ✨ Features\n\n### 🎴 Loyalty Cards\n\n- Digital storage of loyalty cards and membership cards\n- Barcode support (CODE128, QR, EAN13, EAN8)\n- Barcode scanning via smartphone/webcam (html5-qrcode)\n- Server-side barcode generation (bwip-js)\n- Status tracking (Active, Inactive)\n- Merchant management with colors and logos\n- Merchant filter for quick merchant-based filtering\n- Share with other users (with edit permissions)\n\n### 🎟️ Vouchers\n\n- Discount vouchers (percentage, fixed amount, points multiplier)\n- Multiple usage models:\n  - Single-Use (one-time)\n  - One-per-Customer (once per customer)\n  - Multiple-Use (multiple times with/without card tracking)\n  - Unlimited\n- Validity period and minimum order value\n- Barcode scanning for quick capture\n- Merchant filter for targeted searching\n- Sharing (always read-only for shared users)\n\n### 💳 Gift Cards\n\n- Prepaid balance with automatic calculation\n- Transaction history (expenses and recharges)\n- Optional PIN protection\n- Barcode scanning for card numbers\n- Merchant filter for organized overview\n- Expiration date management\n- Share with granular permissions:\n  - Edit (modify details)\n  - Delete (remove card)\n  - Manage transactions (record expenses)\n\n### 👥 Sharing \u0026 Permissions\n\n- All three resource types can be shared\n- Flexible permissions per share\n- Edit/Delete/View permissions for Cards\n- Transaction management for Gift Cards\n- Overview of shared items in dashboard\n- User-specific favorites (shared items can be favorited individually)\n- Owner display for shared items (\"from [Name]\")\n\n### 🔄 Ownership Transfer\n\n- **Complete ownership transfer** for Cards, Vouchers \u0026 Gift Cards\n- Email-based recipient selection with autocomplete\n- Only owner can transfer (Authorization via AuthzService)\n- Clean slate approach: All shares are deleted on transfer\n- Audit logging for all ownership transfers\n- Inline form with warnings before transfer\n- Reactive SvelteKit UI without page reload\n\n### 📊 Dashboard\n\n- Statistics (number of Cards/Vouchers/Gift Cards)\n- Total balance of all Gift Cards\n- ⭐ Favorites system (pinning) - Quick access to frequently used items\n- Recently added items (when no favorites available)\n- Quick access to create new items\n- Mobile-optimized view (favorites before statistics)\n\n### 🔍 Search \u0026 Filter\n\n- Full-text search by merchant/code\n- Filter by owner (Mine / All)\n- Filter by status (Active / Expired)\n- Sort by merchant or date\n- Client-side filtering (Svelte reactive statements) for fast results\n\n### 📱 Progressive Web App (PWA)\n\n- ✅ **Installable**: Can be installed as app on iOS/Android/Desktop\n- ✅ **Offline-first**: Automatic warmup cache for instant offline support\n- ✅ **Custom Service Worker**: NetworkFirst strategy with Workbox Recipes\n- ✅ **Offline detection**: Visual feedback for network issues\n- ✅ **Automatic updates**: Service worker updates transparently in background\n- ✅ **Zero 500 errors**: Cache fallback prevents offline errors\n\n**Offline features**:\n\n- ✅ View cards/vouchers/gift cards (automatically cached on Service Worker install)\n- ✅ Display barcode details\n- ✅ Filter \u0026 sort (client-side)\n- ✅ Browse favorites\n- ✅ Dashboard statistics (automatically cached)\n- ❌ Create/edit/delete items (online only)\n- ❌ Share management (online only)\n\n### 🔔 Notifications\n\n- In-app notification system for shares and transfers\n- Real-time notifications when items are shared with you\n- Permission change alerts for shared resources\n- Ownership transfer notifications\n- Mark as read/unread functionality\n- Delete individual or all notifications\n- Automatic notification generation via service layer\n\n### 🌍 Internationalization\n\n- **Multi-language support**: German (DE), English (EN), French (FR)\n- Language switcher in navigation\n- Fully translated UI including forms, buttons, and messages\n- SvelteKit i18n store with reactive language switching\n- Persistent language preference (localStorage)\n- Date and number localization per language\n\n### 🔐 Authentication \u0026 Authorization\n\n- **OAuth/OIDC**: Provider-agnostic authentication (Google, Microsoft, etc.)\n- **Local Authentication**: Email/Password with bcrypt hashing\n- Session-based authentication with Gorilla Sessions\n- **AuthzService**: Centralized authorization logic for all resources\n- Granular permission checks (view, edit, delete, manage transactions)\n- User impersonation for admin debugging\n- Secure session management with CSRF protection\n\n### 🎛️ Feature Toggles\n\n- **Environment-based feature flags** for flexible deployment:\n  - `ENABLE_CARDS` - Enable/disable loyalty cards feature\n  - `ENABLE_VOUCHERS` - Enable/disable vouchers feature\n  - `ENABLE_GIFT_CARDS` - Enable/disable gift cards feature\n  - `ENABLE_LOCAL_LOGIN` - Enable/disable email/password authentication\n  - `ENABLE_REGISTRATION` - Enable/disable user self-registration\n- Runtime configuration via `/api/v1/config` endpoint\n- Client-side feature detection (SvelteKit reads config on startup)\n- Middleware-based feature enforcement\n\n### 📝 Audit Logging\n\n- **Automatic logging** of all delete operations\n- Comprehensive audit trail with:\n  - User ID, action type, resource type/ID\n  - JSONB snapshot of deleted resource\n  - IP address and user agent\n  - Timestamp with timezone\n- Admin panel access to audit logs\n- Retention policy support\n- Compliance-ready audit trail\n\n### 📊 Observability \u0026 Monitoring\n\n- **Prometheus Metrics** (`/metrics` endpoint):\n  - HTTP request duration and counts\n  - Resource counts (cards, vouchers, gift cards, users)\n  - Active sessions and database connections\n- **Health Checks**:\n  - `/health` - Liveness probe (server running)\n  - `/ready` - Readiness probe (database connectivity)\n- **Structured Logging**: JSON logs with slog\n- **OpenTelemetry**: Optional distributed tracing (OTEL_ENABLED)\n- Performance monitoring (N+1 query prevention, database triggers)\n\n### 👨‍💼 Admin Panel\n\n- **User Management**: View and manage all users\n- **Resource Overview**: Access to all cards/vouchers/gift cards\n- **Audit Log Viewer**: Review deletion history\n- **Resource Restoration**: Recover soft-deleted items\n- **User Impersonation**: Debug user-specific issues\n- **Statistics Dashboard**: System-wide metrics\n- Role-based access control (admin-only features)\n\n## 🚀 Quick Start\n\n### Prerequisites\n\n- Docker \u0026 Docker Compose\n- Make (optional, for Makefile shortcuts)\n\n### Installation \u0026 Start\n\n```bash\n# 1. Clone repository\ngit clone \u003crepository-url\u003e\ncd savvy\n\n# 2. Configure environment variables\ncp .env.example .env\n# Edit .env with your settings\n\n# 3. Start Docker containers (automatically builds everything)\nmake dev\n\n# 4. Load test data (optional, in another terminal)\nmake seed\n```\n\n**Application URL**: \u003chttp://localhost:8080\u003e\n\n\u003e **Note**: Local development without Docker is **not supported** due to Vite proxy requirements.\n\u003e The Vite dev server requires access to `http://api:8080` which only works in the Docker network.\n\u003e See [DEVELOPMENT.md](DEVELOPMENT.md) for details.\n\n### Test Users\n\nAfter seeding, the following test accounts are available (password: `test123`):\n\n| Email                        | Role  | Description                  |\n| ---------------------------- | ----- | ---------------------------- |\n| `admin@example.com`          | Admin | Has admin rights + own items |\n| `anna.mueller@example.com`   | User  | Has access to shared items   |\n| `thomas.schmidt@example.com` | User  | Has access to shared items   |\n| `maria.garcia@example.com`   | User  | Has own items                |\n\n## 💻 Development\n\n### Local Development Environment\n\n**IMPORTANT**: Always use Docker for development!\n\n```bash\n# ✅ RECOMMENDED: Start with Makefile (includes Hot Reload)\nmake dev\n\n# This starts:\n# - PostgreSQL (port 5432)\n# - Go API with Air Hot Reload (port 8080)\n# - Vite Dev Server with HMR (port 5173)\n```\n\n#### Why Docker?\n\n- ✅ Consistent development environment\n- ✅ Vite proxy only works in Docker network (`http://api:8080`)\n- ✅ Air and Vite HMR work automatically\n- ✅ No manual port configurations\n- ✅ All dependencies bundled (PostgreSQL, Go, Node.js)\n\nSee [DEVELOPMENT.md](DEVELOPMENT.md) for details.\n\n### Makefile Commands\n\n```bash\n# Development (Docker-based)\nmake dev         # Start Docker development (alias for make up)\nmake up          # Start Docker containers with hot reload\nmake down        # Stop Docker containers\nmake restart     # Restart containers\nmake rebuild     # Rebuild containers\nmake logs        # View API logs\nmake logs-all    # View all container logs\n\n# Database (runs in Docker)\nmake migrate-up     # Apply migrations\nmake migrate-down   # Rollback migration\nmake migrate-status # Check migration status\nmake seed           # Seed test data\nmake db-shell       # PostgreSQL shell\n\n# Testing \u0026 Build\nmake test        # Run all tests\nmake test-core   # Run core tests (services + models)\nmake build       # Build binary with embedded client\n\n# Container Access\nmake shell       # Application shell\n```\n\n### Code Changes\n\n**All changes are automatically detected in Docker containers:**\n\n```bash\n# Start Docker development environment\nmake dev  # or: make up\n\n# This provides automatic hot reload for:\n# - SvelteKit Frontend: Vite HMR detects changes in client/src/\n# - Go Backend: Air reloads on changes in internal/\n# - Database: GORM AutoMigrate runs on server start\n```\n\n**File locations:**\n\n- **Frontend**: `client/src/` - SvelteKit components, stores, API clients\n- **Backend**: `internal/` - Go handlers, services, repositories\n- **Database Models**: `internal/models/` - GORM models\n- **API Endpoints**: `internal/handlers/api/` - JSON API handlers\n\n**Important**: Always use Docker (`make dev`) - local npm/air commands won't work due to network requirements.\n\n## 📁 Project Structure\n\n```\nsavvy/\n├── cmd/                  # Application entrypoints\n│   ├── server/           # Main application server\n│   ├── seed/             # Database seeding script\n│   ├── migrate/          # Database migration tool\n│   ├── release-tool/     # Release version synchronization\n│   └── e2e/              # E2E test server setup\n│\n├── internal/\n│   ├── setup/            # Server initialization│   │   ├── dependencies.go # DI container, database, telemetry\n│   │   ├── routes.go     # Route registration\n│   │   └── server.go     # Echo configuration\n│   ├── config/           # Configuration management\n│   ├── database/         # Database connection \u0026 utilities\n│   ├── handlers/         # HTTP handlers (Controllers)\n│   │   ├── api/          # JSON API handlers│   │   │   ├── cards.go    # Cards API\n│   │   │   ├── vouchers.go # Vouchers API\n│   │   │   ├── gift_cards.go # Gift Cards API\n│   │   │   ├── notifications.go # Notifications API\n│   │   │   ├── dto.go      # Data Transfer Objects\n│   │   │   └── mappers.go  # Model ↔ DTO mapping\n│   │   ├── shares/       # Share handler abstraction\n│   │   ├── health.go     # Health checks\n│   │   ├── oauth.go      # OAuth/OIDC handlers\n│   │   └── spa.go        # SvelteKit SPA fallback\n│   ├── services/         # Business logic layer\n│   │   ├── card_service.go\n│   │   ├── voucher_service.go\n│   │   ├── gift_card_service.go\n│   │   ├── notification_service.go\n│   │   ├── transfer_service.go\n│   │   ├── authz_service.go\n│   │   └── container.go  # Service DI container\n│   ├── repository/       # Data access layer (GORM)\n│   ├── models/           # GORM models\n│   │   ├── user.go\n│   │   ├── merchant.go\n│   │   ├── notification.go│   │   ├── card.go / voucher.go / gift_card.go\n│   │   └── *_share.go    # Sharing models\n│   ├── middleware/       # HTTP middleware\n│   │   ├── auth.go       # Authentication\n│   │   ├── cors.go       # CORS configuration\n│   │   ├── csrf*.go      # CSRF protection\n│   │   ├── security.go   # Security headers\n│   │   └── ...           # Other middleware\n│   ├── migrations/       # Database migrations (embedded)\n│   ├── mocks/            # Generated mocks for testing (mockery)\n│   ├── audit/            # Audit logging\n│   ├── metrics/          # Prometheus metrics\n│   ├── telemetry/        # OpenTelemetry integration\n│   ├── oauth/            # OAuth/OIDC implementation\n│   ├── security/         # Security utilities\n│   ├── i18n/             # Internationalization\n│   ├── validation/       # Input validation\n│   ├── debug/            # Debug utilities\n│   └── assets/           # Embedded client build\n│       └── client/       # SvelteKit build output\n│\n├── client/               # SvelteKit Frontend│   ├── src/\n│   │   ├── routes/       # SvelteKit pages\n│   │   │   ├── +page.svelte       # Dashboard\n│   │   │   ├── cards/             # Cards routes\n│   │   │   ├── vouchers/          # Vouchers routes\n│   │   │   ├── gift-cards/        # Gift cards routes\n│   │   │   └── admin/             # Admin panel\n│   │   ├── lib/\n│   │   │   ├── components/        # Reusable Svelte components\n│   │   │   ├── api/               # API client modules\n│   │   │   ├── stores/            # Svelte stores (auth, offline, i18n)\n│   │   │   ├── utils/             # Helper functions\n│   │   │   ├── i18n/              # Translations (DE, EN, FR)\n│   │   │   └── types/             # TypeScript types\n│   │   ├── tests/        # E2E tests (Playwright)\n│   │   ├── hooks.client.ts # SvelteKit client hooks\n│   │   └── app.html      # HTML template\n│   ├── static/           # Static assets (favicon, etc.)\n│   ├── vite.config.ts    # Vite configuration\n│   ├── playwright.config.ts # Playwright E2E test config\n│   ├── package.json      # Node.js dependencies\n│   └── tsconfig.json     # TypeScript config\n│\n├── deploy/               # Deployment configurations\n│   ├── helm/             # Helm charts for Kubernetes\n│   ├── kustomize/        # Kustomize overlays\n│   ├── grafana/          # Grafana dashboards\n│   └── observability/    # Observability stack (Prometheus, Loki)\n│\n├── .air.toml            # Hot reload config (Air)\n├── .golangci.yml        # Go linter configuration\n├── .revive.toml         # Revive linter configuration\n├── .mockery.yaml        # Mock generation config\n├── .goreleaser.yaml     # Release automation config\n├── docker-compose.yml   # Docker services (dev)\n├── Dockerfile           # Multi-stage build\n├── Makefile             # Development commands\n├── go.mod / go.sum      # Go dependencies\n├── CODE_OF_CONDUCT.md   # Community guidelines\n├── OBSERVABILITY.md     # Observability guide\n└── README.md            # This file\n```\n\n## 🛠️ Tech Stack\n\n### Core Stack\n\n| Component              | Technology                  | Version | Purpose                       |\n| ---------------------- | --------------------------- | ------- | ----------------------------- |\n| **Backend Framework**  | Echo                        | v4.15   | HTTP Router \u0026 Middleware      |\n| **ORM**                | GORM                        | v1.31   | PostgreSQL Abstraction        |\n| **Frontend**           | SvelteKit + TypeScript      | 2.51    | Modern SPA Framework          |\n| **Build Tool**         | Vite                        | 7.3     | Fast Build \u0026 Dev Server       |\n| **Styling**            | TailwindCSS                 | 4.1     | Utility-First CSS             |\n| **Database**           | PostgreSQL                  | 16      | Primary Data Store            |\n| **Language**           | Go                          | 1.26    | Backend Language              |\n| **Language**           | TypeScript                  | 5.9     | Frontend Language             |\n\n### Features \u0026 Libraries\n\n| Feature                | Technology                  | Purpose                       |\n| ---------------------- | --------------------------- | ----------------------------- |\n| **Auth (Sessions)**    | Gorilla Sessions            | Session-based Authentication  |\n| **Auth (OAuth/OIDC)**  | go-oidc                     | OpenID Connect Provider       |\n| **Barcode Scanning**   | @undecaf/zbar-wasm          | WebAssembly Barcode Scanner   |\n| **Barcode Generation** | bwip-js                     | Server-side Barcode Rendering |\n| **Validation**         | go-playground/validator     | Input Validation              |\n| **i18n**               | go-i18n                     | Internationalization          |\n| **Metrics**            | Prometheus                  | Application Metrics           |\n| **Tracing**            | OpenTelemetry               | Distributed Tracing           |\n| **PWA**                | @vite-pwa/sveltekit         | Service Worker \u0026 Offline      |\n| **Service Worker**     | Workbox                     | Caching \u0026 Offline Strategies  |\n\n### Development \u0026 Testing\n\n| Tool                   | Technology                  | Purpose                       |\n| ---------------------- | --------------------------- | ----------------------------- |\n| **Hot Reload (Go)**    | Air                         | Go Auto-Reload                |\n| **Hot Reload (Vite)**  | Vite HMR                    | Frontend Hot Module Replace   |\n| **Unit Testing (Go)**  | testify                     | Go Test Assertions            |\n| **Unit Testing (JS)**  | Vitest                      | Frontend Unit Tests           |\n| **E2E Testing**        | Playwright                  | End-to-End Browser Tests      |\n| **Mocking**            | Mockery                     | Mock Generation for Tests     |\n| **Linting (Go)**       | golangci-lint + revive      | Go Code Quality               |\n| **Linting (TS)**       | svelte-check                | TypeScript/Svelte Validation  |\n\n## 🗄️ Database\n\nThe application uses **PostgreSQL** with 12 main tables for users, merchants, cards, vouchers,\ngift cards, sharing, favorites, notifications, and audit logs.\n\n**For detailed database schema, ERD diagram, and table descriptions, see:**\n\n📖 [ARCHITECTURE.md - Database Schema](ARCHITECTURE.md#️-database-schema)\n\n## 🔐 Security\n\n- ✅ Bcrypt password hashing\n- ✅ Session-based authentication\n- ✅ CSRF protection (Echo middleware)\n- ✅ SQL injection protection (GORM parameterized queries)\n- ✅ XSS protection (SvelteKit auto-escaping)\n- ✅ UUID instead of integer IDs\n- ✅ Granular permissions for sharing\n\nSee [SECURITY.md](SECURITY.md) for complete security policy and vulnerability reporting.\n\n## 🚀 Deployment\n\nThe application is designed for **containerized deployment** with Traefik reverse proxy for\nproduction use. Supports Docker Compose and Kubernetes (K3s/K8s).\n\n**Production Architecture**:\n\n```\nClient (HTTPS) → Traefik (TLS) → Savvy (HTTP:8080) → PostgreSQL\n```\n\n**For detailed deployment instructions, environment variables, Traefik configuration,\nand Kubernetes manifests, see:**\n\n📖 [OPERATIONS.md - Deployment Guide](OPERATIONS.md)\n\n## 🧪 Testing\n\n### Backend Tests (Go)\n\n```bash\n# Run all tests\nmake test\n\n# Run core tests (services + models)\nmake test-core\n\n# Run tests with coverage report\nmake test-coverage\n\n# Run specific test (direct go test)\ngo test ./internal/models -run TestCard_GetColor\n\n# Run tests with race detection\ngo test -race ./...\n```\n\n**Coverage**: 57.8% (Services), 54.1% (Handlers/API), 100.0% (Models), 97.2% (Repositories)\n\n### Frontend Tests (Vitest)\n\n```bash\ncd client\n\n# Run unit tests\nnpm test\n\n# Run tests with UI\nnpm run test:ui\n\n# Run tests with coverage\nnpm run test:coverage\n```\n\n**Coverage**: 32.8% unit test coverage (19 tests, stores and utils)\n\n### E2E Tests (Playwright)\n\n```bash\ncd client\n\n# Install Playwright browsers\nnpm run playwright:install\n\n# Run all E2E tests\nnpm run test:e2e\n\n# Run tests in UI mode (interactive)\nnpm run test:e2e:ui\n\n# Run tests with visible browser\nnpm run test:e2e:headed\n\n# Run on specific browser\nnpm run test:e2e:chromium\n\n# View test report\nnpm run playwright:report\n```\n\n**Coverage**: 75 E2E tests across 13 test suites covering authentication, CRUD operations, sharing,\nfavorites, notifications, and admin panel.\n\n## 🤝 Contributing\n\nWe welcome contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md) for:\n\n- Contribution guidelines\n- Development setup\n- Code style requirements\n- Pull request process\n- Testing requirements\n\n## 📝 Changelog\n\nSee [CHANGELOG.md](CHANGELOG.md) for full release history and breaking changes.\n\n## 📚 Documentation\n\n### For Users\n\n- **[README.md](README.md)** - This file: Quick Start, Features, Installation\n- **[SUPPORT.md](SUPPORT.md)** - Support resources, FAQ, Troubleshooting\n- **[SECURITY.md](SECURITY.md)** - Security policy, vulnerability reporting\n- **[CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md)** - Community guidelines, code of conduct\n\n### For Developers\n\n- **[CONTRIBUTING.md](CONTRIBUTING.md)** - Contribution guidelines, code style, PR process\n- **[AGENTS.md](AGENTS.md)** - AI agent documentation, offline architecture, cache validation\n- **[ARCHITECTURE.md](ARCHITECTURE.md)** - System design, database schema, clean architecture, PWA\n- **[OPERATIONS.md](OPERATIONS.md)** - Deployment (Traefik/K8s), monitoring, audit logging\n- **[OBSERVABILITY.md](OBSERVABILITY.md)** - Observability stack, Prometheus, Grafana, Loki\n- **[DEVELOPMENT.md](DEVELOPMENT.md)** - Docker development, Air hot reload, best practices\n- **[RELEASE.md](RELEASE.md)** - Release process and versioning\n\n### Project Management\n\n- **[GOVERNANCE.md](GOVERNANCE.md)** - Project governance model, decision-making\n- **[CHANGELOG.md](CHANGELOG.md)** - Release history and breaking changes\n- **[LICENSE](LICENSE)** - MIT License\n- **[NOTICE](NOTICE)** - Third-party software notices\n\n### Technical Details\n\n- **[internal/migrations/migrations.go](internal/migrations/migrations.go)** - Database migrations (embedded)\n\n## 📧 Support\n\nNeed help? We have various support channels:\n\n- **[SUPPORT.md](SUPPORT.md)** - Complete support guide with FAQ and troubleshooting\n- **GitHub Discussions** - Community Q\u0026A and discussions\n- **GitHub Issues** - Bug reports and feature requests (use templates!)\n- **Security Issues** - \u003csecurity@sbaerlo.ch\u003e (NEVER report publicly!)\n\nSee also: **[CONTRIBUTING.md](CONTRIBUTING.md)** for contribution guidelines\n\n## 📄 License\n\nMIT License - see [LICENSE](LICENSE) file for details.\n\n---\n\n**Built with** Go + Echo + SvelteKit + TypeScript + TailwindCSS\n\n**Deployed with** Docker + PostgreSQL (Traefik recommended for production)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbaerlocher%2Fsavvy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsbaerlocher%2Fsavvy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsbaerlocher%2Fsavvy/lists"}