merge main#1
Open
ReuschelCGN wants to merge 59 commits into
Open
Conversation
CI installs Node 22 which ships npm 10.9.7. That version's `npm ci` strictly requires the nested `chokidar@4.0.3` / `readdirp@4.1.2` entries that `@angular-devkit/*` packages declare as optional peer deps. Dependabot regenerates `package-lock.json` with a newer npm that prunes those entries, producing lockfiles npm 10.9.7 rejects with EUSAGE — blocking #248, #250, #256, #261, #262. Aligning CI to npm 11 matches Dependabot's resolution so the post-rebase lockfile is accepted.
Bumps Microsoft.AspNetCore.Authentication.JwtBearer from 10.0.5 to 10.0.8 Bumps Microsoft.AspNetCore.Mvc.Testing from 10.0.5 to 10.0.8 Bumps Microsoft.AspNetCore.OpenApi from 10.0.5 to 10.0.8 Bumps Microsoft.EntityFrameworkCore from 10.0.5 to 10.0.8 Bumps Microsoft.EntityFrameworkCore.Design from 10.0.5 to 10.0.8 Bumps Microsoft.EntityFrameworkCore.InMemory from 10.0.5 to 10.0.8 Bumps Microsoft.Extensions.Caching.Memory from 10.0.5 to 10.0.8 Bumps Microsoft.Extensions.Configuration.Abstractions from 10.0.5 to 10.0.8 Bumps Microsoft.Extensions.Http from 10.0.5 to 10.0.8 Bumps Microsoft.Extensions.Logging.Abstractions from 10.0.5 to 10.0.8 Bumps Microsoft.NET.Test.Sdk from 18.4.0 to 18.5.1 --- updated-dependencies: - dependency-name: Microsoft.AspNetCore.Authentication.JwtBearer dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.AspNetCore.Mvc.Testing dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.AspNetCore.OpenApi dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.EntityFrameworkCore dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.EntityFrameworkCore dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.EntityFrameworkCore.Design dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.EntityFrameworkCore.InMemory dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.Extensions.Caching.Memory dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.Extensions.Logging.Abstractions dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.Extensions.Configuration.Abstractions dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.Extensions.Http dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: microsoft - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.1 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: microsoft ... 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.8` | `21.2.14` | | [@angular/cdk](https://github.com/angular/components) | `21.2.6` | `21.2.12` | | [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `21.2.8` | `21.2.14` | | [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `21.2.8` | `21.2.14` | | [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `21.2.8` | `21.2.14` | | [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `21.2.8` | `21.2.14` | | [@angular/material](https://github.com/angular/components) | `21.2.6` | `21.2.12` | | [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `21.2.8` | `21.2.14` | | [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `21.2.8` | `21.2.14` | | [@angular/build](https://github.com/angular/angular-cli) | `21.2.7` | `21.2.12` | | [@angular/cli](https://github.com/angular/angular-cli) | `21.2.7` | `21.2.12` | | [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `21.2.8` | `21.2.14` | | [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `21.2.8` | `21.2.14` | Updates `@angular/animations` from 21.2.8 to 21.2.14 - [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.14/packages/animations) Updates `@angular/cdk` from 21.2.6 to 21.2.12 - [Release notes](https://github.com/angular/components/releases) - [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md) - [Commits](angular/components@v21.2.6...v21.2.12) Updates `@angular/common` from 21.2.8 to 21.2.14 - [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.14/packages/common) Updates `@angular/compiler` from 21.2.8 to 21.2.14 - [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.14/packages/compiler) Updates `@angular/core` from 21.2.8 to 21.2.14 - [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.14/packages/core) Updates `@angular/forms` from 21.2.8 to 21.2.14 - [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.14/packages/forms) Updates `@angular/material` from 21.2.6 to 21.2.12 - [Release notes](https://github.com/angular/components/releases) - [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md) - [Commits](angular/components@v21.2.6...v21.2.12) Updates `@angular/platform-browser` from 21.2.8 to 21.2.14 - [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.14/packages/platform-browser) Updates `@angular/router` from 21.2.8 to 21.2.14 - [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.14/packages/router) Updates `@angular/build` from 21.2.7 to 21.2.12 - [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.7...v21.2.12) Updates `@angular/cli` from 21.2.7 to 21.2.12 - [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.7...v21.2.12) Updates `@angular/compiler-cli` from 21.2.8 to 21.2.14 - [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.14/packages/compiler-cli) Updates `@angular/platform-browser-dynamic` from 21.2.8 to 21.2.14 - [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.14/packages/platform-browser-dynamic) --- updated-dependencies: - dependency-name: "@angular/animations" dependency-version: 21.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/build" dependency-version: 21.2.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/cdk" dependency-version: 21.2.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/cli" dependency-version: 21.2.8 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/common" dependency-version: 21.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/compiler" dependency-version: 21.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/compiler-cli" dependency-version: 21.2.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/core" dependency-version: 21.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/forms" dependency-version: 21.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/material" dependency-version: 21.2.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/platform-browser" dependency-version: 21.2.10 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/platform-browser-dynamic" dependency-version: 21.2.10 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/router" dependency-version: 21.2.10 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>
Bumps [@jest/globals](https://github.com/jestjs/jest/tree/HEAD/packages/jest-globals) from 30.3.0 to 30.4.1. - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v30.4.1/packages/jest-globals) --- updated-dependencies: - dependency-name: "@jest/globals" dependency-version: 30.4.1 dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
) Bumps [jsdom](https://github.com/jsdom/jsdom) from 28.1.0 to 29.1.1. - [Release notes](https://github.com/jsdom/jsdom/releases) - [Commits](jsdom/jsdom@v28.1.0...v29.1.1) --- updated-dependencies: - dependency-name: jsdom dependency-version: 29.1.1 dependency-type: direct:development 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 jest group with 3 updates in the /Applications/Pgan.PoracleWebNet.App/ClientApp directory: [jest](https://github.com/jestjs/jest/tree/HEAD/packages/jest), [jest-environment-jsdom](https://github.com/jestjs/jest/tree/HEAD/packages/jest-environment-jsdom) and [jest-preset-angular](https://github.com/thymikee/jest-preset-angular). Updates `jest` from 30.3.0 to 30.4.2 - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v30.4.2/packages/jest) Updates `jest-environment-jsdom` from 30.3.0 to 30.4.1 - [Release notes](https://github.com/jestjs/jest/releases) - [Changelog](https://github.com/jestjs/jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/jestjs/jest/commits/v30.4.1/packages/jest-environment-jsdom) Updates `jest-preset-angular` from 16.1.4 to 16.1.5 - [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.4...v16.1.5) --- updated-dependencies: - dependency-name: jest dependency-version: 30.4.2 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: jest - dependency-name: jest-environment-jsdom dependency-version: 30.4.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: jest - dependency-name: jest-preset-angular dependency-version: 16.1.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: jest ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
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.58.1 to 8.59.4 - [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.59.4/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.58.1 to 8.59.4 - [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.59.4/packages/parser) Updates `@typescript-eslint/utils` from 8.58.1 to 8.59.4 - [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.59.4/packages/utils) Updates `eslint-plugin-perfectionist` from 5.8.0 to 5.9.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.8.0...v5.9.0) Updates `prettier` from 3.8.2 to 3.8.3 - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](prettier/prettier@3.8.2...3.8.3) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.58.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@typescript-eslint/parser" dependency-version: 8.58.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: "@typescript-eslint/utils" dependency-version: 8.58.2 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: eslint-plugin-perfectionist dependency-version: 5.9.0 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: prettier dependency-version: 3.8.3 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint ... 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>
The auto-merge-deps workflow listed both `pull_request_target` and `push:` as triggers. In practice GitHub fired it only on push events — the last 100+ runs were all `push`, zero were `pull_request_target` — even though the sibling `pr-labeler.yml` (only `pull_request_target`) fires correctly. The job-level `if: github.event_name == 'pull_request_target'` then skipped every step on those push runs, recording each as failure with 0 successful steps. Two changes: - Drop the `push:` trigger so only pull_request_target events run. - Drop the job-level gate; gate each step instead and add a sentinel first step so non-Dependabot PRs still record as success rather than 0-step failure. #231 attempted this with job-level if assuming "all-skipped = success", but GitHub treats 0-job runs as failure regardless.
The approval body string contained Auto-approved: — an unquoted colon inside an unquoted YAML scalar. PyYAML rejects this with `mapping values are not allowed here`, and GitHub Actions appears to silently fail to register the workflow's `pull_request_target` trigger as a result (the workflow only ever fires on push events, the friendly name from `name:` never resolves in the API). Sibling `pr-labeler.yml` has no such ambiguity and fires correctly. Dropping the colon from the body resolves both symptoms without needing to nest YAML quoting.
--- updated-dependencies: - dependency-name: coverlet.collector dependency-version: 10.0.1 dependency-type: direct:production update-type: version-update:semver-major dependency-group: test - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.5.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>
Bumps Microsoft.EntityFrameworkCore from 10.0.5 to 10.0.8 Bumps Microsoft.EntityFrameworkCore.Design from 10.0.5 to 10.0.8 Bumps Microsoft.EntityFrameworkCore.InMemory from 10.0.5 to 10.0.8 Bumps MySql.EntityFrameworkCore from 10.0.1 to 10.0.7 --- updated-dependencies: - dependency-name: Microsoft.EntityFrameworkCore dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ef-core - dependency-name: Microsoft.EntityFrameworkCore.Design dependency-version: 10.0.8 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ef-core - dependency-name: MySql.EntityFrameworkCore dependency-version: 10.0.7 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: ef-core - dependency-name: Microsoft.EntityFrameworkCore.InMemory dependency-version: 10.0.8 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> Co-authored-by: hokiepokedad2 <38219945+hokiepokedad2@users.noreply.github.com>
Loose .png screenshots from Playwright MCP sessions and the `.playwright-mcp/` output directory keep showing up as untracked at the repo root. None of them belong in the tree (tracked PNGs all live under `Applications/Pgan.PoracleWebNet.App/ClientApp/public/assets/`). Add a root-only `/*.png` rule plus `.playwright-mcp/` so `git status` stays clean.
#260) (#279) LikeEscape (added in #232) used `\` as the SQL LIKE escape character, and ScannerService.SearchGymsAsync passed `\` to EF.Functions.Like via `"\\"`. MariaDB's default mode (`NO_BACKSLASH_ESCAPES=OFF`) also treats `\` as a string-literal escape, so an escaped `\` in the pattern (which LikeEscape itself produces for user-supplied backslashes) left the SQL string literal unbalanced and broke gym search with `near ''\')`. Switch the escape character to `|`, which has no special meaning in MariaDB string literals. The LIKE pattern can no longer interact with quote escaping no matter what the user types. Added a `LikeEscape.EscapeChar` constant so callers stay in sync. Tests updated to match the new escape sequences. Reported by @prof-miles0 in #260.
Bumps the angular group in /Applications/Pgan.PoracleWebNet.App/ClientApp with 13 updates: | Package | From | To | | --- | --- | --- | | [@angular/animations](https://github.com/angular/angular/tree/HEAD/packages/animations) | `21.2.14` | `21.2.15` | | [@angular/cdk](https://github.com/angular/components) | `21.2.12` | `21.2.13` | | [@angular/common](https://github.com/angular/angular/tree/HEAD/packages/common) | `21.2.14` | `21.2.15` | | [@angular/compiler](https://github.com/angular/angular/tree/HEAD/packages/compiler) | `21.2.14` | `21.2.15` | | [@angular/core](https://github.com/angular/angular/tree/HEAD/packages/core) | `21.2.14` | `21.2.15` | | [@angular/forms](https://github.com/angular/angular/tree/HEAD/packages/forms) | `21.2.14` | `21.2.15` | | [@angular/material](https://github.com/angular/components) | `21.2.12` | `21.2.13` | | [@angular/platform-browser](https://github.com/angular/angular/tree/HEAD/packages/platform-browser) | `21.2.14` | `21.2.15` | | [@angular/router](https://github.com/angular/angular/tree/HEAD/packages/router) | `21.2.14` | `21.2.15` | | [@angular/build](https://github.com/angular/angular-cli) | `21.2.12` | `21.2.13` | | [@angular/cli](https://github.com/angular/angular-cli) | `21.2.12` | `21.2.13` | | [@angular/compiler-cli](https://github.com/angular/angular/tree/HEAD/packages/compiler-cli) | `21.2.14` | `21.2.15` | | [@angular/platform-browser-dynamic](https://github.com/angular/angular/tree/HEAD/packages/platform-browser-dynamic) | `21.2.14` | `21.2.15` | Updates `@angular/animations` from 21.2.14 to 21.2.15 - [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.15/packages/animations) Updates `@angular/cdk` from 21.2.12 to 21.2.13 - [Release notes](https://github.com/angular/components/releases) - [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md) - [Commits](angular/components@v21.2.12...v21.2.13) Updates `@angular/common` from 21.2.14 to 21.2.15 - [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.15/packages/common) Updates `@angular/compiler` from 21.2.14 to 21.2.15 - [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.15/packages/compiler) Updates `@angular/core` from 21.2.14 to 21.2.15 - [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.15/packages/core) Updates `@angular/forms` from 21.2.14 to 21.2.15 - [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.15/packages/forms) Updates `@angular/material` from 21.2.12 to 21.2.13 - [Release notes](https://github.com/angular/components/releases) - [Changelog](https://github.com/angular/components/blob/main/CHANGELOG.md) - [Commits](angular/components@v21.2.12...v21.2.13) Updates `@angular/platform-browser` from 21.2.14 to 21.2.15 - [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.15/packages/platform-browser) Updates `@angular/router` from 21.2.14 to 21.2.15 - [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.15/packages/router) Updates `@angular/build` from 21.2.12 to 21.2.13 - [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.12...v21.2.13) Updates `@angular/cli` from 21.2.12 to 21.2.13 - [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.12...v21.2.13) Updates `@angular/compiler-cli` from 21.2.14 to 21.2.15 - [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.15/packages/compiler-cli) Updates `@angular/platform-browser-dynamic` from 21.2.14 to 21.2.15 - [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.15/packages/platform-browser-dynamic) --- updated-dependencies: - dependency-name: "@angular/animations" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/cdk" dependency-version: 21.2.13 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/common" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/compiler" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/core" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/forms" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/material" dependency-version: 21.2.13 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/platform-browser" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/router" dependency-version: 21.2.15 dependency-type: direct:production update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/build" dependency-version: 21.2.13 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/cli" dependency-version: 21.2.13 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/compiler-cli" dependency-version: 21.2.15 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: angular - dependency-name: "@angular/platform-browser-dynamic" dependency-version: 21.2.15 dependency-type: direct:development 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>
#259) (#280) * feat(raids): redesign level selector with named tiers + custom palette (#259) The raid/egg add dialog had three level-pickers (raid checkboxes, egg checkboxes, boss-level dropdown) all driven by a hardcoded `levels = [1, 2, 3, 4, 5, 6]` array, even though PoracleNG accepts any positive integer. Users with Elite Raids (level 7) or custom server schemes had to configure those via the bot's `!command` interface; the UI silently locked them out. Replace all three sites with a new `<app-level-selector>` shared component — a Material 3 chip listbox in three sections: - STANDARD: T1-T5 - SPECIAL: Mega (6), Elite (7), plus "Any" (9000) when showAny=true - CUSTOM: any user-added integer, persisted per-user in localStorage Power users add a custom level via an inline "+ Add level" affordance that transforms into a numeric input. The chip then persists across dialog opens (one-click selection on subsequent alarms) and seeds itself from saved alarm data on open, so editing an existing level-42 alarm renders the chip pre-selected rather than orphaned. Single source of truth for label resolution lives in `core/models/raid-level.models.ts`. `resolveLevel(value)` maps any integer to the right LevelOption — adopted by raid-list cards too, so the dialog and the cards now speak the same vocabulary ("Elite", not "Level 7" vs "7" on different surfaces). Edge cases: - 0 / negatives / non-integers in custom input -> inline validation error - 9000 in custom input -> snaps to the "Any" chip (no duplicate) - duplicate of built-in -> flashes existing chip + selects, no new entry - 20-entry LRU cap on the localStorage palette i18n: new `RAIDS.LEVEL.*` keys added in all 11 locales with English fallbacks for non-en (translation volunteers can localize later, per discussion #211). Bonus correctness: the boss tab used to default level=0 ("any") but PoracleNG's canonical wildcard sentinel is 9000. New alarms now use 9000; old alarms with 0 continue to work and edit fine. 37 new unit tests across the model, store, pipe, and component. Closes #259, reported by @prof-miles0. * fix(raids): address #259 review — compact layout, per-type palette, unblock save Follow-up on d58752e (the initial #259 redesign), addressing visual, correctness, and backend-validation issues found during testing. UI / UX - Collapse the three-section (Standard/Special/Custom) chip layout into one wrapping row per picker. Categories are encoded in chip content (T1 / "Mega · 6" / "42 ⊗") rather than container labels; cuts dialog height roughly in half. - Replace the heavy mat-form-field "+ Add custom level" with a chip-sized inline numeric input. Enter commits, Esc cancels, blur commits. Help text only renders when the input is open or there's a validation error. - Override Material 3 selected-chip font-weight so the selected state actually pops; bind `hideSingleSelectionIndicator` to `!multiple` so multi-select chips get a leading checkmark. - Cap card star icons to levels 1-7 (was 1-100) — alarms at level 23 no longer render 23 stars in the card. Per-type palette - Adding a custom level on the raid picker was leaking it into the egg and boss pickers. `CustomLevelStore` now keys palettes by `paletteKey` ("raid" / "egg" / "boss"), each persisted to its own localStorage slot. Required `paletteKey` input on `<app-level-selector>`. Any chip surfaced where PoracleNG actually honors it - Raid + boss pickers show the `Any` chip (PoracleNG treats level=9000 as the wildcard sentinel — see trackingRaid.go). - Egg picker deliberately omits Any: PoracleNG's trackingEgg.go only validates level >= 1 with no wildcard semantic, so an "Any egg" alarm at 9000 would simply never fire. Server-side fix that was blocking custom-level alarms - `[Range(0, 10)]` on `RaidCreate.Level`, `RaidUpdate.Level`, `EggCreate.Level`, `EggUpdate.Level` was rejecting custom integers (8+) and the new Any=9000 sentinel with 400 Bad Request before they could reach PoracleNG. Relaxed to `[Range(0, int.MaxValue)]` matching PoracleNG's actual range. Label vocabulary consistency - Edit dialog (raid/egg) now uses the same `resolveLevel` resolver as the cards via the new `LevelLabelPipe` — an alarm at level 7 reads "Elite" on the card AND in the edit dialog (was "Level 7" in the dialog before). Egg image alt-text in the card list now uses the pipe too. Error UX - Removing a custom chip (`⊗`) opens a 3-second snackbar with Undo — accidental click is recoverable; intentional removal still wipes the palette entry. State-machine clarity - `addInputOpen: signal(boolean)` replaced with an explicit `addMode: signal<'closed' | 'open'>` and named `isAddClosed()` / `isAddOpen()` getters in the template — removes the `!` negation pattern that prior renders sometimes appeared to misread. Tests - Updated `custom-level-store.service.spec.ts` for the keyed API. - Updated `level-selector.component.spec.ts` to set `paletteKey` per test and assert per-key isolation. - 697/697 frontend tests pass, 1063/1063 backend tests pass. i18n - Added `RAIDS.LEVEL.REMOVED` and `COMMON.UNDO` keys in all 11 locales (English placeholder text for non-en — translation volunteers per discussion #211). * fix(raids): align level selector with WatWowMap masterfile (19 named levels) Builds on the v2 review-pass (2c2f0aa). Follow-up driven by the issue reporter pointing to the canonical Pokémon GO raid level vocabulary in the WatWowMap masterfile — there are 19 named raid types (1-Star through Coordinated 2), not 7, and the prior UI labeled level 7 as "Elite" when the masterfile says it's "Mega Legendary". Backend - `GET /api/masterdata/raid-levels` returns the canonical list with per-level integer, category, and singular/plural English names. - New `IRaidLevelService` / `RaidLevelService` returns a baked-in snapshot of the masterfile. A TODO documents how to swap the implementation for a live fetch from raw.githubusercontent.com/WatWowMap/Masterfile-Generator without changing the wire contract. - 6 new unit tests cover the service + controller endpoint. Frontend - `RaidLevelService` (Angular) calls the new API on first dialog use, caches the result in a signal. Falls back to `KNOWN_LEVELS` baked-in constants when the network fails or before resolve. - `raid-level.models.ts` rewritten around 19 canonical levels keyed by `RAIDS.LEVEL.RAID_1` through `RAID_19` (plus `_PLURAL` variants). Removed the bogus `T1`-`T5` / `MEGA` / `ELITE` keys. - `LevelSelectorComponent` simplified to a `pickerType` input (`'raid' | 'egg' | 'boss'`). Inputs: • raid → primary chips 1-7, overflow menu for 8-19, Any chip, +Add • egg → star tiers (1-5) only, +Add (no overflow, no Any) • boss → single-select with the same primary + overflow as raid "More raid types…" overlay menu (mat-menu) surfaces the 12 less common levels without crowding the chip row. - i18n: 19 singular + 19 plural keys in all 11 locales, with English placeholders for the 10 non-en locales (volunteers per #211). - Card star icons now render only for the literal 1-5 "N Star Raid" tier (was 1-7, producing ~23 stars for custom-level alarms). - Label vocabulary consistency: alarm at level 7 now reads "Mega Legendary Raid" on the card and in the edit dialog (was "Elite" on the card, "Level 7" in the edit dialog). Forward compatibility - Any positive integer remains addable via the `+ Add` chip. When the WatWowMap masterfile adds raid_20+ in the future, the backend service can pick it up automatically (once the live-fetch path is wired); existing custom alarms at that level continue to work. Tests: 711/711 frontend, 1069/1069 backend. Lint + prettier clean. * fix(raids): shorten labels, ephemeral palette, review fixes Follow-up on 12be778 (v3 masterfile alignment). User feedback + internal PR review revealed several issues; this commit addresses them. User feedback - Custom levels typed via `+ Add` were persisting across modal close AND page refresh because the per-type palette was backed by localStorage. Deleted CustomLevelStore entirely; LevelSelector now tracks the palette in a local `customPalette` signal that lives for the component lifetime only. Refresh or close-and-reopen wipes typed-but-not-saved chips. Existing alarms still seed the palette through the `[value]` input. - Chip labels were too long ("Mega Legendary Raid"), and the same string caused "All Mega Legendary Raid Raids" double-Raid in card titles. Dropped the "Raid" suffix from the 19 RAID_N keys in all 11 locales — chips now read "Mega Legendary", "Legendary", "1 Star", etc. The card-title template (`RAIDS.ALL_LEVEL_RAIDS = "All {{level}} Raids"`) supplies the noun once; result reads natural English. Also dropped the unused `pluralKey` from `LevelOption` and the `_PLURAL` i18n keys (the shortened `RAID_N` strings work in both card and chip contexts). Backend `RaidLevelInfo.Name` is now the modifier form ("Mega Legendary") while `NamePlural` retains the full "Mega Legendary Raids" for any future standalone use. Review fixes (MUST FIX) - Snackbar undo subscription in `LevelSelector.removeCustom` now pipes through `takeUntilDestroyed(this.destroyRef)` so closing the dialog mid-toast can't fire the callback against a destroyed component. - `raid-list.getRaidLevelName` was bypassing the live `RaidLevelService.byValue()` and using the baked-in `KNOWN_LEVELS` constant — cards would drift from the dialog if the API ever extended the canonical list. Cards now consult the service first, fall back to the baked-in resolver. `raid-list.ngOnInit` primes the cache so the list page doesn't depend on a dialog open. - `LevelLabelPipe` now detects ngx-translate's "key not found" pass-through (translated string === key) and falls back to "Level {n}" instead of leaking "RAIDS.LEVEL.RAID_20" into the UI. Graceful degradation for future masterfile additions before locales catch up. Review fixes (SHOULD FIX) - `raid-edit-dialog.formatLevel` deleted — the dialog now injects `LevelLabelPipe` and calls `.transform()`, eliminating the duplicate label-resolution logic. Single source of truth. Analyzers - xUnit2032 in `MasterDataControllerRaidLevelsTests`: switched `Assert.IsAssignableFrom<T>` to `Assert.IsType<T>(..., exactMatch: false)`. - CA1707 in `RaidLevelServiceTests` and the new controller test: test method names renamed to PascalCase to match the project's preferred style and silence the analyzer. Dev workflow - New `proxy.conf.json` forwards `/api/*` and `/auth/*` from the Angular dev server to the API. `environment.development.ts` apiUrl set to `''` so all HTTP calls are same-origin from the browser's view — works identically for `ng serve` + proxy and for the production single-port deployment. OAuth flows survive the proxy because Host is preserved. Tests: 700/700 frontend (+1 fallback test), 1069/1069 backend. Lint + prettier + dotnet format (scoped) all clean. * docs: cover the level-selector redesign + ng-serve proxy workflow - features/alarms.md: replace the generic "tier" wording on Raids/Eggs rows with pointers to a new "Raid level selector" subsection that documents the chip layout, the 19 masterfile-defined raid types, primary vs overflow split per pickerType, the ephemeral custom-add affordance, and the wildcard sentinel. - architecture/backend.md: add a "Raid level service" section documenting IRaidLevelService, GET /api/masterdata/raid-levels, the baked-in fallback + live-fetch upgrade path, and the [Range] relax that lets PoracleNG-accepted custom integers pass validation. Also register the singleton in the service lifetimes table. - architecture/frontend.md: document LevelSelectorComponent + the Angular RaidLevelService consumer (signal cache, baked-in fallback, LevelLabelPipe missing-key fallback), and the ephemeral palette behavior. - getting-started/development-setup.md: the "proxies API requests" claim is now accurate thanks to the committed proxy.conf.json — describe it explicitly (changeOrigin: false to preserve Host for OAuth callbacks), note the empty apiUrl + same-origin dev flow, and document the --port override for matching a non-default Discord OAuth redirect URI.
The standalone `dotnet run` DataProtection fallback writes keys to Applications/Pgan.PoracleWebNet.Api/data/ (Program.cs uses ./data when DATA_DIR is unset), and the published Angular bundle is copied into the API host at Applications/Pgan.PoracleWebNet.Api/wwwroot/. Both are regenerated build/runtime output and were showing up as untracked. The existing Data/dataprotection-keys/ rule only covered the Data project path, not the API host path. Added both so a local build/run leaves a clean working tree.
Poracle's `pvp_ranking_cap` field was never surfaced by PoracleWeb.NET, so
every PvP alarm defaulted to matching all caps (L50 + L51) server-side.
New users got flooded with L51 noise even when admins configured
`tracking.defaultUserTrackingLevelCap = 50` in Poracle.
This wires `pvp_ranking_cap` end-to-end and mirrors the PoracleWeb PHP
passthrough pattern — no new admin setting; the cap list and default
come from Poracle's existing `/api/config/poracleWeb` response
(`pvpCaps`, `defaultPvpCap`).
Backend:
- `Monster` / `MonsterCreate` / `MonsterUpdate` / `MonsterEntity`:
new `PvpRankingCap` field (0 = all caps).
- `AlarmMappingExtensions.ToMonster` + `ApplyUpdate`: mapping + null-skip.
- `PoracleConfig.PvpCaps` (list) and `DefaultPvpCap` (int), parsed in
`PoracleApiProxy.GetConfigAsync`. Accepts number or string caps
(PoracleJS is inconsistent on this).
- `QuickPickService.SafeMonsterFilterKeys`: allow `pvpRankingCap` so
quick-pick authors can pin a cap per definition.
Frontend:
- `Monster.pvpRankingCap`, `PoracleServerConfig` interface.
- New `PoracleConfigService` caches `/api/config` behind a signal.
- `pokemon-add-dialog`: `mat-button-toggle-group` under the PvP league
field with `All` / `L{cap}` options. Pre-fills from `defaultPvpCap`.
Italic "Default · from Poracle config" hint disappears the moment
the user changes the selection. Hidden entirely when Poracle offers
only one cap.
- `pokemon-edit-dialog`: same toggle group; shows stored cap on load.
Tests (+1066 backend, +658 frontend):
- Mapping tests cover `PvpRankingCap` in `ToMonster`, null-skip
`ApplyUpdate`, and explicit-overwrite cases.
- `ConfigControllerTests` verify `PvpCaps` + `DefaultPvpCap` flow
through the controller unmodified.
- `monster.service.spec.ts` fixtures updated with the new field.
) * feat(raids): RSVP notification mode for raid and egg alarms (#233) Surface the existing `rsvpChanges` field as a three-option mode toggle (Matches only / Matches + RSVP / RSVP only) in the raid & egg add/edit dialogs, with a matching pill on alarm cards. The field, mapping, and dialog form binding already exist on main; this adds the missing UI control and the third mode value. - New self-contained shared components: rsvp-toggle (FormControl input) and rsvp-pill (numeric value input). - Widen [Range(0, 1)] -> [Range(0, 2)] on RsvpChanges in RaidCreate, RaidUpdate, EggCreate, EggUpdate so mode 2 isn't rejected with HTTP 400. - Wire rsvp-toggle into both dialogs (raid + egg) bound to the rsvpChanges form control; rsvp-pill onto raid/egg cards. - RSVP i18n keys added to all 11 locales (incl. new pl/sv/da). - RsvpRangeValidationTests covering the 0..2 range and null updates. Salvaged from #235, dropping that branch's raid-dialog section-refactor which conflicted with the #280 level-selector restructure already on main. * feat(raids): set edit-in-place bit when RSVP updates are enabled PoracleNG's `clean` field is a bitmask (bit 1 = auto-delete, bit 2 = edit-in-place). Raid/egg RSVP updates are PoracleNG's first edit-tracking consumer: with the edit bit set, RSVP count changes edit the existing alert in place; without it, each change sends a brand-new message. Verified against PoracleNG main (processor/internal/dts/renderer.go): the per-user editKey is gated on db.IsEdit(user.Clean), so RSVP mode alone is not enough — the edit bit must accompany it. - raid/egg add + edit dialogs: OR in `clean` bit 2 when rsvpChanges >= 1. - edit dialog: read the auto-delete toggle from `clean & 1` (was `clean === 1`) so it round-trips correctly once bit 2 can be set. - raid-list: new isAutoDelete() helper masks bit 1 for the card auto-delete badge (Angular templates can't express bitwise &). - CHANGELOG + docs note the edit-in-place coupling. * style(raids): align RSVP toggle + pill with the app design system The RSVP components were copied from a pre-#280 branch and used a bespoke look (stacked icon+label+description button rows, hardcoded indigo pill) that didn't match the current Material 3 language. rsvp-toggle: rebuilt to mirror the #237 PvP-cap pattern — a <fieldset> with an uppercase <legend> section header, a plain full-width segmented mat-button-toggle-group (no icons/no inline descriptions), and a single hint below that shows the selected mode's description (so the "RSVP only silences without a scanner" caveat stays visible). Uses --text-muted / --text-secondary tokens instead of raw opacity. rsvp-pill: now a .clean-tag-style status badge themed with --mat-sys-primary / --mat-sys-on-primary (was hardcoded #3f51b5). Moved out of the stat grid into card-top-actions so it sits beside the auto-delete tag as a sibling status indicator. Specs updated for the new structure; docs reworded (themed badge, not "indigo pill"). prettier/lint/jest(712)/ng build all green. * chore: keep Dockerfile.local out of the PR (local test artifact) * style(raids): square off the RSVP toggle ends (--mat-button-toggle-shape) M3 defaults the segmented button group to a pill radius; override the shape token to 4px so the end segments read as a crisp Material control rather than a rounded pill. * fix(raids): stop RSVP toggle overflow + vertically center labels - fieldset defaulted to min-inline-size: auto and overflowed its container (right edge clipped); force min-inline-size: 0 / width 100% / border-box. - flex-center the button-toggle label content so single-line options align with the wrapped 'Matches + RSVP updates' segment. * fix(raids): RSVP toggle overflow (drop fieldset, border-box) + drop dead i18n key - Replace the <fieldset>/<legend> with a plain block + border-box group so the segmented control fits the dialog width (right edge was clipped); the toggle group keeps its aria-label for the accessible name. - Remove the now-unused RSVP_HINT key from all 11 locales (the restyle replaced the static hint with the per-mode description). * fix(raids): widen Clean [Range] to bitmask 0-7 so RSVP edit bit saves The RSVP edit-in-place coupling sets clean bit 2 (clean = 2 or 3), but Clean was still [Range(0, 1)] on RaidCreate/RaidUpdate/EggCreate/EggUpdate -> creating/editing an RSVP alarm failed model validation with HTTP 400 ('failed to create alarm'). clean is a PoracleNG bitmask (auto-delete | edit-in-place | summary); widened to [Range(0, 7)]. Added validation tests. * style(raids): hide RSVP toggle selection checkmark for more label room Single-select group, so the M3 checkmark only ate ~24px and pushed labels to wrap. hideSingleSelectionIndicator drops it; the accent fill + bold already signal the selected mode.
node:22-alpine bundles npm 10.9.x, which rejects the npm-11-generated package-lock.json with EUSAGE (pruned chokidar/readdirp optional peers), so docker build / compose up --build failed from source. CI already pins npm 11 for this; mirror it in the Dockerfile's angular-build stage.
…292 PR1) (#294) PoracleNG reads `clean` as a 3-bit bitmask (1=auto-delete, 2=edit-in-place, 4=summary) but PoracleWeb treated it as a boolean for 8 of 10 alarm types, which (a) 400'd bot-set values >1 via [Range(0,1)] and (b) clobbered bits 2/4 on every web edit. This is the invisible correctness fix; the lure-edit and quest-summary user controls follow in PR2. - New CleanFlags helper (Core.Models) + clean-flags.ts twin with Preserve(existing, mask, changes) read-modify-write; unit tests for both. - Widen Clean [Range(0,1)] -> [Range(0,7)] on the 16 Monster/Quest/Invasion/ Lure/Nest/Gym/MaxBattle/FortChange Create+Update models (Raid/Egg already done). - CleaningService: preserve unknown bits on bulk-clean toggle; bit-aware AllClean. - All 10 alarm types' edit dialogs preserve unknown bits on save and read auto-delete via the bit; list cards + profile overview gate the badge via an isAutoDelete() method (Angular templates can't parse bitwise &). - Fix the raid/egg RSVP save dropping bit 4; fix the quick-pick apply clobber. - Tests: CleanFlags, clean-range validation (8 types), CleaningService bit preservation, mapping round-trip. Backend 1324 pass; frontend 743 pass.
…PR2) (#295) * feat(alarms): lure edit-in-place + quest daily-summary controls (#292 PR2) Surfaces the two remaining meaningful clean bits as user controls, building on PR1's CleanFlags helper and preservation fixes. - Lure add+edit dialogs: "Edit message in place" toggle (clean bit 2), default off, edit-dialog inits from isEdit() and save composes via preserve(clean, AUTO_DELETE|EDIT, ...) so the summary bit survives. - Quest add+edit dialogs: "Daily summary" toggle (clean bit 4), default off, same preserve pattern; hint notes it needs a summary schedule on the bot. - Card badges: lure edit (--mat-sys-secondary), quest summary (--mat-sys-tertiary), gated via methods, matching .clean-tag/.rsvp-tag. - i18n: LURES.EDIT_* / QUESTS.SUMMARY_* added + translated in all 11 locales. - Only lure/quest get controls (the only types whose PoracleNG processor reads the bit). New dialog specs cover init-from-bit + save-preserves-bits. Frontend: prettier/eslint/build clean, jest 781 pass. No backend change. * docs(#292): document clean delivery modes (alarms doc, in-app help, CLAUDE.md) - docs/features/alarms.md: new 'Delivery & message modes' section covering the clean bitmask (auto-delete / edit-in-place / daily-summary), which types support each, and that PoracleWeb preserves bot-set bits (gh-pages). - In-app Help (HELP.CONTENT_DELIVERY): appended an 'Edit in place & summaries' block describing the lure edit + quest daily-summary modes, translated in all 11 locales. - CLAUDE.md: dev note on the clean bitmask + CleanFlags helper + the Angular 'templates can't parse &' gotcha. * docs(rsvp): document RSVP notification mode (alarms doc + in-app help, 11 locales) Mirrors the #292 delivery-mode docs for RSVP (#233), authored by a tech-writer swarm: - docs/features/alarms.md: new '### RSVP updates (raids & eggs)' subsection under Delivery & message modes, explaining the 3 modes + edit-in-place coupling + the scanner caveat. - In-app Help (HELP.CONTENT_DELIVERY): appended an 'RSVP updates' block in all 11 locales, alongside the edit/summary block. Jest 781 pass; all 11 i18n files valid JSON.
Bumps [peter-evans/create-pull-request](https://github.com/peter-evans/create-pull-request) from 7 to 8. - [Release notes](https://github.com/peter-evans/create-pull-request/releases) - [Commits](peter-evans/create-pull-request@v7...v8) --- updated-dependencies: - dependency-name: peter-evans/create-pull-request dependency-version: '8' 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 [marocchino/sticky-pull-request-comment](https://github.com/marocchino/sticky-pull-request-comment) from 2 to 3. - [Release notes](https://github.com/marocchino/sticky-pull-request-comment/releases) - [Commits](marocchino/sticky-pull-request-comment@v2...v3) --- updated-dependencies: - dependency-name: marocchino/sticky-pull-request-comment 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/upload-artifact](https://github.com/actions/upload-artifact) from 4 to 7. - [Release notes](https://github.com/actions/upload-artifact/releases) - [Commits](actions/upload-artifact@v4...v7) --- updated-dependencies: - dependency-name: actions/upload-artifact 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/github-script](https://github.com/actions/github-script) from 7 to 9. - [Release notes](https://github.com/actions/github-script/releases) - [Commits](actions/github-script@v7...v9) --- updated-dependencies: - dependency-name: actions/github-script dependency-version: '9' 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 Microsoft.NET.Test.Sdk from 18.5.1 to 18.6.0 --- updated-dependencies: - dependency-name: Microsoft.NET.Test.Sdk dependency-version: 18.6.0 dependency-type: direct:production update-type: version-update:semver-minor dependency-group: microsoft ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps the eslint group in /Applications/Pgan.PoracleWebNet.App/ClientApp with 5 updates: | Package | From | To | | --- | --- | --- | | [@typescript-eslint/eslint-plugin](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/eslint-plugin) | `8.59.4` | `8.60.1` | | [@typescript-eslint/parser](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/parser) | `8.59.4` | `8.60.1` | | [@typescript-eslint/utils](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils) | `8.59.4` | `8.60.1` | | [eslint-import-resolver-typescript](https://github.com/import-js/eslint-import-resolver-typescript) | `4.4.4` | `4.4.5` | | [eslint-plugin-prettier](https://github.com/prettier/eslint-plugin-prettier) | `5.5.5` | `5.5.6` | Updates `@typescript-eslint/eslint-plugin` from 8.59.4 to 8.60.1 - [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.60.1/packages/eslint-plugin) Updates `@typescript-eslint/parser` from 8.59.4 to 8.60.1 - [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.60.1/packages/parser) Updates `@typescript-eslint/utils` from 8.59.4 to 8.60.1 - [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.60.1/packages/utils) Updates `eslint-import-resolver-typescript` from 4.4.4 to 4.4.5 - [Release notes](https://github.com/import-js/eslint-import-resolver-typescript/releases) - [Changelog](https://github.com/import-js/eslint-import-resolver-typescript/blob/master/CHANGELOG.md) - [Commits](import-js/eslint-import-resolver-typescript@v4.4.4...v4.4.5) Updates `eslint-plugin-prettier` from 5.5.5 to 5.5.6 - [Release notes](https://github.com/prettier/eslint-plugin-prettier/releases) - [Changelog](https://github.com/prettier/eslint-plugin-prettier/blob/main/CHANGELOG.md) - [Commits](prettier/eslint-plugin-prettier@v5.5.5...v5.5.6) --- updated-dependencies: - dependency-name: "@typescript-eslint/eslint-plugin" dependency-version: 8.60.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: "@typescript-eslint/parser" dependency-version: 8.60.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: "@typescript-eslint/utils" dependency-version: 8.60.1 dependency-type: direct:development update-type: version-update:semver-minor dependency-group: eslint - dependency-name: eslint-import-resolver-typescript dependency-version: 4.4.5 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint - dependency-name: eslint-plugin-prettier dependency-version: 5.5.6 dependency-type: direct:development update-type: version-update:semver-patch dependency-group: eslint ... Signed-off-by: dependabot[bot] <support@github.com> Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [actions/setup-node](https://github.com/actions/setup-node) from 4 to 6. - [Release notes](https://github.com/actions/setup-node/releases) - [Commits](actions/setup-node@v4...v6) --- updated-dependencies: - dependency-name: actions/setup-node 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>
) Surface the Poracle `notes` field on channel-type users in the admin user list so admins can disambiguate channels that share the same name across different servers. PoracleJS/PoracleNG can auto-fill notes with the Discord guild name and channel category; that column already existed on the humans table but was dropped at every layer. Reuses data PoracleNG already provides — no new database queries and no live Discord API calls: - Single-user reads come from the PoracleNG human JSON (HumanService .DeserializeHuman now reads `notes`). - The admin bulk list maps the `notes` column through the existing read (Human model + EntityMappingExtensions); projected by GET /api/admin/users and GET /api/admin/users/by-id. Frontend renders notes as a muted second line under the name with a tooltip, and the admin search box matches against it. A notesLabel() normalizer trims whitespace and strips a surrounding quote layer so PoracleJS/NG's quoted-empty `""` sentinel (and any JSON-quoted note) doesn't render a stray value. Tests: extend HumanEntity.ToModel mapping test and the admin.service spec mock.
) * feat: add admin setting to disable user-submitted geofences (#297) From discussion #214: let operators turn off the custom/user-drawn geofence feature via a new `disable_user_geofences` site setting, reusing the existing `disable_*` feature-gate pattern. Backend - DisableFeatureKeys.UserGeofences constant. - Gate the "provide a geofence" actions on UserGeofenceController (create, submit-for-review, GeoJSON import) with [RequireFeatureEnabled], plus a defense-in-depth IFeatureGate.EnsureEnabledAsync guard in UserGeofenceService .CreateAsync (also covers import, which funnels through it) and .SubmitForReviewAsync. - Reads, delete, activate/deactivate and the admin review queue stay ungated so existing geofences keep working and are still served by /api/geofence-feed. - SettingsMigrationService CategoryMap + BooleanKeys carry the key. Frontend - Hide the My Geofences nav item (disableKey) and guard the /geofences route (disabledFeatureGuard) -> redirect to dashboard with the existing ERROR.FEATURE_DISABLED toast; the 403 interceptor handles direct API hits. - Admin settings toggle in the Features group. - ADMIN_SETTINGS.DISABLE_USER_GEOFENCES_* label/description added and translated across all 11 locales. Tests: UserGeofenceService gate tests for CreateAsync and SubmitForReviewAsync; existing test setup updated for the new IFeatureGate dependency. * feat: hide admin "User Geofences" review queue when disabled Extend disable_user_geofences to also hide the admin-facing geofence review queue: add the disableKey to the /admin/geofence-submissions nav item, make the adminNavItems computed honour isFeatureDisabled (it previously ignored disableKey), and guard the route with disabledFeatureGuard. Enabling the toggle now hides the whole feature end to end. The admin review backend stays ungated so any pre-existing submissions aren't bricked and reappear if the feature is re-enabled.
New alarms always opened pre-set to Areas; radius users had to switch the location mode and re-type a distance on every add. Add a user-level default. - AlertDefaultsService persists mode + default distance (km) to localStorage, mirroring the theme/accent/language pattern; distance clamped 0.1-100 km. - New Alert Defaults dialog (user menu) reusing the distance-dialog idiom: Areas/Distance mode cards, km input, live delivery preview. - All 9 add-alarm dialogs (Pokemon, Raids/Eggs, Quests, Invasions, Lures, Nests, Gyms, Fort Changes, Max Battles) and the quick-pick apply dialog seed distanceMode/distanceKm from the service instead of hard-coded values. - ALERT_DEFAULTS.* + MENU.ALERT_DEFAULTS i18n keys across all 11 locales. - Service + dialog unit tests; CHANGELOG entry. - Docs: gh-pages site (features/alarms.md "Default delivery scope" section + Quick Picks note, index.md + README feature bullets), in-app Help (Delivery Settings section), and CLAUDE.md developer note. Tracks discussion #217.
) #301 changed the quick-pick apply dialog (and every add-dialog) to seed the delivery form's distanceKm from AlertDefaultsService.defaultDistanceKm() (default 1 km), so the radius is pre-filled if the user switches to Distance mode. The quick-pick-apply-dialog spec still asserted the pre-#301 default of 0, so it failed and turned the Frontend (Angular) CI red on main from the #301 merge onward. The component is correct and matches all sibling add-dialogs (in Areas mode apply() sends 0 m regardless of distanceKm); only the assertion was stale. Updated it to expect the AlertDefaultsService default (1) with a comment. Verified: full Jest suite green (792/792), prettier + eslint clean.
* feat(quests): quest summary delivery schedule management UI (#300) Implements the deferred summary_schedules management UI from #292 — the piece the per-alarm quest "Daily summary" clean-bit toggle (#295) depends on. Users can now view, edit, clear, and force-deliver ("Send summary now") their quest summary schedule, wired to PoracleNG's /api/summaries endpoints. Backend - IPoracleSummaryProxy / PoracleSummaryProxy mirroring PoracleHumanProxy: X-Poracle-Secret, Uri.EscapeDataString, raw-JSON active_hours pass-through, 404 -> null, 503 -> SummaryBackendUnavailableException (transient, not feature-off). Distinguishes 400/404/500 rather than collapsing them. - SummaryScheduleController: GET/GET{alertType}/PUT/DELETE/POST trigger, all derived from this.UserId (JWT) with NO {userId} route segment (IDOR-safe); [RequireFeatureEnabled(disable_quests)]; trigger rate-limited test-alert (5/60s), writes auth-read; quest-only alertType allow-set. - Capability from tracking.quest_summary_enabled via the config proxy, surfaced as questSummaryEnabled in auth/me (Golbat-style 200 boolean), IMemoryCache 5-min. Defaults true when the field is absent from a successful config, degrades to false on fault. - Extracted ProfileController.ValidateActiveHours into a shared ActiveHoursValidator; both controllers and the tests re-pointed. Frontend - SummaryScheduleService (CRUD + trigger, 404 -> null, capability signal). - SummaryScheduleDialogComponent reusing ActiveHoursEditorDialogComponent and LocationWarningComponent; staggered schedule pills, empty/loading states, accent-theme tokens, reduced-motion + ARIA; client cooldown/dedup on trigger. - Quests toolbar menu entry gated on capability; SUMMARY_DISABLED_HINT on the quest dialogs when off (clean-bit logic untouched). - New QUESTS.SUMMARY_SCHEDULE_* keys across all 11 locales. Tests: PoracleSummaryProxyTests, SummaryScheduleControllerTests, SummaryCapabilityServiceTests, ActiveHoursValidationTests (re-pointed), and summary-schedule service + dialog Jest specs. Verified locally: dotnet test 1382 pass; ng build (AOT) ok; jest feature suites pass; eslint + prettier clean. * docs(changelog): add quest summary delivery schedule UI entry (#300) * fix(quests): return 200 empty schedule (not 404) when no summary schedule exists Opening the Quest summary delivery dialog calls GET /api/summary-schedules/{alertType}, which returned 404 when the user had no schedule yet — a normal empty state. The SPA's global error interceptor toasts ERROR.NOT_FOUND on any non-silent 404, so users saw 'The requested resource was not found.' on first open. Return 200 with an empty schedule (active_hours = []), consistent with the list endpoint returning []. The dialog renders its empty state and no toast fires. * feat(quests): honest capability default + Send-now expectation copy (#300) (1) Default quest-summary capability to OFF when PoracleNG's tracking.quest_summary_enabled is absent, instead of ON. When the flag is unset PoracleNG's matcher never buffers quests, so showing the UI was a dead-end (schedule + per-alarm bit set, but nothing ever delivered). PoracleConfig.QuestSummaryEnabled now defaults false; the menu appears only when the bot has the feature explicitly enabled. PoracleWeb stays read-only on Poracle config — no toggle here. (2) "Send summary now" now sets expectations: it flushes only quest matches PoracleNG has buffered since the last summary, so an empty send isn't surprising. Added QUESTS.SUMMARY_SCHEDULE_SEND_NOW_HINT (all 11 locales), shown under the schedule pills and as the button tooltip. Verified: dotnet test 1382 pass; ng build (AOT) ok; jest + eslint + prettier clean. * fix(quests): read quest_summary_enabled from /api/config/values, not /api/config/poracleWeb The capability probe read tracking.quest_summary_enabled from GetConfigAsync() — which hits /api/config/poracleWeb, a PoracleWeb-specific view that does NOT include the [tracking] section. So the flag was never read. It happened to "work" only while the default was true-when-absent; once that flipped to off-when-absent, the menu could never appear even with the flag set on the bot. Add IPoracleApiProxy.GetQuestSummaryEnabledAsync() which reads the effective value from /api/config/values (values.tracking.quest_summary_enabled) — the config-editor endpoint that exposes the merged-with-defaults config. SummaryCapabilityService now uses it: true -> enabled, false/absent/fault -> hidden. Removed the dead parse in GetConfigAsync and the now-unused PoracleConfig.QuestSummaryEnabled property; rewrote SummaryCapabilityServiceTests against the new method. Verified: dotnet test 1381 pass. * style(quests): mobile refinements for the summary schedule dialog - openSummaryDialog now passes maxWidth: '95vw' (matches the reused active-hours editor) so the dialog uses the full phone width instead of Material's 80vw default. - At <=600px: action buttons get a 44px min-height (comfortable thumb targets), the "Send summary now" button goes full-width as a clear primary action, and the flex spacer is dropped so the secondary buttons pack cleanly. Verified: ng build (AOT) ok, jest + eslint + prettier clean. * docs: document quest summary delivery (MkDocs site + in-app help) gh-pages (MkDocs): - New features/quest-summary-schedules.md — user + operator guide with a mermaid buffer/delivery diagram, the two-part model (per-alarm Daily summary toggle + per-user delivery schedule), the schedule editor, Send-now semantics, the per-user (not per-profile) note, validation table, timezone/location warning, and a "For server operators" section (quest_summary_enabled + processor bind). - mkdocs.yml: add the page to the Features nav. - troubleshooting.md: "Quest summary delivery menu is missing" and "Send summary now delivers nothing" entries. In-app help: - help-sections.ts: new "Quest Summary Delivery" section (schedule_send / amber). - i18n: HELP.SECTION_QUEST_SUMMARY(+_SUB) and HELP.CONTENT_QUEST_SUMMARY added and fully translated for all 11 locales (da, de, en, es, fr, it, nl, pl, pt, pt-BR, sv), reusing the existing UI terminology (menu name, Edit schedule, Send now). - Updated the en Delivery help section's "Daily summary" line to point at the new schedule UI instead of "configure on the bot". Verified: jest (help + i18n parity) pass, ng build (AOT) ok, eslint + prettier clean. * refactor(quests): code-review cleanups for the summary-schedule feature - Remove the unused auth/me quest-summary capability "fast-path": nothing consumed UserInfo.questSummaryEnabled / auth.service.questSummaryEnabled — the UI gates on the dedicated GET /api/summary-schedules/capability endpoint. Drops a per-auth/me capability call (a hot path) and dead frontend state. Removed the property, AuthController dependency + Me() call, the TS field + computed, and the now-moot ISummaryCapabilityService args in the AuthController tests. - PoracleSummaryProxy now Encode()s the alertType path segment too (defense-in-depth consistency with userId), and the helper doc reflects it. - dotnet format applied to the changed files (whitespace + analyzer fixes: CA1861 array hoist in tests, redundant `public` removed from IPoracleApiProxy members). Verified: dotnet test 1381 pass, dotnet format 0 errors on changed files, ng build (AOT) ok, eslint + prettier clean, jest feature suites pass.
… matches the codebase (#305) `.editorconfig` had `csharp_preserve_single_line_statements = false`, which makes `dotnet format` explode the codebase's deliberate compact one-liners. The clearest victim is `AlarmMappingExtensions.cs`, whose ~98 null-skip mappings (`if (src.X != null) dest.X = src.X.Value;`) `dotnet format` rewrites into ~480 lines — a 5x readability regression. The single-line style is used throughout the mapping/guard code, so the setting contradicted the actual code (and was never enforced — CI does not run `dotnet format`). Flipping it to `true` makes `dotnet format` PRESERVE existing single-line statements (it never collapses multi-line into single-line), so the tool aligns with the codebase and `dotnet format --verify` stops flagging these files — with zero code changes. (Sibling `csharp_preserve_single_line_blocks` is left as-is; this targets the reported single-line *statement* explosion.)
Co-authored-by: hokiepokedad2 <38219945+hokiepokedad2@users.noreply.github.com>
… cut workflow (#307) The `release-changelog.yml` "Update comparison links" step used `grep ... | head -2 | tail -1`, which picks the *second*-newest version as the previous release — an off-by-one. Every cut release since has produced a wrong `[x.y.z]:` compare link (e.g. `[2.9.0]: compare/v2.7.0...v2.9.0` instead of `v2.8.0...v2.9.0`), and re-runs accumulated duplicate link-def lines. - Workflow: `head -2 | tail -1` -> `head -1`. The new version's link-def isn't added until the following sed, so the first existing version link is the immediately-preceding release. - CHANGELOG.md: regenerated the footer compare links so each points at its true predecessor tag (10 corrected), and removed 5 duplicate link-def lines. Only the footer link section changed — no changelog content touched. The three pre-tag entries (0.1.0–0.3.0) and the oldest tag (0.4.0) are left as-is.
…308) (#311) The admin settings page rendered two rows that both wrote to the allowed_languages key -- "Allowed UI Languages" (Features group) and "Allowed Languages" (Administration group). The component keys its value map by the setting key, so the two collapsed onto one entry: editing one changed the other, and a save could silently clobber the value with an empty string. Remove the redundant Administration-group row and its now-unused ADMIN_ALLOWED_LANGUAGES_LABEL / ADMIN_ALLOWED_LANGUAGES_DESC keys across all 11 locales, keeping the single Features-group control whose description matches the actual behavior.
The LanguageSelectorComponent — the only path from the web app to a user's Poracle DM language (human.Language, which controls alert text and Pokemon names) — was imported into app.ts but never rendered in any template, so it was unreachable dead code. The toolbar globe menu only calls i18n.use(), changing the Angular UI translation, not the bot's DM language. - Render the selector in a labelled "Notification language" section on the Areas & Location page, distinct from the toolbar display-language menu. - Reconcile its stale hardcoded 18-language list with I18nService.allLanguages (the 11 supported locales) so it can't drift again. - Seed the value from the persisted human.Language via a new GET /api/location/language endpoint (reconciles with bot-set changes) instead of trusting only localStorage; show success/failure feedback. - Remove the now-orphaned dead import and app-language-selector style from the app shell. - Add AREAS.NOTIFICATION_LANGUAGE / _DESC / SNACK_LANGUAGE_UPDATED / _FAILED i18n keys across all 11 locales. Whether localized Pokemon names actually render still depends on the Poracle server having that language's master data loaded — PoracleWeb's responsibility ends at writing human.Language. Service and component tests cover the new GET endpoint and the load/save/revert behavior.
Co-authored-by: hokiepokedad2 <38219945+hokiepokedad2@users.noreply.github.com>
…ator docs (#315) * fix(geofences): make region optional, set Koji __parent null for region-less geofences (#314) The geofence draw dialog forced the user to pick a region before saving, but the region list is derived from Koji's parent/child nesting. A flat Koji project has no regions, so the dropdown was a dead end and the geofence could not be saved. - Region is now optional in the draw dialog; the picker hides when no regions exist, and the "All Regions" sentinel clears the field instead of leaving a blank chip. - Admins can set or override the region at approval time (approval dialog plus a parentId/groupName override on ApproveSubmissionAsync and the approve endpoint). - KojiService now sends __parent: null (not 0) when parentId <= 0. A live probe confirmed Koji returns HTTP 500 "[GEOFENCE]: Does not exist" on __parent: 0 while still persisting the row, which would otherwise break every region-less promotion. The same guard is applied to the currently-unused PromoteGeofenceAsync. Adds KojiServiceTests plus controller/service/dialog coverage. Updates CHANGELOG. * docs(geofences): add operator guide for custom geofences, areas & regions Replace the single Custom Geofences page with a multi-page, operator-focused section under Features (MkDocs Material + Mermaid): - Overview, with a summary of how PoracleJS/PoracleNG reads geofences from PoracleWeb.NET instead of Koji, and why. - Key concepts: areas vs geofences vs regions. - Koji & regions: connection config plus how to set up regions, with the geofence-to-region relationship diagram. - Private geofences & promotion: private by default, and the promote-to-public flow. - Admin operations: review/approve/reject/delete, Discord forum, limits. - Troubleshooting: empty region dropdown, the combined feed, Koji errors. Wires the new section into mkdocs.yml nav and updates the home-page link.
…ased] check (#316) (#317) The old "Update Changelog" workflow ran after merge, auto-generated an entry, and pushed directly to `main` — which is protected, so the push was always rejected (GH006). It failed on every feat/fix PR, risked duplicate entries (its skip-guard keyed on PR number while manual entries reference the issue number), and fought the project's manual-changelog convention. Replace it with a verify-only check on pull_request that confirms the PR adds an entry under "## [Unreleased]". It never writes to the repo, so branch protection is a non-issue; it gives authors feedback before merge instead of red noise after. - Exempt PR types: docs/style/chore/ci/test/build. - Escape hatch: the `skip-changelog` label (re-runs on label change). - Detects new top-level entries by diffing the [Unreleased] block between base and head. - PR title/labels passed via env to avoid shell injection; permissions dropped to read. release-changelog.yml (the release-cut flow) is unchanged. Docs updated. Closes #316.
* feat(pokemon): multi-select forms in alarm add dialog (#318) The Form & Gender picker only allowed one specific form or "All Forms", so tracking e.g. Meowth's Alola and Galarian forms while ignoring Kanto meant adding each alarm by hand. PoracleNG models `form` as a single int per tracking entry (no array support on the wire), so instead of changing the data model end-to-end the add dialog reuses its existing per-Pokemon forkJoin fan-out and now emits one MonsterCreate per (Pokemon x selected form) combination. An empty selection means "all forms" (form 0), matching the previous default; a hint makes that explicit. Scope is the add dialog only -- the edit dialog stays single-form, since splitting one existing alarm into several on edit is a create-plus-delete operation. A dedicated `forms` control backs the multi-select, leaving the manual numeric form-id fallback on the original `form` control. New POKEMON.FORM_MULTI_HINT i18n key added and translated across all 11 locales. * test(pokemon): cover multi-select form fan-out in add dialog Adds pokemon-add-dialog.component.spec.ts verifying save() emits one MonsterCreate per (Pokemon x form): multi-form fan-out, empty selection => all forms (0), cartesian product across pokemon, manual numeric form-id fallback, snackbar total, and the no-selection no-op. MatSnackBar is providedIn MatSnackBarModule (imported by the standalone component), so it resolves from the element injector and shadows an environment-level useValue -- overridden via TestBed.overrideComponent.
The #319 squash merge anchored the new changelog bullet to its surrounding context (the notification-language line), which had since moved under ## [2.10.0] when v2.10.0 was cut (#313). As a result the multi-select forms entry landed under the already-released 2.10.0 section instead of [Unreleased], making it look like the feature shipped in 2.10.0 (it did not). Relocates the bullet to ## [Unreleased] > ### Added and corrects the wording ("translated across all 11 locales" — the locale translations landed in #319; the unit tests too).
Co-authored-by: hokiepokedad2 <38219945+hokiepokedad2@users.noreply.github.com>
…token (#322) * ci(changelog): auto-approve and auto-merge the release changelog cut The cut-changelog PR was opened with GITHUB_TOKEN, which (by GitHub's recursion guard) does not trigger the required CI checks (Backend/Frontend/Changelog). Those required checks therefore never reported, leaving every changelog-cut PR permanently BLOCKED and needing a manual admin merge (e.g. v2.11.0 / #321). Open the PR with a fine-grained PAT (secrets.CHANGELOG_PAT) instead, so the push/PR events trigger the required checks. Then approve from the github-actions[bot] identity (distinct from the PAT author, so it satisfies the 1-approval rule) and enable squash auto-merge. Degrades gracefully: when CHANGELOG_PAT is absent the PR is still opened with GITHUB_TOKEN (a warning is emitted) and the approve/merge steps are skipped, preserving today's manual-merge behavior. * ci(changelog): use a GitHub App token instead of a PAT Switch the auto-merge mechanism from a fine-grained PAT to a GitHub App installation token (actions/create-github-app-token). App tokens are minted per run and short-lived, so there is no token to rotate, and the app's permissions are scoped to exactly what it needs. The PR is authored by the app bot (a real, non-GITHUB_TOKEN identity), so push/PR events trigger the required CI checks. github-actions[bot] then approves (distinct identity -> satisfies the 1-approval rule) and squash auto-merge finishes the job. Falls back to GITHUB_TOKEN (manual merge, with a warning) when the app secrets are absent. Secrets: CHANGELOG_APP_ID, CHANGELOG_APP_PRIVATE_KEY.
…324) MasterDataService.loadForms() discarded every form named Normal, but for a species with a regional variant the Normal entry is the original/base form (e.g. Stunfisk lists Normal id 2246 for Unova and Galarian id 2345). That left only All Forms and Galarian, with no way to alert on Unova Stunfisk alone. Keep all real forms (form.id !== 0, including Normal) and only drop a Normal form when it is a species' lone form, where All Forms already covers it. Tests cover keep-when-sibling and drop-when-lone. Fixes #323
Co-authored-by: hokiepokedad2 <38219945+hokiepokedad2@users.noreply.github.com>
The mkdocs-material header version badge is baked into the static HTML at gh-deploy time from the GitHub Releases API. Since docs.yml only triggered on docs/ or mkdocs.yml changes, code-only releases (v2.11.0, v2.11.1) never rebuilt the site, leaving the badge frozen at v2.10.0. Add release:published and workflow_dispatch triggers so the docs (and badge) refresh on every release and on demand.
…s + docs (#328) * feat(auth): add generic external SSO / OIDC login provider (#327) Delegate PoracleWeb login to any external OAuth2/OpenID Connect provider, alongside the built-in Discord and Telegram methods. Enables single sign-on (e.g. pointing PoracleWeb at the PogoAlerts OAuth2 server) while staying provider-agnostic so any self-hoster can configure their own IdP. Implemented as a configurable twin of the Discord flow: - OidcSettings (URLs, client id/secret, scopes, claim mapping, PKCE flag) - GET /api/auth/oidc/login + /callback: auth-code exchange with PKCE, CSRF state in HttpOnly cookies; reads a configurable identity claim (default discord_id, falls back to sub), looks it up in the human table, reuses GetRolesAsync + guild-role gating, mints the existing internal JWT - providers endpoint gains an oidc block; enable_oidc site-setting runtime toggle (admins can always log in to re-enable); OIDC_* env bridge with auto-infer; documented in .env.example - Frontend: oidc provider model, loginWithOidc(), /auth/oidc/callback route, login button + disabled hint + error codes, admin External SSO group, English i18n keys Tests: backend providers oidc block + /oidc/login redirect/PKCE (1394 pass); frontend OIDC button visibility + click delegation (48 pass). * feat(auth): OIDC refresh-token sessions, SSO refinements, and docs Optional, provider-agnostic consumption of the external SSO provider's refresh token for silent session renewal + revocation propagation (default OFF via OIDC_USE_REFRESH_TOKENS), plus surrounding SSO login refinements and a comprehensive OIDC documentation set. Fully OIDC-provider-agnostic; PogoAlerts is only the reference provider. Backend: - oidc_sessions table (EF migration AddOidcSessions): the provider refresh token is stored server-side, DataProtection-encrypted, never sent to the browser; the browser holds only an opaque rotating token keyed to a rotation family. - POST /api/auth/oidc/refresh (rotate + live user re-validation + family-revoke on replay/provider-revoke) and /oidc/refresh/revoke; OidcSessionCleanupService reaps expired/stale rows (OIDC_SESSION_REVOKED_RETENTION_DAYS, default 2). - Provider-agnostic IOidcClient shared by login callback and refresh: configurable client_secret_post|client_secret_basic, optional/non-rotating refresh tokens, offline_access auto-appended; no discovery/JWKS/id_token dependency. - Per-login short JWT for refresh-backed OIDC sessions (OIDC_ACCESS_TOKEN_MINUTES, default 30); Discord/Telegram/local logins keep the 24h JWT. - Refresh is env-controlled only (no runtime admin toggle — coupled to JWT lifetime). Frontend: - TokenStoreService (single-flight refresh) + oidcRefreshInterceptor (proactive pre-expiry + reactive 401-retry, null-refresh-token guard so non-refresh logins keep the existing 401->logout path); callback stores the opaque token; logout revokes the session server-side. - SSO login refinements: Local/SSO auth-mode switch, single-logout toggle, auto-redirect + signed-out panel, i18n. Docs (MkDocs / gh-pages): - New "External SSO (OIDC)" setup page + reworked "OIDC Refresh Tokens" page (Mermaid flows, security model, provider matrix: Keycloak/Authentik/Auth0/ Google/Azure-Entra/Okta/PogoAlerts). - OIDC env vars added to the Configuration Reference, enable_oidc/enable_oidc_slo to Site Settings, an OIDC troubleshooting section, and nav entries. Tests: xUnit (session rotation/replay/cap/cleanup over SQLite, provider-agnostic client, providers/callback) + Jest (token-store single-flight, interceptor proactive/reactive/loop-guard). Backend 1422 pass, frontend 872 pass.
The EXTERNAL SSO / OIDC sample in .env.example hardcoded PGAN's pogoalerts.net endpoints as the example provider. PoracleWeb is fully OIDC-provider-agnostic and open source, so the example should not be branded to one deployment. Replace the sample provider name and authorize/token/userinfo URLs with neutral placeholders (My SSO / https://sso.example.com/...), generalize the intro to list common providers (Keycloak, Authentik, Auth0, Okta), and add a note to swap in your provider's real endpoints. The per-provider reference matrix (which carries no URLs) is unchanged.
…t URLs (#331) PogoAlerts was made standards-compliant (it now issues a refresh token only when the offline_access scope is requested), so the docs that told operators to leave OIDC_OFFLINE_ACCESS_SCOPE empty for PogoAlerts were stale. PogoAlerts now uses offline_access (the default), like every other standards-compliant provider — this already matched .env.example, which the docs contradicted. - external-sso.md / oidc-refresh-tokens.md provider matrices: PogoAlerts OIDC_OFFLINE_ACCESS_SCOPE (empty) -> offline_access. - oidc-refresh-tokens.md: drop "(PogoAlerts)" from the "set empty / issues unconditionally" guidance; Google's access_type=offline remains the empty case. De-branding (open-source hygiene): remove the dedicated "PogoAlerts (reference)" copy-paste snippets (the only place carrying real pogoalerts.net URLs). PogoAlerts remains documented as a row in the provider matrix; Keycloak/Auth0 serve as the concrete copy-paste examples. No pogoalerts.net URLs remain in the docs.
* i18n: translate OIDC/SSO keys into all locales The external SSO / OIDC login feature (#327/#328) added 30 i18n keys to en.json only, so every non-English locale fell back to English for the SSO sign-in button, the signed-out panel, OIDC error messages, and the entire admin Authentication / External SSO settings group. Translate all 30 keys (ADMIN_SETTINGS.* OIDC config + auth-mode + single-logout, AUTH.* SSO sign-in / signed-out / OIDC errors, MENU.LOGOUT_EVERYWHERE) into the 10 remaining locales: da, de, es, fr, it, nl, pl, pt, pt-BR, sv. Placeholders ({{provider}}), technical tokens (OIDC/SSO/PKCE/URL/ID), env names (AUTH_FORCE_LOCAL, OIDC_END_SESSION_URL, OIDC_*, .env) and brand names are preserved verbatim. Additive only — no existing keys changed or removed; all files valid JSON and Prettier-clean. * docs(changelog): note OIDC locale translations
…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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
No description provided.