4.5 KiB
Hamkar
Hamkar is a small team presence tracker built for startups that work with the Persian (Solar Hijri/Shamsi) calendar. It ships as one Go binary with embedded HTMX templates and uses SQLite by default.
Included
- Self-service account creation with email or username and a salted PBKDF2 password
- Login with either email address or username
- Optional Google and GitHub OAuth login
- Admin-created username/password teammate accounts
- Persistent light and dark modes with automatic system-theme detection
- Vazirmatn as the default interface font
- Office and remote check-in/check-out
- Persian month calendar with attendance, approved leave, remote days, Fridays, and fixed Solar Hijri public holidays
- Team day detail showing who is present, remote, absent, or expected at the office
- Period-based teammate work updates for completed, blocked, and pending tasks
- Shared Trello-style team board with assignment, Jalali due dates, and drag-and-drop columns
- Time-off and remote-day requests with a dependency-free Jalali date picker and typed Persian-date fallback
- Admin approval/rejection with review notes
- Excel-compatible UTF-8 CSV reports for attendance and teammate work updates
- Accumulated per-teammate summaries combining office, remote, leave, and work-update results
- CSRF protection, secure session cookies, security headers, and role checks
- Responsive UI with no JavaScript build step
Start locally
Requirements: Go 1.26 or later.
cp .env.example .env
go run ./cmd/server
The app listens at http://localhost:8080. On a fresh database, use:
username: admin
password: admin123
Set INITIAL_ADMIN_PASSWORD before the first start to replace the demo password. It is only read when creating an empty database. The database is created at ./data/teammate.db.
Environment files are not loaded automatically. Export values in your shell, use a process manager, or run:
set -a
source .env
set +a
go run ./cmd/server
OAuth
Create OAuth applications with these callback URLs:
http://localhost:8080/auth/github/callback
http://localhost:8080/auth/google/callback
Set the matching client ID and secret in the environment. Provider buttons only appear when configured. For production, set APP_BASE_URL to the public HTTPS origin and SESSION_SECURE=true.
Production
go build -o teammate ./cmd/server
APP_ADDR=:8080 DATABASE_PATH=/var/lib/teammate/teammate.db SESSION_SECURE=true ./teammate
Place a TLS reverse proxy such as Caddy or nginx in front of the binary. Back up the SQLite database and its WAL files together, or use SQLite's online backup command. The store is intentionally serialized to one connection, which is a good fit for a small startup deployment.
Docker
The multi-stage image runs tests during the build, compiles a static Go binary, uses a non-root runtime user, persists SQLite under /data, and exposes a /healthz container health check.
docker build -t hamkar:local .
docker run --rm -p 8080:8080 \
-e SESSION_SECURE=false \
-e INITIAL_ADMIN_PASSWORD='replace-this-password' \
-v hamkar-data:/data \
hamkar:local
Gitea Actions
The workflow under .gitea/workflows/ci.yaml is adapted from the Sana API pipeline. Pull requests build and test the container without publishing it. Pushes to main build and publish both main and immutable commit-SHA tags.
Configure this repository secret:
REG_PASS Password for oci.reg.darano.ir
The registry username defaults to admin, and the image defaults to oci.reg.darano.ir/personal/tracking-personel. Change the workflow environment if the repository uses a different registry path.
Persian calendar behavior
The application stores dates in ISO Gregorian form internally and converts at the UI boundary. This keeps SQL comparisons and exports straightforward while making the primary calendar and request input Solar Hijri. Request dates use YYYY-MM-DD, for example 1405-05-06.
Fixed national holidays are included. Lunar Islamic holidays move each year and should be added from an authoritative annual calendar before production use.
Development
make test
make build
The main packages are:
internal/jalali: dependency-free Persian/Gregorian date conversioninternal/app/store.go: SQLite schema and data accessinternal/app/server.go: HTTP routes, auth, workflows, and CSV exportinternal/app/templates: embedded server-rendered viewsinternal/app/static: responsive application styling