1 — Multi-Database Platform Support (MSSQL & PostgreSQL)
Current State
All four projects (Web, Infrastructure, Daemon, Awards) are coupled to MySQL via Pomelo.EntityFrameworkCore.MySql 9.0.0. EF Core is pinned at 9.x because Pomelo has no 10.x release yet. All database-specific work lives in HLStatsX.NET.Infrastructure.
MySQL-specific blockers
| Location |
Issue |
Affects |
All Program.cs files |
UseMySql(connStr, ServerVersion.AutoDetect(...)) |
Web, Daemon, Awards |
AdminRepository.cs — all raw SQL |
Backtick identifier quoting `tableName` |
All raw SQL statements |
AdminRepository.cs:722–723 |
OPTIMIZE TABLE / ANALYZE TABLE — MySQL-only |
No MSSQL equivalent; PostgreSQL uses VACUUM ANALYZE |
AdminRepository.cs:831–832 |
DELETE FROM `t` USING `t` INNER JOIN … — MySQL multi-table delete |
Needs rewriting as subquery / CTE for other providers |
AdminRepository.cs:870–871 |
DELETE c FROM … LEFT JOIN … — MySQL alias delete |
MSSQL compatible; needs rewrite for PostgreSQL |
AdminRepository.cs:963–1001 |
ALTER DATABASE … CHARACTER SET … COLLATE … |
Entire Reset DB Collations feature is MySQL-only |
appsettings.json (all projects) |
CharSet=utf8mb4 connection string parameter |
MySQL-only parameter |
All .csproj files |
Pomelo.EntityFrameworkCore.MySql package reference |
All four projects |
Implementation steps
-
1
Configuration abstraction ~4 hrs
Add a DatabaseProvider config key (MySql | SqlServer | PostgreSql). Read it in each Program.cs and conditionally call the correct Use* method. Document all three connection string formats.
-
2
NuGet packages ~2 hrs
Add Microsoft.EntityFrameworkCore.SqlServer and Npgsql.EntityFrameworkCore.PostgreSQL to all four projects. With Pomelo no longer the only provider, EF Core can be upgraded to 10.x for non-MySQL targets.
-
3
SQL dialect abstraction ~8–12 hrs
Introduce an ISqlDialect interface with QuoteIdentifier, OptimizeTables, and multi-table delete helpers. Provide MySQL, MSSQL, and PostgreSQL implementations. Register via DI based on the provider config. Update all ExecuteSqlRawAsync call sites in AdminRepository.
-
4
Feature flags for MySQL-only tools ~2 hrs
Conditionally hide the Reset DB Collations admin menu item and page when not running MySQL. Show a provider notice if accessed directly on an unsupported provider.
-
5
EF Core model configuration review ~3 hrs
Audit HLStatsDbContext.OnModelCreating for MySQL-specific API calls. Verify column type mappings (tinyint, int unsigned, text) translate correctly. Unsigned integers map to long in MSSQL/PostgreSQL — confirm no overflow risk.
-
6
Migrations ~4–6 hrs
No EF migrations exist today (schema maintained by the legacy PHP installer). If added, separate migration bundles are needed per provider. Consider a --provider CLI argument to select the migration project at generation time.
-
7
Integration testing ~16–20 hrs
Spin up MSSQL (mcr.microsoft.com/mssql/server) and PostgreSQL Docker containers. Run the full repository test suite against each provider. Verify admin bulk operations, reset stats, cleanup, and daemon event handling end-to-end.
Estimated total effort — Multi-database support
41–51 hours
2 — Localisation (French, Spanish, German, Russian)
Current State
No localisation infrastructure exists. All ~1,700 user-visible strings are hardcoded English across 121 Razor view files, 4 layout files, and scattered controller TempData/ViewData calls. There are zero .resx files, no IStringLocalizer usage, and no culture middleware.
String volume by area
| Area | Files | ~Strings |
| Admin panel | 52 views | 400–500 |
| Public leaderboards & profiles | 69 views | 750–900 |
| Shared layouts & partials | 4 layouts + partials | 100–120 |
| Controller messages (TempData) | — | 50–80 |
| Total | 121 + layouts | ~1,300–1,600 |
Implementation phases
-
1
Infrastructure ~20–25 hrs
Register AddLocalization, AddViewLocalization, and AddDataAnnotationsLocalization in all Program.cs files. Configure RequestLocalizationOptions for en, fr, es, de, ru. Add UseRequestLocalization middleware. Implement cookie-based culture selection with Accept-Language header fallback. Add a language-switcher UI component to _Layout.cshtml. Create the Resources/ folder structure with shared, per-view, and controller resource files.
-
2
View string extraction ~80–100 hrs
Replace all hardcoded strings in 121 .cshtml files with @Localizer["key"] calls. Inject IViewLocalizer at the top of each view. Use IHtmlLocalizer<SharedResources> for shared strings (Prev/Next, Save, Delete, Search, etc.). Update all 4 layout files. Approximate: 30–40 min per file.
-
3
Controller & service strings ~15–20 hrs
Inject IStringLocalizer<T> into controllers. Migrate hardcoded TempData success/error messages and ViewData["Title"] page titles to localised keys. Create per-controller .resx files.
-
4
Translation content — 4 languages ~70–86 hrs
Use Google Translate API or Azure Translator for an initial machine-translation pass (~$20–30 for all four languages), then professional or community review per language. Russian note: requires 3-form plural rules — use custom plural helpers for any count-bearing strings (e.g. "1 kill / 2 kills / 5 kills").
-
5
Database-driven content ~10–15 hrs
Action names, weapon names, rank/ribbon descriptions, and award names are stored in the database and are not covered by .resx files. Recommended approach: introduce a generic hlstats_Translations(entity_type, entity_id, language, text) table with a translation admin UI. Scope as a separate sub-task.
-
6
Testing & QA ~15–20 hrs
Test all views in each locale. Check for layout overflow — translated strings are often 20–40% longer than English. Verify number and date formatting respects locale. Confirm no RTL regressions (not required for these 4 languages but worth checking for future-proofing).
Translation effort by language
| Language | Machine pass | Review | Total |
| 🇫🇷 French | ~4 hrs | ~12–16 hrs | ~16–20 hrs |
| 🇪🇸 Spanish | ~4 hrs | ~12–16 hrs | ~16–20 hrs |
| 🇩🇪 German | ~4 hrs | ~14–18 hrs | ~18–22 hrs |
| 🇷🇺 Russian | ~4 hrs | ~16–20 hrs | ~20–24 hrs |
| Total | ~16 hrs | ~54–70 hrs | ~70–86 hrs |
Russian pluralisation — Russian has three plural forms (1, 2–4, 5+). Any count-bearing string (kills, deaths, sessions, etc.) requires custom plural rule helpers rather than a simple IStringLocalizer key lookup.
Phase summary
| Phase | Hours |
| 1 — Infrastructure | 20–25 |
| 2 — View string extraction | 80–100 |
| 3 — Controller & service strings | 15–20 |
| 4 — Translations (4 languages) | 70–86 |
| 5 — Database-driven content | 10–15 |
| 6 — Testing & QA | 15–20 |
Minimum viable path: Infrastructure + view extraction + one language ≈ 3–4 weeks.
Full four-language release: all phases + QA ≈ 6–7 weeks.
Estimated total effort — Full localisation (4 languages)
210–266 hours
3 — Mobile-Responsive Site Work in Progress
Current State
Mobile responsiveness is actively in progress. The home page, server pages, and public leaderboard and list pages have been updated for small screens. Profile pages, the admin panel, and some detail views still use fixed-width layouts that require horizontal scrolling on mobile.
Areas
| Area |
Status |
Notes |
| Home / server pages | ✅ Done | Responsive layout implemented |
| Public leaderboards & lists | ✅ Done | Responsive layout implemented |
| Maps — detail view | ✅ Done | Thumbnail hidden on mobile |
| Player / clan profile pages | ⚠️ Partial | Tab layout and stat tables need breakpoints |
| Admin panel | ❌ Not started | Fixed-width forms; admin use on desktop assumed |
| In-game pages | ❌ Not started | Low priority — typically displayed inside game overlays |
Implementation steps
-
1
Profile pages ~8–12 hrs
Rework the tabbed layout (General, Weapons, Maps, Sessions, Awards) to stack on small screens. Make stat tables horizontally scrollable with overflow-x: auto wrappers. Ensure the trend chart and ribbon grid reflow correctly.
-
2
Remaining detail pages ~4–6 hrs
Apply responsive patterns to weapon detail, map detail, clan profile, action/role info, award detail, and rank/ribbon detail pages.
-
3
Admin panel ~12–16 hrs
Admin use on desktop is assumed, so this is lower priority. Minimum: ensure forms do not overflow the viewport. Full responsive rework is optional and can be deferred post-1.0.
-
4
Cross-browser / device testing ~4–6 hrs
Test on iOS Safari and Android Chrome at 375px and 768px breakpoints. Verify nav, stat tables, progress bars, and charts render correctly.
Estimated total effort — Mobile responsiveness
28–40 hours