DEENESH

C#/.NET · Angular · Azure

JobTrack

A job-search tracker I built end to end to show how I work on a current .NET stack: an Angular board and list UI, a JWT-protected ASP.NET Core API, SQL Server, a scheduled Azure Function, tests, Docker, and a deploy pipeline.

Goal

One small product that touches every layer: identity, API design, relational data, background work, testing, and delivery.

Architecture

Angular 22 over a JWT-protected ASP.NET Core API and SQL Server, plus a separate Azure Functions service.

Trade-off

Access tokens live in memory, not browser storage. That limits exposure, and a page refresh signs you out.

Status

Multi-user app that runs with one docker compose up. The follow-up function only logs; it does not send email yet.

Job hunting turns into a spreadsheet of companies, dates, and “should I follow up yet?” JobTrack replaces the spreadsheet with a board where each application moves through Saved, Applied, Interview, Offer, Rejected, and Withdrawn, and a background job that spots applications that have gone quiet for seven days. It is a small product, and that is the point: small enough to read in an afternoon, complete enough to show how the pieces fit.

What a reviewer can look at

If you are skimming the repo, these are the places where the decisions are visible:

The application

The Angular 22 client uses standalone components, signals, and reactive forms. It has route guards and an HTTP interceptor that attaches the token. You can register, sign in, and then create, edit, move, search, filter, sort, and delete applications in either a board or a list view.

Tokens are kept in memory only. The trade-off is a sign-in after every refresh, which I accepted because a token in local storage is readable by any script that runs on the page. A refresh-token flow is the natural next step, and it is not built yet.

The API and data

The API is ASP.NET Core 10 with controllers, ASP.NET Core Identity for accounts, and signed JWTs. EF Core 10 maps to SQL Server through checked-in migrations. The model enforces required fields and length limits, stores salary as a decimal, saves dates in UTC, and normalizes status values so interview and Interview mean the same thing. Reads use no-tracking queries where change tracking would only add overhead.

One migration adds identity and ownership, and it leaves earlier rows with no owner. The API hides them from every user, and the README explains how to assign them to an account before upgrading an existing database.

Running it

Copy the example env file and run docker compose up --build. That starts Angular, the API, and SQL Server with a health check, and the schema is created automatically. Each project still runs on its own if you want to work on one layer.

Known gaps

I listed these in the README, and they are the work between here and production: