WebOps is a full-stack website template with an admin panel for dynamic content and configuration.
Current stack:
- Backend: ASP.NET Core 10, Entity Framework Core 10, JWT auth, Serilog
- Frontend: Angular 21, Bootstrap 5, ng-bootstrap, ngx-charts
- Database: SQL Server / LocalDB
- Setup wizard for first-time project initialization
- JWT login for admin access
- Dynamic text sections and text items
- Dynamic services section (CRUD)
- Dynamic navbar items (CRUD + reorder)
- Dynamic price list (CRUD)
- Dynamic image gallery (upload/list/delete)
- Global website configuration (SEO, branding, hero, footer, social/contact)
- Contact form email sending via SMTP
- Google Analytics integration + dashboard endpoint
- Background analytics sync hosted service
WebOps.sln
|- WebOps.Server/ ASP.NET Core API + static hosting
|- WebOps.client/ Angular SPA
|- WebOps.Entities/ Additional project (targets .NET 10)
`- WebOps.Server.Entities/ Additional project (targets .NET 10)
Backend:
- Target framework: net10.0
- SDK pinned in global.json: 10.0.100
Frontend:
- Angular packages: 21.x
- TypeScript: 5.9.x
- .NET SDK 10.0.100 (or compatible 10.x SDK)
- Node.js 20+ and npm
- SQL Server or LocalDB
Edit WebOps.Server/appsettings.json:
ConnectionStrings:DefConnectionJwt:Issuer,Jwt:Audience,Jwt:KeySMTP_CONFIG(mail provider settings)GoogleAnalytics:KeyFilePath
Important:
- The backend currently requires the Google Analytics key file to exist at startup.
- Default expected file name is
WebOps.Server/webops-google.json.
- Restore backend dependencies:
cd WebOps.Server
dotnet restore- Install frontend dependencies:
cd ../WebOps.client
npm install- Start backend:
cd ../WebOps.Server
dotnet run- Open the app:
- HTTPS profile serves on
https://localhost:7064(HTTPhttp://localhost:5156) - SPA proxy launches Angular dev server through
npm start
- Complete setup wizard:
- Navigate to
/setup - Configure identity, SEO, contact, features, branding
- Create first admin account
- Finalize setup
Notes:
- EF Core migrations are applied automatically at startup (
Database.Migrate()). - If database does not exist, ensure the configured SQL Server user has create permissions.
Base routes are shown as implemented.
Authentication:
- POST
/api/auth/login
Setup:
- GET
/api/setup/status - POST
/api/setup/identity - POST
/api/setup/seo - POST
/api/setup/contact - POST
/api/setup/features - POST
/api/setup/branding - POST
/api/setup/admin-account - POST
/api/setup/complete - POST
/api/setup/reset-all(Admin)
Global web config:
- GET
/api/webconfig - PUT
/api/webconfig(Admin) - POST
/api/webconfig/favicon(Admin)
Text config:
- GET
/api/admin/textconfig - PUT
/api/admin/textconfig/text-item/{id}(Admin)
Services config:
- GET
/api/admin/servicesconfig/{sectionId} - POST
/api/admin/servicesconfig(Admin) - PUT
/api/admin/servicesconfig/{id}(Admin) - DELETE
/api/admin/servicesconfig/{id}(Admin)
Navbar config:
- GET
/api/admin/navbar(public read) - POST
/api/admin/navbar(Admin) - PUT
/api/admin/navbar/{id}(Admin) - DELETE
/api/admin/navbar/{id}(Admin) - PUT
/api/admin/navbar/reorder(Admin)
Price list:
- GET
/api/admin/pricelist - POST
/api/admin/pricelist(Admin) - PUT
/api/admin/pricelist/{id}(Admin) - DELETE
/api/admin/pricelist/{id}(Admin)
Images:
- GET
/api/admin/image - POST
/api/admin/image/upload(Admin) - DELETE
/api/admin/image/{id}(Admin)
Mail:
- POST
/api/mail/sendMail
Analytics and dashboard:
- GET
/api/analytics/report/pageviews-test - GET
/api/dashboard(Admin)
Public:
/setup/login//gallery
Admin (guarded):
/admin/dashboard/admin/text-config/admin/services-config/admin/prices-config/admin/images-config/admin/web-config/admin/navbar-config
Main entities in the current DbContext:
- GlobalSettings
- Section
- TextItem
- ServiceItem
- PriceListEntry
- ImageItem
- NavbarItem
- TrafficRecord
- AppUser
GlobalSettings includes dynamic fields for:
- Hero: background image + CTA links
- Footer: company name, copyright text, show/hide contact/social
- Branding: logo, favicon, OG image, theme mode, primary color
Backend:
cd WebOps.Server
dotnet runFrontend only:
cd WebOps.client
npm startFrontend tests:
cd WebOps.client
npm testBackend tests:
- No dedicated backend test project is currently included in this solution.
Startup fails with file-not-found for Google key:
- Check
GoogleAnalytics:KeyFilePathin appsettings - Ensure the JSON key file exists in the backend content root
401/403 on admin endpoints:
- Login via
/api/auth/login - Include
Authorization: Bearer <token> - Confirm user role is
Admin
SPA not loading through backend:
- Ensure frontend dependencies are installed in
WebOps.client - Check Angular dev server startup output
Image upload issues:
- Ensure
wwwroot/images/galleryis writable - Verify uploaded file size and format
May 28, 2026