Skip to content

luigi-bellio/marginio

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Marginio

Time-tracking and engagement margin management for professional services teams.

Node.js TypeScript PostgreSQL License


Overview

Marginio is a full-stack web application that helps professional services organisations track employee time, manage client engagements, and monitor engagement profitability in real time.

Administrators create clients and engagements (fixed-price or time-and-materials), assign employees with per-assignment billing rates, and define internal cost rates per employee. Employees log daily hours against their assignments through a monthly timesheet workflow with built-in validation rules. Submitted timesheets are reviewed by admins, who can edit, approve, or send them back.

The built-in margin dashboard computes revenue, cost, and margin per engagement automatically, giving managers instant visibility into which projects are profitable and which need attention. Three report views — by user/month, by T&M engagement, and by T&M client — can be exported to Excel (.xlsx) with a single click.


Key Features

Admin

  • Client management — create, edit, activate/deactivate client records
  • Engagement management — fixed-price and T&M engagements with budget, date range, and code
  • User management — create employees and admins, change passwords, toggle active status
  • Cost rates — define per-employee hourly cost rates with date ranges
  • Assignments — assign users to engagements with billing rates and validated date ranges
  • Timesheet management — review submitted timesheets, edit entries, approve or send back to draft
  • Reports — user monthly, user/engagement (T&M), user/client (T&M) with Excel export
  • Margin dashboard — per-engagement revenue, cost, margin, and margin-per-hour with sortable columns

Employee

  • Monthly timesheet — pick a month, add/edit/delete time entries against active assignments
  • Validation feedback — blocking errors (>= 24 h/day) and non-blocking warnings (> 8 h/day)
  • Submit workflow — submit a draft timesheet for admin review; entries become read-only after submission

Tech Stack

Layer Technology
Frontend React 18, TypeScript, Tailwind CSS 3, Vite 6
Backend Node.js 20, Express 4, TypeScript
Database PostgreSQL 16
ORM Prisma 5
Auth JWT (access token 15 min + HTTP-only refresh cookie 7 days)
Excel export exceljs
HTTP client Axios
Notifications react-hot-toast
Routing react-router-dom 6
Infrastructure Docker Compose (3 services: db, backend, frontend)

Repository Structure

marginio/
├── docker-compose.yml          # Orchestrates db, backend, frontend
├── README.md
├── INSTALLING.md               # Full installation guide
├── docs/                       # Project documentation
│   ├── architecture.md
│   ├── data-model.md
│   ├── api.md
│   ├── features.md
│   ├── roles-and-permissions.md
│   └── development.md
├── backend/
│   ├── Dockerfile
│   ├── package.json
│   ├── tsconfig.json
│   ├── prisma/
│   │   ├── schema.prisma       # Database schema
│   │   ├── seed.ts             # Seed data script
│   │   └── migrations/         # SQL migration files
│   └── src/
│       ├── server.ts           # Express app entry point
│       ├── middleware/          # auth, errorHandler
│       ├── routes/             # auth, clients, engagements, users, costRates,
│       │                       # assignments, timesheets, timeEntries, reports, margins
│       └── utils/              # jwt helpers
└── frontend/
    ├── Dockerfile
    ├── package.json
    ├── tsconfig.json
    ├── vite.config.ts
    ├── tailwind.config.ts
    ├── index.html
    └── src/
        ├── main.tsx            # React entry point
        ├── App.tsx             # Router + route definitions
        ├── api/                # Axios client with interceptors
        ├── auth/               # AuthContext, ProtectedRoute, LoginPage
        ├── components/         # Layout, Modal, MonthPicker, SearchableSelect, etc.
        ├── features/
        │   ├── admin/          # Clients, Engagements, Users, CostRates, Assignments,
        │   │                   # AdminTimesheets CRUD pages
        │   ├── timesheets/     # Employee timesheet page
        │   └── reports/        # UserMonthlyReport, UserEngagementReport,
        │                       # UserClientReport, MarginsPage
        └── types/              # Shared TypeScript interfaces

Quick Start

git clone <repository-url> marginio
cd marginio
docker compose up --build
Service URL
Frontend http://localhost:5173
Backend API http://localhost:3001/api
PostgreSQL localhost:5432 (user: marginio, password: marginio)

The backend container automatically pushes the Prisma schema and seeds the database on first start.

For the full installation guide, see INSTALLING.md.


Default Seeded Credentials

Username Password Role
admin admin123 Admin
john.doe password123 Employee
jane.smith password123 Employee

Warning: Change all default passwords before deploying to any non-local environment.


Documentation Index

Document Description
INSTALLING.md Step-by-step installation and first-run guide
docs/architecture.md System architecture and component diagram
docs/data-model.md Database schema reference with relationships
docs/api.md Full REST API reference
docs/features.md Functional description of every feature
docs/roles-and-permissions.md Role-based access control matrix
docs/development.md Local development workflow and conventions

Scripts Reference

backend/

Script Command Description
npm run dev tsx watch src/server.ts Start backend in dev mode with hot reload
npm run build tsc Compile TypeScript to dist/
npm start node dist/server.js Run compiled production build
npm run prisma:generate prisma generate Regenerate Prisma client
npm run prisma:migrate prisma migrate deploy Apply pending migrations
npm run prisma:seed tsx prisma/seed.ts Seed the database

frontend/

Script Command Description
npm run dev vite --host 0.0.0.0 Start Vite dev server
npm run build tsc -b && vite build Type-check and build for production
npm run preview vite preview Preview the production build locally

Environment Variables

Backend

Variable Required Default Description
DATABASE_URL Yes PostgreSQL connection string
JWT_SECRET Yes change-me-in-production Secret for signing access tokens
JWT_REFRESH_SECRET Yes change-me-refresh Secret for signing refresh tokens
PORT No 3001 HTTP port for the Express server
NODE_ENV No Set to production to enable secure cookies

Frontend

Variable Required Default Description
VITE_API_URL No http://localhost:3001/api Backend API base URL

Contributing

  1. Create a feature branch from develop: git checkout -b feature/my-feature
  2. Make your changes and ensure tsc --noEmit passes for both backend/ and frontend/
  3. Write concise commit messages in imperative mood (e.g. "Add client search filter")
  4. Open a pull request against develop with a clear description of the change

License

This project is licensed under the GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later). See the LICENSE.md file for the full text.

In short — you may use, modify, and distribute this software, but any modified version that is accessible over a network must also make its complete source code available under the same licence.


Copyright

Copyright (C) 2026 Marginio
Prompting by Luigi Bellio and Development by Claude Code

About

Time-tracking and engagement margin management for professional services teams.

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors

Languages