nfel 06fa677ec6
Test and publish / verify (push) Has been cancelled
Add workspace management foundation
2026-08-02 23:17:42 +03:30
2026-07-28 14:48:15 +03:30
2026-07-28 14:47:25 +03:30
2026-07-28 02:04:36 +03:30
2026-07-28 14:43:54 +03:30
2026-07-28 02:04:36 +03:30
2026-07-28 14:43:54 +03:30
2026-07-28 14:43:54 +03:30
2026-07-28 02:04:36 +03:30
2026-07-28 02:04:36 +03:30

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
  • SaturdayFriday team week schedule as the default team view, with calendar-style presence records
  • Period-based teammate work updates for completed, blocked, and pending tasks
  • Shared Trello-style team board with reusable colored tags, multiple assignees, importance levels, card archiving, 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.

APP_TIMEZONE controls attendance dates and displayed check-in/out times. It defaults to Asia/Tehran, and timezone data is embedded in the Go binary so the same value is used inside minimal Docker images.

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 -f build/dockerfile -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

Docker Compose

Compose builds from build/dockerfile, persists SQLite in the hamkar-data volume, and publishes the application at http://localhost:8080.

cp .env.example .env
docker compose -f compose.yml up -d --build
docker compose -f compose.yml ps

Stop the application without deleting its database:

docker compose -f compose.yml down

To intentionally delete the database volume as well:

docker compose -f compose.yml down --volumes

Set a secure INITIAL_ADMIN_PASSWORD before the first start. For HTTPS deployments, also set the public APP_BASE_URL and SESSION_SECURE=true.

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 conversion
  • internal/app/store.go: SQLite schema and data access
  • internal/app/server.go: HTTP routes, auth, workflows, and CSV export
  • internal/app/templates: embedded server-rendered views
  • internal/app/static: responsive application styling
S
Description
No description provided
Readme 1.4 MiB
Languages
Go 52%
CSS 23.7%
HTML 19.2%
JavaScript 5%
Makefile 0.1%