Skip to content

merge main - #1

Open
ReuschelCGN wants to merge 302 commits into
ReuschelCGN:develop-testfrom
PGAN-Dev:main
Open

merge main#1
ReuschelCGN wants to merge 302 commits into
ReuschelCGN:develop-testfrom
PGAN-Dev:main

Conversation

@ReuschelCGN

Copy link
Copy Markdown
Owner

No description provided.

hokiepokedad2 and others added 30 commits June 8, 2026 11:56
…tive toggles (#332)

* feat(admin-settings): search, sticky save, collapsible sections, positive toggles

Reworks the admin Server Settings page for clarity and scannability.

- Live search/filter: sticky search bar that filters settings across all sections
  with <mark> highlighting; '/' or Ctrl/Cmd+K focuses it, Esc clears.
- Sticky save + discard bar: replaces the header-only save button; appears with the
  unsaved count and a Discard (revert to loaded values) action whenever there are
  pending changes, so saving is always reachable on the long page.
- Regrouped auth: Telegram and Discord now sit directly under the Authentication
  section so all sign-in config is together.
- Collapsible sections (persisted in localStorage) with a per-section "unsaved"
  chip and a state summary in the header (e.g. "7 of 9 enabled").
- Positive toggles: the alarm-type/feature toggles were a confusing double negative
  (ON = "Disable X" = feature off) mixed with positive enable_* toggles. They are
  now uniformly positive — ON = enabled, labels are the feature name ("Pokémon",
  "Areas", …), descriptions are "Let users …". The stored disable_* keys are
  UNCHANGED (presentation-only inversion), so backend feature-gating is unaffected.
- Polish: staggered fade-in on load (respects prefers-reduced-motion) and a subtle
  per-section color tint.
- i18n: new ADMIN_SETTINGS UX keys and the reframed (positive) alarm/feature
  labels+descriptions translated across all 11 locales.

ng build + prettier + eslint clean.

* docs(changelog): note admin settings UX overhaul
Bumps [docker/build-push-action](https://github.com/docker/build-push-action) from 5 to 7.
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v5...v7)

---
updated-dependencies:
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 5 to 6.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/create-github-app-token](https://github.com/actions/create-github-app-token) from 2 to 3.
- [Release notes](https://github.com/actions/create-github-app-token/releases)
- [Changelog](https://github.com/actions/create-github-app-token/blob/main/CHANGELOG.md)
- [Commits](actions/create-github-app-token@v2...v3)

---
updated-dependencies:
- dependency-name: actions/create-github-app-token
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [dependabot/fetch-metadata](https://github.com/dependabot/fetch-metadata) from 2 to 3.
- [Release notes](https://github.com/dependabot/fetch-metadata/releases)
- [Commits](dependabot/fetch-metadata@v2...v3)

---
updated-dependencies:
- dependency-name: dependabot/fetch-metadata
  dependency-version: '3'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/cache](https://github.com/actions/cache) from 4 to 5.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](actions/cache@v4...v5)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the angular group with 13 updates in the /Applications/Pgan.PoracleWebNet.App/ClientApp directory:

| Package | From | To |
| --- | --- | --- |
| [@angular/animations](https://github.com/angular/angular/tree/HEAD/packages/animations) | `21.2.15` | `21.2.16` |
| [@angular/cdk](https://github.com/angular/components) | `21.2.13` | `21.2.14` |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `21.2.15` | `21.2.16` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `21.2.15` | `21.2.16` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `21.2.15` | `21.2.16` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `21.2.15` | `21.2.16` |
| [@angular/material](https://github.com/angular/components) | `21.2.13` | `21.2.14` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `21.2.15` | `21.2.16` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `21.2.15` | `21.2.16` |
| [@angular/build](https://github.com/angular/angular-cli) | `21.2.13` | `21.2.14` |
| [@angular/cli](https://github.com/angular/angular-cli) | `21.2.13` | `21.2.14` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `21.2.15` | `21.2.16` |
| [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `21.2.15` | `21.2.16` |



Updates `@angular/animations` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/animations)

Updates `@angular/cdk` from 21.2.13 to 21.2.14
- [Release notes](https://github.com/angular/components/releases)
- [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md)
- [Commits](angular/components@v21.2.13...v21.2.14)

Updates `@angular/common` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/common)

Updates `@angular/compiler` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/compiler)

Updates `@angular/core` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/core)

Updates `@angular/forms` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/forms)

Updates `@angular/material` from 21.2.13 to 21.2.14
- [Release notes](https://github.com/angular/components/releases)
- [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md)
- [Commits](angular/components@v21.2.13...v21.2.14)

Updates `@angular/platform-browser` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/platform-browser)

Updates `@angular/router` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/router)

Updates `@angular/build` from 21.2.13 to 21.2.14
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](angular/angular-cli@v21.2.13...v21.2.14)

Updates `@angular/cli` from 21.2.13 to 21.2.14
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](angular/angular-cli@v21.2.13...v21.2.14)

Updates `@angular/compiler-cli` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/compiler-cli)

Updates `@angular/platform-browser-dynamic` from 21.2.15 to 21.2.16
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.16/packages/platform-browser-dynamic)

---
updated-dependencies:
- dependency-name: "@angular/animations"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/build"
  dependency-version: 21.2.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/cdk"
  dependency-version: 21.2.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/cli"
  dependency-version: 21.2.14
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/common"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/compiler"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/compiler-cli"
  dependency-version: 21.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/core"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/forms"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/material"
  dependency-version: 21.2.14
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/platform-browser"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/platform-browser-dynamic"
  dependency-version: 21.2.16
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/router"
  dependency-version: 21.2.16
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Dependabot's npm/nuget PRs use a `deps:` commit prefix, which was not in the
changelog check's exempt list. Since Dependabot never writes a CHANGELOG entry,
"Changelog entry present" -- a required status check on main -- failed on every
one of those PRs, so auto-merge sat waiting on a check that could never pass.

Exempting `deps:` alone would drop dependency bumps from the changelog entirely.
Instead, release-changelog.yml now collects every `deps:` squash commit between
the previous tag and the release tag and appends them as a "### Dependencies"
section in the version block it cuts.

Collecting at release time rather than committing an entry onto each Dependabot
branch avoids two problems: concurrent Dependabot PRs would conflict on the same
lines of CHANGELOG.md, and Dependabot stops rebasing any PR another actor has
modified.

`ci:` (Actions) and `build:` (Docker base images) stay exempt and are not
collected -- they aren't runtime dependencies of the shipped product.
---
updated-dependencies:
- dependency-name: Microsoft.NET.Test.Sdk
  dependency-version: 18.8.1
  dependency-type: direct:production
  update-type: version-update:semver-minor
  dependency-group: test
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…#363)

Bumps Microsoft.AspNetCore.Authentication.JwtBearer from 10.0.8 to 10.0.10
Bumps Microsoft.AspNetCore.Mvc.Testing from 10.0.8 to 10.0.10
Bumps Microsoft.AspNetCore.OpenApi from 10.0.8 to 10.0.10
Bumps Microsoft.Extensions.Caching.Memory from 10.0.8 to 10.0.10
Bumps Microsoft.Extensions.Configuration.Abstractions to 10.0.10
Bumps Microsoft.Extensions.Http from 10.0.8 to 10.0.10
Bumps Microsoft.Extensions.Logging.Abstractions from 10.0.8 to 10.0.10

---
updated-dependencies:
- dependency-name: Microsoft.AspNetCore.Authentication.JwtBearer
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
- dependency-name: Microsoft.AspNetCore.Mvc.Testing
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
- dependency-name: Microsoft.AspNetCore.OpenApi
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
- dependency-name: Microsoft.Extensions.Caching.Memory
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
- dependency-name: Microsoft.Extensions.Configuration.Abstractions
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
- dependency-name: Microsoft.Extensions.Http
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
- dependency-name: Microsoft.Extensions.Logging.Abstractions
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: aspnetcore
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps Microsoft.EntityFrameworkCore from 10.0.8 to 10.0.10
Bumps Microsoft.EntityFrameworkCore.Design from 10.0.8 to 10.0.10
Bumps Microsoft.EntityFrameworkCore.InMemory from 10.0.8 to 10.0.10
Bumps Microsoft.EntityFrameworkCore.Sqlite from 10.0.8 to 10.0.10
Bumps MySql.EntityFrameworkCore from 10.0.7 to 10.0.9

---
updated-dependencies:
- dependency-name: Microsoft.EntityFrameworkCore
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
- dependency-name: Microsoft.EntityFrameworkCore
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
- dependency-name: Microsoft.EntityFrameworkCore.Design
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
- dependency-name: Microsoft.EntityFrameworkCore.InMemory
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
- dependency-name: Microsoft.EntityFrameworkCore.Sqlite
  dependency-version: 10.0.10
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
- dependency-name: MySql.EntityFrameworkCore
  dependency-version: 10.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
- dependency-name: MySql.EntityFrameworkCore
  dependency-version: 10.0.9
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: ef-core
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The `microsoft`, `aspnetcore`, and `ef-core` groups had overlapping patterns --
`Microsoft.*` is a superset of both `Microsoft.AspNetCore.*` and
`Microsoft.EntityFrameworkCore*`. Dependabot cut three PRs that carved up a
single package set, and only the widest of them could actually build.

The .NET platform packages ship as one versioned set: EF Core 10.0.x
transitively requires Microsoft.Extensions.* at >= the same 10.0.x. #366 raised
EF Core to 10.0.10 while Extensions stayed at 10.0.8 (those live in the other
two groups), producing `NU1605: Detected package downgrade` -- a hard error
under the .NET 10 SDK, not a warning. #363 was green only because it happened to
be self-consistent.

Collapse the three into a single `dotnet` group. MySql.EntityFrameworkCore joins
it because it version-locks to Microsoft.EntityFrameworkCore.Relational and
drags the same Extensions floor along.

Microsoft.NET.Test.Sdk is excluded from `dotnet` so it stays in `test` -- it
versions independently (18.x) and keeping it separate leaves a runtime bump and
a test-tooling bump reviewable apart from each other.

Verified by simulating pattern assignment over every PackageReference in the
solution: all platform packages land in `dotnet`, all test tooling in `test`,
nothing ungrouped.
Bumps the jest group with 1 update in the /Applications/Pgan.PoracleWebNet.App/ClientApp directory: [jest-preset-angular](https://github.com/thymikee/jest-preset-angular).


Updates `jest-preset-angular` from 16.1.5 to 17.0.0
- [Release notes](https://github.com/thymikee/jest-preset-angular/releases)
- [Changelog](https://github.com/thymikee/jest-preset-angular/blob/main/CHANGELOG.md)
- [Commits](thymikee/jest-preset-angular@v16.1.5...v17.0.0)

---
updated-dependencies:
- dependency-name: jest-preset-angular
  dependency-version: 16.2.0
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: jest
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
The workflow's own comment says "Majors and runtime-dep minors wait for human
review", but `dependency-group != ''` waved through a major inside any curated
group, so the group clause quietly overrode the stated policy.

Not hypothetical: #344 opened as jest-preset-angular 16.1.5 -> 16.2.0 and
Dependabot recreated it in place as 16.1.5 -> 17.0.0. It stayed auto-merge
eligible, and pre-approved, purely because it belongs to the `jest` group.

Hoist the major exclusion in front of the group clause on both the merge gate
and the approve gate. Approving a held bundle would satisfy the branch
protection review requirement without anyone having looked at it, so both need
the same guard.

For a grouped PR, fetch-metadata reports `update-type` as the highest semver
change in the bundle, so one major anywhere holds the whole bundle. If that
output is ever absent the comparison is true and grouped bundles behave as they
did before -- this cannot fail closed.

Verified by simulating both gates over eight scenarios: grouped patch, grouped
major, grouped minor, ungrouped patch, ungrouped major, Actions minor, Actions
major, and absent update-type.
Bumps [actions/cache](https://github.com/actions/cache) from 5 to 6.
- [Release notes](https://github.com/actions/cache/releases)
- [Changelog](https://github.com/actions/cache/blob/main/RELEASES.md)
- [Commits](actions/cache@v5...v6)

---
updated-dependencies:
- dependency-name: actions/cache
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-python](https://github.com/actions/setup-python) from 6 to 7.
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-python
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…t setup (#374)

Angular deprecated @angular/platform-browser-dynamic ("use @angular/platform-
browser instead") and it pins its peer @angular/common to an exact version.
That exact pin is what breaks #359: the angular group moves @angular/common to
21.2.19 while platform-browser-dynamic stays at 21.2.16 and demands
@angular/common@21.2.16, so npm fails with ERESOLVE. Any future Angular patch
bump hits the same wall.

jest-preset-angular 17 (#344, merged) dropped platform-browser-dynamic from its
peer dependencies, so nothing requires it any more. Its only remaining use was
one import in setup-jest.ts.

Remove the devDependency and repoint the test bootstrap at
@angular/platform-browser/testing, which exports the equivalent
BrowserTestingModule / platformBrowserTesting pair.

Verified: 872 tests across 78 suites pass, production build succeeds with no
errors, npm install resolves with no ERESOLVE, and platform-browser-dynamic is
gone from both node_modules and package-lock.json.
Bumps the angular group with 9 updates in the /Applications/Pgan.PoracleWebNet.App/ClientApp directory:

| Package | From | To |
| --- | --- | --- |
| [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `21.2.16` | `21.2.19` |
| [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `21.2.16` | `21.2.19` |
| [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `21.2.16` | `21.2.19` |
| [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `21.2.16` | `21.2.19` |
| [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `21.2.16` | `21.2.19` |
| [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `21.2.16` | `21.2.19` |
| [@angular/build](https://github.com/angular/angular-cli) | `21.2.14` | `21.2.19` |
| [@angular/cli](https://github.com/angular/angular-cli) | `21.2.14` | `21.2.19` |
| [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `21.2.16` | `21.2.19` |



Updates `@angular/common` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/common)

Updates `@angular/compiler` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/compiler)

Updates `@angular/core` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/core)

Updates `@angular/forms` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/forms)

Updates `@angular/platform-browser` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/platform-browser)

Updates `@angular/router` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/router)

Updates `@angular/build` from 21.2.14 to 21.2.19
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](angular/angular-cli@v21.2.14...v21.2.19)

Updates `@angular/cli` from 21.2.14 to 21.2.19
- [Release notes](https://github.com/angular/angular-cli/releases)
- [Changelog](https://github.com/angular/angular-cli/blob/main/CHANGELOG.md)
- [Commits](angular/angular-cli@v21.2.14...v21.2.19)

Updates `@angular/compiler-cli` from 21.2.16 to 21.2.19
- [Release notes](https://github.com/angular/angular/releases)
- [Changelog](https://github.com/angular/angular/blob/main/CHANGELOG.md)
- [Commits](https://github.com/angular/angular/commits/v21.2.19/packages/compiler-cli)

---
updated-dependencies:
- dependency-name: "@angular/build"
  dependency-version: 21.2.19
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/cli"
  dependency-version: 21.2.19
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/common"
  dependency-version: 21.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/compiler"
  dependency-version: 21.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/compiler-cli"
  dependency-version: 21.2.18
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/core"
  dependency-version: 21.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/forms"
  dependency-version: 21.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/platform-browser"
  dependency-version: 21.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
- dependency-name: "@angular/router"
  dependency-version: 21.2.18
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: angular
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
prettier-eslint is not used by anything in this repo. It appears only in
package.json: no script invokes it (`lint` runs `ng lint`, and the prettier
scripts call the `prettier` binary directly), `.eslintrc.json` never references
it, and nothing in the lockfile depends on it except the root package.

The formatting integration actually in use is `plugin:prettier/recommended`,
which comes from eslint-plugin-prettier and eslint-config-prettier -- both
separate packages, both still present. prettier-eslint is a different library
(a programmatic prettier-then-eslint API for editor integrations).

This supersedes #373, which bumps the unused package 16.4.2 -> 17.1.1. Removing
it is better than upgrading it, and drops 71 packages from the install.

Verified: prettier still resolves to 3.8.3 (unchanged), lint clean,
prettier-check clean, 872 tests across 78 suites pass, production build has no
errors.
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 6 to 7.
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v6...v7)

---
updated-dependencies:
- dependency-name: actions/setup-node
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…376)

GHSA-v5pm-xwqc-g5wc (high): a circular schema reference can terminate OpenAPI
parsing. Microsoft.OpenApi is vulnerable from 2.0.0-preview.11 through 2.7.4;
2.7.5 is the first patched release.

The recent ASP.NET Core bumps did not clear this. Microsoft.AspNetCore.OpenApi
pins Microsoft.OpenApi 2.0.0 transitively and pins the *same* 2.0.0 at both
10.0.8 and 10.0.10, so #362/#363 moved the parent without moving the vulnerable
child. A direct PackageReference is the only way to raise it, and can be removed
once Microsoft.AspNetCore.OpenApi ships a patched floor of its own.

Pinned to 2.7.5 rather than the newest 2.11.0 to keep the delta from the
transitively-expected 2.0.0 as small as possible while still clearing the
advisory.

Scope: AddOpenApi() is registered unconditionally but MapOpenApi() is gated on
IsDevelopment(), so the parsing path is not reachable in production.

The other outstanding NU1903 (SQLitePCLRaw.lib.e_sqlite3, GHSA-2m69-gcr7-jv3q)
is deliberately untouched: the advisory records no patched version, and the
package is reached only through EntityFrameworkCore.Sqlite in the test project.

Verified: restore reports no NU1903 for Microsoft.OpenApi and no NU1605
downgrades, resolved version is 2.7.5, solution builds with 0 errors, and all
1422 backend tests pass.
* deps: bump the eslint group across 1 directory with 5 updates

Bumps the eslint group with 3 updates in the /Applications/Pgan.PoracleWebNet.App/ClientApp directory: [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin), [eslint-plugin-perfectionist](https://github.com/azat-io/eslint-plugin-perfectionist) and [prettier](https://github.com/prettier/prettier).

Updates `@typescript-eslint/eslint-plugin` from 8.60.1 to 8.65.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/eslint-plugin/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.65.0/packages/eslint-plugin)

Updates `@typescript-eslint/parser` from 8.60.1 to 8.66.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/parser/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.66.0/packages/parser)

Updates `@typescript-eslint/utils` from 8.60.1 to 8.65.0
- [Release notes](https://github.com/typescript-eslint/typescript-eslint/releases)
- [Changelog](https://github.com/typescript-eslint/typescript-eslint/blob/main/packages/utils/CHANGELOG.md)
- [Commits](https://github.com/typescript-eslint/typescript-eslint/commits/v8.65.0/packages/utils)

Updates `eslint-plugin-perfectionist` from 5.9.0 to 5.10.0
- [Release notes](https://github.com/azat-io/eslint-plugin-perfectionist/releases)
- [Changelog](https://github.com/azat-io/eslint-plugin-perfectionist/blob/main/changelog.md)
- [Commits](azat-io/eslint-plugin-perfectionist@v5.9.0...v5.10.0)

Updates `prettier` from 3.8.3 to 3.9.6
- [Release notes](https://github.com/prettier/prettier/releases)
- [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md)
- [Commits](prettier/prettier@3.8.3...3.9.6)

---
updated-dependencies:
- dependency-name: "@typescript-eslint/eslint-plugin"
  dependency-version: 8.61.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/parser"
  dependency-version: 8.61.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: "@typescript-eslint/utils"
  dependency-version: 8.61.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
  dependency-group: eslint
- dependency-name: eslint-plugin-perfectionist
  dependency-version: 5.9.1
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
- dependency-name: prettier
  dependency-version: 3.8.4
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: eslint
...

Signed-off-by: dependabot[bot] <support@github.com>

* style: reformat CleanAlarmType for prettier 3.9.6

Prettier 3.9.6 (this PR's eslint group bump, up from 3.8.3) collapses the
CleanAlarmType union onto a single continuation line instead of one
pipe-prefixed member per line. That makes CI fail here on prettier/prettier.

This cannot land as a separate PR ahead of the bump: the two prettier versions
are mutually exclusive on this file. 3.8.3 rejects the collapsed form and 3.9.6
rejects the expanded one, so the reformat is only valid once the bump is in.

cleaning.service.ts is the only file affected across the whole repo -- verified
by running prettier 3.9.6 over everything and byte-comparing the result.

Verified on this branch with its own toolchain: lint clean, prettier-check
clean, 872 tests across 78 suites pass.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: hokiepokedad2 <38219945+hokiepokedad2@users.noreply.github.com>
Co-authored-by: HokiePokeDad <hokiepokedad@pogoalerts.net>
Bumps [actions/checkout](https://github.com/actions/checkout) from 6 to 7.
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v6...v7)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…377)

Supersedes #345, which bumped @ngx-translate/core alone and left 323 of 872
tests failing.

Two things #345 got wrong:

1. It moved core to 18 while leaving @ngx-translate/http-loader at 17. The two
   version together -- http-loader 18 declares a peer of core >= 18.0.0. Both
   are bumped here.

2. That mismatch was not actually the cause of the failures. v18 removes
   TranslateModule entirely in favour of standalone APIs, so every TestBed
   importing it died with NG0919 "Cannot read @NgModule metadata".

Migration:

- 72 non-spec files: TranslateModule -> TranslatePipe, in both the import and
  the standalone `imports` array. The codebase uses the `| translate` pipe 1530
  times and the translate *directive* zero times, so TranslatePipe alone covers
  every call site; TranslateDirective is not needed.
- 7 spec files: TranslateModule.forRoot() dropped from `imports`, with
  provideTranslateService() added to the enclosing `providers` array instead.
- setDefaultLang() -> setFallbackLang() and getDefaultLang() -> getFallbackLang();
  these are the only renamed TranslateService members the codebase touches
  (instant/use/addLangs all survive v18 unchanged).
- provideTranslateService({ defaultLanguage }) -> ({ fallbackLang }); v18's
  RootTranslateServiceConfig has no defaultLanguage key.

Verified: 872 tests across 78 suites pass (from 323 failing), lint clean,
prettier clean, production build 0 errors. The remaining NG8107 build warning
predates this change.
Bumps [actions/setup-dotnet](https://github.com/actions/setup-dotnet) from 5 to 6.
- [Release notes](https://github.com/actions/setup-dotnet/releases)
- [Commits](actions/setup-dotnet@v5...v6)

---
updated-dependencies:
- dependency-name: actions/setup-dotnet
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: HokiePokeDad <hokiepokedad@pogoalerts.net>
Prerequisite for enabling a merge queue on `main`. A queued PR waits on the
required checks being reported against the queue's temporary merge branch, not
against the PR head. Any required check whose workflow lacks a `merge_group`
trigger simply never runs there, and the PR sits in the queue until it times
out -- strictly worse than the current behaviour. So this has to land before
the queue is switched on, not alongside it.

ci.yml supplies "Backend (.NET)" and "Frontend (Angular)": trigger added, no
other change needed since both jobs just build and test.

changelog.yml supplies "Changelog entry present" and needs more care. A
merge_group payload carries no `pull_request` object, so TITLE, LABELS,
BASE_SHA and HEAD_SHA would all resolve empty: the exempt-prefix test would
miss, `git show ":CHANGELOG.md"` would fail, and the job would report a bogus
failure on a PR that already passed the gate. The check is a pull-request-level
policy, so it is now explicitly a no-op on merge_group and runs only on
pull_request.

The job keeps at least one unconditional step, because a job whose every step
is skipped by an `if:` is recorded as a failure -- which would block the queue.
That is the same trap already documented in auto-merge-deps.yml.

Also corrects the failure message, which still listed the pre-#368 exempt set
and omitted `deps`.

Job names are unchanged, so the three required status check contexts still
match.
CheckRoleAccessAsync compared allowed roles with HashSet.IsSubsetOf, so a
user had to hold *every* listed role to log in, while the setting is
documented everywhere as an allow-list. Match on Overlaps instead.

The setting's tooltip also showed its example wrapped in quotes, so admins
pasted the quotes in and every entry became unmatchable, denying all
non-admin logins with only an info-level log. Parsing now strips the quote
styles used across the translated tooltips, drops non-snowflake entries with
a warning, and fails closed with role_check_failed when nothing usable is
left rather than silently allowing everyone.

Tooltip copy (11 locales) and the settings/SSO docs drop the quotes and
state the any-of semantics. Tests cover the parser and the grant decision.
…ses (#380)

The Compose healthcheck probes the app with `curl -sf http://localhost:8080/`,
but the aspnet:10.0 runtime base (Ubuntu 24.04) ships neither curl nor wget.
Every probe failed with `/bin/sh: 1: curl: not found` and Docker flipped the
container to `unhealthy` while ASP.NET Core was serving traffic normally.
Cosmetic on a single host, but Swarm/Kubernetes/auto-healers treat `unhealthy`
as a restart signal.

Installs curl in the runtime stage before the drop to appuser
(--no-install-recommends, apt lists removed, ~6.5 MB).

Fixes #239
AutoMapper was dropped in v2.6.0 (#173) in favour of manual mapping
extensions, but four docs pages still described it as the live mapping
layer -- architecture/backend.md even carried a .ForAllMembers snippet
that exists nowhere in the codebase.

The mapping sections in architecture/overview.md and
architecture/backend.md now describe AlarmMappingExtensions (To*() /
ApplyUpdate()) and EntityMappingExtensions (ToModel() / ToEntity() /
ApplyTo()), with a real ApplyUpdate snippet showing the explicit
null-skip guards. The Core.Mappings/ line in the solution tree, the
test-coverage bullet in development/testing.md, and a passing mention
in architecture/poracleng-proxy.md are corrected to match.

Also renames the mapping test file, which was still called
PoracleMappingProfileTests.cs while the class inside it had already
been renamed to MappingExtensionTests. Nothing referenced the old file
name; all 66 tests pass unchanged.
…379)

Rename ScannerDbContext -> ScannerContext so all three DbContext
subclasses share one convention (PoracleContext, PoracleWebContext,
ScannerContext). #232 had renamed RdmScannerContext -> ScannerDbContext
and introduced the odd-one-out Db infix; this restores the pattern.

Touches the class and its file, the DbContextOptions<> type argument,
the ScannerService ctor parameter and field, the AddDbContext<>
registration, and the two doc mentions.

No functional change: IScannerService is unchanged, the optional
ConnectionStrings:ScannerDb key is unchanged, and no EF migrations are
involved (the scanner DB is read-only and never migrated by PoracleWeb).
hokiepokedad2 and others added 30 commits August 21, 2026 13:42
…ng it

It showed up in the admin page's Other catch-all as an editable text box.
It is not a setting: the API synthesizes it from Poracle's general.locale so
the SPA can default the display language (#773). Upsert guarded only
InternalKeys, so an edit wrote a real site_settings row -- and a real row wins
over the synthesized value, so one save pinned the language default forever and
silently stopped tracking Poracle. The XML comment already said 'not an
admin-editable row'; nothing enforced it.

This is #560 again, for a key that was never in a group: anything reaching the
settings response undeclared becomes an editable control. The client-side half
is now a named PROJECTED_KEYS list so the next projection has somewhere to go,
but the server-side refusal is the actual guarantee.

Tests: refusal (both casings), plus an ordinary key still writing -- without
that last one the guard passes equally well with the endpoint broken.

Closes #780
Hiding the projection entirely answers the bug but loses the information: an
admin wondering why new users land on English had nothing in the UI to look at.

The value now appears as a hint line under Allowed UI Languages, which is the
setting it interacts with -- it decides what a user gets when they have never
chosen a language and their browser sends one this site does not ship. Read-only,
because it is Poracle's to set and writes are refused server-side.

Reuses the existing per-key config-hint pattern (favicon_url, forced-by-Poracle).
Translated into all eleven locales.
The first wording described the precedence rule before saying what the value
is. It now leads with the thing an admin wants to know -- 'Default language for
new users: de' -- names where it comes from, and only then covers who overrides
it.

Verified on dev by setting Poracle's locale to de: a visitor with nothing stored
and a ja-JP browser lands on German, a fr-FR browser still gets French, and a
stored choice still wins. Neither auto-pick is persisted.
fix: refuse writes to the poracle_locale projection, and stop rendering it
One entry from today used the short form. Unreleased, so it costs nothing to
correct now.
Seven places explained a behaviour by pointing at the older implementation
rather than saying what is true: an area-lowercasing comment, the UI language
list, the monster defaults table, the i18n intro, and three lines in the size
filter troubleshooting.

Each now states the fact directly -- Poracle matches areas case-sensitively,
the defaults are the values Poracle expects -- which is both the rule and the
more useful sentence.

Three of them had also been mangled by an earlier find-and-replace into
phrases like "the PHP PoracleWeb.NET defaults", so they were wrong twice.
docs: use the project's full name, and state facts on their own terms
… locale default

The internationalization page was wrong in a way that mattered: it said Pokemon
names follow the alert language. They follow the display language now, come from
Poracle rather than the masterfile, and the page explains the resolution order,
what happens for the four languages Poracle has no translations for, and that
moves and items stay English.

Site settings gains the Poracle-side disable flags as a floor, with a screenshot
of a forced toggle and the note that it fails open; a section on projections --
values on the settings response that are not rows and cannot be written; and the
language default with its own screenshot.

Also: the proxy doc's read-only calls table, MasterDataService and
UpstreamFeatureFlagService in the architecture docs, the browser no longer
calling GitHub in the Docker network notes, two troubleshooting entries, the two
upstream gaps filed as jfberry/PoracleNG#194 and #195, and the in-app help
guide's language section in all eleven locales.

Screenshots were captured against dev with the account name, avatar, site title,
logo, nav link and SSO hostname neutralised in-page first.
…ting

docs: update for localized game data, upstream feature gating and the locale default
Switching a type off used to 403 the whole controller and drop the nav item, so
the rules a user had already created became invisible and unremovable until
someone switched it back on. An alarm of a disabled type can never fire, so
removing it is the one action still worth taking -- and when Poracle is the side
that disabled it, its bot refuses the matching command too, leaving this page as
the only way to clean up.

Backend: the ten alarm controllers move [RequireFeatureEnabled] from the class
to their write actions (create, update, both distance bulk updates). Reads and
deletes are open. The service-layer guards on Create/BulkCreate/Update are
unchanged and still cover the service-to-service paths.

FeatureGateCoverageTests caught the partially-gated shape immediately, which is
what it is for; the twenty delete actions are recorded in its
IntentionallyUngatedWrites set with the reasoning, beside the geofence delete
that set the precedent. DisabledAlarmTypeAccessTests fails if a class-level
attribute returns or a new write ships ungated.

Frontend: route guards dropped for the ten alarm routes, nav items kept with a
padlock, a shared banner naming the source, and every create/edit control --
add, edit, bulk distance, test alert -- wrapped in @if (!writesDisabled()).
Delete is untouched. The delivery-scope chip stays because it says where the
alarm reaches you; its handler refuses with a message instead.

The #236 nav tests asserted the old contract and are rewritten to the new one,
keeping that issue's actual point: settings items still hide outright, and
admins get no bypass anywhere.

alarm-list-readonly.spec.ts reads the ten templates and pins both halves, which
caught the two mistakes I made getting here: a wrapper that swallowed bulkDelete
in all nine, and editScope slipping through because it is not a button.
Rebasing onto the docs update brought in a troubleshooting entry and a
site-settings note written against the old behaviour, where a disabled type
took its whole page with it. Both now describe what actually happens: no Add
button, no Edit, a padlock in the nav, and the existing alarms still listed and
still deletable.

Also trims the overlap the rebase created between the two admonitions -- the
Poracle-side point belongs in the Poracle one.
…ypes

feat: a disabled alarm type is read-and-delete, not hidden
SummaryScheduleController was the last one still gated at the class level, so
turning quests off hid a user's summary schedule and left no way to clear it --
the same trap #784 removed everywhere else.

The gate moves to SetSchedule and Trigger. The three reads and DeleteSchedule
are open: a schedule for a disabled type delivers nothing, so clearing it is the
one useful thing left, and Poracle's bot refuses the command while quests are
off there.

In the dialog, Save and Send now are hidden along with the send hint that
described them; Clear and Close stay. The exemption is recorded in
FeatureGateCoverageTests beside the alarm deletes.

Its own spec asserted the class-level attribute, which was the old contract --
rewritten to assert the per-action split in both directions.

Closes the gap noted in #784.
…elete

fix: quest summary schedules are read-and-delete when quests are off
The response drives whether the My Webhooks nav item renders, and it read the
managedWebhooks JWT claim -- minted at login, good for 24 hours. So a delegate
granted access today saw nothing until their token refreshed, while the page
itself and POST /api/admin/impersonate would both already have let them in:
those moved to live resolution in #601 and #626, and this was the last consumer
of the claim. Revocation lagged the same way, leaving the item pointing at an
empty page.

Two cases still prefer the claim. An impersonation session, where this.UserId is
the impersonated account and resolving its delegations answers a different
question -- the trap #663 fixed for admin status, and the resolver is not called
at all there. And a degraded resolve, where an unreachable PoracleNG or a
poracle_web blip would otherwise strip a delegate mid-session (#656, #667); the
two sets are unioned there, since a partial answer may have found a new grant
while missing an old one.

Nothing authorises off the claim any more -- it is a cold fallback for the
degraded path. Both real checks resolve live and fail closed.

The resolver caches for a minute per user, so this adds no round trip per call.

Watched red first: putting the claim back fails three of the five new tests.
fix: resolve managed webhooks live in /api/auth/me
The button read 'Back to Admin'. That was written when only admins could view
another account; delegates can do the same for the webhooks they manage, and
were being pointed back to a place they have never been -- a delegate has no
admin pages at all.

'Back to your account' is true for both, so the string carries no role. Renamed
from BANNER.BACK_TO_ADMIN to BANNER.EXIT_IMPERSONATION since the old name
carried the same wrong assumption, and translated into all eleven locales.

Found by walking the delegate flow through Playwright on dev.
fix: address the impersonation banner to whoever is actually looking
The feature was documented only as a table in the database reference. Everything
an operator actually needs -- what a webhook is, how a delegate is added, what
they can and cannot do, and whether Poracle's config has to change -- lived only
in the source. Those exact questions came up today and had to be answered by
reading it.

New features/webhooks.md covers the flow end to end, including the distinction
that keeps catching people out: managing a webhook on this site needs no Poracle
config edit, and managing it through the Discord bot does. The two grants are
independent, and this site accepts either as proof for its own access.

Also:
- quest-summary-schedules.md gains what happens once quests are switched off,
  matching the read-and-delete rule the alarm types follow.
- A troubleshooting entry for a delegate who cannot see My Webhooks, covering
  the account-must-exist rule, the one-minute cache, admins never seeing the
  item, and the bot-versus-web confusion.
- CLAUDE.md gains the resolution rules and the four bugs that came from one
  surface disagreeing with another (#564, #601, #626, #786), plus why the JWT
  claim is now a cold fallback nothing authorises off.
docs: write down webhooks and delegation
chore: sync the 2.17.0 changelog cut back to develop
…card

#784 left a padlocked nav item so people holding rules of a disabled type could
still reach and delete them. That served the minority and showed everyone else a
locked entry to an empty page -- on an instance that never enabled nests, every
user carried a padlocked Nests item.

The dashboard does the job better. It already renders a card per type with its
count, it is not filtered by the disable settings, and it has the numbers the nav
does not: the sidebar is drawn at bootstrap, where counts have not loaded, so
gating it on 'do they have any' meant a new request per page load or an item that
pops in late.

So the card is now shown for a disabled type only while alarms remain on it,
marked and muted so it does not read as an invitation, and the sidebar item goes.
Nothing is stranded while there is something to reach; once the last alarm is
deleted both disappear, which is the right end state. The route stays ungated, so
the link and any bookmark still work.

The nav tests from #784 asserted the padlocked item and are rewritten, keeping
#236's point that admins get no bypass. New dashboard-cards.spec.ts pins both
directions, including eggs sharing the raid key.

Closes #792
Reverses the read-and-delete model from #784 and #785. That model kept a
disabled type half-present so nobody was left holding rules they could not
remove; in practice it put a locked, empty page in front of every user of an
instance that never enabled the type, to serve the few who had one.

Disabling a type now removes it. The gate is class-level again on the ten alarm
controllers and on SummaryScheduleController, so every action answers 403 --
reads and deletes included -- the route guards are back, and the sidebar item
and dashboard card are gone.

Nothing is destroyed: rules already stored cannot fire while the type is off,
are not deleted, and come back intact when it is switched on again.

That makes the whole read-only apparatus unreachable, so it goes: the banner
component, the writesDisabled computeds, ~46 per-control @if wrappers across
nine templates and the summary-schedule dialog, the editScope guards, and five
i18n strings in eleven locales each.

Tests follow the contract rather than the other way round:
DisabledAlarmTypeAccessTests asserted the per-action split and is replaced by
DisabledAlarmTypeGatingTests, which fails if the gate moves off the class. The
alarm delete exemptions leave FeatureGateCoverageTests, since a class-gated
controller is not partially gated. alarm-list-readonly.spec.ts and the dialog's
disabled-state tests are removed with the code they covered.

Closes #792
fix: a disabled alarm type disappears completely
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants