A timesheet submission and approval system built for Frontier Blade Solutions, a wind-turbine maintenance company. The system supports three roles: employees submit their timesheets, admins manage teams and approve submitted timesheets, and accountants review and export approved timesheets for payroll and reporting.
This is an umbrella repository. The application lives in two submodules, pinned to their current main commits:
./frontend- Vue 3 single-page app./backend- C# .NET 8 Web API
The frontend is a Vue 3 single-page application using Vuex for state and Vue Router for navigation. It talks to the backend over REST and authenticates with JWTs. The backend is a C# .NET 8 Web API persisting to MongoDB, using JWT bearer auth, Mapster for DTO mapping, SendGrid for transactional email, and Mongo.Migration for schema migrations.
flowchart LR
FE["Frontend<br/>Vue 3 + Vuex + Vue Router"]
API["Web API<br/>C# .NET 8"]
DB[("MongoDB")]
MAIL["SendGrid"]
FE -->|"REST + JWT"| API
API -->|"MongoDB.Driver + Mongo.Migration"| DB
API -->|"transactional email"| MAIL
The frontend carries two test layers:
- Vitest (unit and component): 17 test cases across 5 files. Unit coverage for the auth service and the
authandtimesheetsVuex modules; component coverage forAppandLoginusing@vue/test-utilsand@testing-library/vuein a jsdom environment. - Cypress (end to end): 1 spec present. At the pinned commit this is still the default Vite scaffold spec, not a Frontier Blade user flow, so real e2e coverage is planned rather than complete.
Note: at the pinned commit the Vitest suite does not run to green. Collection fails on an unresolved @/store/enums import referenced by TimeSheetDetails.vue. See Status below.
Prerequisites: Node.js 20+, the .NET 8 SDK, and a reachable MongoDB instance.
Clone with submodules:
git clone --recurse-submodules https://github.com/tzieba1/frontier-blade.git
cd frontier-bladeBackend (start this first; it takes port 5173):
cd backend/FbsApi
# appsettings.json and appsettings.*.json are gitignored. Create
# appsettings.Development.json with your MongoDB connection string,
# JWT settings, and SendGrid API key before running.
dotnet run
# API and Swagger UI at http://localhost:5173/swaggerFrontend (in a second terminal):
cd frontend
npm install
# point the app at the API
echo "VITE_API_BASE_URL=http://localhost:5173" > .env
npm run dev # Vite dev server; serves on the next free port (e.g. 5174) since the API holds 5173
npm run test # Vitest unit and component tests
npm run cypress # Cypress e2e (headless)Verified on this machine: npm install and dotnet build both succeed, npm run dev boots the Vite server and serves HTTP 200, and npm run test executes the Vitest runner.
Active development is paused. The following reflects what is actually in the code at the pinned commits.
Complete:
- JWT authentication with refresh tokens and a policy plus permission based authorization layer (
AuthController, token service,DynamicAuthorizationHandler,PolicyService) on the backend, and anauthVuex module plusLoginpage on the frontend. - A broad REST API surface: 14 controllers covering timesheets, timesheet entries, approvals, teams, employees, customers, sites, rates, rate hours, expenses, vacation requests, users, and permissions.
- MongoDB persistence with versioned Mongo migrations for the core entities (timesheets, entries, approvals, teams, employees, users, refresh tokens).
- Mapster DTO mapping and a SendGrid email service.
- Frontend role-based UI: Dashboard, timesheet index and details, team management, and a Vuex store spanning roughly fifteen domains, wired to an OpenAPI-generated typed API client.
Planned or in progress:
- Resolve the missing
@/store/enumsimport that breaksTimeSheetDetails.vueand the Vitest suite. - Replace the placeholder Cypress spec with real end-to-end flows (submit, approve, export).
- Commit an example configuration template for the gitignored backend settings.