Files
nfel 5a3ca4eb40
Test and publish / verify (push) Successful in 2m22s
feat: expand kanban assignment and filtering
2026-07-29 13:53:31 +03:30

144 lines
5.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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.
```bash
cp .env.example .env
go run ./cmd/server
```
The app listens at <http://localhost:8080>. On a fresh database, use:
```text
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:
```bash
set -a
source .env
set +a
go run ./cmd/server
```
## OAuth
Create OAuth applications with these callback URLs:
```text
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
```bash
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.
```bash
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>.
```bash
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:
```bash
docker compose -f compose.yml down
```
To intentionally delete the database volume as well:
```bash
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:
```text
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
```bash
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