Setup Guide
Step-by-step from the source archive to a running, signed-in application. Cross-platform notes called out where they matter; defaults assume Windows (since the project path is D:\AssetTrackingSystem).
If you've never touched .NET or Angular: this guide covers the full path. If you've already shipped .NET + Angular apps before, jump to Quick start (TL;DR).
Quick start (TL;DR)
# 1. Download and extract the source archive (e.g. AssetTrackingSystem.zip)
# Resulting folder: AssetTrackingSystem/
cd AssetTrackingSystem
# 2. Install SQL Server locally (skip if already running)
# Windows: SQL Server Express + SSMS, OR Docker. See §3.
# 3. Configure the connection string in src/AssetTracking.API/appsettings.json
# Default points at the local Windows-auth instance "Server=.;Database=AssetTracking"
# 4. Backend
dotnet restore
dotnet ef database update --project src/AssetTracking.Persistence --startup-project src/AssetTracking.API
# 5. Frontend
cd frontend && npm install && cd ..
# 6. Run (two terminals)
dotnet run --project src/AssetTracking.API # terminal 1 (backend)
cd frontend && npm start # terminal 2 (frontend)
# 7. Open http://localhost:4200
# Sign in: admin@assettracking.local / Admin@123456
If any of those steps are unfamiliar, the rest of this doc walks each in detail.
Index
- Prerequisites
- Get the source code
- Set up SQL Server
- Configure the API
- Restore and build the backend
- Apply database migrations
- Set up the frontend
- Run the API
- Run the frontend dev server
- Sign in for the first time
- Optional configuration
- Troubleshooting
1. Prerequisites
Install these once before starting:
| Tool | Minimum version | Why | Install |
|---|---|---|---|
| .NET SDK | 8.0.x | Backend runtime + EF Core CLI | https://dotnet.microsoft.com/download/dotnet/8.0 |
| Node.js | 18.x or 20.x LTS | Frontend build (Angular 18) | https://nodejs.org/ |
| npm | 9+ (ships with Node) | Frontend dependency manager | (bundled with Node) |
| SQL Server | 2019 or newer | Database. Express/Developer/LocalDB/Docker all work | See §3 |
| An archive extractor | any recent | Unpack the source zip | Built-in on Windows / macOS / Linux |
dotnet ef CLI |
8.0.11 | Apply migrations | dotnet tool install --global dotnet-ef --version 8.0.11 |
Verify each:
dotnet --version # should print 8.0.x
node --version # v18.x or v20.x
npm --version # 9.x or higher
dotnet ef --version # 8.0.x
If dotnet ef returns "command not found", run the install command from the table above. The Path may need a shell restart afterwards.
Recommended (optional)
- Visual Studio 2022 (Community is free) or Rider for a friendly C# debugger experience. The project also works fine with VS Code + C# Dev Kit.
- SQL Server Management Studio (SSMS) for poking at the database. Free.
- Postman or Insomnia for hitting the API directly while testing.
2. Get the source code
The source is delivered as a zip archive (e.g. AssetTrackingSystem.zip) via download link.
Download the archive to a working location — e.g.
D:\AssetTrackingSystem.zipon Windows or~/AssetTrackingSystem.zipon macOS/Linux.Extract it. On Windows, right-click → Extract All... (or use 7-Zip / WinRAR). On macOS/Linux:
unzip AssetTrackingSystem.zip.Open a terminal in the extracted folder:
cd AssetTrackingSystem
You should now have:
AssetTrackingSystem/
├── AssetTracking.slnx ← solution file
├── docs/ ← all documentation
├── src/
│ ├── AssetTracking.API/
│ ├── AssetTracking.Application/
│ ├── AssetTracking.Domain/
│ ├── AssetTracking.Infrastructure/
│ └── AssetTracking.Persistence/
├── tests/
└── frontend/
3. Set up SQL Server
You need one of these options running before the API can connect.
Option A — Local SQL Server Express (Windows, easiest)
- Download SQL Server Express from https://www.microsoft.com/sql-server/sql-server-downloads.
- Choose Basic install. Accept the default instance name (
SQLEXPRESSor defaultMSSQLSERVER). - Optionally install SSMS for a GUI.
The connection string in appsettings.json ships pointing at the default instance (Server=.). If you installed SQLEXPRESS instead of the default instance, you'll need to update the connection string in §4.
Option B — SQL Server Developer Edition
Same as Express, but unlimited capacity (free for non-production).
Option C — LocalDB (Windows, lightweight)
Comes with Visual Studio. No service to manage. Connection string:
Server=(localdb)\\MSSQLLocalDB;Database=AssetTracking;Trusted_Connection=True;TrustServerCertificate=True
Option D — Docker (cross-platform — Mac, Linux, also fine on Windows)
docker run -e "ACCEPT_EULA=Y" -e "MSSQL_SA_PASSWORD=Strong@Passw0rd" \
-p 1433:1433 --name mssql -d mcr.microsoft.com/mssql/server:2022-latest
Then connect with:
Server=localhost,1433;Database=AssetTracking;User ID=sa;Password=Strong@Passw0rd;TrustServerCertificate=True
(Pick a stronger password than the example. Add a volume mount for persistence: -v mssql-data:/var/opt/mssql.)
Verify the connection
From the command line:
# If you have sqlcmd installed:
sqlcmd -S . -E -Q "SELECT @@VERSION" # Windows-auth
sqlcmd -S localhost,1433 -U sa -P Strong@Passw0rd -Q "SELECT @@VERSION" # SQL-auth
Or open SSMS / Azure Data Studio and connect with the same credentials.
You don't need to create the AssetTracking database manually. EF Core will create it when migrations run in §6.
4. Configure the API
Open src/AssetTracking.API/appsettings.json. The defaults look like this:
{
"ConnectionStrings": {
"SqlServer": "Server=.;Database=AssetTracking;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=true"
},
"JwtSettings": {
"Secret": "YourSuperSecretKeyThatIsAtLeast32CharactersLong!!",
"Issuer": "AssetTracking",
"Audience": "AssetTrackingClients",
"AccessTokenExpirationMinutes": 15,
"RefreshTokenExpirationDays": 30
},
"Cors": { "AllowedOrigins": [ "http://localhost:4200" ] },
"FileStorage": { "RootPath": "AppData/Documents" },
"Seeding": {
"HierarchyConfigs": true,
"WorkflowRoles": true,
"DemoUsers": true
}
}
What to change
Always
ConnectionStrings:SqlServer— point this at the SQL Server instance you set up in §3. Common variations:Setup Connection string Default instance, Windows auth (default) Server=.;Database=AssetTracking;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=trueSQL Server Express Server=.\\SQLEXPRESS;Database=AssetTracking;Trusted_Connection=True;TrustServerCertificate=TrueLocalDB Server=(localdb)\\MSSQLLocalDB;Database=AssetTracking;Trusted_Connection=True;TrustServerCertificate=TrueDocker (sa user) Server=localhost,1433;Database=AssetTracking;User ID=sa;Password=Strong@Passw0rd;TrustServerCertificate=True
For production (or any non-local environment)
JwtSettings:Secret— generate a fresh random string at least 32 characters. Don't ship the default secret to anything reachable from the internet. A quick way:# PowerShell: -join ((48..57) + (65..90) + (97..122) | Get-Random -Count 64 | % {[char]$_}) # Linux / macOS: head -c 64 /dev/urandom | base64Cors:AllowedOrigins— add the URL where the SPA will be served. The defaulthttp://localhost:4200is the Angular dev server.
For development (defaults are fine)
JwtSettings:AccessTokenExpirationMinutes(15) andRefreshTokenExpirationDays(30) — leave alone unless you have a security policy.FileStorage:RootPath— relative to the API process working directory. Created automatically. Make sure the process can write there.Seedingflags — see §10 / §11. Leave alltruefor the default demo experience.
Production secret management
For production, don't put secrets in appsettings.json. Standard ASP.NET Core layering applies — override via:
- Environment variables:
JwtSettings__Secret=...(note double underscores) appsettings.Production.jsondotnet user-secrets(development only)- Whatever your hosting provider uses (Azure Key Vault, AWS Secrets Manager, …)
5. Restore and build the backend
From the project root (the folder containing AssetTracking.slnx):
dotnet restore
dotnet build
Expected output ends with Build succeeded. and zero errors. Compilation should take 30-60 seconds on a first run; subsequent builds are seconds.
If the build fails, see Troubleshooting.
6. Apply database migrations
This creates the AssetTracking database (if it doesn't exist) and adds every table.
dotnet ef database update --project src/AssetTracking.Persistence --startup-project src/AssetTracking.API
Output should end with Done. (no errors).
Heads up — file lock. If the API process is running in another terminal, this command will fail with a
MSB3027"file is locked" error because EF can't recompile the API project while it's executing. Stop the running API first (Ctrl+C in its terminal), run the migration, then restart.
Verify
Connect with SSMS / Azure Data Studio / sqlcmd. You should see the AssetTracking database with ~50 tables (Users, Roles, Permissions, Assets, AuditPlans, …).
7. Set up the frontend
cd frontend
npm install
This downloads ~600 MB of packages (Angular, PrimeNG, Puppeteer's Chromium for tests, etc.). Allow 2-5 minutes on first run.
If npm install fails with peer-dependency conflicts, try:
npm install --legacy-peer-deps
(The project's package versions are tested as a known-good combination; the --legacy-peer-deps flag relaxes npm's strictness.)
8. Run the API
In a terminal at the project root:
dotnet run --project src/AssetTracking.API
Expected boot output (abridged):
[INF] Now listening on: https://localhost:5001
[INF] Now listening on: http://localhost:5000
[INF] Application started.
The API does three things on startup:
- Applies any pending migrations (idempotent — safe to run repeatedly).
- Runs the database seeder — inserts the permission catalog, the SuperAdmin role, the default admin user, the asset statuses, the notification templates, and (when
Seeding.WorkflowRoles = true) the 10 workflow roles + (whenSeeding.DemoUsers = true) 11 demo users. - Drops sample import templates into
AppData/SampleData/for organizations, locations, classifications, vendors, manufacturers, and assets — useful when testing the bulk-import features. (Skipped if the folder already has files.)
You can verify it's running by visiting http://localhost:5000/swagger in a browser (Development environment only). You should see the Swagger UI listing every endpoint.
9. Run the frontend dev server
In a second terminal:
cd frontend
npm start
Wait for:
✔ Compiled successfully.
Local: http://localhost:4200/
The dev server proxies /api/* to the backend via frontend/proxy.conf.json (default target http://localhost:5000). So the SPA never sees a CORS problem in development.
If your API is running on a non-default port, update frontend/proxy.conf.json:
{
"/api": {
"target": "http://localhost:5000",
"secure": false,
"changeOrigin": true
}
}
(Replace 5000 with your actual API port.)
10. Sign in for the first time
Open http://localhost:4200. You should land on the login page.
Default Super Admin credentials:
| Field | Value |
|---|---|
admin@assettracking.local |
|
| Password | Admin@123456 |
Sign in. You should land on the Dashboard with every nav group visible (because the Super Admin holds every permission).
Demo accounts (development only)
If you left Seeding.DemoUsers = true, ten more accounts are available with the shared password Demo@123456. Try them to see the system from each role's perspective:
| Role | Lands in | |
|---|---|---|
requester@assettracking.local |
Transfer Requester | Desktop shell |
approver@assettracking.local |
Transfer Approver | Desktop shell |
receiver@assettracking.local |
Transfer Receiver | Desktop shell |
planner@assettracking.local |
Audit Planner | Desktop shell |
auditor@assettracking.local |
Auditor | Desktop shell |
reviewer@assettracking.local |
Audit Reviewer | Desktop shell |
mobile@assettracking.local |
Mobile Auditor | Mobile shell at /mobile |
issuer@assettracking.local |
Checkout Issuer | Desktop shell |
returner@assettracking.local |
Checkout Returner | Desktop shell |
custodian@assettracking.local |
Asset Custodian | Desktop shell |
Logging in as mobile@... automatically lands you at /mobile because that user has UserType = Mobile.
What to do next
- Add some master data: at least one Organization, Location, and Classification. Use
/organizations,/locations,/classifications— or import from the sample Excel files dropped intoAppData/SampleData/. - Register a few assets at
/assets. They need an Organization, Location, Classification, and Status. - Create your real users at
/usersand assign them roles. - Disable demo users before going live — see §11.
For deeper walkthroughs of every screen, see docs/business/04-features-by-module.
11. Optional configuration
Email (SMTP)
Outbound notifications need an SMTP server. Without configuration, in-app notifications still work — only emails are blocked.
Configure at runtime via the UI: log in as admin, go to Settings → Email Provider (/settings/email).
Fill in:
| Field | Example |
|---|---|
| Enabled | ✅ |
| Host | smtp.gmail.com |
| Port | 587 |
| Enable SSL | ✅ |
| Username | noreply@yourcompany.com |
| Password | (see below — generate App Password for Gmail) |
| From address | noreply@yourcompany.com |
| From name | Asset Tracking |
Click Send test email to a live address to verify.
Gmail-specific tip
A regular Gmail password won't work — Google blocks SMTP basic-auth. Generate an App Password:
- https://myaccount.google.com/security → enable 2-Step Verification.
- Go to App passwords → generate a new one (16 characters).
- Paste that into the Password field.
Bilingual settings
The system is bilingual by design. Out of the box:
- Primary language = English (
en) - Secondary language = Arabic (
ar)
If your deployment uses different languages (e.g., Spanish + English), change at Settings → App Languages (/settings/languages). Pick the two languages from the dropdown. The change is immediate and propagates across all users on their next page render.
UI translation overrides
The bundled translations cover English and Arabic completely; the other 9 languages have partial coverage. To customize labels (or fill in missing translations) without re-deploying:
Settings → Translations (/settings/translations). Pick a language tab, edit any cell, save. Reset clears the override. See docs/business/06-localization-and-rtl for the full editor walkthrough.
Hierarchy depth
Each of Organization / Location / Classification has a configurable depth and per-level labels.
Settings → Hierarchy (/settings/hierarchy). For Locations: e.g., 4 levels = Site / Building / Floor / Room. For Organizations: e.g., 3 levels = Company / Department / Team. Bilingual labels per level.
Disable demo users (production)
Before deploying to staging or production, edit appsettings.json:
"Seeding": {
"HierarchyConfigs": true,
"WorkflowRoles": true,
"DemoUsers": false
}
The WorkflowRoles flag stays true so the seeded roles are still available for assigning to your real users. Setting DemoUsers = false skips creating the 11 demo accounts on subsequent restarts.
If demo users were already created on a prior boot, delete them manually at /users (the IsDeleted flag is sufficient for soft-delete) — the seeder doesn't remove existing demos when you flip the flag.
Change the admin password
Critical for production. Sign in as admin → Profile → Change password. Pick a strong unique password.
12. Troubleshooting
dotnet restore or dotnet build fails
- NuGet feed unreachable — check internet/firewall. Verify with
dotnet nuget list sourceand addhttps://api.nuget.org/v3/index.jsonif missing. - Wrong .NET SDK version —
dotnet --versionshould be 8.0.x. The csproj files targetnet8.0.
dotnet ef database update fails
- "Could not connect to SQL Server" — your connection string is wrong or the SQL Server service isn't running. Verify with
sqlcmdor SSMS. - "Login failed for user 'X'" — credentials in the connection string are wrong, OR Windows-auth user lacks DB-create rights. Either fix permissions or switch to SQL-auth.
- "file is locked" — the API is running. Stop it first.
- "No DbContext was found" — make sure both
--projectand--startup-projectflags are present.
npm install fails
- Peer-dependency conflicts —
npm install --legacy-peer-deps. - Network errors during Puppeteer / Chromium download — re-run
npm install. Or setPUPPETEER_SKIP_CHROMIUM_DOWNLOAD=trueif you don't need the PDF generation feature locally. - Permission errors on Linux — don't use
sudo npm install. Instead, install Node vianvmso it lives in your home directory.
npm start fails
- Port 4200 already in use —
npm start -- --port 4201. - Cannot find module 'X' — try
rm -rf node_modules package-lock.json && npm install. - Proxy error /
ECONNREFUSED— the API isn't running on the port the proxy expects. Either start the API first, or updatefrontend/proxy.conf.json.
API starts but throws on first request
- "Migration not applied" — re-run
dotnet ef database update. - "Cannot open database" — connection-string database name doesn't exist. EF should create it on first migration; if it didn't, check permissions of the SQL login.
- CORS errors in browser console — your SPA origin isn't in
Cors:AllowedOrigins. Add it toappsettings.jsonand restart the API.
Login page rejects the default credentials
- Seeder didn't run — check the API console output. Look for
Seeded SuperAdmin user. If absent, the seeder may have errored. Check the connection string and re-run. - Database is missing the
Userstable — migrations weren't applied. Rundotnet ef database update. - Typo in the password — it's
Admin@123456(zero, not letter O; capital A; @ sign).
Camera doesn't work in the mobile shell
- Browser blocked the camera prompt — open browser settings → Site Permissions → allow camera for
http://localhost:4200. - Camera works on the system but the scanner area is black — a CSS quirk we already fixed. If the issue resurfaces after a code change, check that no descendant of
.reader-wraphasbackground: #000 !importantpainting over the QR-box overlay. - Running on a non-localhost HTTP origin — camera APIs are blocked on LAN-IP HTTP. Either use
localhostor set up HTTPS.
"Another instance with the same key value is already being tracked"
This was a known bug pattern. Every handler that adds multiple child entities sets Id = Guid.NewGuid() explicitly. If you see this error on a new handler you've written, you've reproduced the same bug pattern — set the Id on each child before saving.
Notifications not arriving in email
- Email provider not configured — see §11. Settings → Email Provider.
Enabled = falsein email settings — flip it on.- User has no email address — user creation requires a non-empty Email field; verify.
- Notification preferences toggled off — at
/preferences, the user has opted out of that template + channel. - Worker not running — check API console for
NotificationDeliveryWorkerstartup logs. The worker is a hosted background service; if the API is up, it should be running. - Looking in the queue — the
NotificationDeliveriestable stores every queued email. Filter byStatusto see what's stuck (Failedrows have anErrorMessage).
Where to find more
| Topic | See |
|---|---|
| How the system is built (technical) | docs/00-overview |
| What each user role does (business) | docs/business/01-user-roles |
| Build/deploy/seeding details | docs/06-operations |
| Every endpoint with permissions | docs/07-api-reference |
| Every screen described in plain English | docs/business/04-features-by-module |
Going to production
This guide gets you to a running dev environment. For production deployment, additional steps:
- Real secrets: generate a fresh JWT signing key, never use the default. Use environment variables / a secret store.
- Real SMTP: configure email at
/settings/email. Test withSend test email. - Real users: create your real accounts at
/users; assign roles; deactivate demo users. - Change the admin password: at
/profile. - HTTPS: terminate TLS at a reverse proxy (nginx, IIS, App Service) — the .NET host runs HTTP behind it.
- Regular backups: SQL Server full + log backups; the
AppData/Documentsfolder; the ASP.NET Core data-protection key ring (else the encrypted SMTP password becomes unrecoverable on restore). - Retention jobs:
RequestLogs(90 days),Notifications(180 days after read),LoginAudits(per security policy). Operator-driven — no built-in cleaner.
See docs/06-operations for the operations-focused detail and a Dockerfile template.