Adds a self-contained way to run the SqlServer to Postgres copy anywhere: a multi-stage Dockerfile (net9.0 SDK build, ASP.NET runtime because the project references Microsoft.AspNetCore.App), a compose file that joins the shared greenNetwork so the target is reachable as postgres, an env template for the two connection strings, and a src/.dockerignore so the build context excludes node_modules and bin/obj.
The image restores explicitly from NuGet.org because the repo's nuget.config declares an empty packageSources, which would leave a clean container with no feed at all.
DataCopy read SqlServer datetime2 values, which carry Kind=Unspecified, straight into Postgres timestamptz columns that reject them. It previously worked around this with the process-wide Npgsql legacy switch; now every copied entity has its DateTime and DateTime? properties normalized to Kind=Utc before the write. That names the existing value without shifting it, so the stored instant stays exactly what SqlServer held, and no global behaviour is changed.
PowerOutageLogService called ToPersianDate on Kind=Utc values, which converts to the machine-local timezone inside PersianDateHelper. That now also happens on the DB-read path because Postgres DateTime columns are timestamptz and read back as Kind=Utc. Normalize to Unspecified first - the rule TelemetryService already applies - so the stored PersianDate does not shift with the server timezone.
Device reset: Device.ResetRequested is a one-shot flag claimed atomically with a single UPDATE, so a queued reset is delivered exactly once. GET api/telemetry/AddData answers it with the bare token RST and nothing else; subsequent requests resume the normal routine. Adds POST api/admin/devices/{id}/request-reset (audited) plus an admin panel button, pending badge and confirm dialog.
Postgres migrations: PostgresGreenHomeDbContext owns Data/Migrations/Postgres while the SqlServer set stays untouched. Registers one context per provider with the base type forwarded, replaces EnsureCreated() with Migrate() for both, adds a complete InitialPostgres migration and an incremental AddDeviceResetRequested for SqlServer, and adds design-time factories so dotnet ef does not have to boot the API host.
Timestamps: Postgres DateTime columns are now timestamp with time zone, because Npgsql rejects Kind=Utc values on a naive timestamp column, which broke every write path (auth, settings, posts, checklists, alerts, audit logs). Removes the SpecifyKind(Unspecified) workarounds, fixes a 3:30 offset where already-UTC filters were passed through ToLocalTime(), and makes DataCopy migrate instead of EnsureCreated while passing timestamps through verbatim.
Tests: Test/GreenHome.SelfCheck applies the Postgres migrations and asserts that a queued reset is consumed exactly once and that timestamps round-trip as Utc.
- set server timestamp as UTC with unspecified kind
- use unspecified kind for dto before persian conversion
- avoid timezone and kind issues in persian date conversion
- debounce admin searches to reduce API calls while typing
- apply 300ms debounce to alerts, audit, devices, posts
- allow clearing selected owner in device creation form
🐛 fix(admin): correct admin data and filters
- use invariant culture for CSV numeric report values
- align default report end date with UTC day boundary
- prevent duplicate owner row in device member list
- make user growth date filtering EF translatable
- clear report preset when user picks a custom date range
- send zero-valued admin filter parameters in API client
- add admin endpoints to create devices and update device settings
- expose device members and post detail for admin management
- add post filters by device, author, type, and date range
- add user growth, device uptime, and usage reports with CSV export
- improve admin layout with sticky header, user info, and logout
- add device and author search filters across admin pages
- Add MIME type mapping for .apk files to allow proper download
- Configure static file serving for new "files" directory at /files endpoint
- Enable serving APK and other downloadable files from dedicated folder