Skip to content

chore(deps): bump the all-actions group with 10 updates - #7

Merged
DavidHLP merged 1 commit into
mainfrom
dependabot/github_actions/all-actions-a0574495ef
Apr 18, 2026
Merged

chore(deps): bump the all-actions group with 10 updates#7
DavidHLP merged 1 commit into
mainfrom
dependabot/github_actions/all-actions-a0574495ef

Conversation

@dependabot

@dependabot dependabot Bot commented on behalf of github Apr 18, 2026

Copy link
Copy Markdown
Contributor

Bumps the all-actions group with 10 updates:

Package From To
actions/checkout 4 6
actions/setup-java 4 5
actions/upload-artifact 4 7
actions/setup-python 5 6
pnpm/action-setup 4 6
actions/setup-node 4 6
docker/setup-buildx-action 3 4
docker/build-push-action 6 7
docker/login-action 3 4
docker/metadata-action 5 6

Updates actions/checkout from 4 to 6

Release notes

Sourced from actions/checkout's releases.

v6.0.0

What's Changed

Full Changelog: actions/checkout@v5.0.0...v6.0.0

v6-beta

What's Changed

Updated persist-credentials to store the credentials under $RUNNER_TEMP instead of directly in the local git config.

This requires a minimum Actions Runner version of v2.329.0 to access the persisted credentials for Docker container action scenarios.

v5.0.1

What's Changed

Full Changelog: actions/checkout@v5...v5.0.1

v5.0.0

What's Changed

⚠️ Minimum Compatible Runner Version

v2.327.1
Release Notes

Make sure your runner is updated to this version or newer to use this release.

Full Changelog: actions/checkout@v4...v5.0.0

v4.3.1

What's Changed

Full Changelog: actions/checkout@v4...v4.3.1

v4.3.0

What's Changed

... (truncated)

Changelog

Sourced from actions/checkout's changelog.

Changelog

v6.0.2

v6.0.1

v6.0.0

v5.0.1

v5.0.0

v4.3.1

v4.3.0

v4.2.2

v4.2.1

v4.2.0

v4.1.7

v4.1.6

... (truncated)

Commits

Updates actions/setup-java from 4 to 5

Release notes

Sourced from actions/setup-java's releases.

v5.0.0

What's Changed

Breaking Changes

Make sure your runner is updated to this version or newer to use this release. v2.327.1 Release Notes

Dependency Upgrades

Bug Fixes

New Contributors

Full Changelog: actions/setup-java@v4...v5.0.0

v4.8.0

What's Changed

Full Changelog: actions/setup-java@v4...v4.8.0

v4.7.1

What's Changed

Documentation changes

Dependency updates:

Full Changelog: actions/setup-java@v4...v4.7.1

v4.7.0

What's Changed

... (truncated)

Commits
  • be666c2 Chore: Version Update and Checkout Update to v6 (#973)
  • f7a6fef Bump actions/checkout from 5 to 6 (#961)
  • d81c4e4 Upgrade @​actions/cache to v5 (#968)
  • 1b1bbe1 readme update (#972)
  • 5d7b214 Retry on HTTP 522 Connection timed out (#964)
  • f2beeb2 Bump actions/publish-action from 0.3.0 to 0.4.0 (#912)
  • 4e7e684 feat: Add support for .sdkmanrc file in java-version-file parameter (#736)
  • 46c56d6 Add GitHub Token Support for GraalVM and Refactor Code (#849)
  • 66b9457 Update SapMachine URLs (#955)
  • 6ba5449 Enhance error logging for network failures to include endpoint/IP details, ad...
  • Additional commits viewable in compare view

Updates actions/upload-artifact from 4 to 7

Release notes

Sourced from actions/upload-artifact's releases.

v7.0.0

v7 What's new

Direct Uploads

Adds support for uploading single files directly (unzipped). Callers can set the new archive parameter to false to skip zipping the file during upload. Right now, we only support single files. The action will fail if the glob passed resolves to multiple files. The name parameter is also ignored with this setting. Instead, the name of the artifact will be the name of the uploaded file.

ESM

To support new versions of the @actions/* packages, we've upgraded the package to ESM.

What's Changed

New Contributors

Full Changelog: actions/upload-artifact@v6...v7.0.0

v6.0.0

v6 - What's new

[!IMPORTANT] actions/upload-artifact@v6 now runs on Node.js 24 (runs.using: node24) and requires a minimum Actions Runner version of 2.327.1. If you are using self-hosted runners, ensure they are updated before upgrading.

Node.js 24

This release updates the runtime to Node.js 24. v5 had preliminary support for Node.js 24, however this action was by default still running on Node.js 20. Now this action by default will run on Node.js 24.

What's Changed

Full Changelog: actions/upload-artifact@v5.0.0...v6.0.0

v5.0.0

What's Changed

BREAKING CHANGE: this update supports Node v24.x. This is not a breaking change per-se but we're treating it as such.

... (truncated)

Commits
  • 043fb46 Merge pull request #797 from actions/yacaovsnc/update-dependency
  • 634250c Include changes in typespec/ts-http-runtime 0.3.5
  • e454baa Readme: bump all the example versions to v7 (#796)
  • 74fad66 Update the readme with direct upload details (#795)
  • bbbca2d Support direct file uploads (#764)
  • 589182c Upgrade the module to ESM and bump dependencies (#762)
  • 47309c9 Merge pull request #754 from actions/Link-/add-proxy-integration-tests
  • 02a8460 Add proxy integration test
  • b7c566a Merge pull request #745 from actions/upload-artifact-v6-release
  • e516bc8 docs: correct description of Node.js 24 support in README
  • Additional commits viewable in compare view

Updates actions/setup-python from 5 to 6

Release notes

Sourced from actions/setup-python's releases.

v6.0.0

What's Changed

Breaking Changes

Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. See Release Notes

Enhancements:

Bug fixes:

Dependency updates:

New Contributors

Full Changelog: actions/setup-python@v5...v6.0.0

v5.6.0

What's Changed

Full Changelog: actions/setup-python@v5...v5.6.0

v5.5.0

What's Changed

Enhancements:

Bug fixes:

... (truncated)

Commits
  • a309ff8 Bump urllib3 from 2.6.0 to 2.6.3 in /tests/data (#1264)
  • bfe8cc5 Upgrade @​actions dependencies to Node 24 compatible versions (#1259)
  • 4f41a90 Bump urllib3 from 2.5.0 to 2.6.0 in /tests/data (#1253)
  • 83679a8 Bump @​types/node from 24.1.0 to 24.9.1 and update macos-13 to macos-15-intel ...
  • bfc4944 Bump prettier from 3.5.3 to 3.6.2 (#1234)
  • 97aeb3e Bump requests from 2.32.2 to 2.32.4 in /tests/data (#1130)
  • 443da59 Bump actions/publish-action from 0.3.0 to 0.4.0 & Documentation update for pi...
  • cfd55ca graalpy: add graalpy early-access and windows builds (#880)
  • bba65e5 Bump typescript from 5.4.2 to 5.9.3 and update docs/advanced-usage.md (#1094)
  • 18566f8 Improve wording and "fix example" (remove 3.13) on testing against pre-releas...
  • Additional commits viewable in compare view

Updates pnpm/action-setup from 4 to 6

Release notes

Sourced from pnpm/action-setup's releases.

v6.0.0

Added support for pnpm v11.

v5.0.0

Updated the action to use Node.js 24.

v4.4.0

Updated the action to use Node.js 24.

v4.3.0

What's Changed

New Contributors

Full Changelog: pnpm/action-setup@v4.2.0...v4.3.0

v4.2.0

When there's a .npmrc file at the root of the repository, pnpm will be fetched from the registry that is specified in that .npmrc file #179

v4.1.0

Add support for package.yaml #156.

Commits
  • 078e9d4 fix: update pnpm to 11.0.0-rc.2
  • 08c4be7 docs(README): update action-setup version
  • 5798914 chore: update .gitignore
  • ddffd66 fix: remove accidentally committed file
  • b43f991 fix: update pnpm to 11.0.0-rc.0
  • 3852509 README.md: bring versions up-to-date (#222)
  • 6e7bdbd chore: bump bootstrap pnpm to 11.0.0-beta.4-1 and add update script
  • 6b87c46 fix: Windows standalone mode — bypass broken npm shims (#217)
  • 994d756 feat: read pnpm version from devEngines.packageManager (#211)
  • 738f428 docs: upgrade pnpm/action-setup from v4 to v5
  • Additional commits viewable in compare view

Updates actions/setup-node from 4 to 6

Release notes

Sourced from actions/setup-node's releases.

v6.0.0

What's Changed

Breaking Changes

Dependency Upgrades

Full Changelog: actions/setup-node@v5...v6.0.0

v5.0.0

What's Changed

Breaking Changes

This update, introduces automatic caching when a valid packageManager field is present in your package.json. This aims to improve workflow performance and make dependency management more seamless. To disable this automatic caching, set package-manager-cache: false

steps:
- uses: actions/checkout@v5
- uses: actions/setup-node@v5
  with:
    package-manager-cache: false

Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. See Release Notes

Dependency Upgrades

New Contributors

Full Changelog: actions/setup-node@v4...v5.0.0

v4.4.0

... (truncated)

Commits

Updates docker/setup-buildx-action from 3 to 4

Release notes

Sourced from docker/setup-buildx-action's releases.

v4.0.0

Full Changelog: docker/setup-buildx-action@v3.12.0...v4.0.0

v3.12.0

Full Changelog: docker/setup-buildx-action@v3.11.1...v3.12.0

v3.11.1

Full Changelog: docker/setup-buildx-action@v3.11.0...v3.11.1

v3.11.0

Full Changelog: docker/setup-buildx-action@v3.10.0...v3.11.0

v3.10.0

Full Changelog: docker/setup-buildx-action@v3.9.0...v3.10.0

v3.9.0

Full Changelog: docker/setup-buildx-action@v3.8.0...v3.9.0

v3.8.0

Full Changelog: docker/setup-buildx-action@v3.7.1...v3.8.0

... (truncated)

Commits
  • 4d04d5d Merge pull request #485 from docker/dependabot/npm_and_yarn/docker/actions-to...
  • cd74e05 chore: update generated content
  • eee38ec build(deps): bump @​docker/actions-toolkit from 0.77.0 to 0.79.0
  • 7a83f65 Merge pull request #484 from docker/dependabot/github_actions/docker/setup-qe...
  • a5aa967 Merge pull request #464 from crazy-max/rm-deprecated
  • e73d53f build(deps): bump docker/setup-qemu-action from 3 to 4
  • 28a438e Merge pull request #483 from crazy-max/node24
  • 034e9d3 chore: update generated content
  • b4664d8 remove deprecated inputs/outputs
  • a8257de node 24 as default runtime
  • Additional commits viewable in compare view

Updates docker/build-push-action from 6 to 7

Release notes

Sourced from docker/build-push-action's releases.

v7.0.0

Full Changelog: docker/build-push-action@v6.19.2...v7.0.0

v6.19.2

Full Changelog: docker/build-push-action@v6.19.1...v6.19.2

v6.19.1

Full Changelog: docker/build-push-action@v6.19.0...v6.19.1

v6.19.0

@dependabot @github

dependabot Bot commented on behalf of github Apr 18, 2026

Copy link
Copy Markdown
Contributor Author

Labels

The following labels could not be found: automated, dependencies. Please create them before Dependabot can add them to a pull request.

Please fix the above issues or remove invalid values from dependabot.yml.

Bumps the all-actions group with 10 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4` | `6` |
| [actions/setup-java](https://github.com/actions/setup-java) | `4` | `5` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4` | `7` |
| [actions/setup-python](https://github.com/actions/setup-python) | `5` | `6` |
| [pnpm/action-setup](https://github.com/pnpm/action-setup) | `4` | `6` |
| [actions/setup-node](https://github.com/actions/setup-node) | `4` | `6` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3` | `4` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6` | `7` |
| [docker/login-action](https://github.com/docker/login-action) | `3` | `4` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5` | `6` |


Updates `actions/checkout` from 4 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

Updates `actions/setup-java` from 4 to 5
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@v4...v5)

Updates `actions/upload-artifact` from 4 to 7
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

Updates `actions/setup-python` from 5 to 6
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

Updates `pnpm/action-setup` from 4 to 6
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](pnpm/action-setup@v4...v6)

Updates `actions/setup-node` from 4 to 6
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v6)

Updates `docker/setup-buildx-action` from 3 to 4
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v3...v4)

Updates `docker/build-push-action` from 6 to 7
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v6...v7)

Updates `docker/login-action` from 3 to 4
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@v3...v4)

Updates `docker/metadata-action` from 5 to 6
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: pnpm/action-setup
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
@DavidHLP
DavidHLP force-pushed the dependabot/github_actions/all-actions-a0574495ef branch from 747a4e0 to f249d76 Compare April 18, 2026 06:27
@DavidHLP
DavidHLP merged commit 1547fea into main Apr 18, 2026
2 of 13 checks passed
@dependabot
dependabot Bot deleted the dependabot/github_actions/all-actions-a0574495ef branch April 18, 2026 06:35
DavidHLP added a commit that referenced this pull request Jun 8, 2026
…_ADMIN + rankings 404 + is_deleted filter + Unicode title + @Audited + new ErrorCode + controller XSS guard + mutator tests)

修复 docs/contests-api-test-report.md 报告的 7 处缺陷 (1 HIGH + 6 MEDIUM/LOW):

缺陷 #1 (HIGH) — DELETE 软删除 is_deleted 字段未持久化
  - 根因:Contest.isDeleted 字段 @TableLogic + mapper.updateById(entity) 自动忽略逻辑删除字段
  - 修复:改用 mapper.update(null, LambdaUpdateWrapper.set(...)) 显式写入

缺陷 #2 — PATCH on FINISHED/RUNNING 比赛无状态守卫
  - 修复:service 层加 status guard,仅允许 UPCOMING 修改
  - 新增 ErrorCode CONTEST_ONLY_UPDATE_UPCOMING (70006) 区分注册与修改语义

缺陷 #3 — service 层 hasRole("ADMIN") 拒绝 SUPER_ADMIN,与控制器 @PreAuthorize 不一致
  - 修复:SecurityUtil 新增 hasAnyRole(String...) 工具方法,ContestServiceImpl 7 处 mutator 替换

缺陷 #4 — CreateContestDTO/UpdateContestDTO title @pattern 拒绝 CJK 字符
  - 修复:正则放宽为 [\p{L}\p{N}\s\p{P}]+ 接受 Unicode 字母
  - AdminContestController 新增 rejectUnsafeTitleChars helper 显式排除 < 和 >

缺陷 #5 — GET /admin/contest/{id}/rankings 对不存在 contest 返 200+空
  - 修复:getAdminContestRanking 入口加 contest 存在性 + is_deleted 校验

缺陷 #6 — addProblem/removeProblem/startContest/endContest 未校验 is_deleted
  - 修复:4 个 mutator 入口加 .filter(c -> !isDeleted).orElseThrow(COMPETITION_NOT_FOUND)

缺陷 #7@Audited 注解缺失导致 audit_logs 无 contest 记录
  - 修复:7 个 mutator 方法加 @Audited + AuditContext.setOldValues/setNewValues/setUserId
  - 复用 AuditActionUtil.CREATE_CONTEST/UPDATE_CONTEST/DELETE_CONTEST 常量

新增测试 ContestServiceImplMutatorTest:5 case 覆盖缺陷 #2/#5/#6 的状态守卫 + 软删除过滤 + 404 路径。
缺陷 #1 的 LambdaUpdateWrapper.getSqlSet() 断言需 @SpringBootTest 上下文,保留为 follow-up,
运行时 curl 验证已确认三列同改 (docs/contests-api-test-report.md §3.5)。

验证:
- mvnw compile -B:0 错误
- mvnw test -Dtest=ContestServiceImplMutatorTest:5/5 通过,2.0s
- 运行时 curl 5/5 critical 缺陷修复确认 (PM2 重启 ulticode-9001)

Artifacts:
- Plan: .claude/PRPs/plans/completed/admin-contests-mutator-fixes.plan.md
- Report: .claude/PRPs/reports/admin-contests-mutator-fixes-report.md
- Review v1: .claude/reviews/admin-contests-mutator-review.md
- Review v2: .claude/reviews/admin-contests-mutator-review-v2.md
- Test report: docs/contests-api-test-report.md
DavidHLP pushed a commit that referenced this pull request Jun 11, 2026
… handler, compute real progress

Fixes 6 issues from docs/achievement-api-test-report-2026-06-11.md
plus 2 newly-discovered typeHandler bugs (Bug #7, Bug #8) surfaced
during validation.

CRITICAL #1 — escape `key` column via @TableField(value = "`key`")
  - Achievement.java:19 — affects MyBatis-Plus auto-generated column
    lists in selectById / selectPage / selectBatchIds.
  - Without this, every SQL that lists the achievements columns fails
    with 'You have an error in your SQL syntax ... near key,...'.

CRITICAL #2 — escape `key` in @select SQL
  - AchievementMapper.findByKey:24 — WHERE clause now backticks.
  - Fixes admin POST /achievements which called findByKey for dedup.

HIGH #3 — T2b /achievements/{invalid} now returns 404 (was 500)
  - Follows from CRITICAL #1+#2: the BadSqlGrammarException
    no longer fires before the business-level ACHIEVEMENT_NOT_FOUND
    can be raised.

MEDIUM #4 — BadSqlGrammarException → DATABASE_ERROR (50001)
  - GlobalExceptionHandler:227 — new handler preserves root cause
    in server log while returning generic 'Database error' to clients.
  - Pairs with existing MyBatisSystemException / BindingException /
    DataIntegrityViolationException handlers (no fallback to 50000
    'Unknown error').

LOW #5 — getUserAchievements progress is no longer hard-coded to 0
  - AchievementServiceImpl:280 — mirrors getUserProgress logic,
    reads criteria.type from JSON Map, dispatches to SubmissionMapper
    counter.

LOW #6 — re-scoped Javadoc: getUserAchievements and
  getUserProgress are NOT duplicates (verified UserController
  /me/achievements/progress uses the latter). Both serve different
  endpoints with different DTO shapes.

Bug #7 — findAllActive missing JacksonTypeHandler
  - AchievementMapper:46 — @select bypassed @TableField(typeHandler=
    JacksonTypeHandler.class), returning criteria=null.
  - Converted to default method via BaseMapper.selectList.

Bug #8 — findByKey same typeHandler bypass
  - Discovered by AchievementMapperIT (L2) on first run;
    findByKey_criteriaIsDeserializedAsMap failed.
  - AchievementMapper:24 — also converted to default method.
  - Latent: only caller (create) never read criteria.

Refactors
  - M1 (review): getUserAchievements extracted buildProgressDTO helper
    (52 → 16 lines).
  - L1 (review): findAllActive uses LambdaQueryWrapper<Achievement>
    method refs instead of string column names.
  - L3 (review): Javadoc clarified the two service methods.

Tests
  + AchievementMapperSQLGuardTest: 3 reflection-guard tests
    (CRITICAL #1, CRITICAL #2, no @select on findAllActive/findByKey).
  + AchievementMapperIT: 5 Testcontainers MySQL 8.0 IT tests
    verifying JacksonTypeHandler runtime behavior + Bug #7/#8
    regression guards.
  + AchievementServiceTest: 3 progress tests + 2 new mock fields
    (SubmissionMapper, ContestParticipantMapper).
  + GlobalExceptionHandlerTest: 2 BadSqlGrammarException tests.

Validation
  - compile / package: BUILD SUCCESS
  - Unit tests: 36/36 pass
  - Testcontainers IT: 5/5 pass
  - 8 curl integration tests on worktree:9091: all match expected
    HTTP codes (200/400/404/409) and real progress values
    (admin 6 accepted problems → progress=6 for all 3 rows).

Refs: docs/achievement-api-test-report-2026-06-11.md,
      .claude/PRPs/plans/completed/achievement-api-fixes.plan.md,
      .claude/PRPs/reports/achievement-api-fixes-report.md,
      .claude/reviews/achievement-api-fixes-review.md
DavidHLP pushed a commit that referenced this pull request Jun 11, 2026
…dation

Merges the fix/achievement-api worktree changes:
- CRITICAL #1, #2 (MySQL reserved word `key`)
- HIGH #3 (T2b 404)
- MEDIUM #4 (BadSqlGrammarException handler)
- LOW #5 (real progress computation)
- LOW #6 (Javadoc re-scoped)
- Bug #7 (findAllActive typeHandler)
- Bug #8 (findByKey typeHandler, IT-discovered)

M1/L1/L2/L3/L4 from .claude/reviews/achievement-api-fixes-review.md
all addressed. Test coverage: 36 unit + 5 Testcontainers IT.
DavidHLP pushed a commit that referenced this pull request Jun 13, 2026
…T 死分支

Review finding #7: NotificationCategory.CONTEST was a dead enum value
— every caller used NotificationCategory.SYSTEM, and the dispatcher's
CONTEST branch (mapping to preference.getSystemEnabled()) was
indistinguishable from a typo. Grep across production + tests showed
zero references outside the dispatcher switch itself.

Removed the enum value and the matching switch arm. A future
"contest preferences" ADR can re-introduce the value alongside a
dedicated preference column.

mvn test on the notification slice: green.

Refs: docs/adr/ADR-004-notification-intents.md (M4d-1 review finding
#7).
DavidHLP added a commit that referenced this pull request Jun 13, 2026
…T 死分支

Review finding #7: NotificationCategory.CONTEST was a dead enum value
— every caller used NotificationCategory.SYSTEM, and the dispatcher's
CONTEST branch (mapping to preference.getSystemEnabled()) was
indistinguishable from a typo. Grep across production + tests showed
zero references outside the dispatcher switch itself.

Removed the enum value and the matching switch arm. A future
"contest preferences" ADR can re-introduce the value alongside a
dedicated preference column.

mvn test on the notification slice: green.

Refs: docs/adr/ADR-004-notification-intents.md (M4d-1 review finding
#7).
DavidHLP added a commit that referenced this pull request Jun 14, 2026
…rationProperties)

Pre-P0-2: FeatureFlagsProperties 用 flat 字段 judgeQueueUsePort/judgeQueueEnvelopeVersion,
但 application.yml 用 nested key app.features.judge-queue.use-port。Spring Binder 的
kebab→camel 转换只作用于叶节点名,不作用于路径段,导致 YAML override 永远不生效,
M3c cutover flag 静默卡在 false。

Fix: 改为 @NestedConfigurationProperty JudgeQueue inner class (usePort/envelopeVersion/cutoverAt),
与 app.features 整体 prefix 一致,方便后续 FlagCombinationValidator 单 bean 聚合校验。
cutover-at (F13 watermark) 之前被 Binder 静默忽略,本轮一并补字段。

调用方更新 (2 处):
- JudgeWorkerProcessor.pollAndProcessFromPort
- SubmissionServiceImpl.submit (portActive)

Note: JudgeOutboxDispatcher 仍用 @value 直接读 YAML key (reviewer 补充 #1),
task #7 统一切到 FeatureFlagsProperties,避免 YAML 双解析。
@ConditionalOnProperty 4 处 (RedissonStreamsJudgeQueueAdapter/QueueConfig/...) 不动
(reviewer 补充 #2 — 它们直接读 YAML key,P0-2 只修 API 暴露层)。

Tests: FeatureFlagsPropertiesBindingTest (3 case, 真实 Binder 端到端验证) +
回归 41 case 全 PASS (JudgeWorkerProcessorTest + P0-1 测试集)。

Refs: task #5 (P0-2)

Co-Authored-By: Claude <noreply@anthropic.com>
DavidHLP added a commit that referenced this pull request Jul 3, 2026
管理后台鉴权初始化(CRITICAL #1):
- management/src/main.ts: 新增完整 auth bootstrap 流程
- management/src/stores/auth.ts: 新增 setupSessionExpiredCallback + clearUser

WebSocket Token 安全泄露(CRITICAL #2):
- console/src/lib/socket.ts: 移除 URL ?token= 参数,token 改走 connectHeaders
- console/src/composables/contest/useContestSocket.ts: 同上

OAuth 重定向 URL 统一(CRITICAL #4):
- management/src/views/auth/components/OAuthButton.vue: 相对路径→绝对路径

Router Guard 错误处理(HIGH #5):
- console/src/router/index.ts: catch 块增加 ApiError instanceof 判断

WebSocket Token 传递优化(HIGH #6):
- useContestSocket.ts: 已正确从 socket.ts 导入 getTokenFromCookie

verifyAuth 绕过 axios 拦截器(HIGH #7):
- console/src/utils/auth.ts: fetch() → apiGet()

性能优化(HIGH #9):
- console/src/contexts/AuthContext.ts: setInterval(1000) → watch(isAuthenticated)

代码质量提升(MEDIUM):
- console/src/stores/auth.ts: 移除 LOGOUT_KEY localStorage 追踪
- 新增 hasAuthCookie() 提前检查,173 行净减少
- clearUser() 重置 status="idle" 允许重新初始化
- 移除所有调试 console.log

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DavidHLP pushed a commit that referenced this pull request Jul 3, 2026
Bumps the all-actions group with 10 updates:

| Package | From | To |
| --- | --- | --- |
| [actions/checkout](https://github.com/actions/checkout) | `4` | `6` |
| [actions/setup-java](https://github.com/actions/setup-java) | `4` | `5` |
| [actions/upload-artifact](https://github.com/actions/upload-artifact) | `4` | `7` |
| [actions/setup-python](https://github.com/actions/setup-python) | `5` | `6` |
| [pnpm/action-setup](https://github.com/pnpm/action-setup) | `4` | `6` |
| [actions/setup-node](https://github.com/actions/setup-node) | `4` | `6` |
| [docker/setup-buildx-action](https://github.com/docker/setup-buildx-action) | `3` | `4` |
| [docker/build-push-action](https://github.com/docker/build-push-action) | `6` | `7` |
| [docker/login-action](https://github.com/docker/login-action) | `3` | `4` |
| [docker/metadata-action](https://github.com/docker/metadata-action) | `5` | `6` |


Updates `actions/checkout` from 4 to 6
- [Release notes](https://github.com/actions/checkout/releases)
- [Changelog](https://github.com/actions/checkout/blob/main/CHANGELOG.md)
- [Commits](actions/checkout@v4...v6)

Updates `actions/setup-java` from 4 to 5
- [Release notes](https://github.com/actions/setup-java/releases)
- [Commits](actions/setup-java@v4...v5)

Updates `actions/upload-artifact` from 4 to 7
- [Release notes](https://github.com/actions/upload-artifact/releases)
- [Commits](actions/upload-artifact@v4...v7)

Updates `actions/setup-python` from 5 to 6
- [Release notes](https://github.com/actions/setup-python/releases)
- [Commits](actions/setup-python@v5...v6)

Updates `pnpm/action-setup` from 4 to 6
- [Release notes](https://github.com/pnpm/action-setup/releases)
- [Commits](pnpm/action-setup@v4...v6)

Updates `actions/setup-node` from 4 to 6
- [Release notes](https://github.com/actions/setup-node/releases)
- [Commits](actions/setup-node@v4...v6)

Updates `docker/setup-buildx-action` from 3 to 4
- [Release notes](https://github.com/docker/setup-buildx-action/releases)
- [Commits](docker/setup-buildx-action@v3...v4)

Updates `docker/build-push-action` from 6 to 7
- [Release notes](https://github.com/docker/build-push-action/releases)
- [Commits](docker/build-push-action@v6...v7)

Updates `docker/login-action` from 3 to 4
- [Release notes](https://github.com/docker/login-action/releases)
- [Commits](docker/login-action@v3...v4)

Updates `docker/metadata-action` from 5 to 6
- [Release notes](https://github.com/docker/metadata-action/releases)
- [Commits](docker/metadata-action@v5...v6)

---
updated-dependencies:
- dependency-name: actions/checkout
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/setup-java
  dependency-version: '5'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/upload-artifact
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/setup-python
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: pnpm/action-setup
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: actions/setup-node
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/setup-buildx-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/build-push-action
  dependency-version: '7'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/login-action
  dependency-version: '4'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
- dependency-name: docker/metadata-action
  dependency-version: '6'
  dependency-type: direct:production
  update-type: version-update:semver-major
  dependency-group: all-actions
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
DavidHLP added a commit that referenced this pull request Jul 3, 2026
…_ADMIN + rankings 404 + is_deleted filter + Unicode title + @Audited + new ErrorCode + controller XSS guard + mutator tests)

修复 docs/contests-api-test-report.md 报告的 7 处缺陷 (1 HIGH + 6 MEDIUM/LOW):

缺陷 #1 (HIGH) — DELETE 软删除 is_deleted 字段未持久化
  - 根因:Contest.isDeleted 字段 @TableLogic + mapper.updateById(entity) 自动忽略逻辑删除字段
  - 修复:改用 mapper.update(null, LambdaUpdateWrapper.set(...)) 显式写入

缺陷 #2 — PATCH on FINISHED/RUNNING 比赛无状态守卫
  - 修复:service 层加 status guard,仅允许 UPCOMING 修改
  - 新增 ErrorCode CONTEST_ONLY_UPDATE_UPCOMING (70006) 区分注册与修改语义

缺陷 #3 — service 层 hasRole("ADMIN") 拒绝 SUPER_ADMIN,与控制器 @PreAuthorize 不一致
  - 修复:SecurityUtil 新增 hasAnyRole(String...) 工具方法,ContestServiceImpl 7 处 mutator 替换

缺陷 #4 — CreateContestDTO/UpdateContestDTO title @pattern 拒绝 CJK 字符
  - 修复:正则放宽为 [\p{L}\p{N}\s\p{P}]+ 接受 Unicode 字母
  - AdminContestController 新增 rejectUnsafeTitleChars helper 显式排除 < 和 >

缺陷 #5 — GET /admin/contest/{id}/rankings 对不存在 contest 返 200+空
  - 修复:getAdminContestRanking 入口加 contest 存在性 + is_deleted 校验

缺陷 #6 — addProblem/removeProblem/startContest/endContest 未校验 is_deleted
  - 修复:4 个 mutator 入口加 .filter(c -> !isDeleted).orElseThrow(COMPETITION_NOT_FOUND)

缺陷 #7@Audited 注解缺失导致 audit_logs 无 contest 记录
  - 修复:7 个 mutator 方法加 @Audited + AuditContext.setOldValues/setNewValues/setUserId
  - 复用 AuditActionUtil.CREATE_CONTEST/UPDATE_CONTEST/DELETE_CONTEST 常量

新增测试 ContestServiceImplMutatorTest:5 case 覆盖缺陷 #2/#5/#6 的状态守卫 + 软删除过滤 + 404 路径。
缺陷 #1 的 LambdaUpdateWrapper.getSqlSet() 断言需 @SpringBootTest 上下文,保留为 follow-up,
运行时 curl 验证已确认三列同改 (docs/contests-api-test-report.md §3.5)。

验证:
- mvnw compile -B:0 错误
- mvnw test -Dtest=ContestServiceImplMutatorTest:5/5 通过,2.0s
- 运行时 curl 5/5 critical 缺陷修复确认 (PM2 重启 ulticode-9001)

Artifacts:
- Plan: .claude/PRPs/plans/completed/admin-contests-mutator-fixes.plan.md
- Report: .claude/PRPs/reports/admin-contests-mutator-fixes-report.md
- Review v1: .claude/reviews/admin-contests-mutator-review.md
- Review v2: .claude/reviews/admin-contests-mutator-review-v2.md
- Test report: docs/contests-api-test-report.md
DavidHLP added a commit that referenced this pull request Jul 3, 2026
… handler, compute real progress

Fixes 6 issues from docs/achievement-api-test-report-2026-06-11.md
plus 2 newly-discovered typeHandler bugs (Bug #7, Bug #8) surfaced
during validation.

CRITICAL #1 — escape `key` column via @TableField(value = "`key`")
  - Achievement.java:19 — affects MyBatis-Plus auto-generated column
    lists in selectById / selectPage / selectBatchIds.
  - Without this, every SQL that lists the achievements columns fails
    with 'You have an error in your SQL syntax ... near key,...'.

CRITICAL #2 — escape `key` in @select SQL
  - AchievementMapper.findByKey:24 — WHERE clause now backticks.
  - Fixes admin POST /achievements which called findByKey for dedup.

HIGH #3 — T2b /achievements/{invalid} now returns 404 (was 500)
  - Follows from CRITICAL #1+#2: the BadSqlGrammarException
    no longer fires before the business-level ACHIEVEMENT_NOT_FOUND
    can be raised.

MEDIUM #4 — BadSqlGrammarException → DATABASE_ERROR (50001)
  - GlobalExceptionHandler:227 — new handler preserves root cause
    in server log while returning generic 'Database error' to clients.
  - Pairs with existing MyBatisSystemException / BindingException /
    DataIntegrityViolationException handlers (no fallback to 50000
    'Unknown error').

LOW #5 — getUserAchievements progress is no longer hard-coded to 0
  - AchievementServiceImpl:280 — mirrors getUserProgress logic,
    reads criteria.type from JSON Map, dispatches to SubmissionMapper
    counter.

LOW #6 — re-scoped Javadoc: getUserAchievements and
  getUserProgress are NOT duplicates (verified UserController
  /me/achievements/progress uses the latter). Both serve different
  endpoints with different DTO shapes.

Bug #7 — findAllActive missing JacksonTypeHandler
  - AchievementMapper:46 — @select bypassed @TableField(typeHandler=
    JacksonTypeHandler.class), returning criteria=null.
  - Converted to default method via BaseMapper.selectList.

Bug #8 — findByKey same typeHandler bypass
  - Discovered by AchievementMapperIT (L2) on first run;
    findByKey_criteriaIsDeserializedAsMap failed.
  - AchievementMapper:24 — also converted to default method.
  - Latent: only caller (create) never read criteria.

Refactors
  - M1 (review): getUserAchievements extracted buildProgressDTO helper
    (52 → 16 lines).
  - L1 (review): findAllActive uses LambdaQueryWrapper<Achievement>
    method refs instead of string column names.
  - L3 (review): Javadoc clarified the two service methods.

Tests
  + AchievementMapperSQLGuardTest: 3 reflection-guard tests
    (CRITICAL #1, CRITICAL #2, no @select on findAllActive/findByKey).
  + AchievementMapperIT: 5 Testcontainers MySQL 8.0 IT tests
    verifying JacksonTypeHandler runtime behavior + Bug #7/#8
    regression guards.
  + AchievementServiceTest: 3 progress tests + 2 new mock fields
    (SubmissionMapper, ContestParticipantMapper).
  + GlobalExceptionHandlerTest: 2 BadSqlGrammarException tests.

Validation
  - compile / package: BUILD SUCCESS
  - Unit tests: 36/36 pass
  - Testcontainers IT: 5/5 pass
  - 8 curl integration tests on worktree:9091: all match expected
    HTTP codes (200/400/404/409) and real progress values
    (admin 6 accepted problems → progress=6 for all 3 rows).

Refs: docs/achievement-api-test-report-2026-06-11.md,
      .claude/PRPs/plans/completed/achievement-api-fixes.plan.md,
      .claude/PRPs/reports/achievement-api-fixes-report.md,
      .claude/reviews/achievement-api-fixes-review.md
DavidHLP added a commit that referenced this pull request Jul 3, 2026
…dation

Merges the fix/achievement-api worktree changes:
- CRITICAL #1, #2 (MySQL reserved word `key`)
- HIGH #3 (T2b 404)
- MEDIUM #4 (BadSqlGrammarException handler)
- LOW #5 (real progress computation)
- LOW #6 (Javadoc re-scoped)
- Bug #7 (findAllActive typeHandler)
- Bug #8 (findByKey typeHandler, IT-discovered)

M1/L1/L2/L3/L4 from .claude/reviews/achievement-api-fixes-review.md
all addressed. Test coverage: 36 unit + 5 Testcontainers IT.
DavidHLP added a commit that referenced this pull request Jul 3, 2026
…T 死分支

Review finding #7: NotificationCategory.CONTEST was a dead enum value
— every caller used NotificationCategory.SYSTEM, and the dispatcher's
CONTEST branch (mapping to preference.getSystemEnabled()) was
indistinguishable from a typo. Grep across production + tests showed
zero references outside the dispatcher switch itself.

Removed the enum value and the matching switch arm. A future
"contest preferences" ADR can re-introduce the value alongside a
dedicated preference column.

mvn test on the notification slice: green.

Refs: docs/adr/ADR-004-notification-intents.md (M4d-1 review finding
#7).
DavidHLP added a commit that referenced this pull request Jul 3, 2026
…rationProperties)

Pre-P0-2: FeatureFlagsProperties 用 flat 字段 judgeQueueUsePort/judgeQueueEnvelopeVersion,
但 application.yml 用 nested key app.features.judge-queue.use-port。Spring Binder 的
kebab→camel 转换只作用于叶节点名,不作用于路径段,导致 YAML override 永远不生效,
M3c cutover flag 静默卡在 false。

Fix: 改为 @NestedConfigurationProperty JudgeQueue inner class (usePort/envelopeVersion/cutoverAt),
与 app.features 整体 prefix 一致,方便后续 FlagCombinationValidator 单 bean 聚合校验。
cutover-at (F13 watermark) 之前被 Binder 静默忽略,本轮一并补字段。

调用方更新 (2 处):
- JudgeWorkerProcessor.pollAndProcessFromPort
- SubmissionServiceImpl.submit (portActive)

Note: JudgeOutboxDispatcher 仍用 @value 直接读 YAML key (reviewer 补充 #1),
task #7 统一切到 FeatureFlagsProperties,避免 YAML 双解析。
@ConditionalOnProperty 4 处 (RedissonStreamsJudgeQueueAdapter/QueueConfig/...) 不动
(reviewer 补充 #2 — 它们直接读 YAML key,P0-2 只修 API 暴露层)。

Tests: FeatureFlagsPropertiesBindingTest (3 case, 真实 Binder 端到端验证) +
回归 41 case 全 PASS (JudgeWorkerProcessorTest + P0-1 测试集)。

Refs: task #5 (P0-2)

Co-Authored-By: Claude <noreply@anthropic.com>
DavidHLP added a commit that referenced this pull request Jul 10, 2026
SolutionsEditView.vue imported axios directly to call axios.isAxiosError,
bypassing the http-client seam that wires CSRF, retry, dedup, locale
headers, and the 401 auth-failure strategy. Replace with the typed
ApiError check that the interceptors already produce.

Architecture review Card #7 — see /tmp/architecture-review-1783403689.html.
DavidHLP added a commit that referenced this pull request Jul 10, 2026
…1 of 2)

Architecture review candidate #7 — the pagination normalization rule
'default page 1, default page-size 20, hard cap 100' was hand-rolled
across 26 service implementations with silent drift:
  - default page-size varied (10 in admin/, 20 in forum/, 50 in contest/)
  - cap varied (50 in some contest code, 100 elsewhere)
  - variable names varied (currentPage, currentLimit, safeLimit, ps, max)

This commit establishes the deep module that owns the rule:

  common/response/PaginationRequest.java
    record (int page, int pageSize)
    PaginationRequest.of(page, pageSize)              // platform defaults
    PaginationRequest.of(page, pageSize, defaultSize) // caller default
    req.offset()                                      // for LIMIT/OFFSET
    DEFAULT_PAGE=1, DEFAULT_PAGE_SIZE=20, MAX_PAGE_SIZE=100

  common/response/PageResult.java
    + of(items, total, PaginationRequest)  // new overload
    existing of(items, total, page, pageSize) unchanged — no breakage

Phase 2 (mechanical follow-up): migrate 26 callers to the new overload.
The migration pattern is documented in PageResult.of()'s javadoc:
each site replaces 3-4 lines of drift-prone normalization with a single
PaginationRequest.of(...) call. Sites:

  DefaultSolutionProjection, DefaultUserReadProjection,
  DefaultForumReadProjection, DefaultContestProjection,
  DefaultAchievementProjection, DefaultProblemProjection,
  DefaultModerationProjection, DefaultAdminSubmissionProjection,
  DefaultAdminForumProjection, DefaultAdminUserProjection,
  DefaultAdminSolutionProjection, AdminProblemAdapter,
  ForumPostServiceImpl, RankingServiceImpl, SubmissionServiceImpl,
  AdminTestCaseService, AdminProblemServiceImpl,
  AdminNotificationServiceImpl, AuditServiceImpl,
  AdminContestServiceImpl, AdminCommentServiceImpl,
  AdminProblemListServiceImpl, EmailServiceImpl,
  NotificationServiceImpl, DefaultFollowInspector, BackupServiceImpl.

Verified: ./mvnw compile clean (BUILD SUCCESS).
DavidHLP added a commit that referenced this pull request Jul 10, 2026
…ReadProjection to PaginationRequest

Architecture review candidate #7 phase 2 (batch 1 of N) — mechanical
migration of PageResult.of() callers to the PaginationRequest deep module
introduced in 581f623.

Each migration replaces the drift-prone 3-line normalization block:

  int currentPage = (page != null && page > 0) ? page : 1;
  int currentPageSize = (pageSize != null && pageSize > 0) ? pageSize : 20;
  currentPageSize = Math.min(currentPageSize, 100);

with the single deep-module seam:

  PaginationRequest pageRequest = PaginationRequest.of(page, pageSize);

  PageResult.of(items, total, pageRequest);     // overload
  new Page<>(pageRequest.page(), pageRequest.pageSize());

Files migrated (2 of 26):
  - DefaultSolutionProjection.java  (5 sites collapsed to 1 PaginationRequest)
  - DefaultUserReadProjection.java  (3 sites collapsed to 1 PaginationRequest)

Verified: ./mvnw compile clean. DefaultUserReadProjectionTest 24/24 pass.
DefaultSolutionProjectionTest not present — relying on compile + integration.

Remaining 24 callers (mechanical follow-up): see PageResult.of(items, total,
PaginationRequest) javadoc for the migration pattern.
DavidHLP added a commit that referenced this pull request Jul 10, 2026
…rn, default 10)

Architecture review candidate #7 phase 2 (batch 2 of N) — first
migration of an admin-pattern caller using PaginationRequest.of(page,
limit, 10) (3-arg overload with caller-specified default page-size).

Admin pattern differs from user-facing pattern:
  - default page-size = 10 (vs 20 for user-facing)
  - reads from query DTO (query.getPage() / query.getLimit()) rather
    than direct method params

Mechanical replacement:
  int page = query.getPage() != null && query.getPage() > 0 ? ... : 1;
  int limit = query.getLimit() != null && query.getLimit() > 0 ? Math.min(..., 100) : 10;
  → PaginationRequest.of(query.getPage(), query.getLimit(), 10)

Verified: ./mvnw compile clean.

3 of 26 callers migrated. 23 remaining — same mechanical pattern.
DavidHLP added a commit that referenced this pull request Jul 10, 2026
#1 SecurityUtil → CurrentUserProvider port
  - New CurrentUserProvider interface in common/auth/
  - SecurityCurrentUserProvider @component adapter (wraps SecurityContextHolder)
  - 37 files migrated from static SecurityUtil calls to injected interface
  - Eliminates duplicated userId==null guards across controller layer

#2 DashboardMapper+Service → DashboardStatsProjection
  - New DashboardStatsProjection interface + DefaultDashboardStatsProjection
  - Absorbs 7 private sub-aggregators + 6 mapper default methods
  - DashboardService + DashboardServiceImpl deleted
  - DashboardController now injects the projection directly
  - Mirrors ADR-0011 *Projection pattern

#3 AdminCommentService → CommentModerator polymorphic seam
  - New CommentModerator interface with ForumCommentModerator + SolutionCommentModerator
  - AdminCommentServiceImpl refactored to thin router
  - Eliminates 5x duplicated forum/solution type-string switch

#5 SubmissionMapper.calculateStreak → SubmissionStreakCalculator
  - New SubmissionStreakCalculator interface + JdbcSubmissionStreakCalculator
  - Streak algorithm (recursive CTE) now behind a JVM-testable interface
  - 3 production callers redirected + 3 test classes updated

#7 Frontend wrapper cleanup
  - 8 re-export wrapper files deleted (markdown, useTheme, useTypographyDensity, cn)
  - tsconfig path remaps @/lib/utils → @/shared/auth-core/src/utils
  - shared/sidebar-menu cn() consolidated to import from auth-core
  - LOCALE_HEADER_KEY duplicate declarations removed

#8 OAuthService → OAuthClient port + adapters
  - New OAuthClient interface + OAuthTokenResponse/OAuthUserInfo DTOs
  - GithubOAuthClient + GoogleOAuthClient @component adapters
  - OAuthService refactored to thin coordinator (221→195 LoC)
  - 11 unit tests covering dispatch, callback, DB upsert

Production code compiles (BUILD SUCCESS). 53 test compilation errors
from constructor signature changes — mechanical @mock field additions.
Candidates #4 (analytics projections) and #6 (contest.ts split) pending.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant