Skip to main content

Home · Projects · Enterprise

Birch Gold Employee Dashboard

Internal HR/ops dashboard: RBAC, indexed Postgres reports, CSV exports.

Role
Dashboard Engineering
Type
Internal operations dashboard
Client
Birch Gold Group
Status
Private project
ReactNode.jsPostgreSQLREST API
Private project

Outcome

Internal reporting refresh is query-bound (indexed SQL) instead of operator-bound spreadsheet rebuilds, with RBAC at both route and handler.

Problem

HR, ops, and leadership used disconnected tools. Permissions differed by team. Recurring reports were manual. Staff would ignore a tool that added clicks to daily work.

Solution

Normalized employee and activity tables. API maps roles to actions and row filters. Dashboard modules share auth/session and errors so new screens do not reimplement guards.

Architecture
Frontend
React feature foldersClaim-driven navReports · tasks · CSV
API
Node.js REST + RBACBoundary validationPaginated/streaming CSV
Database
PostgreSQL FKs + report indexes
Frontend
React, feature folders per domain (HR, ops, reporting).
Backend
Node services encapsulate transactions. Validation at the HTTP boundary.
APIs
Resource-oriented REST. Each handler queries only tables the role may access.
Databases
PostgreSQL with FKs, migrations in repo, indexes on report filters.
Auth
Internal session or token. Logout and expiry handled against server 401s.
Key features
  • Route-level and API-level RBAC; UI hides nav, server still enforces
  • Report endpoints with stable CSV headers for Excel/BI
  • Task boards on status columns; optimistic updates only where conflicts are rare
  • Session/token auth with explicit logout and expired-session handling
  • Shared table/pagination primitives
Engineering challenges

Challenge

Teams needed different permissions and views.

Decision

Role claims in the token; middleware on every handler.

Implementation

Handler checks scope before the query. UI derives nav from the same claims, but is not trusted.

Result

New screens inherit the same guard pattern. Unauthorized API calls still 403.

Challenge

Reporting was manual and slow.

Decision

A small set of parameterized report routes instead of spreadsheet macros.

Implementation

Indexed SQL (or ORM equivalents) with fixed output schemas. On-demand or scheduled generation.

Result

Refresh time tracks query cost at current volume, not an operator rebuilding a workbook. No claimed hour-savings number.

Technology decisions

PostgreSQL rather than a document store

Employee graphs and reports need constraints and predictable aggregates.

Alternative. Mongo-style iteration.

Tradeoff. Schema changes go through migrations. Correctness over ad hoc nested documents.

RBAC in handlers, not only in the UI

Hidden nav is not a security control.

Alternative. Frontend-only role routing.

Tradeoff. Every new endpoint needs a scope check. That is the point.

My ownership
  • BuiltDashboard modules and shared list/report primitives
  • BuiltNode handlers with RBAC and report/CSV routes
  • BuiltPostgres schema/indexes used by those reports
  • Private enterprise engagement — no public demo.
  • Corporate SSO details not claimed unless separately documented.
Results

Daily ops and leadership exports use the same API. Permissions are enforced on the server. Qualitative: less spreadsheet rework for the report set that was moved. No public metrics.