{"id":51601392,"url":"https://github.com/frontendfixer/ewms-hr-notebook","last_synced_at":"2026-07-11T22:31:13.738Z","repository":{"id":368480338,"uuid":"1285352319","full_name":"frontendfixer/ewms-hr-notebook","owner":"frontendfixer","description":"Personal Indian Railways HR notebook with an event-first, ledger-first architecture. The UI speaks in actions (\"Take Leave\", \"Add CR\") rather than database terms.","archived":false,"fork":false,"pushed_at":"2026-06-30T18:16:13.000Z","size":204,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-30T20:12:28.527Z","etag":null,"topics":["hr","hrms","nextjs"],"latest_commit_sha":null,"homepage":"https://ewms-ir.frontendfixer.dev/login","language":"TypeScript","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/frontendfixer.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null}},"created_at":"2026-06-30T18:06:52.000Z","updated_at":"2026-06-30T18:29:36.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/frontendfixer/ewms-hr-notebook","commit_stats":null,"previous_names":["frontendfixer/ewms-hr-notebook"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/frontendfixer/ewms-hr-notebook","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Fewms-hr-notebook","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Fewms-hr-notebook/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Fewms-hr-notebook/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Fewms-hr-notebook/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/frontendfixer","download_url":"https://codeload.github.com/frontendfixer/ewms-hr-notebook/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/frontendfixer%2Fewms-hr-notebook/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":35377012,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-07-11T02:00:05.354Z","response_time":104,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["hr","hrms","nextjs"],"created_at":"2026-07-11T22:31:13.153Z","updated_at":"2026-07-11T22:31:13.732Z","avatar_url":"https://github.com/frontendfixer.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# EWMS — Personal HR Notebook\n\nPersonal Indian Railways HR notebook with an event-first, ledger-first architecture. The UI speaks in actions (\"Take Leave\", \"Add CR\") rather than database terms.\n\n## Stack\n\n- **Runtime:** Bun 1.3, Node.js ≥24\n- **Frontend:** Next.js 16, React 19, TypeScript, Tailwind CSS v4\n- **Data:** Prisma 7 + MySQL (MariaDB adapter)\n- **Auth:** Better Auth (Google OAuth)\n- **Forms \u0026 state:** React Hook Form, Zod, TanStack Query\n- **PWA:** `@ducanh2912/next-pwa` (enabled in production builds)\n\n## Quick start\n\n```bash\ncp .env.example .env\n# Fill in GOOGLE_CLIENT_ID and GOOGLE_CLIENT_SECRET\n\ndocker compose up -d\nbun install\nbun run db:push      # or: bun run db:migrate\nbun run dev\n```\n\nOpen [http://localhost:3000](http://localhost:3000). Sign in with Google, complete onboarding, then land on the Home feed.\n\n### Environment variables\n\n| Variable | Purpose |\n|----------|---------|\n| `DATABASE_URL` | MySQL connection string |\n| `BETTER_AUTH_SECRET` | Session signing secret (≥32 chars) |\n| `BETTER_AUTH_URL` | App base URL (e.g. `http://localhost:3000`) |\n| `GOOGLE_CLIENT_ID` | Google OAuth client ID |\n| `GOOGLE_CLIENT_SECRET` | Google OAuth client secret |\n\n## Architecture\n\n- **WorkEvent** — append-only event stream (source of truth)\n- **LedgerEntry** — balance mutations linked to events; balances are always derived, never manually edited\n- **Correlation** — related events share a `correlationId` (e.g. leave + CR consumed)\n- **Corrections** — append `EVENT_VOIDED` with compensating ledger entries; never edit event bodies in place\n\nBusiness logic lives in `src/lib/services/`. Server actions are in `src/actions/events.ts`.\n\n## Routes\n\n### Public\n\n| Route | Purpose |\n|-------|---------|\n| `/` | Auth router → `/login`, `/onboarding`, or `/home` |\n| `/login` | Google OAuth sign-in |\n| `/onboarding` | 4-step wizard (profile + opening leave balances) |\n\n### App (authenticated)\n\n| Route | Purpose |\n|-------|---------|\n| `/home` | Command center: balances, reminders, insights, recent activity |\n| `/calendar` | Month view with domain-colored event dots |\n| `/timeline` | Chronological event cards with domain/period filters |\n| `/timeline/[eventId]` | Event detail, claim stepper, ledger impact, void |\n| `/claims` | Pending night-duty and travel claims (₹ total) |\n| `/records/[type]` | Filtered lists: `all`, `cr`, `leave`, `night`, `ta` |\n| `/reports` | Monthly domain chart, year stats, CSV export |\n| `/reports/insights` | Personal insights (Sundays worked, avg night duty, top destination) |\n| `/search` | Full-text search on title/remarks (`?q=`) |\n| `/settings` | Theme, pay \u0026 allowance settings |\n| `/settings/holidays` | User-defined public holidays |\n| `/profile` | Name, personnel no., designation, department |\n| `/more` | Mobile hub for records, reports, settings, search |\n\n### Add flows (FAB)\n\n| Route | Action |\n|-------|--------|\n| `/add/leave` | Leave wizard with FIFO CR recommendation |\n| `/add/cr` | Record holiday/Sunday work → CR credit |\n| `/add/night-duty` | Night duty with NDA preview |\n| `/add/travel` | Travel allowance with TA preview |\n| `/add/payment` | Redirects to `/claims` |\n| `/add/sunday-work` | Redirects to `/add/cr` (legacy alias) |\n\n## API\n\n| Method | Path | Auth | Description |\n|--------|------|------|-------------|\n| `GET` | `/api/health` | No | Health check (includes DB ping) |\n| `GET` | `/api/feed` | Yes | Home feed JSON (`feed`, `balances`) |\n| `GET` | `/api/export/monthly` | Yes | CSV export of current month domain counts |\n| `*` | `/api/auth/[...all]` | — | Better Auth (sessions, OAuth) |\n\n## Server actions\n\n`recordHolidayWork`, `recordLeave`, `recordNightDuty`, `recordTravel`, `transitionClaimStatus`, `voidEvent`, `updateProfile`, `completeOnboarding`, `addHoliday`, `updatePaySettings`\n\n## Allowance formulas\n\n- **DA:** `basicPay × daPercent / 100`\n- **NDA per night:** `(basicPay + DA) / 200`\n- **TA:** `taBaseAmount × claimPercent / 100` (default base ₹625)\n- **CR expiry:** configurable, default 90 days from work date\n\n## Project structure\n\n```\nsrc/\n├── app/                  # Next.js App Router (pages, API routes, manifest)\n├── actions/events.ts     # Server actions\n├── components/           # UI (shell, flows, calendar, timeline, …)\n├── generated/prisma/     # Prisma client (generated)\n└── lib/\n    ├── services/         # event, ledger, feed, insight, claim-status\n    ├── calculations/     # allowance formulas\n    └── design-tokens.ts  # Domain palette, status colors, defaults\nprisma/schema.prisma\ntests/unit/               # Vitest (allowances, utils)\ndocs/                     # PRD, UX spec, event taxonomy, design tokens\n```\n\n## Scripts\n\n| Command | Description |\n|---------|-------------|\n| `bun run dev` | Development server |\n| `bun run build` | Production build (webpack) |\n| `bun run start` | Production server |\n| `bun run lint` | ESLint |\n| `bun run test` | Vitest unit tests |\n| `bun run db:migrate` | `prisma migrate dev` |\n| `bun run db:push` | `prisma db push` |\n\n## PWA\n\nStandalone installable app with portrait orientation. Service worker is disabled in development; icons and manifest are generated at build time. See `src/app/manifest.ts`.\n\n## Documentation\n\n- [`docs/PRD.md`](docs/PRD.md) — product requirements and implementation status\n- [`docs/UX-SPEC.md`](docs/UX-SPEC.md) — navigation, flows, design principles\n- [`docs/EVENT-TAXONOMY.md`](docs/EVENT-TAXONOMY.md) — event types, ledger accounts, correlation\n- [`docs/DESIGN-TOKENS.md`](docs/DESIGN-TOKENS.md) — colors, domain palette, spacing\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontendfixer%2Fewms-hr-notebook","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffrontendfixer%2Fewms-hr-notebook","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffrontendfixer%2Fewms-hr-notebook/lists"}