Commit Graph

57 Commits

Author SHA1 Message Date
APF Portal Bot 4244f63831 chore(deps): update actions/setup-node action to v6 (#27)
CI / check (push) Successful in 1m0s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 2m13s
CI / a11y (push) Successful in 1m58s
CI / perf (push) Successful in 3m21s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/setup-node](https://github.com/actions/setup-node) | action | major | `v4` -> `v6` |

---

### Release Notes

<details>
<summary>actions/setup-node (actions/setup-node)</summary>

### [`v6`](https://github.com/actions/setup-node/compare/v5...v6)

[Compare Source](https://github.com/actions/setup-node/compare/v5...v6)

### [`v5`](https://github.com/actions/setup-node/compare/v4...v5)

[Compare Source](https://github.com/actions/setup-node/compare/v4...v5)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #27
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 23:25:41 +02:00
APF Portal Bot adc14c14e0 chore(deps): update actions/checkout action to v6 (#26)
CI / commits (push) Has been skipped
CI / check (push) Successful in 1m16s
CI / scan (push) Failing after 1m25s
CI / a11y (push) Successful in 1m0s
CI / perf (push) Successful in 2m38s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [actions/checkout](https://github.com/actions/checkout) | action | major | `v4` -> `v6` |

---

### Release Notes

<details>
<summary>actions/checkout (actions/checkout)</summary>

### [`v6`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v602)

[Compare Source](https://github.com/actions/checkout/compare/v5...v6)

- Fix tag handling: preserve annotations and explicit fetch-tags by [@&#8203;ericsciple](https://github.com/ericsciple) in https://github.com/actions/checkout/pull/2356

### [`v5`](https://github.com/actions/checkout/blob/HEAD/CHANGELOG.md#v501)

[Compare Source](https://github.com/actions/checkout/compare/v4...v5)

- Port v6 cleanup to v5 by [@&#8203;ericsciple](https://github.com/ericsciple) in https://github.com/actions/checkout/pull/2301

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #26
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 23:25:10 +02:00
APF Portal Bot c86804effa fix(deps): update dependency reflect-metadata to ^0.2.0 (#25)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 2m24s
CI / check (push) Successful in 2m55s
CI / a11y (push) Successful in 1m5s
CI / perf (push) Successful in 3m41s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [reflect-metadata](http://rbuckton.github.io/reflect-metadata) ([source](https://github.com/rbuckton/reflect-metadata)) | dependencies | minor | [`^0.1.13` -> `^0.2.0`](https://renovatebot.com/diffs/npm/reflect-metadata/0.1.14/0.2.2) |

---

### Release Notes

<details>
<summary>rbuckton/reflect-metadata (reflect-metadata)</summary>

### [`v0.2.2`](https://github.com/rbuckton/reflect-metadata/compare/v0.2.1...ca9650a46e3dfa32d0b384936eed539bd9109b12)

[Compare Source](https://github.com/rbuckton/reflect-metadata/compare/v0.2.1...ca9650a46e3dfa32d0b384936eed539bd9109b12)

### [`v0.2.1`](https://github.com/microsoft/reflect-metadata/releases/tag/v0.2.1)

[Compare Source](https://github.com/rbuckton/reflect-metadata/compare/v0.2.0...v0.2.1)

#### What's Changed

- Fix stack overflow crash in isProviderFor by [@&#8203;rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/155
- Update main to v0.2.1 by [@&#8203;rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/156

**Full Changelog**: https://github.com/rbuckton/reflect-metadata/compare/v0.2.0...v0.2.1

### [`v0.2.0`](https://github.com/microsoft/reflect-metadata/releases/tag/v0.2.0): reflect-metadata 0.2.0

[Compare Source](https://github.com/rbuckton/reflect-metadata/compare/v0.1.14...v0.2.0)

#### What's Changed

- Add /lite and /no-conflict exports by [@&#8203;rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/144
- No dynamic evaluation in `/lite` mode by [@&#8203;rbuckton](https://github.com/rbuckton) in https://github.com/rbuckton/reflect-metadata/pull/149

**Full Changelog**: https://github.com/rbuckton/reflect-metadata/compare/v0.1.14...v0.2.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #25
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 23:17:25 +02:00
APF Portal Bot 4f6765c5c1 chore(deps): update dependency @oxc-project/runtime to ^0.129.0 (#22)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 2m13s
CI / check (push) Successful in 3m10s
CI / a11y (push) Successful in 1m7s
CI / perf (push) Successful in 3m25s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@oxc-project/runtime](https://oxc.rs) ([source](https://github.com/oxc-project/oxc/tree/HEAD/npm/runtime)) | devDependencies | minor | [`^0.115.0` -> `^0.129.0`](https://renovatebot.com/diffs/npm/@oxc-project%2fruntime/0.115.0/0.129.0) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #22
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 23:07:09 +02:00
APF Portal Bot 214970a63e chore(deps): update analog monorepo to ~2.5.0 (#21)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 2m4s
CI / check (push) Successful in 2m23s
CI / a11y (push) Successful in 53s
CI / perf (push) Successful in 3m1s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@analogjs/vite-plugin-angular](https://github.com/analogjs/analog) | devDependencies | minor | [`~2.1.2` -> `~2.5.0`](https://renovatebot.com/diffs/npm/@analogjs%2fvite-plugin-angular/2.1.3/2.5.0) |
| [@analogjs/vitest-angular](https://analogjs.org) ([source](https://github.com/analogjs/analog)) | devDependencies | minor | [`~2.1.2` -> `~2.5.0`](https://renovatebot.com/diffs/npm/@analogjs%2fvitest-angular/2.1.3/2.5.0) |

---

### Release Notes

<details>
<summary>analogjs/analog (@&#8203;analogjs/vite-plugin-angular)</summary>

### [`v2.5.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#250-2026-04-28)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.10...v2.5.0)

##### Bug Fixes

- add angular-compiler to publish script ([5c86802](https://github.com/analogjs/analog/commit/5c86802ab4e3858414de47f84039181c846c7012))
- **angular-compiler:** add type-only import elision to angular compiler ([#&#8203;2249](https://github.com/analogjs/analog/issues/2249)) ([f66f042](https://github.com/analogjs/analog/commit/f66f0424afd815b91abbf01528c66eeb3c846dc0))
- **angular-compiler:** auto-import decorator classes for signal api downleveling in jit ([d8a6265](https://github.com/analogjs/analog/commit/d8a62650878e537eac70bdf1285962cf09d6e044))
- **angular-compiler:** construct setClassMetadata entries as plain objects ([546f427](https://github.com/analogjs/analog/commit/546f427e5495232987d497d5ebfe08cad20f6d51))
- **angular-compiler:** correct signal aliases, query refs, inheritance ([d57bc61](https://github.com/analogjs/analog/commit/d57bc61f1736ad66e1b5fabf479e058f63f58484))
- **angular-compiler:** dedupe declarations across imports and module exports ([919009a](https://github.com/analogjs/analog/commit/919009a744c62c1abffdcd7dc9f063d80900c05d))
- **angular-compiler:** default contentChild() descendants to true ([4849312](https://github.com/analogjs/analog/commit/4849312e327aa9363a6f024269981d2de93f284a))
- **angular-compiler:** defensive BinaryOperator map for Angular v19/v20 ([1a91f93](https://github.com/analogjs/analog/commit/1a91f932cc353efff9caf907bd48ceecc4480635))
- **angular-compiler:** defensive isAssignment check for Angular 20.0.0 ([8583dd1](https://github.com/analogjs/analog/commit/8583dd1ee3d5a61850975d45b677f423fb772895))
- **angular-compiler:** emit /*@&#8203;**PURE***/ on Ivy field assignments ([c0d4f69](https://github.com/analogjs/analog/commit/c0d4f696110becded1b90c77dd0d5b84f46ac2de))
- **angular-compiler:** emit bracket access for non-identifier field keys ([956c703](https://github.com/analogjs/analog/commit/956c703af97b1628b93f93fdd688910178a4dd5d))
- **angular-compiler:** emit defer deps as import().then(m => m.X) ([56d9fd5](https://github.com/analogjs/analog/commit/56d9fd580c25a77cde285876babffc6564a12543))
- **angular-compiler:** emit invalidfactory for explicit import type di tokens ([2f2204f](https://github.com/analogjs/analog/commit/2f2204f2883677636a7d4678594d6bf2b6c4f871))
- **angular-compiler:** extract output() alias in registry ([e7b1d0d](https://github.com/analogjs/analog/commit/e7b1d0d71fe2332b0eedf1f97bd76e3d34655308))
- **angular-compiler:** forward [@&#8203;Injectable](https://github.com/Injectable) provider config to compileInjectable ([ed9c264](https://github.com/analogjs/analog/commit/ed9c2641e36bc503b1611551b2d265f236b0a959))
- **angular-compiler:** hoist helpers via appendLeft when insertPos is 0 ([8a15184](https://github.com/analogjs/analog/commit/8a15184d423b0818c3c6d9f7429095554eecbd05))
- **angular-compiler:** hoisted helpers survive type-only import elision ([99e1ba4](https://github.com/analogjs/analog/commit/99e1ba48d8b08f8eb8de53fdae5801ea7e909d7a))
- **angular-compiler:** hostDirectives, emitExpr safety, TDZ hoisting, misc compilation fixes ([#&#8203;2255](https://github.com/analogjs/analog/issues/2255)) ([796e3e0](https://github.com/analogjs/analog/commit/796e3e09b0e7e5055fed2f1c765cd60a35c6d5b2))
- **angular-compiler:** improve handling of type elision for imports/exports ([#&#8203;2257](https://github.com/analogjs/analog/issues/2257)) ([1605a7b](https://github.com/analogjs/analog/commit/1605a7b6eb0870f9bb09e79c07debf2ac63984c4))
- **angular-compiler:** make hoisting dependency-aware to prevent TDZ ([#&#8203;2286](https://github.com/analogjs/analog/issues/2286)) ([f33f6b5](https://github.com/analogjs/analog/commit/f33f6b514cd204df79e7661058fc79312e561324))
- **angular-compiler:** merge styleUrl into existing inline styles array ([56b109f](https://github.com/analogjs/analog/commit/56b109f2c0c8c7e79f5116758b501519a610380d))
- **angular-compiler:** parse signal query read/descendants options ([175356c](https://github.com/analogjs/analog/commit/175356c0f45a90bd6a159c0c6ce43b04ef54b3fe))
- **angular-compiler:** preserve [@&#8203;Injectable](https://github.com/Injectable) in JIT mode for providedIn registration ([1a9745c](https://github.com/analogjs/analog/commit/1a9745c41745d5c9c3c538b905b9a3861dd5e421))
- **angular-compiler:** preserve constructor di token imports from elision ([#&#8203;2270](https://github.com/analogjs/analog/issues/2270)) ([9de43fa](https://github.com/analogjs/analog/commit/9de43fa35ee1926170d936d848098c62fafd7c74))
- **angular-compiler:** preserve ivy fields when lowering trailing class field ([79cd5c1](https://github.com/analogjs/analog/commit/79cd5c1a1a97c5964ffba2a53a8fd0769d12b381))
- **angular-compiler:** preserve operator precedence in emitted binary expressions ([#&#8203;2275](https://github.com/analogjs/analog/issues/2275)) ([e2dfb5a](https://github.com/analogjs/analog/commit/e2dfb5a9211b7f7718eb10e953379271f6ca5597))
- **angular-compiler:** provide flat defer fields on Angular v17 ([70a4d9b](https://github.com/analogjs/analog/commit/70a4d9b20dd10db0261d22e81d46640de323c8da))
- **angular-compiler:** reject ambiguous union/intersection DI tokens ([c379707](https://github.com/analogjs/analog/commit/c3797079ec4b6b92451d9a642524ac5f92cc07a9))
- **angular-compiler:** set componentMeta.interpolation for partial mode on v19/v20 ([a09ff88](https://github.com/analogjs/analog/commit/a09ff889e2b93a6a6c1c0839884e1f91f537497b))
- **angular-compiler:** skip arrow fn types when finding assignment = … ([#&#8203;2274](https://github.com/analogjs/analog/issues/2274)) ([992e180](https://github.com/analogjs/analog/commit/992e1803937db2fac381940982cc2f1141ddf3ff))
- **angular-compiler:** strip ESM .js extension when probing dts re-exports ([d1f65ef](https://github.com/analogjs/analog/commit/d1f65efb69f2972279425c47ee63b73edeb980ae))
- **angular-compiler:** track hasTransform on signal inputs in registry ([fd8acd4](https://github.com/analogjs/analog/commit/fd8acd49ebf2f80ee7b6e861fca5ad4578cfa78b))
- **angular-compiler:** unwrap forwardRef inside [@&#8203;Inject](https://github.com/Inject) decorator ([dcb221a](https://github.com/analogjs/analog/commit/dcb221a5cef963ee97feee80f8ac77ecd52393da))
- **angular-compiler:** use original export name for aliased defer imports ([6ab34dd](https://github.com/analogjs/analog/commit/6ab34dd0be10784b26e2117e4dd54fb21ed10f50))
- **angular-compiler:** wrap switch cases in blocks for biome lint ([8fc75d9](https://github.com/analogjs/analog/commit/8fc75d9f6a55e0592aae4a72c831c4f6f951bfea))
- **angular-compiler:** wrap Write\*Expr emissions in parens for nesting precedence ([48f80e4](https://github.com/analogjs/analog/commit/48f80e422bfe58b30810f5a850af4accf171cd94))
- **content:** scope slash-containing slugs to file's subdirectory ([#&#8203;2318](https://github.com/analogjs/analog/issues/2318)) ([ee69df7](https://github.com/analogjs/analog/commit/ee69df77415582d03f071080d59dc1766419da4c))
- correct release config replacement file path ([c91ce2d](https://github.com/analogjs/analog/commit/c91ce2dc2fb5e49991acf16a6fd2fb147835b579))
- **platform:** reset cached tViews between SSR requests for correct i18n locale switching ([#&#8203;2301](https://github.com/analogjs/analog/issues/2301)) ([a29465d](https://github.com/analogjs/analog/commit/a29465d31743a8871bc93ed3d62d9649d5d40a71))
- **router:** reset cached tViews between SSR requests for correct i18n locale switching ([#&#8203;2295](https://github.com/analogjs/analog/issues/2295)) ([d2ce3e5](https://github.com/analogjs/analog/commit/d2ce3e5f1738fd586a39b1a9d87b668cd1971e38))
- **storybook-angular:** forward applyDecorators in testing ([#&#8203;2236](https://github.com/analogjs/analog/issues/2236)) ([31d996c](https://github.com/analogjs/analog/commit/31d996c035f7a6b9e533a39f735176663fcc07d3))
- **storybook-angular:** use oxc config instead of esbuild for Vite 8 ([#&#8203;2313](https://github.com/analogjs/analog/issues/2313)) ([ef16e7e](https://github.com/analogjs/analog/commit/ef16e7e9cf1676b37bbbc781f60789ff1e5811ff))
- **vite-plugin-angular,angular-compiler:** support Vite 6-8 and fix type-elision helper loss ([0aa26e0](https://github.com/analogjs/analog/commit/0aa26e06b99cc52b6e2b09c69602d44c62a0fdee))
- **vite-plugin-angular:** add Vite Plugin Registry compatibility ([#&#8203;2314](https://github.com/analogjs/analog/issues/2314)) ([c3444d1](https://github.com/analogjs/analog/commit/c3444d105f8b924cd815f4b8168eaa9575e18035))
- **vite-plugin-angular:** bypass server.fs restrictions on ?raw template imports ([#&#8203;2259](https://github.com/analogjs/analog/issues/2259)) ([87512a2](https://github.com/analogjs/analog/commit/87512a254698ce78439d0c79eb86a7784dea0c17))
- **vite-plugin-angular:** fix vitest sourcemap plugin for Vite 7 ([74d52e7](https://github.com/analogjs/analog/commit/74d52e7f72d01e972df1c182f5c11c6c70e033a4))
- **vite-plugin-angular:** handle .ts files not in Angular program ([#&#8203;2265](https://github.com/analogjs/analog/issues/2265)) ([fda852d](https://github.com/analogjs/analog/commit/fda852d389b1506d8969ff05c4c610b6673b7888))
- **vite-plugin-angular:** honor Vitest test.css semantics to skip CSS preprocessing ([#&#8203;2298](https://github.com/analogjs/analog/issues/2298)) ([d7bd331](https://github.com/analogjs/analog/commit/d7bd3315543488665c4a9c1cfd0c0a3426552986))
- **vite-plugin-angular:** keep barrel registry in sync at dev time ([f5f7ef1](https://github.com/analogjs/analog/commit/f5f7ef1e013b8352d1875764a74337f18ced271f))
- **vite-plugin-angular:** let CSS ?inline imports flow through Vite's pipeline ([#&#8203;2311](https://github.com/analogjs/analog/issues/2311)) ([ae803bb](https://github.com/analogjs/analog/commit/ae803bb410638b42436d173ce53b7bb81040988a))
- **vite-plugin-angular:** return empty CSS instead of raw SCSS when test.css is disabled ([#&#8203;2306](https://github.com/analogjs/analog/issues/2306)) ([eef84de](https://github.com/analogjs/analog/commit/eef84de75f5c2ea14a753afe6c2920fb27fc1b35))
- **vite-plugin-angular:** route template/style imports through virtual module ids ([#&#8203;2287](https://github.com/analogjs/analog/issues/2287)) ([98cfe64](https://github.com/analogjs/analog/commit/98cfe649c3a72c9e1a6daf97cc5ba6eb9f825c5f))
- **vite-plugin-angular:** stop matching .tsrx in TS extension regex ([2d23b19](https://github.com/analogjs/analog/commit/2d23b197f30146a0822bdf9cec6559b44d2f8135))
- **vite-plugin-angular:** use empty string instead of undefined for mapRoot/sourceRoot overrides (beta) ([#&#8203;2322](https://github.com/analogjs/analog/issues/2322)) ([cfd6cd6](https://github.com/analogjs/analog/commit/cfd6cd660f04cd98eae7a0dd231ce8ad793ed4d5))
- **vite-plugin-angular:** use virtual modules for external JIT styles ([#&#8203;2283](https://github.com/analogjs/analog/issues/2283)) ([add0337](https://github.com/analogjs/analog/commit/add033798aa82e806dbe94cb66dab8bee53ba792))
- **vitest-angular:** clean generated snapshot ids ([#&#8203;2238](https://github.com/analogjs/analog/issues/2238)) ([ac933ba](https://github.com/analogjs/analog/commit/ac933ba18321c5536a59ccd067fefdd769e59c9c))
- **vitest-angular:** normalize snapshot whitespace ([#&#8203;2237](https://github.com/analogjs/analog/issues/2237)) ([d1ba31f](https://github.com/analogjs/analog/commit/d1ba31f90b7515ba49e7cbe27857b5bb983d8ceb))

##### Features

- add [@&#8203;analogjs/angular-compiler](https://github.com/analogjs/angular-compiler) package ([#&#8203;2221](https://github.com/analogjs/analog/issues/2221)) ([d2dfbe0](https://github.com/analogjs/analog/commit/d2dfbe0b599d4739d62fffb3f7b3740e84eb31d6))
- **angular-compiler:** add partial compilation mode for library support ([#&#8203;2269](https://github.com/analogjs/analog/issues/2269)) ([bfe0c62](https://github.com/analogjs/analog/commit/bfe0c62d86fd6286942d06eff41f06e7db314357))
- **angular-compiler:** expand tuple barrel imports for spartan-style libs ([bf4595f](https://github.com/analogjs/analog/commit/bf4595f19f03bedcbb0ba8fa80376b68285a90f5))
- **angular-compiler:** resolve ${var} interpolation in metadata strings ([79ade33](https://github.com/analogjs/analog/commit/79ade33e96e8f07316b7231c97837d2384fdb96d))
- **angular-compiler:** structured debug logging via obug ([b155f53](https://github.com/analogjs/analog/commit/b155f53b9fd207c09fccca019d3939e891c344a8))
- **angular-compiler:** support useDefineForClassFields: false ([#&#8203;2267](https://github.com/analogjs/analog/issues/2267)) ([f0a5908](https://github.com/analogjs/analog/commit/f0a59081593fdfec28656c719f27117f3f0bd325))
- **astro-angular:** add support for client hydration with Angular components ([#&#8203;2212](https://github.com/analogjs/analog/issues/2212)) ([d36de5b](https://github.com/analogjs/analog/commit/d36de5baa8fa70341c0d67731d5ba32fe70ea743))
- **docs:** add AI integrations guide ([#&#8203;2234](https://github.com/analogjs/analog/issues/2234)) ([545f8fc](https://github.com/analogjs/analog/commit/545f8fc5c714e97ee784ed9f6db0052eb2ee086b))
- improve hmr with dynamic ivy field copying and directive/pipe support ([d568bf2](https://github.com/analogjs/analog/commit/d568bf26b8cf562cb6aebffddadb01b827c40ae8))
- **platform:** add shiki skipLangs option for analog v2 ([#&#8203;2282](https://github.com/analogjs/analog/issues/2282)) ([d6e932c](https://github.com/analogjs/analog/commit/d6e932c0d4031d45bc259b89c7b4bc797e5099aa))
- **platform:** passthrough fastCompile and fastCompileMode to vite-plugin-angular ([f085ecc](https://github.com/analogjs/analog/commit/f085ecc0389a2bb5e94bd9391f551e960c378e1c))
- resolve ngmodule exports to correct sub-entry import paths ([07bc3d1](https://github.com/analogjs/analog/commit/07bc3d141104082664a55cf928918194f9ba8850))
- runtime i18n support with $localize ([#&#8203;2268](https://github.com/analogjs/analog/issues/2268)) ([7dbc7df](https://github.com/analogjs/analog/commit/7dbc7dfa65140b63c7e0958a3c5da49963ea9b05))
- **vite-plugin-angular:** add globalThis external-registry hook for fastCompile ([aabb5ab](https://github.com/analogjs/analog/commit/aabb5abcad5c5eb0ceaf34e5234c9ad42aac29d5))
- **vite-plugin-nitro:** add recursive option to PrerenderContentDir ([#&#8203;2318](https://github.com/analogjs/analog/issues/2318)) ([42a5524](https://github.com/analogjs/analog/commit/42a5524acf0a2860758fc1a11997b3d15215a793))

##### Performance Improvements

- **angular-compiler:** optimize using oxc, add tests, consolidate strings ([#&#8203;2260](https://github.com/analogjs/analog/issues/2260)) ([64a4696](https://github.com/analogjs/analog/commit/64a469627926e2125cf45b95925fecb4919e13a7))

#### [2.4.10](https://github.com/analogjs/analog/compare/v2.4.9...v2.4.10) (2026-04-21)

##### Bug Fixes

- **vite-plugin-angular:** let CSS ?inline imports flow through Vite's native pipeline ([#&#8203;2310](https://github.com/analogjs/analog/issues/2310)) ([07f8b47](https://github.com/analogjs/analog/commit/07f8b471628cdaa6e3c452a24ff965c06b4d4355))

#### [2.4.9](https://github.com/analogjs/analog/compare/v2.4.8...v2.4.9) (2026-04-20)

##### Bug Fixes

- **content:** scope slash-containing slugs to file's subdirectory ([#&#8203;2318](https://github.com/analogjs/analog/issues/2318)) ([ee69df7](https://github.com/analogjs/analog/commit/ee69df77415582d03f071080d59dc1766419da4c))

##### Features

- **vite-plugin-nitro:** add recursive option to PrerenderContentDir ([#&#8203;2318](https://github.com/analogjs/analog/issues/2318)) ([42a5524](https://github.com/analogjs/analog/commit/42a5524acf0a2860758fc1a11997b3d15215a793))

### [`v2.4.10`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#2410-2026-04-21)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.9...v2.4.10)

##### Bug Fixes

- **vite-plugin-angular:** let CSS ?inline imports flow through Vite's native pipeline ([#&#8203;2310](https://github.com/analogjs/analog/issues/2310)) ([07f8b47](https://github.com/analogjs/analog/commit/07f8b471628cdaa6e3c452a24ff965c06b4d4355))

### [`v2.4.9`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#249-2026-04-20)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.8...v2.4.9)

##### Bug Fixes

- **content:** scope slash-containing slugs to file's subdirectory ([#&#8203;2318](https://github.com/analogjs/analog/issues/2318)) ([ee69df7](https://github.com/analogjs/analog/commit/ee69df77415582d03f071080d59dc1766419da4c))

##### Features

- **vite-plugin-nitro:** add recursive option to PrerenderContentDir ([#&#8203;2318](https://github.com/analogjs/analog/issues/2318)) ([42a5524](https://github.com/analogjs/analog/commit/42a5524acf0a2860758fc1a11997b3d15215a793))

### [`v2.4.8`](https://github.com/analogjs/analog/releases/tag/v2.4.8)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.7...v2.4.8)

##### Bug Fixes

- **vite-plugin-angular:** honor Vitest test.css semantics to skip CSS preprocessing ([#&#8203;2298](https://github.com/analogjs/analog/issues/2298)) ([90ac242](https://github.com/analogjs/analog/commit/90ac242b3d03dd6745b9a957bd6bc7d8c7eaeb1d))

### [`v2.4.7`](https://github.com/analogjs/analog/releases/tag/v2.4.7)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.6...v2.4.7)

##### Bug Fixes

- **vite-plugin-angular:** route template/style imports through virtual module ids ([#&#8203;2287](https://github.com/analogjs/analog/issues/2287)) ([6ae244c](https://github.com/analogjs/analog/commit/6ae244c421b54a2834f58bc3ee8a51958f8d3347))

### [`v2.4.6`](https://github.com/analogjs/analog/releases/tag/v2.4.6)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.5...v2.4.6)

##### Bug Fixes

- **vite-plugin-angular:** use virtual modules for external JIT styles ([#&#8203;2283](https://github.com/analogjs/analog/issues/2283)) ([358faf7](https://github.com/analogjs/analog/commit/358faf70499680f29f60e05bcaa61055f0f52557))

### [`v2.4.5`](https://github.com/analogjs/analog/releases/tag/v2.4.5)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.4...v2.4.5)

##### Bug Fixes

- **vite-plugin-angular:** emit ?analog-{inline,raw} from JIT transform output ([#&#8203;2272](https://github.com/analogjs/analog/issues/2272)) ([48f3ff9](https://github.com/analogjs/analog/commit/48f3ff9c7db10028fd08e95a5153043bf591d5f9))

### [`v2.4.4`](https://github.com/analogjs/analog/releases/tag/v2.4.4)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.3...v2.4.4)

##### Bug Fixes

- **vite-plugin-angular:** handle ?inline style imports in load hook for Vitest ([#&#8203;2271](https://github.com/analogjs/analog/issues/2271)) ([32d5b2d](https://github.com/analogjs/analog/commit/32d5b2ddeea0b7f7e93c32b40f53b184bd12923e))

### [`v2.4.3`](https://github.com/analogjs/analog/releases/tag/v2.4.3)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.2...v2.4.3)

##### Bug Fixes

- **vite-plugin-angular:** bypass Vite 8.0.5+ Denied ID for style ?inline imports ([#&#8203;2264](https://github.com/analogjs/analog/issues/2264)) ([812c011](https://github.com/analogjs/analog/commit/812c011277ad72382def7ff77581b0fa61eec695))

### [`v2.4.2`](https://github.com/analogjs/analog/releases/tag/v2.4.2)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.1...v2.4.2)

##### Bug Fixes

- **vite-plugin-angular:** bypass Vite 7.3.2+ server.fs restrictions for style ?inline imports ([#&#8203;2262](https://github.com/analogjs/analog/issues/2262)) ([7e43cc4](https://github.com/analogjs/analog/commit/7e43cc4281b0a78ebee93bbdd58b64381b5cab2a))

### [`v2.4.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#2410-2026-04-21)

[Compare Source](https://github.com/analogjs/analog/compare/v2.4.0...v2.4.1)

##### Bug Fixes

- **vite-plugin-angular:** let CSS ?inline imports flow through Vite's native pipeline ([#&#8203;2310](https://github.com/analogjs/analog/issues/2310)) ([07f8b47](https://github.com/analogjs/analog/commit/07f8b471628cdaa6e3c452a24ff965c06b4d4355))

### [`v2.4.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#240-2026-03-30)

[Compare Source](https://github.com/analogjs/analog/compare/v2.3.1...v2.4.0)

##### Bug Fixes

- **astro-angular:** style tag ordering for multiple islands ([#&#8203;2210](https://github.com/analogjs/analog/issues/2210)) ([b306097](https://github.com/analogjs/analog/commit/b306097442be5f1f38f7b47762c67c09febec628))
- **astro-angular:** support astro v6 using vite environment api ([#&#8203;2133](https://github.com/analogjs/analog/issues/2133)) ([e9fd9c6](https://github.com/analogjs/analog/commit/e9fd9c6134fa33aa0283bda7efb3c8f54cef15ab))
- **content:** resolve content files by bare slug lookup ([#&#8203;2205](https://github.com/analogjs/analog/issues/2205)) ([7e79d24](https://github.com/analogjs/analog/commit/7e79d24a9cd2a8e70dea5b458db59cd4e5ae31ff))
- **create-analog:** bump to Vitest 4.1, update CI workflow versions ([54b5112](https://github.com/analogjs/analog/commit/54b51125130e897faf787db2b918d5ae16e4802f))
- fix build and unit tests ([dc6842c](https://github.com/analogjs/analog/commit/dc6842cd9ef79cc1274d92b908f25ec80bbca9d3))
- fix vitest build and ci workflows ([a4b129a](https://github.com/analogjs/analog/commit/a4b129a589090043d0b06f6e72bbbc259aa23f9e))
- **nx-plugin:** remove full path to main.ts for Nx projects ([#&#8203;2164](https://github.com/analogjs/analog/issues/2164)) ([39f0d7c](https://github.com/analogjs/analog/commit/39f0d7ce411cf4c59b5b446337affaa818a4e48f))
- **nx-plugin:** restore builders configuration ([1d2e4e8](https://github.com/analogjs/analog/commit/1d2e4e8b115da2fb1b63c67f017f861dac7b2f4c))
- **nx-plugin:** restore schematics configuration ([#&#8203;2167](https://github.com/analogjs/analog/issues/2167)) ([e74fa68](https://github.com/analogjs/analog/commit/e74fa6829c340976403ba46ca933bd72be2dde2d))
- **platform:** allow using custom vite plugins for Angular compilation ([#&#8203;2102](https://github.com/analogjs/analog/issues/2102)) ([8bb4fb4](https://github.com/analogjs/analog/commit/8bb4fb44c4ccb1a0d9c51dcd6fe8c9ab840f0e4e))
- **platform:** separate disabling highlighting from content discovery ([#&#8203;2110](https://github.com/analogjs/analog/issues/2110)) ([618c42c](https://github.com/analogjs/analog/commit/618c42cf7bc859e552cb1a3b02c6092c18e99e21))
- **router:** fix and add unit tests for route module invalidation on file changes ([b9325af](https://github.com/analogjs/analog/commit/b9325af0f0748c7a69610de5782e1fe12461164e))
- **router:** use non-greedy regex for path normalization ([#&#8203;2093](https://github.com/analogjs/analog/issues/2093)) ([fa5dd9b](https://github.com/analogjs/analog/commit/fa5dd9b7e6f9e245f5c6379f2f35ee35c7be75e3))
- update dependencies and package manager versions across projects ([#&#8203;2106](https://github.com/analogjs/analog/issues/2106)) ([429536c](https://github.com/analogjs/analog/commit/429536c7e5f479aa06eb61a3df51cf4223e30e14)), closes [#&#8203;2040](https://github.com/analogjs/analog/issues/2040)
- **vite-plugin-angular:** ensure sequential compilation for client and ssr bundles ([#&#8203;2109](https://github.com/analogjs/analog/issues/2109)) ([008bd1c](https://github.com/analogjs/analog/commit/008bd1c20daa4c16fe92da036e99219056da4ff3))
- **vite-plugin-angular:** hash styleId to prevent filename exceeding max length ([#&#8203;2090](https://github.com/analogjs/analog/issues/2090)) ([2aa2114](https://github.com/analogjs/analog/commit/2aa211479e16cc106f957d5e373ea3a1386abfc6))
- **vite-plugin-angular:** normalize paths across plugin & live reload ([#&#8203;2126](https://github.com/analogjs/analog/issues/2126)) ([cc98bf7](https://github.com/analogjs/analog/commit/cc98bf727b181077c87a536f29d7128414d8904d))
- **vite-plugin-angular:** skip esm transform with Rolldown for Vitest ([#&#8203;2169](https://github.com/analogjs/analog/issues/2169)) ([20c720b](https://github.com/analogjs/analog/commit/20c720bc8178174041002f400ed4d694dabb30c1))
- **vitest-angular:** fix imports for snapshot serializers ([#&#8203;2211](https://github.com/analogjs/analog/issues/2211)) ([8e9f73d](https://github.com/analogjs/analog/commit/8e9f73dfde0e03e0943512dd18f432f20307f3f5))
- **vitest-angular:** support environment providers ([#&#8203;2129](https://github.com/analogjs/analog/issues/2129)) ([a90aa12](https://github.com/analogjs/analog/commit/a90aa1272ed64d626386283ae7b9a09775a07287))

##### Features

- **astro-angular:** add option to move component styles to document head ([#&#8203;2162](https://github.com/analogjs/analog/issues/2162)) ([2361afa](https://github.com/analogjs/analog/commit/2361afaa31247e61483517d321f541c7419bc79b))
- **content:** extract TOC to be property on contentFile ([#&#8203;2091](https://github.com/analogjs/analog/issues/2091)) ([4e870cc](https://github.com/analogjs/analog/commit/4e870cc99e74c889743503522ae4c6f3be5d9247))
- **create-analog:** add snapshot serializers ([3318263](https://github.com/analogjs/analog/commit/33182636a130e4c7b3f213aece7a020cf0981c3e))
- update vite to stable v8.0.0 ([#&#8203;2111](https://github.com/analogjs/analog/issues/2111)) ([cf35c65](https://github.com/analogjs/analog/commit/cf35c658a3966a514e95aa2c0e4c9c514999c4bd))
- **vite-plugin-angular:** working fileReplacements and liveReload for Angular Compilation API ([7adf8c1](https://github.com/analogjs/analog/commit/7adf8c18b7786047dc6156eb6c2eaeff0961e5f4))
- **vitest-angular:** add `teardown.destroyAfterEach` option and deprecate `browserMode` option ([#&#8203;2054](https://github.com/analogjs/analog/issues/2054)) ([2fe2e1c](https://github.com/analogjs/analog/commit/2fe2e1c9304a933b0070fb2e28c8e92def68f077))
- **vitest-angular:** add reusable snapshot serializers ([#&#8203;2163](https://github.com/analogjs/analog/issues/2163)) ([9089c8d](https://github.com/analogjs/analog/commit/9089c8d8f315aad4792d6b37b18db62d951301b2))

### [`v2.3.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#231-beta1-2026-02-27)

[Compare Source](https://github.com/analogjs/analog/compare/v2.3.0...v2.3.1)

##### Bug Fixes

- **vite-plugin-angular:** hash styleId to prevent filename exceeding max length ([#&#8203;2090](https://github.com/analogjs/analog/issues/2090)) ([2aa2114](https://github.com/analogjs/analog/commit/2aa211479e16cc106f957d5e373ea3a1386abfc6))

### [`v2.3.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#230-2026-02-25)

[Compare Source](https://github.com/analogjs/analog/compare/v2.2.3...v2.3.0)

##### Bug Fixes

- add dependsOn to astro-angular build ([1a6182d](https://github.com/analogjs/analog/commit/1a6182d311e6235a6b1d3ae2e6a3dfa37697ee46))
- build before publish ([432ffa6](https://github.com/analogjs/analog/commit/432ffa6a987c679bb7eea45f5c6fa7eb235dc286))
- bump build ([1c61fbc](https://github.com/analogjs/analog/commit/1c61fbc289a079a2ef5e3ce65dce9c7e9f2a7fed))
- publish from workflow ([390dd74](https://github.com/analogjs/analog/commit/390dd747f2d2e341260ac20d57f2b7d4057e371c))
- remove npm token from semantic release ([ba42f16](https://github.com/analogjs/analog/commit/ba42f16842772315e61e7ea29608c9df42504c97))
- remove npm token publishing ([1c490ad](https://github.com/analogjs/analog/commit/1c490ad360733095e56abd9be97f59f81322714a))
- revert back to semantic release ([ea10b1b](https://github.com/analogjs/analog/commit/ea10b1b7caa573ef65b7796ab81796073fc6183b))
- **storybook-angular): revert "fix(storybook-angular:** add missing applyDecorators to render annotaions" ([#&#8203;2088](https://github.com/analogjs/analog/issues/2088)) ([86e2a6a](https://github.com/analogjs/analog/commit/86e2a6a4c30aa7ab2d469bd18db32b0ec7daca44))
- **storybook-angular:** add missing applyDecorators to render annotaions ([#&#8203;2086](https://github.com/analogjs/analog/issues/2086)) ([9a14163](https://github.com/analogjs/analog/commit/9a141638ad674e4b5356ed6a0120f41d8ac90f18))
- **storybook-angular:** add missing await to storybook-angular preset core ([#&#8203;2081](https://github.com/analogjs/analog/issues/2081)) ([352870a](https://github.com/analogjs/analog/commit/352870a86ca8dd08446b8538e04487e64398d0f4))
- **storybook-angular:** resolve experimentalZoneless in Vitest path ([#&#8203;2059](https://github.com/analogjs/analog/issues/2059)) ([447dad2](https://github.com/analogjs/analog/commit/447dad2129f8840bb279d1e1eda6e838bca0d8da))
- update implicit dependencies for build ([cfb0abc](https://github.com/analogjs/analog/commit/cfb0abc5b0be91dc498f443778e5fa1bef95a2c3))
- update node setup in release workflow ([5bd0923](https://github.com/analogjs/analog/commit/5bd0923d965dcea4fda160cdde8aab9b61601a76))
- update node version ([4aaa6bd](https://github.com/analogjs/analog/commit/4aaa6bdb79e1909b1b8671a6cda7312a190e9082))
- **vite-plugin-angular:** add missing tinyglobby dependency ([#&#8203;2069](https://github.com/analogjs/analog/issues/2069)) ([8661cb6](https://github.com/analogjs/analog/commit/8661cb6ab3754c05ed3b38a268570cd92dfd7147))
- **vitest-angular:** add missing zone.js optional peer dependency ([#&#8203;2071](https://github.com/analogjs/analog/issues/2071)) ([88a1a55](https://github.com/analogjs/analog/commit/88a1a55825e715842e28d810894fa86986c1b1e4))
- **vitest-angular:** fix setupTestBed's providers option ([#&#8203;2072](https://github.com/analogjs/analog/issues/2072)) ([2e7a02f](https://github.com/analogjs/analog/commit/2e7a02f4f541b8c5a02a0f5e9f7f0b7ad354f087))

##### Features

- **router:** support optional catch all routes ([#&#8203;2043](https://github.com/analogjs/analog/issues/2043)) ([ba9fc09](https://github.com/analogjs/analog/commit/ba9fc09fdd293d338299d949cadbfdc8137677e8))
- **vite-plugin-nitro:** add option for markdown source output alongside prerendered routes ([#&#8203;2082](https://github.com/analogjs/analog/issues/2082)) ([c15d20b](https://github.com/analogjs/analog/commit/c15d20b9887008fda7714437280dbfc1bb66b336))
- **vitest-angular:** add setup schematic and ng-add support ([#&#8203;2056](https://github.com/analogjs/analog/issues/2056)) ([cc26771](https://github.com/analogjs/analog/commit/cc26771aa72cb2a38c2fb7ca070840eccf1e7951))

### [`v2.2.3`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#223-2026-01-29)

[Compare Source](https://github.com/analogjs/analog/compare/v2.2.2...v2.2.3)

##### Bug Fixes

- **content:** allow retrieving content file resource by slug ([#&#8203;2051](https://github.com/analogjs/analog/issues/2051)) ([5ac1013](https://github.com/analogjs/analog/commit/5ac101396c73856e52a1fb888c55eacd54abd62a))
- **content:** export content loader tokens for custom content list/file ([#&#8203;2050](https://github.com/analogjs/analog/issues/2050)) ([e45f189](https://github.com/analogjs/analog/commit/e45f1894cb8ba204481df7bd1d17d133639370c4))
- **vite-plugin-nitro:** trigger environment builds before server build ([#&#8203;2048](https://github.com/analogjs/analog/issues/2048)) ([3dd3755](https://github.com/analogjs/analog/commit/3dd375532d4f830ab5e04e970b4c1f869f99abcc))

### [`v2.2.2`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#222-2026-01-14)

[Compare Source](https://github.com/analogjs/analog/compare/v2.2.1...v2.2.2)

##### Bug Fixes

- **storybook-angular:** use vite config root when angularBuilderContext unavailable ([#&#8203;2033](https://github.com/analogjs/analog/issues/2033)) ([76cfb94](https://github.com/analogjs/analog/commit/76cfb948c2571bf21522d185d4dc43fa4e4c121e))

### [`v2.2.1`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#221-2026-01-05)

[Compare Source](https://github.com/analogjs/analog/compare/v2.2.0...v2.2.1)

##### Bug Fixes

- **nx-plugin:** add [@&#8203;nx/vite](https://github.com/nx/vite) for Nx workspaces ([08ba372](https://github.com/analogjs/analog/commit/08ba372257044890aa2f90bff8898c293b15dba5))
- **nx-plugin:** add [@&#8203;nx/vite](https://github.com/nx/vite) to preset packages ([0aca507](https://github.com/analogjs/analog/commit/0aca507648fb28e1d77a2902ab10299856270e11))
- **nx-plugin:** skip installing Vitest packages when skipped during migration ([#&#8203;2017](https://github.com/analogjs/analog/issues/2017)) ([a573684](https://github.com/analogjs/analog/commit/a57368484ca8632f325d966964dae07055e43dcb))
- **storybook-angular:** resolve relative styles from project root ([#&#8203;2025](https://github.com/analogjs/analog/issues/2025)) ([33e7b6c](https://github.com/analogjs/analog/commit/33e7b6cf19a51b49774b7405cec1abed494d46f7))
- **vite-plugin-angular:** improve compatibility with older TypeScript versions ([#&#8203;2021](https://github.com/analogjs/analog/issues/2021)) ([aab2f2a](https://github.com/analogjs/analog/commit/aab2f2a4e7297bc1c86b7f185efe204c4592a828))
- **vite-plugin-angular:** process styles in jit mode instead of returning raw output ([#&#8203;2024](https://github.com/analogjs/analog/issues/2024)) ([bcb6da9](https://github.com/analogjs/analog/commit/bcb6da9f6d112fe174e90a390235eb5adf14982e))
- **vitest-angular:** ensure setupTestBed defaults merge ([#&#8203;2019](https://github.com/analogjs/analog/issues/2019)) ([f36339f](https://github.com/analogjs/analog/commit/f36339ff9835b04f6137b1a235ec2f35157293d7))

### [`v2.2.0`](https://github.com/analogjs/analog/blob/HEAD/CHANGELOG.md#220-2025-12-16)

[Compare Source](https://github.com/analogjs/analog/compare/v2.1.3...v2.2.0)

##### Bug Fixes

- **create-analog:** remove angular-devkit/build-angular from devDependencies ([ada2ecc](https://github.com/analogjs/analog/commit/ada2ecc7fddf8247472b30439d15ba014eb4df30))
- **nx-plugin:** adjust Vitest version for Angular v20 ([c4b2ea7](https://github.com/analogjs/analog/commit/c4b2ea77c757ebd1aa6c17ff5e3aaab96d239fb3))
- **nx-plugin:** pass Nx version for package version detection ([42a9630](https://github.com/analogjs/analog/commit/42a963025bd31cc6279e9d135d7cd7cce894e00c))
- **storybook-angular:** creates config.plugin array when undefined ([#&#8203;1998](https://github.com/analogjs/analog/issues/1998)) ([0dd147c](https://github.com/analogjs/analog/commit/0dd147c4f764dbaa2c82a04e887b3ecad91d1e1a))
- support canary Nx releases ([664b1a2](https://github.com/analogjs/analog/commit/664b1a27d86acbc53c71d4ab2fedbf0e1a12040f))
- **vitest-angular:** reset TestBed between tests ([6f704b0](https://github.com/analogjs/analog/commit/6f704b0146303f6804ca0be1e4af959b1b70e0e4)), closes [#&#8203;1994](https://github.com/analogjs/analog/issues/1994)

##### Features

- add itemprop meta tag support to MetaTag types ([543b351](https://github.com/analogjs/analog/commit/543b35196da5f07676c2e065a6d6a108b846638c))
- add itemprop meta tag support to parent and child meta tag values ([830a50f](https://github.com/analogjs/analog/commit/830a50fe72dc3a58eddb6431581fe2169f99a36e))
- add support for Vite 8.x releases ([#&#8203;1989](https://github.com/analogjs/analog/issues/1989)) ([fd4031e](https://github.com/analogjs/analog/commit/fd4031e49efb4f12e9cb874055c0cfb4ef012fb9))
- **storybook-angular:** allows setting tsconfig via framework options ([#&#8203;1999](https://github.com/analogjs/analog/issues/1999)) ([cbd358d](https://github.com/analogjs/analog/commit/cbd358dd7c28d5f9c1212c428af77f44a2bd5498))
- **vite-plugin-angular:** improve dev/build performance with caches and plugin optimizations ([#&#8203;1987](https://github.com/analogjs/analog/issues/1987)) ([47ed20f](https://github.com/analogjs/analog/commit/47ed20f17bd42502c6d9845361a61556f7fdd2ae))
- **vitest-angular:** added support for browser mode preview ([#&#8203;2012](https://github.com/analogjs/analog/issues/2012)) ([dc27af2](https://github.com/analogjs/analog/commit/dc27af22c5f251d2bb583476fcb953c7fe9cc5e4))

##### Performance Improvements

- **vite-plugin-angular:** apply transform filter to plugins ([#&#8203;2011](https://github.com/analogjs/analog/issues/2011)) ([0bfe92d](https://github.com/analogjs/analog/commit/0bfe92d4ec2a5422b9decec09c54f045fac8c135))
- **vite-plugin-angular:** pass modified files for incremental compilation ([#&#8203;2010](https://github.com/analogjs/analog/issues/2010)) ([7cb7970](https://github.com/analogjs/analog/commit/7cb797067f2df37b7f884cac6f6b211e88d2e662))
- **vite-plugin-angular:** re-use builder between compilations ([#&#8203;1990](https://github.com/analogjs/analog/issues/1990)) ([e4ae778](https://github.com/analogjs/analog/commit/e4ae7787ece34443d6cbe8b77050ea94447a97e0))

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about these updates again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/21
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 16:44:55 +02:00
APF Portal Bot c8c8eafde1 chore(deps): update typescript tooling (#20)
CI / commits (push) Has been skipped
CI / check (push) Successful in 2m54s
CI / scan (push) Failing after 3m0s
CI / a11y (push) Successful in 2m20s
CI / perf (push) Successful in 3m36s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@typescript-eslint/utils](https://typescript-eslint.io/packages/utils) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/utils)) | devDependencies | patch | [`8.59.1` -> `8.59.2`](https://renovatebot.com/diffs/npm/@typescript-eslint%2futils/8.59.1/8.59.2) |
| [ts-node](https://typestrong.org/ts-node) ([source](https://github.com/TypeStrong/ts-node)) | devDependencies | patch | [`10.9.1` -> `10.9.2`](https://renovatebot.com/diffs/npm/ts-node/10.9.1/10.9.2) |
| [typescript-eslint](https://typescript-eslint.io/packages/typescript-eslint) ([source](https://github.com/typescript-eslint/typescript-eslint/tree/HEAD/packages/typescript-eslint)) | devDependencies | patch | [`8.59.1` -> `8.59.2`](https://renovatebot.com/diffs/npm/typescript-eslint/8.59.1/8.59.2) |

---

### Release Notes

<details>
<summary>typescript-eslint/typescript-eslint (@&#8203;typescript-eslint/utils)</summary>

### [`v8.59.2`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/utils/CHANGELOG.md#8592-2026-05-04)

[Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.1...v8.59.2)

This was a version bump only for utils to align it with other projects, there were no code changes.

See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2) for more information.

You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website.

</details>

<details>
<summary>TypeStrong/ts-node (ts-node)</summary>

### [`v10.9.2`](https://github.com/TypeStrong/ts-node/releases/tag/v10.9.2): Fix `tsconfig.json` file not found

[Compare Source](https://github.com/TypeStrong/ts-node/compare/v10.9.1...v10.9.2)

**Fixed**

- Fixed `tsconfig.json` file not found on latest TypeScript version (https://github.com/TypeStrong/ts-node/pull/2091)

</details>

<details>
<summary>typescript-eslint/typescript-eslint (typescript-eslint)</summary>

### [`v8.59.2`](https://github.com/typescript-eslint/typescript-eslint/blob/HEAD/packages/typescript-eslint/CHANGELOG.md#8592-2026-05-04)

[Compare Source](https://github.com/typescript-eslint/typescript-eslint/compare/v8.59.1...v8.59.2)

This was a version bump only for typescript-eslint to align it with other projects, there were no code changes.

See [GitHub Releases](https://github.com/typescript-eslint/typescript-eslint/releases/tag/v8.59.2) for more information.

You can read about our [versioning strategy](https://typescript-eslint.io/users/versioning) and [releases](https://typescript-eslint.io/users/releases) on our website.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #20
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 16:29:09 +02:00
APF Portal Bot 403b0750d6 chore(deps): update swc (#19)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 1m58s
CI / check (push) Successful in 2m21s
CI / a11y (push) Successful in 57s
CI / perf (push) Successful in 3m1s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@swc/core](https://swc.rs) ([source](https://github.com/swc-project/swc/tree/HEAD/packages/core)) | devDependencies | patch | [`1.15.8` -> `1.15.33`](https://renovatebot.com/diffs/npm/@swc%2fcore/1.15.8/1.15.33) |
| [@swc/helpers](https://swc.rs) ([source](https://github.com/swc-project/swc/tree/HEAD/packages/helpers)) | devDependencies | patch | [`0.5.18` -> `0.5.21`](https://renovatebot.com/diffs/npm/@swc%2fhelpers/0.5.18/0.5.21) |

---

### Release Notes

<details>
<summary>swc-project/swc (@&#8203;swc/core)</summary>

### [`v1.15.33`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11533---2026-05-02)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.32...v1.15.33)

##### Bug Fixes

- **(ci)** Update rand lockfile entries ([#&#8203;11827](https://github.com/swc-project/swc/issues/11827)) ([7988966](https://github.com/swc-project/swc/commit/7988966eb33d2404fe588ec50345100ea57a3cf4))

- **(es/minifier)** Fold unary bool nullish coalescing ([#&#8203;11826](https://github.com/swc-project/swc/issues/11826)) ([e39ae3d](https://github.com/swc-project/swc/commit/e39ae3d3489373414ef23177b82f0ab77250a1f2))

- **(es/minifier)** Preserve for-init sequence order ([#&#8203;11837](https://github.com/swc-project/swc/issues/11837)) ([16a56d0](https://github.com/swc-project/swc/commit/16a56d031fd801796df6b648bc533b97e27b39f8))

- **(es/parser)** Parse empty Flow exact object type ([#&#8203;11836](https://github.com/swc-project/swc/issues/11836)) ([3d18a26](https://github.com/swc-project/swc/commit/3d18a2673a69e6e6172c161815fd576c41d59330))

##### Features

- Move swc ast explorer into workspace ([#&#8203;11831](https://github.com/swc-project/swc/issues/11831)) ([02a8f81](https://github.com/swc-project/swc/commit/02a8f8123bdec3e8291a2f82ccf01d3e44114c49))

### [`v1.15.32`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11532---2026-04-27)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.30...v1.15.32)

##### Bug Fixes

- **(es/flow)** Fix Flow type-only modules in script transforms ([#&#8203;11817](https://github.com/swc-project/swc/issues/11817)) ([be38316](https://github.com/swc-project/swc/commit/be38316f9a7242f2d3765503216b9c3116021b1c))

- **(es/flow)** Avoid restoring module context when flow syntax is enabled ([#&#8203;11819](https://github.com/swc-project/swc/issues/11819)) ([3ed7243](https://github.com/swc-project/swc/commit/3ed724389a55847f5e236421c23f2cd85a7208b3))

- **(es/minifier)** Preserve frozen spread registry keys ([#&#8203;11825](https://github.com/swc-project/swc/issues/11825)) ([347181c](https://github.com/swc-project/swc/commit/347181c45717431a64cb60e0d6ccbe667322a809))

- **(es/parser)** Align Flow generic arrow JSX disambiguation ([#&#8203;11821](https://github.com/swc-project/swc/issues/11821)) ([28a7fad](https://github.com/swc-project/swc/commit/28a7fadc2acf95500d934988617b73f0debf5a53))

##### Features

- **(es)** Add `jsc.preserveSymlinks` to `swc::Options` ([#&#8203;11813](https://github.com/swc-project/swc/issues/11813)) ([fe38342](https://github.com/swc-project/swc/commit/fe38342b8fa960b430300f2491a5695c09debf4c))

### [`v1.15.30`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11530---2026-04-19)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.26...v1.15.30)

##### Bug Fixes

- **(deploy)** Fix musl binding test workflow ([#&#8203;11804](https://github.com/swc-project/swc/issues/11804)) ([c30a522](https://github.com/swc-project/swc/commit/c30a5226920311a26f2b9692d057a50b18266d30))

- **(deploy)** Build package ts before Linux GNU binding tests ([#&#8203;11806](https://github.com/swc-project/swc/issues/11806)) ([a3d3ef3](https://github.com/swc-project/swc/commit/a3d3ef3924a80e19101a9735bf357ac14cd68fbc))

- **(es/jsx)** Preserve quoted JSX attribute newlines ([#&#8203;11796](https://github.com/swc-project/swc/issues/11796)) ([9fe56c8](https://github.com/swc-project/swc/commit/9fe56c88553bb79254a7a5e991bfedc5f6c689e1))

- **(es/minifier)** Support full ES version parsing in minify ([#&#8203;11800](https://github.com/swc-project/swc/issues/11800)) ([af1f08f](https://github.com/swc-project/swc/commit/af1f08f09e749392815f0449ffac2bdd62a5b0e3))

- **(es/module)** Add opt-in symlink-preserving resolver ([#&#8203;11801](https://github.com/swc-project/swc/issues/11801)) ([6028240](https://github.com/swc-project/swc/commit/6028240017608aac8d80d2c1ff37cf9f13534af6))

- **(es/parser)** Allow return type annotation on Flow constructors ([#&#8203;11790](https://github.com/swc-project/swc/issues/11790)) ([d66b29c](https://github.com/swc-project/swc/commit/d66b29c11d7e9709906e7c6ba6a98fcde428ca65))

- **(es/parser)** Support Flow anonymous keyof indexers ([#&#8203;11792](https://github.com/swc-project/swc/issues/11792)) ([452c4e5](https://github.com/swc-project/swc/commit/452c4e59e6230e36ab2ef19608d214b72d3baf72))

- **(es/parser)** Add Flow strip RN and RNW regression corpus ([#&#8203;11799](https://github.com/swc-project/swc/issues/11799)) ([23a9109](https://github.com/swc-project/swc/commit/23a9109396dc1fcd496e2fbf90552fce0d5ca55b))

##### Documentation

- Require PR template for pull requests ([#&#8203;11793](https://github.com/swc-project/swc/issues/11793)) ([3a1084a](https://github.com/swc-project/swc/commit/3a1084ad1860afdbea2703f13030c3baaaf778db))

##### Features

- **(es/minify)** Support extracting comments ([#&#8203;11798](https://github.com/swc-project/swc/issues/11798)) ([5986411](https://github.com/swc-project/swc/commit/5986411655d7b9e3a1d4e401de9fbda94164c0a3))

### [`v1.15.26`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11526---2026-04-14)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.24...v1.15.26)

##### Bug Fixes

- **(es/decorators)** Preserve super in moved static members ([#&#8203;11781](https://github.com/swc-project/swc/issues/11781)) ([778328e](https://github.com/swc-project/swc/commit/778328e5b40232b311e33e0dede4f1f53e523c4a))

- **(es/decorators)** Scope moved static super rewrite ([#&#8203;11782](https://github.com/swc-project/swc/issues/11782)) ([f73cacc](https://github.com/swc-project/swc/commit/f73cacca16c628cf59820eddb6594fd08f124d6d))

- **(es/parser)** Parse mixed Flow anonymous callable params ([#&#8203;11786](https://github.com/swc-project/swc/issues/11786)) ([05e7b69](https://github.com/swc-project/swc/commit/05e7b69373d3b1e4957f557cb3d640b59998d8a7))

- **(es/transforms)** Rewrite class references in non-static members ([#&#8203;11772](https://github.com/swc-project/swc/issues/11772)) ([fff1426](https://github.com/swc-project/swc/commit/fff1426c86cd47d0d879c5e7c4f029c4adb132e7))

- **(es/typescript)** Handle TypeScript expressions in enum transformation ([#&#8203;11769](https://github.com/swc-project/swc/issues/11769)) ([85aa4a8](https://github.com/swc-project/swc/commit/85aa4a8b95f08d97df47d11f5c2fd11f7db97381))

##### Documentation

- Document Flow strip support ([#&#8203;11778](https://github.com/swc-project/swc/issues/11778)) ([8f176cc](https://github.com/swc-project/swc/commit/8f176cc907093bc80c6792744ea215b69ff62efb))

##### Features

- **(swc\_common)** Add SourceMapper.map\_raw\_pos ([#&#8203;11777](https://github.com/swc-project/swc/issues/11777)) ([7d2e94c](https://github.com/swc-project/swc/commit/7d2e94ce379ba8fc738a5697299cdb9a3c748e8a))

- **(swc\_config)** Add Hash/Eq for options and CachedRegex ([#&#8203;11775](https://github.com/swc-project/swc/issues/11775)) ([86a4c38](https://github.com/swc-project/swc/commit/86a4c383b8da40a53bad1b1b5098227d3087927c))

##### Performance

- **(swc)** Use larger input for es/full benchmarks ([#&#8203;11779](https://github.com/swc-project/swc/issues/11779)) ([4409920](https://github.com/swc-project/swc/commit/44099207878c2e7f6ec75379040402057ad4f97b))

##### Refactor

- **(es/minifier)** Inline into shorthand prop early ([#&#8203;11766](https://github.com/swc-project/swc/issues/11766)) ([450bdfa](https://github.com/swc-project/swc/commit/450bdfa14f61ca008f5399d7292d5d9bc5e07380))

##### Build

- Update `rustc` to `nightly-2026-04-10` ([#&#8203;11783](https://github.com/swc-project/swc/issues/11783)) ([6facc79](https://github.com/swc-project/swc/commit/6facc79dc4022e9a31dcb1c7e8952917f88867e9))

### [`v1.15.24`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11524---2026-04-04)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.21...v1.15.24)

##### Bug Fixes

- **(es/decorators)** Scope 2023-11 implicit-global rewrite to decorator-lifted exprs ([#&#8203;11743](https://github.com/swc-project/swc/issues/11743)) ([1c01bbb](https://github.com/swc-project/swc/commit/1c01bbb46ddb33b380b8216235c1e6f2767d0aae))

- **(es/minifier)** Handle `toExponential(undefined)` ([#&#8203;11583](https://github.com/swc-project/swc/issues/11583)) ([cd94a31](https://github.com/swc-project/swc/commit/cd94a3141621cec617dac7e84c50070cd598ec46))

- **(es/minifier)** Cap deep if\_return conditional chains ([#&#8203;11758](https://github.com/swc-project/swc/issues/11758)) ([a92fa3e](https://github.com/swc-project/swc/commit/a92fa3e8e27f604186a2393284d3deb67a9146f1))

- **(es/minifier)** Inline prop shorthand in computed props ([#&#8203;11760](https://github.com/swc-project/swc/issues/11760)) ([71feafb](https://github.com/swc-project/swc/commit/71feafb4bc79883a558164e9543ae4ecedc9187e))

- **(es/parser)** Parse key Flow forms from [#&#8203;11729](https://github.com/swc-project/swc/issues/11729) (phase 1) ([#&#8203;11733](https://github.com/swc-project/swc/issues/11733)) ([886fe53](https://github.com/swc-project/swc/commit/886fe533ad7edfb13804be3a779eccb160cf69e7))

- **(es/parser)** Close remaining Flow parser gaps for [#&#8203;11729](https://github.com/swc-project/swc/issues/11729) (phase 2) ([#&#8203;11740](https://github.com/swc-project/swc/issues/11740)) ([8d36f05](https://github.com/swc-project/swc/commit/8d36f05499f7e2cc5c568227d05e5f912e01509b))

- **(es/regexp)** Preserve source for wrapped named groups ([#&#8203;11757](https://github.com/swc-project/swc/issues/11757)) ([7e56fe5](https://github.com/swc-project/swc/commit/7e56fe5cb4dfc3fc1758e2139949107d5eaa8e47))

- **(html/codegen)** Keep </p> for span-parent paragraphs ([#&#8203;11756](https://github.com/swc-project/swc/issues/11756)) ([ede9950](https://github.com/swc-project/swc/commit/ede9950d35cdd4968331ac0111cdb413e60f3438))

- **(swc\_common)** Make `eat_byte` unsafe to prevent UTF-8 boundary violation ([#&#8203;11731](https://github.com/swc-project/swc/issues/11731)) ([669a659](https://github.com/swc-project/swc/commit/669a659c6e29c12eba793e646c6b29002782a84c))

##### Features

- **(es/minifier)** Remove useless arguments for non inlined callee ([#&#8203;11645](https://github.com/swc-project/swc/issues/11645)) ([bab249e](https://github.com/swc-project/swc/commit/bab249ef031f71ebe4089b15a03b435d7258e895))

- **(react-compiler)** Advance SWC parity for upstream fixtures ([#&#8203;11724](https://github.com/swc-project/swc/issues/11724)) ([468da70](https://github.com/swc-project/swc/commit/468da70bbdf876e44155fda09cbca7ee939fa68f))

- **(react-compiler)** Tighten core validation parity for upstream fixtures ([#&#8203;11734](https://github.com/swc-project/swc/issues/11734)) ([7e2cf8d](https://github.com/swc-project/swc/commit/7e2cf8d46a6f41967b93858d9f3269ae46370d14))

- **(react-compiler)** Improve SWC parity for early-return and hooks validation ([#&#8203;11738](https://github.com/swc-project/swc/issues/11738)) ([4739c58](https://github.com/swc-project/swc/commit/4739c586d0deb88d3d536835adb873b9c036bef5))

- **(react-compiler)** M1 memo validators + lint gating alignment ([#&#8203;11739](https://github.com/swc-project/swc/issues/11739)) ([7e1ad26](https://github.com/swc-project/swc/commit/7e1ad26b49295085208c2e4ddfb175c479da53bc))

- **(react-compiler)** Improve Stage A diagnostic parity and validation aggregation ([#&#8203;11745](https://github.com/swc-project/swc/issues/11745)) ([0e2075e](https://github.com/swc-project/swc/commit/0e2075e4addc9771dbe5388b6d30fd4344308bd1))

- **(react-compiler)** Continue swc parity for dependency handling ([#&#8203;11747](https://github.com/swc-project/swc/issues/11747)) ([83688c8](https://github.com/swc-project/swc/commit/83688c8af8695b895d871a4d6d9530d89fcba2a9))

##### Refactor

- **(es/minifier)** Inline usage analyzer and remove crate ([#&#8203;11750](https://github.com/swc-project/swc/issues/11750)) ([7d8d11b](https://github.com/swc-project/swc/commit/7d8d11b53ad046cafce6aff76672df41ad276615))

- **(react-compiler)** Remove compiler impl and keep fast\_check ([#&#8203;11753](https://github.com/swc-project/swc/issues/11753)) ([f21d336](https://github.com/swc-project/swc/commit/f21d33629033f305d300d91982d0a87bc807e427))

##### Ci

- Add manual Publish crates workflow ([#&#8203;11763](https://github.com/swc-project/swc/issues/11763)) ([169c961](https://github.com/swc-project/swc/commit/169c96107357653fa0d1c0feb715aa2312481e0a))

- Add misc npm publish workflow ([#&#8203;11764](https://github.com/swc-project/swc/issues/11764)) ([236eff0](https://github.com/swc-project/swc/commit/236eff01dd30e780596ed33704b85bf91491bc10))

### [`v1.15.21`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11521---2026-03-22)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.18...v1.15.21)

##### Bug Fixes

- **(cli)** Honor externalHelpers=false in rust binary ([#&#8203;11693](https://github.com/swc-project/swc/issues/11693)) ([1be052e](https://github.com/swc-project/swc/commit/1be052e36154ed0382aeb93a4ff8f9e441ffbdca))

- **(cli)** Skip mkdir when --out-file targets the current directory ([#&#8203;11720](https://github.com/swc-project/swc/issues/11720)) ([f3f4e51](https://github.com/swc-project/swc/commit/f3f4e51cedb3051a7c75c0cdecaa17e1d276597f))

- **(es/decorators)** Resolve 2022-03 issues [#&#8203;9565](https://github.com/swc-project/swc/issues/9565)/[#&#8203;9078](https://github.com/swc-project/swc/issues/9078)/[#&#8203;9079](https://github.com/swc-project/swc/issues/9079) and add regressions ([#&#8203;11698](https://github.com/swc-project/swc/issues/11698)) ([a025d2b](https://github.com/swc-project/swc/commit/a025d2bc2fa482b675084f5802865cd02c8b63c4))

- **(es/fixer)** Wrap new opt chain ([#&#8203;11618](https://github.com/swc-project/swc/issues/11618)) ([fdcd184](https://github.com/swc-project/swc/commit/fdcd184a2ad3295015faf51fde62dbe4b700515e))

- **(es/flow)** Normalize module await bindings for Hermes parity ([#&#8203;11703](https://github.com/swc-project/swc/issues/11703)) ([73d8761](https://github.com/swc-project/swc/commit/73d87616f5db5146fac774cd60d5ec18195140c3))

- **(es/minifier)** Fix compatibility for Wasm plugin (`swc_ast_unknown`) ([#&#8203;11641](https://github.com/swc-project/swc/issues/11641)) ([abd0e45](https://github.com/swc-project/swc/commit/abd0e45fb9cee9f79fb58d3a520f9ff92ecf4566))

- **(es/module)** Preserve explicit index.js import path when baseUrl is set ([#&#8203;11597](https://github.com/swc-project/swc/issues/11597)) ([830dbeb](https://github.com/swc-project/swc/commit/830dbeb44f3bf6faf807808d596d970442b6e6e3))

- **(es/module)** Avoid rewriting unknown relative extensions ([#&#8203;11713](https://github.com/swc-project/swc/issues/11713)) ([ed09218](https://github.com/swc-project/swc/commit/ed092184839057467702976ad43ed4e3f902dc6b))

- **(es/regexp)** Implement transform-named-capturing-groups-regex ([#&#8203;11642](https://github.com/swc-project/swc/issues/11642)) ([f62bfa9](https://github.com/swc-project/swc/commit/f62bfa90701cdcfe87af082d5104f0c1e2dd7e0d))

- **(es/types)** Add new options types ([#&#8203;11683](https://github.com/swc-project/swc/issues/11683)) ([62eeee1](https://github.com/swc-project/swc/commit/62eeee15324a6aa25a2e17d497f1d41900cbac99))

- **(malloc)** Fallback to system allocator on linux gnu s390x/powerpc ([#&#8203;11606](https://github.com/swc-project/swc/issues/11606)) ([e103fac](https://github.com/swc-project/swc/commit/e103facd4451349478efbaf8caaf89294d4780f9))

- Update lz4\_flex to resolve RUSTSEC-2026-0041 ([#&#8203;11701](https://github.com/swc-project/swc/issues/11701)) ([7528507](https://github.com/swc-project/swc/commit/7528507bc6d3fb723742e62abb156d510fba1329))

##### Documentation

- **(agents)** Improve guidance ([#&#8203;11626](https://github.com/swc-project/swc/issues/11626)) ([1cdfec9](https://github.com/swc-project/swc/commit/1cdfec9f298d0979f40d2be5a227ea4dc973138b))

- **(agents)** Add AGENTS two-pass rules for es crates ([#&#8203;11634](https://github.com/swc-project/swc/issues/11634)) ([12af4a1](https://github.com/swc-project/swc/commit/12af4a1fcffff0bcefaa5ca766914d1aae2c7847))

- Move parser design guidance into AGENTS.md ([#&#8203;11600](https://github.com/swc-project/swc/issues/11600)) ([e6e91a3](https://github.com/swc-project/swc/commit/e6e91a3d525774fb3453ebda64793d3d253771b5))

- Clarify workaround comment requirement in AGENTS ([#&#8203;11700](https://github.com/swc-project/swc/issues/11700)) ([e2ad6f6](https://github.com/swc-project/swc/commit/e2ad6f61c882b6b302d886268170560087cd5684))

##### Features

- **(bindings)** Add linux ppc64le and s390x support across npm bindings ([#&#8203;11602](https://github.com/swc-project/swc/issues/11602)) ([357255d](https://github.com/swc-project/swc/commit/357255d56d4cc61b55be27a4b052f2f3019d018d))

- **(bindings)** Enable flow strip support in [@&#8203;swc/core](https://github.com/swc/core) ([#&#8203;11696](https://github.com/swc-project/swc/issues/11696)) ([93da89a](https://github.com/swc-project/swc/commit/93da89a272408ec5d4cf43d9c087774794661657))

- **(cli)** Enable Flow strip support in swc\_cli\_impl ([#&#8203;11705](https://github.com/swc-project/swc/issues/11705)) ([0ea9950](https://github.com/swc-project/swc/commit/0ea99502686a43bf33c397ef47fad344de78abb9))

- **(dbg-swc)** Add flow strip verification command ([#&#8203;11706](https://github.com/swc-project/swc/issues/11706)) ([77b7854](https://github.com/swc-project/swc/commit/77b7854046b584a933935b9252fd6df183828409))

- **(es)** Add `swc_es_codegen` for `swc_es_ast` ([#&#8203;11628](https://github.com/swc-project/swc/issues/11628)) ([c282d86](https://github.com/swc-project/swc/commit/c282d8616b4626ba880096e356ad1200108def9e))

- **(es)** Add 2-pass transformer and minifier crates ([#&#8203;11632](https://github.com/swc-project/swc/issues/11632)) ([f70a4b7](https://github.com/swc-project/swc/commit/f70a4b7c15324a0d7d771e11ff1ab738f964e43b))

- **(es)** Add TypeScript + React transforms and tsc corpus tests ([#&#8203;11635](https://github.com/swc-project/swc/issues/11635)) ([09a5d8d](https://github.com/swc-project/swc/commit/09a5d8d39f65684f4dc88558b92804dcb19a1c0b))

- **(es/helpers)** Prevent recursive instanceof helper transforms ([#&#8203;11609](https://github.com/swc-project/swc/issues/11609)) ([cb755a3](https://github.com/swc-project/swc/commit/cb755a3260aac2a1aaeab8ccf0458b783607511b))

- **(es/parser)** Add `with_capacity` for `Capturing` ([#&#8203;11679](https://github.com/swc-project/swc/issues/11679)) ([60df582](https://github.com/swc-project/swc/commit/60df58288867757038c6eec45ccc54bf1799f10c))

- **(es/parser)** Add flow syntax mode and strip integration ([#&#8203;11685](https://github.com/swc-project/swc/issues/11685)) ([015bbe8](https://github.com/swc-project/swc/commit/015bbe8759da1a57a33dd8c7791bc835e4150034))

- **(es/parser)** Finish flow strip support for core syntax gaps ([#&#8203;11689](https://github.com/swc-project/swc/issues/11689)) ([584a12f](https://github.com/swc-project/swc/commit/584a12f6fa15f4beaf030fa6224ba77be1874e0f))

- **(es/parser)** Extend flow declare export strip compatibility ([#&#8203;11691](https://github.com/swc-project/swc/issues/11691)) ([a8315aa](https://github.com/swc-project/swc/commit/a8315aaea70d2b9dcd5da56b5726190c84ed3036))

- **(es/parser)** Support Flow declare export default interface strip path ([#&#8203;11692](https://github.com/swc-project/swc/issues/11692)) ([588577c](https://github.com/swc-project/swc/commit/588577c5c2541ae0d4c198648ba74265eb05dc39))

- **(es/parser)** Add Hermes Flow parity harness and fixes ([#&#8203;11699](https://github.com/swc-project/swc/issues/11699)) ([918b6ac](https://github.com/swc-project/swc/commit/918b6ac1f5ca151aa70b6b5f4fcb2443be80eacb))

- **(es/parser)** Complete Hermes Flow stripping parity ([#&#8203;11702](https://github.com/swc-project/swc/issues/11702)) ([f041f4c](https://github.com/swc-project/swc/commit/f041f4c2f2c757489a2c1194fe03d890052d131e))

- **(es/proposal)** Add decorators 2023-11 support ([#&#8203;11686](https://github.com/swc-project/swc/issues/11686)) ([e96eb6a](https://github.com/swc-project/swc/commit/e96eb6a82897f80910e9cf81ae5b0649a0a0855a))

- **(es/react-compiler)** Scaffold SWC port of Babel entrypoint ([#&#8203;11687](https://github.com/swc-project/swc/issues/11687)) ([4a1d3ce](https://github.com/swc-project/swc/commit/4a1d3ce3175428a4113eda8f4bc7b07ccb18b60f))

- **(es/react-compiler)** Phase1 crate API baseline and fixture harness ([#&#8203;11690](https://github.com/swc-project/swc/issues/11690)) ([31364dc](https://github.com/swc-project/swc/commit/31364dcb26860e49ff64f60fa60d4b5cd39b199d))

- **(es/react-compiler)** Strict upstream parity finalization (crate-only, WIP) ([#&#8203;11697](https://github.com/swc-project/swc/issues/11697)) ([a3994aa](https://github.com/swc-project/swc/commit/a3994aa5f853836c528614a89e435fc5eacb7f13))

- **(es/react-compiler)** Advance strict upstream parity ([#&#8203;11709](https://github.com/swc-project/swc/issues/11709)) ([9b3abe0](https://github.com/swc-project/swc/commit/9b3abe078f86db7e6cc80b7cd1c3c1150c41a71a))

- **(es/react-compiler)** Advance upstream fixture parity pipeline ([#&#8203;11716](https://github.com/swc-project/swc/issues/11716)) ([33fe6f2](https://github.com/swc-project/swc/commit/33fe6f26aa4a5dcc6542d752632e75b4f3595e7d))

- **(es/semantics)** Add scope analysis and statement-level cfg ([#&#8203;11623](https://github.com/swc-project/swc/issues/11623)) ([86815b1](https://github.com/swc-project/swc/commit/86815b1e9cecd2c0b67c17c5d4ba2b99f904b355))

- **(es\_parser)** Complete parity suite with zero ignores ([#&#8203;11615](https://github.com/swc-project/swc/issues/11615)) ([ee3fdd5](https://github.com/swc-project/swc/commit/ee3fdd553564a1af8490ff1f2b1d1b74c8574ba9))

- **(es\_parser)** Complete internal parser wiring without ecma runtime dep ([#&#8203;11622](https://github.com/swc-project/swc/issues/11622)) ([1c51891](https://github.com/swc-project/swc/commit/1c518913a5abd64e60fe7fa5c5ece856a2861147))

- **(es\_parser)** Expand benchmark corpus ([#&#8203;11633](https://github.com/swc-project/swc/issues/11633)) ([ff3adef](https://github.com/swc-project/swc/commit/ff3adef43b0b49a611f1f1704400ca20ec1111f3))

- **(react-compiler)** Advance SWC upstream fixture parity ([#&#8203;11718](https://github.com/swc-project/swc/issues/11718)) ([e8d1696](https://github.com/swc-project/swc/commit/e8d16969b74d21f13b1594ef71ceef3d550d0a59))

- **(react-compiler)** Improve lint rename and gating parity ([#&#8203;11721](https://github.com/swc-project/swc/issues/11721)) ([5f89ee7](https://github.com/swc-project/swc/commit/5f89ee70d5af99a382a8f8ca16ba913b1ddd746e))

- **(swc\_es\_parser)** Enforce full parity suite and extend grammar surface ([#&#8203;11611](https://github.com/swc-project/swc/issues/11611)) ([585f7d0](https://github.com/swc-project/swc/commit/585f7d07a44b2508b05d6b07e9fcd83cb5cb7185))

- **(swc\_es\_parser)** Complete lossless modeling for with/TS module/decorators ([#&#8203;11613](https://github.com/swc-project/swc/issues/11613)) ([59b1189](https://github.com/swc-project/swc/commit/59b11898fe247382bed44fddfb29c9592050b8bc))

- **(swc\_es\_parser)** Close parity gaps with full core/large fixture pass-fail parity ([#&#8203;11614](https://github.com/swc-project/swc/issues/11614)) ([3085f52](https://github.com/swc-project/swc/commit/3085f52a0f2aafc194d01a4394ddce72c455c6a5))

- Complete core parity parser coverage ([#&#8203;11603](https://github.com/swc-project/swc/issues/11603)) ([18e0edc](https://github.com/swc-project/swc/commit/18e0edce9ebdd50508c9e60f50d1adf5a286e865))

##### Performance

- **(es/modules)** Avoid export sort key clones ([#&#8203;11669](https://github.com/swc-project/swc/issues/11669)) ([e74e17d](https://github.com/swc-project/swc/commit/e74e17dcf2e23ced12e199d05146e88a55b6174f))

- **(es/parser)** Reduce JSX identifier rescan allocations ([#&#8203;11671](https://github.com/swc-project/swc/issues/11671)) ([f9214fe](https://github.com/swc-project/swc/commit/f9214fed47818f2df75865645ef6a3358300d86a))

- **(es/parser)** Optimize underscore stripping in numeric literal hot path ([#&#8203;11670](https://github.com/swc-project/swc/issues/11670)) ([874338b](https://github.com/swc-project/swc/commit/874338b77f93b22cebc58d4ec4b43fe02bebb7e2))

- **(es/transformer)** Remove O(n^2) statement mutation hotspots ([#&#8203;11672](https://github.com/swc-project/swc/issues/11672)) ([bdc24b7](https://github.com/swc-project/swc/commit/bdc24b7fdc006c77f4b5303bf4ff903b71fd8bcb))

- **(es\_parser)** Byte-search lexer optimization pass ([#&#8203;11616](https://github.com/swc-project/swc/issues/11616)) ([607f2db](https://github.com/swc-project/swc/commit/607f2dbba4cdc681447657f07bda10c0533d0d7f))

- **(es\_parser)** Reduce lookahead and allocation overhead ([#&#8203;11673](https://github.com/swc-project/swc/issues/11673)) ([becd9b0](https://github.com/swc-project/swc/commit/becd9b0352db53611cd7ab3f922ff3b1f89d73fe))

- **(ts/fast-strip)** Avoid token capture in default transform path ([#&#8203;11668](https://github.com/swc-project/swc/issues/11668)) ([06aa0db](https://github.com/swc-project/swc/commit/06aa0db37d19ddec7f3255f92eef84f07c7f2d61))

##### Refactor

- **(es/minifier)** Use arguments data from scope ([#&#8203;11604](https://github.com/swc-project/swc/issues/11604)) ([4738539](https://github.com/swc-project/swc/commit/473853951651a013c896122b88d5fb7db43c2412))

##### Testing

- **(es/flow)** Add flow strip corpus correctness test ([#&#8203;11694](https://github.com/swc-project/swc/issues/11694)) ([cd5ed81](https://github.com/swc-project/swc/commit/cd5ed813da185d8aacc3d9bf7a64acb2e1c32116))

- **(es/parser)** Enforce full ecma fixture parity ([#&#8203;11637](https://github.com/swc-project/swc/issues/11637)) ([0bf8a46](https://github.com/swc-project/swc/commit/0bf8a4656011bdfeb80afb94fb8f2764739d099e))

- **(es/parser)** Expand flow strip fixture coverage ([#&#8203;11695](https://github.com/swc-project/swc/issues/11695)) ([e231262](https://github.com/swc-project/swc/commit/e23126212595d32265e0d4478592a15dc9e0ceef))

- **(es\_parser)** Add core snapshot suite ([#&#8203;11617](https://github.com/swc-project/swc/issues/11617)) ([23c56fe](https://github.com/swc-project/swc/commit/23c56fe60f60689994e3cc2b08301886cd0cea65))

- **(es\_parser)** De-arenaize ecma\_reuse fixture snapshots ([#&#8203;11639](https://github.com/swc-project/swc/issues/11639)) ([aa6727a](https://github.com/swc-project/swc/commit/aa6727a26dac1a8802ea06d35b5c3ac1ff7633f4))

- **(es\_parser)** Recover swc\_es\_parser benchmark coverage ([#&#8203;11640](https://github.com/swc-project/swc/issues/11640)) ([0f24ee1](https://github.com/swc-project/swc/commit/0f24ee1dfdea41e7e22218fd3bfc466772d557b7))

- Expand swc\_es\_parser snapshot suites (ecma-style) ([#&#8203;11621](https://github.com/swc-project/swc/issues/11621)) ([325170f](https://github.com/swc-project/swc/commit/325170fff9b5c99abe1da19ec63fe6d2d8c6a9bb))

- Move TS decorator fixtures out of proposal crate ([#&#8203;11723](https://github.com/swc-project/swc/issues/11723)) ([e29d58c](https://github.com/swc-project/swc/commit/e29d58c74b345dc783b8132bea15439f8dcd4119))

##### Ci

- Bump cargo-mono to 0.5.0 ([#&#8203;11605](https://github.com/swc-project/swc/issues/11605)) ([7118713](https://github.com/swc-project/swc/commit/7118713176d7d2c244c1c7c637dbfa7ffa37f167))

- Remove --no-verify flag from cargo mono publish ([02eb5ec](https://github.com/swc-project/swc/commit/02eb5ec20ea24a90c577991d6bb756b346c9c6a3))

- Optimize cargo-test matrix with cargo mono changed ([#&#8203;11681](https://github.com/swc-project/swc/issues/11681)) ([99e61c4](https://github.com/swc-project/swc/commit/99e61c4cc172b772437dcabcf8f937a8f24dc4bd))

- Bump cargo-mono to 0.5.3 ([#&#8203;11722](https://github.com/swc-project/swc/issues/11722)) ([b5272af](https://github.com/swc-project/swc/commit/b5272af0f80047ffb98a1eed5de1f1d391657aa2))

- Install zig for core ppc64le/s390x nightly cross builds ([#&#8203;11725](https://github.com/swc-project/swc/issues/11725)) ([09c4be0](https://github.com/swc-project/swc/commit/09c4be00656d2d64e80ffb0ae250c53db645a39c))

### [`v1.15.18`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11518---2026-03-01)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.17...v1.15.18)

##### Bug Fixes

- **(html/wasm)** Publish [@&#8203;swc/html-wasm](https://github.com/swc/html-wasm) for nodejs ([#&#8203;11601](https://github.com/swc-project/swc/issues/11601)) ([bd443f5](https://github.com/swc-project/swc/commit/bd443f582c553e9d898a1d5e7395abaad60b26d2))

##### Documentation

- Add AGENTS note about next-gen ast ([#&#8203;11592](https://github.com/swc-project/swc/issues/11592)) ([80b4be8](https://github.com/swc-project/swc/commit/80b4be872d85dc82cbb6e84c91fe102d807a2780))

- Add typescript-eslint AST compatibility note ([#&#8203;11598](https://github.com/swc-project/swc/issues/11598)) ([c7bfebe](https://github.com/swc-project/swc/commit/c7bfebec4fb691e6e49f3c3b7b257be178e7f238))

##### Features

- **(es/ast)** Add runtime arena crate and bootstrap swc\_es\_ast ([#&#8203;11588](https://github.com/swc-project/swc/issues/11588)) ([7a06d96](https://github.com/swc-project/swc/commit/7a06d967e43fe2f84078fc241bc655b41450d2c1))

- **(es/parser)** Add `swc_es_parser` ([#&#8203;11593](https://github.com/swc-project/swc/issues/11593)) ([f11fd70](https://github.com/swc-project/swc/commit/f11fd705ee84909f6b0f984b1b5fc35abf73ec05))

##### Ci

- Triage main CI breakage ([#&#8203;11589](https://github.com/swc-project/swc/issues/11589)) ([075af57](https://github.com/swc-project/swc/commit/075af578c46c0bfdb74c450c157d0e1753024a36))

### [`v1.15.17`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11517---2026-02-26)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.13...v1.15.17)

##### Documentation

- Add submodule update step before test runs ([#&#8203;11576](https://github.com/swc-project/swc/issues/11576)) ([81b22c3](https://github.com/swc-project/swc/commit/81b22c31d1acb447caae1a2d2bd530b2e6a40c26))

##### Features

- **(bindings)** Add html wasm binding and publish wiring ([#&#8203;11587](https://github.com/swc-project/swc/issues/11587)) ([b3869c3](https://github.com/swc-project/swc/commit/b3869c3ae2a592d4539f4cbfbabeaf615e55d69e))

- **(sourcemap)** Support safe scopes round-trip metadata ([#&#8203;11581](https://github.com/swc-project/swc/issues/11581)) ([de2a348](https://github.com/swc-project/swc/commit/de2a348daed80e47c75dabaf2f0ce945d850210a))

- Emit ECMA-426 source map scopes behind experimental flag ([#&#8203;11582](https://github.com/swc-project/swc/issues/11582)) ([2385a22](https://github.com/swc-project/swc/commit/2385a2279ee71abca3ae485d04a800e24bf55bae))

### [`v1.15.13`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11513---2026-02-23)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.11...v1.15.13)

##### Bug Fixes

- **(errors)** Avoid panic on invalid diagnostic spans ([#&#8203;11561](https://github.com/swc-project/swc/issues/11561)) ([b24b8e0](https://github.com/swc-project/swc/commit/b24b8e0253e4e2db4a36a2180906d65ee89495da))

- **(es/helpers)** Fix `_object_without_properties` crash on primitive values ([#&#8203;11571](https://github.com/swc-project/swc/issues/11571)) ([4f35904](https://github.com/swc-project/swc/commit/4f35904ebfc7d924b75635af4166dd8e2b26c069))

- **(es/jsx)** Preserve whitespace before HTML entities ([#&#8203;11521](https://github.com/swc-project/swc/issues/11521)) ([64be077](https://github.com/swc-project/swc/commit/64be077515ee15501b179ebe523fa68d2c29f905))

- **(es/minifier)** Do not merge if statements with different local variable values ([#&#8203;11518](https://github.com/swc-project/swc/issues/11518)) ([3e63627](https://github.com/swc-project/swc/commit/3e636273d4ba0563c9fa15736cfa4c57d80c943d))

- **(es/minifier)** Prevent convert\_tpl\_to\_str when there's emoji under es5 ([#&#8203;11529](https://github.com/swc-project/swc/issues/11529)) ([ff6cf88](https://github.com/swc-project/swc/commit/ff6cf88c88497881839ccb40fa18d33225971203))

- **(es/minifier)** Inline before merge if ([#&#8203;11526](https://github.com/swc-project/swc/issues/11526)) ([aa5a9ac](https://github.com/swc-project/swc/commit/aa5a9ac3ebae1f2a5775d980da65bc6a1c2574d7))

- **(es/minifier)** Preserve array join("") nullish semantics ([#&#8203;11558](https://github.com/swc-project/swc/issues/11558)) ([d477f61](https://github.com/swc-project/swc/commit/d477f61d85de8d88113e886f5e5d8076192ca76a))

- **(es/minifier)** Inline side-effect-free default params ([#&#8203;11564](https://github.com/swc-project/swc/issues/11564)) ([1babda7](https://github.com/swc-project/swc/commit/1babda721a42de7a85cd0da6f6231f9a67c54bfa))

- **(es/parser)** Fix generic arrow function in TSX mode ([#&#8203;11549](https://github.com/swc-project/swc/issues/11549)) ([366a16b](https://github.com/swc-project/swc/commit/366a16b4a469d61ca816ec8187d3d476a57860d7))

- **(es/react)** Preserve first-line leading whitespace with entities ([#&#8203;11568](https://github.com/swc-project/swc/issues/11568)) ([fc62617](https://github.com/swc-project/swc/commit/fc62617f31707bb464dc167d3317dcc705aecd4c))

- **(es/regexp)** Transpile unicode property escapes in RegExp constructor ([#&#8203;11554](https://github.com/swc-project/swc/issues/11554)) ([476d544](https://github.com/swc-project/swc/commit/476d544f911ea643fcc8434e46aaddd344fa49f8))

##### Documentation

- **(agents)** Clarify sandbox escalation for progress ([#&#8203;11574](https://github.com/swc-project/swc/issues/11574)) ([cb31d0d](https://github.com/swc-project/swc/commit/cb31d0da37b35858986ba63e0dab300555f8ec82))

##### Features

- **(es/minifier)** Add `unsafe_hoist_static_method_alias` option ([#&#8203;11493](https://github.com/swc-project/swc/issues/11493)) ([6e7dbe2](https://github.com/swc-project/swc/commit/6e7dbe234555f926f98d8714789b5cd4a5e65b3d))

- **(es/minifier)** Remove unused args for IIFE ([#&#8203;11536](https://github.com/swc-project/swc/issues/11536)) ([3cc286b](https://github.com/swc-project/swc/commit/3cc286b2f16489c8175faf5a72601c5be1376bdc))

##### Refactor

- **(es/parser)** Compare token kind rather than strings ([#&#8203;11531](https://github.com/swc-project/swc/issues/11531)) ([5872ffa](https://github.com/swc-project/swc/commit/5872ffa74a5b214bd6fd03732a26479118c41011))

- **(es/typescript)** Run typescript transform in two passes ([#&#8203;11532](https://github.com/swc-project/swc/issues/11532)) ([b069558](https://github.com/swc-project/swc/commit/b06955813af93cd784aad90e7e98ab06fb648438))

- **(es/typescript)** Precompute namespace import-equals usage in semantic pass ([#&#8203;11534](https://github.com/swc-project/swc/issues/11534)) ([b7e87c7](https://github.com/swc-project/swc/commit/b7e87c7b951cb8f62d6b22a5cfa2105310a91ccc))

##### Testing

- **(es/minifier)** Add execution tests for issue [#&#8203;11517](https://github.com/swc-project/swc/issues/11517) ([#&#8203;11530](https://github.com/swc-project/swc/issues/11530)) ([01b3b64](https://github.com/swc-project/swc/commit/01b3b648114ddb2e1e5ded32856397b996cb9fc2))

- Disable `cva` ecosystem ci temporariliy ([55bc966](https://github.com/swc-project/swc/commit/55bc966be4e2a393b926317e228f6d33eacb7715))

##### Ci

- Reset closed issue and PR milestone to Planned ([#&#8203;11559](https://github.com/swc-project/swc/issues/11559)) ([d5c4ebe](https://github.com/swc-project/swc/commit/d5c4ebe3d991b05697f01d8fb67efe7ad708a1f8))

- Add permission ([431c576](https://github.com/swc-project/swc/commit/431c5764b84d43fad0e30d25dcc0a8e049e8beae))

### [`v1.15.11`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11511---2026-01-27)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.10...v1.15.11)

##### Bug Fixes

- **(es/codegen)** Emit leading comments for JSX elements, fragments, and empty expressions ([#&#8203;11488](https://github.com/swc-project/swc/issues/11488)) ([1520633](https://github.com/swc-project/swc/commit/1520633549965eb6838c80d4389431074613bd0e))

- **(es/decorators)** Invoke addInitializer callbacks for decorated fields ([#&#8203;11495](https://github.com/swc-project/swc/issues/11495)) ([11cfe4d](https://github.com/swc-project/swc/commit/11cfe4deaea8c66cd1f78e8894b4df11ebdbe0f7))

- **(es/es3)** Visit export decl body even if name is not reserved ([#&#8203;11473](https://github.com/swc-project/swc/issues/11473)) ([9113fff](https://github.com/swc-project/swc/commit/9113fffc8cae6d379c5ce7bfd9f5373f6ee9a3aa))

- **(es/es3)** Remove duplicate code ([#&#8203;11499](https://github.com/swc-project/swc/issues/11499)) ([fbee775](https://github.com/swc-project/swc/commit/fbee7752443e491ce24b590e00d78677b7e4c8f4))

- **(es/minifier)** Treat new expression with empty class as side-effect free ([#&#8203;11455](https://github.com/swc-project/swc/issues/11455)) ([a33a45e](https://github.com/swc-project/swc/commit/a33a45e3bd4e6227d143174198d36f7cbc4b9f2b))

- **(es/minifier)** Escape control characters when converting strings to template literals ([#&#8203;11464](https://github.com/swc-project/swc/issues/11464)) ([028551f](https://github.com/swc-project/swc/commit/028551f4f0d00c3880df8af324d3b5eb2637cfb9))

- **(es/minifier)** Handle unused parameters with default values ([#&#8203;11494](https://github.com/swc-project/swc/issues/11494)) ([6ed1ee9](https://github.com/swc-project/swc/commit/6ed1ee9ca1e816aedfe0387d240479c1dbfcffef))

- **(es/module)** Preserve ./ prefix for hidden directory imports ([#&#8203;11489](https://github.com/swc-project/swc/issues/11489)) ([a005391](https://github.com/swc-project/swc/commit/a0053916e786711be01f73c767e3c2283c9fb4f6))

- **(es/parser)** Validate dynamic import argument count ([#&#8203;11462](https://github.com/swc-project/swc/issues/11462)) ([2f67591](https://github.com/swc-project/swc/commit/2f67591e2c9bb41a711d739e6bc81d20a673bfd6))

- **(es/parser)** Allow compilation with --no-default-features ([#&#8203;11460](https://github.com/swc-project/swc/issues/11460)) ([b70c5f8](https://github.com/swc-project/swc/commit/b70c5f8ade85c3e4a17e0fed61ce850ab6b1f53c))

- **(es/parser)** Skip emitting TS1102 in TypeScript mode ([#&#8203;11463](https://github.com/swc-project/swc/issues/11463)) ([e6f5b06](https://github.com/swc-project/swc/commit/e6f5b06561c1d87d0235aea5cfce9c253afdcc74))

- **(es/parser)** Reject ambiguous generic arrow functions in TSX mode ([#&#8203;11491](https://github.com/swc-project/swc/issues/11491)) ([ac00915](https://github.com/swc-project/swc/commit/ac00915ba027bbb2c805ad0abd8d945d7dcf4055))

- **(es/parser)** Disallow NumericLiteralSeparator with BigInts ([#&#8203;11510](https://github.com/swc-project/swc/issues/11510)) ([6b3644b](https://github.com/swc-project/swc/commit/6b3644b9ca58530a5e0bb92586bdf8210b89124f))

- **(es/react)** Preserve HTML entity-encoded whitespace in JSX ([#&#8203;11474](https://github.com/swc-project/swc/issues/11474)) ([7d433a9](https://github.com/swc-project/swc/commit/7d433a95ccc372535b4f5b9dc691cbd313c2f388))

- **(es/renamer)** Prevent duplicate parameter names with destructuring patterns ([#&#8203;11456](https://github.com/swc-project/swc/issues/11456)) ([e25a2c8](https://github.com/swc-project/swc/commit/e25a2c82db0e33c098a8ecd19bb933115e74ac1a))

- **(es/testing)** Skip update when expected output has invalid code ([#&#8203;11469](https://github.com/swc-project/swc/issues/11469)) ([2be6b8a](https://github.com/swc-project/swc/commit/2be6b8a1fe3f55c30655f82dcf0cf6c04aa9a331))

- **(es/typescript)** Don't mark enums with opaque members as pure ([#&#8203;11452](https://github.com/swc-project/swc/issues/11452)) ([b713fae](https://github.com/swc-project/swc/commit/b713fae8cc1b4fb7a45ffb4bf4a7e9d1facb651f))

- **(preset-env)** Distinguish unknown browser vs empty config ([#&#8203;11457](https://github.com/swc-project/swc/issues/11457)) ([1310957](https://github.com/swc-project/swc/commit/1310957bec15ce2352dcb2dde8adb77664625c69))

##### Documentation

- Replace swc.config.js references with .swcrc ([#&#8203;11485](https://github.com/swc-project/swc/issues/11485)) ([fec8d2c](https://github.com/swc-project/swc/commit/fec8d2cbb8e7f5eaaed369dd1b45347839fa0c18))

##### Features

- **(cli)** Add --root-mode argument for .swcrc resolution ([#&#8203;11501](https://github.com/swc-project/swc/issues/11501)) ([b53a0e2](https://github.com/swc-project/swc/commit/b53a0e2a98a7556c5f8a74270a717e4078793053))

- **(es/module)** Make module transforms optional via `module` feature ([#&#8203;11509](https://github.com/swc-project/swc/issues/11509)) ([b94a178](https://github.com/swc-project/swc/commit/b94a17851c9032e0e17c3c9912cfdb60d00722f4))

- **(es/regexp)** Implement unicode property escape transpilation ([#&#8203;11472](https://github.com/swc-project/swc/issues/11472)) ([a2e0ba0](https://github.com/swc-project/swc/commit/a2e0ba0151fdde2c11c093d3ab2960410f4ffb86))

- **(es/transformer)** Merge ES3 hooks into swc\_ecma\_transformer ([#&#8203;11503](https://github.com/swc-project/swc/issues/11503)) ([5efcac9](https://github.com/swc-project/swc/commit/5efcac946f5cf88e900da2867dc8b92c411bdd18))

##### Miscellaneous Tasks

- **(es/minifier)** Extend OrderedChain to support more node types ([#&#8203;11477](https://github.com/swc-project/swc/issues/11477)) ([aa9d789](https://github.com/swc-project/swc/commit/aa9d789953fc8e62e07b91e25137573d3a4d70d7))

##### Performance

- **(bindings)** Optimize string handling by avoiding unnecessary clones ([#&#8203;11490](https://github.com/swc-project/swc/issues/11490)) ([81daaaa](https://github.com/swc-project/swc/commit/81daaaa054a579fd2b425c5362b33ffc90471e6f))

- **(es/codegen)** Make `commit_pending_semi` explicit in `write_punct` ([#&#8203;11492](https://github.com/swc-project/swc/issues/11492)) ([5a27fc0](https://github.com/swc-project/swc/commit/5a27fc0c49872098339bf897957af5a6b459abf9))

- **(es/es2015)** Port ES2015 transforms to hook-based visitors ([#&#8203;11484](https://github.com/swc-project/swc/issues/11484)) ([a54eb0e](https://github.com/swc-project/swc/commit/a54eb0ef7518f759e52636162870f90233ef8532))

- **(es/es3)** Use hooks pattern for single AST traversal ([#&#8203;11483](https://github.com/swc-project/swc/issues/11483)) ([a139fba](https://github.com/swc-project/swc/commit/a139fba3b9aca632e02e64333312c989f10e0ef8))

- **(es/minifier)** Use combined AST traversal ([#&#8203;11471](https://github.com/swc-project/swc/issues/11471)) ([c611663](https://github.com/swc-project/swc/commit/c611663e9f22293233d5bd8084c3de703dec8b14))

- **(es/transformer)** Add inline hint ([#&#8203;11508](https://github.com/swc-project/swc/issues/11508)) ([d72c9df](https://github.com/swc-project/swc/commit/d72c9df7e390389c3f9a2645341f920c5d42d0db))

##### Refactor

- **(es/compat)** Put ES3 crates behind feature flag ([#&#8203;11480](https://github.com/swc-project/swc/issues/11480)) ([d5a8d84](https://github.com/swc-project/swc/commit/d5a8d8447a6a4517372a5d52151e6732d74a1ade))

##### Testing

- **(es/minifier)** Add test case for `merge_imports` order preservation ([#&#8203;11458](https://github.com/swc-project/swc/issues/11458)) ([b874a05](https://github.com/swc-project/swc/commit/b874a05d5cde160c4d40f0d73f871fdb1746a753))

- **(es/parser)** Add error tests for import.source and import.defer with too many args ([#&#8203;11466](https://github.com/swc-project/swc/issues/11466)) ([7313462](https://github.com/swc-project/swc/commit/731346282ebdb11fd3a1fb6b558cc83982e4afcb))

- **(es/parser)** Check `handler.has_errors()` in test error parsing ([#&#8203;11487](https://github.com/swc-project/swc/issues/11487)) ([fade647](https://github.com/swc-project/swc/commit/fade647452ed288d42336a4c5580b49bd4953e23))

- Replace deprecated `cargo_bin` function with `cargo_bin!` macro ([#&#8203;11461](https://github.com/swc-project/swc/issues/11461)) ([73f77b6](https://github.com/swc-project/swc/commit/73f77b6331b1501592315b78babcc96d9ae9b483))

### [`v1.15.10`](https://github.com/swc-project/swc/blob/HEAD/CHANGELOG.md#11510---2026-01-19)

[Compare Source](https://github.com/swc-project/swc/compare/v1.15.8...v1.15.10)

##### Bug Fixes

- **(ci)** Handle merged PRs separately in milestone manager ([#&#8203;11409](https://github.com/swc-project/swc/issues/11409)) ([3554268](https://github.com/swc-project/swc/commit/3554268dcb7c8af4abfe0a06e61a382a23c4a3eb))

- **(es/compat)** Preserve this context in nested arrow functions ([#&#8203;11423](https://github.com/swc-project/swc/issues/11423)) ([f2bdaf2](https://github.com/swc-project/swc/commit/f2bdaf27d869a6d54a3dd47cd47e63c5b39a4d5c))

- **(es/es2017)** Replace `this` in arrow functions during async-to-generator ([#&#8203;11450](https://github.com/swc-project/swc/issues/11450)) ([a993da6](https://github.com/swc-project/swc/commit/a993da6fb6e43bdbc2cd3a288c8b5be1b79e08c0))

##### Features

- **(bindings/wasm)** Enable ecma\_lints feature to support semantic error detection ([#&#8203;11414](https://github.com/swc-project/swc/issues/11414)) ([1faa4a5](https://github.com/swc-project/swc/commit/1faa4a57454ef3932c75a1aca7dd36e37bb215d3))

- **(es/hooks)** Implement VisitMutHook for Either type ([#&#8203;11428](https://github.com/swc-project/swc/issues/11428)) ([395c85e](https://github.com/swc-project/swc/commit/395c85e921eeb0cad661c8714d97372970cbfb6c))

- **(es/hooks)** Implement VisitMutHook for Option<H> ([#&#8203;11429](https://github.com/swc-project/swc/issues/11429)) ([0bf1954](https://github.com/swc-project/swc/commit/0bf195421de167b3a01f710be7578d1cedf033b9))

- **(es/hooks)** Add VisitHook trait for immutable AST visitors ([#&#8203;11437](https://github.com/swc-project/swc/issues/11437)) ([3efb41d](https://github.com/swc-project/swc/commit/3efb41d97e2cdb1d593c55c841c016eb2958ee72))

- **(es/minifier)** Improve nested template literal evaluation ([#&#8203;11411](https://github.com/swc-project/swc/issues/11411)) ([147df2f](https://github.com/swc-project/swc/commit/147df2f0233c4b701311675dc7c237ee18f0c854))

- **(es/minifier)** Remove inlined IIFE arg and param ([#&#8203;11436](https://github.com/swc-project/swc/issues/11436)) ([2bc5d40](https://github.com/swc-project/swc/commit/2bc5d402ade64f84523bfa7cf0c2da88ef494ad6))

- **(es/minifier)** Remove inlined IIFE arg and param ([#&#8203;11446](https://github.com/swc-project/swc/issues/11446)) ([baa1ae3](https://github.com/swc-project/swc/commit/baa1ae3510668f9969bf5cd73ba4e3d66aa74fa0))

##### Miscellaneous Tasks

- **(deps)** Update `rkyv` ([#&#8203;11419](https://github.com/swc-project/swc/issues/11419)) ([432197b](https://github.com/swc-project/swc/commit/432197bdc7c574fbd8829ad5a6e0b3108ccb1d3c))

- **(deps)** Update lru to 0.16.3 ([#&#8203;11438](https://github.com/swc-project/swc/issues/11438)) ([67c2d75](https://github.com/swc-project/swc/commit/67c2d752910c945732cf4deebf2af0f8a110e880))

- **(deps)** Update browserslist-data to v0.1.5 ([#&#8203;11454](https://github.com/swc-project/swc/issues/11454)) ([e9f78f0](https://github.com/swc-project/swc/commit/e9f78f032f7d85a500037cdc82babdcf2d2be99a))

- **(helpers)** Replace MagicString with ast-grep's built-in edit API ([#&#8203;11410](https://github.com/swc-project/swc/issues/11410)) ([a3f0d33](https://github.com/swc-project/swc/commit/a3f0d33916f7ad225d8320c499a8dd0f7b46e5b9))

- **(hstr/wtf8)** Address legacy FIXME comments by switching to derives ([#&#8203;11416](https://github.com/swc-project/swc/issues/11416)) ([f03bfd8](https://github.com/swc-project/swc/commit/f03bfd8dd15630acbcdb011d64bdea5c1a0ccf79))

##### Performance

- **(es/codegen, es/utils)** Migrate to dragonbox\_ecma for faster Number::toString ([#&#8203;11412](https://github.com/swc-project/swc/issues/11412)) ([b7978cc](https://github.com/swc-project/swc/commit/b7978cc9dbe92b26d781748d09ad50e2f1a6343b))

- **(es/react)** Optimize JSX transforms to reduce allocations ([#&#8203;11425](https://github.com/swc-project/swc/issues/11425)) ([2a20cb6](https://github.com/swc-project/swc/commit/2a20cb6e34bed4260efe2a1b87165f52f9b3d45c))

##### Refactor

- **(es)** Improve TypeScript transform configuration structure ([#&#8203;11434](https://github.com/swc-project/swc/issues/11434)) ([f33a975](https://github.com/swc-project/swc/commit/f33a975c74f63f8d8e3c05db5166912c432ae18b))

- **(es/minifier)** Migrate MinifierPass to Pass trait ([#&#8203;11442](https://github.com/swc-project/swc/issues/11442)) ([a41e631](https://github.com/swc-project/swc/commit/a41e63193c86290f20fec6529d7aa944562df713))

- **(es/minifier)** Improve tpl to str ([#&#8203;11415](https://github.com/swc-project/swc/issues/11415)) ([0239523](https://github.com/swc-project/swc/commit/0239523c3863f3c0c8f8a3c7d486b64213fc60ff))

- **(es/react)** Port to VisitMutHook ([#&#8203;11418](https://github.com/swc-project/swc/issues/11418)) ([9604d9c](https://github.com/swc-project/swc/commit/9604d9cc8a3d265d66ab32c1f70c25031b09cc18))

- **(es/transformer)** Remove OptionalHook wrapper in favor of Option<H> ([#&#8203;11430](https://github.com/swc-project/swc/issues/11430)) ([72da6bd](https://github.com/swc-project/swc/commit/72da6bdd526eff0fdde76f22a978cbec736b9d3c))

- **(es/transforms)** Migrate TypeScript transform to Pass trait ([#&#8203;11439](https://github.com/swc-project/swc/issues/11439)) ([dd007c6](https://github.com/swc-project/swc/commit/dd007c64a691d37f6d4903624a8dfa39d389f912))

##### Testing

- **(es)** Enable benchmark for `swc` ([#&#8203;11420](https://github.com/swc-project/swc/issues/11420)) ([3a50a25](https://github.com/swc-project/swc/commit/3a50a2592784a418ef3312b0f445bde2762959ca))

- Disable LTO for benchmarks ([#&#8203;11421](https://github.com/swc-project/swc/issues/11421)) ([af3c2d3](https://github.com/swc-project/swc/commit/af3c2d36d772eab7905db717f8be2080fd14abec))

- Use rstest as the test framework ([#&#8203;11417](https://github.com/swc-project/swc/issues/11417)) ([fae258f](https://github.com/swc-project/swc/commit/fae258f530d2f54fa148f90225e9a7740de57d96))

##### Ci

- Collapse preivous `claude[bot]` PR review comments ([affb6a2](https://github.com/swc-project/swc/commit/affb6a29de9a511148a3483149aa5a574720fccf))

</details>

<details>
<summary>swc-project/swc (@&#8203;swc/helpers)</summary>

### [`v0.5.21`](https://github.com/swc-project/swc/compare/c2f628aba81c4d9c9e41c31a70e593902828584b...52303ecaacdec85cac9b3200e1ab1dd3863d3f5c)

[Compare Source](https://github.com/swc-project/swc/compare/c2f628aba81c4d9c9e41c31a70e593902828584b...52303ecaacdec85cac9b3200e1ab1dd3863d3f5c)

### [`v0.5.20`](https://github.com/swc-project/swc/compare/80296b38b16652f395db75bec0e80c87da0803ce...c2f628aba81c4d9c9e41c31a70e593902828584b)

[Compare Source](https://github.com/swc-project/swc/compare/80296b38b16652f395db75bec0e80c87da0803ce...c2f628aba81c4d9c9e41c31a70e593902828584b)

### [`v0.5.19`](https://github.com/swc-project/swc/compare/3c24b02a9c63fa32dc8389c08a01f36249029da7...80296b38b16652f395db75bec0e80c87da0803ce)

[Compare Source](https://github.com/swc-project/swc/compare/3c24b02a9c63fa32dc8389c08a01f36249029da7...80296b38b16652f395db75bec0e80c87da0803ce)

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

👻 **Immortal**: This PR will be recreated if closed unmerged. Get [config help](https://github.com/renovatebot/renovate/discussions) if that's undesired.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/19
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 16:18:54 +02:00
julien f9ed3cf82a chore(ci): skip perf and commits gates on Renovate-authored PRs (#23)
CI / commits (push) Has been skipped
CI / check (push) Successful in 2m20s
CI / scan (push) Failing after 2m34s
CI / a11y (push) Successful in 1m7s
CI / perf (push) Successful in 3m43s
## Summary
Renovate's dep-bump PRs run the full pipeline today (`check`, `scan`, `commits`, `perf`, `a11y`). Two of those gates have near-zero signal on a typical bump and dominate the wall-clock cost:

- **`perf`** — Lighthouse build + 3-iteration median across the critical-routes list. 3-5 min per PR for a metric that is essentially zero on a patch/minor dep bump (the SPA today serves the static placeholder; even with real routes a typical bump stays inside the median noise floor).
- **`commits`** — re-validates commit messages that Renovate generates from a Conventional-Commits-conformant template. Tautological.

Skip both when the PR author is the `apf-portal-bot` Gitea user. The `push` event on `main` still runs the full pipeline post-merge, so any regression caught by `perf` is detected seconds after merge — fast enough to revert.

Net result: Renovate PRs run `check + scan + a11y` only, ≈ 4-5 min faster per PR.

## ADR amendment

ADR-0017 is amended in the same change:
- "Where Lighthouse CI runs" table now distinguishes human PR / bot PR / push to main / scheduled / local.
- New "Pre-merge gating policy: human PRs vs bot PRs" subsection records the rationale and the human-takeover edge case.
- §Confirmation entry for `perf` is reworded to reflect the conditional gate.

## Test plan
- [ ] After merge, the next Renovate-triggered PR (auto-rebase or new bump) shows only `check`, `scan`, `a11y` queued — no `perf`, no `commits`.
- [ ] A human-opened PR (e.g. this one) still queues all 5 gates.
- [ ] On `push` to `main` post-merge, the full pipeline runs including `perf`.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #23
2026-05-05 16:12:19 +02:00
APF Portal Bot 0c6a3f2b27 chore(deps): update dependency nx to v22.7.1 (#15)
CI / commits (push) Has been skipped
CI / check (push) Successful in 3m5s
CI / scan (push) Failing after 2m36s
CI / a11y (push) Successful in 2m25s
CI / perf (push) Successful in 4m35s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [nx](https://nx.dev) ([source](https://github.com/nrwl/nx/tree/HEAD/packages/nx)) | devDependencies | patch | [`22.7.0` -> `22.7.1`](https://renovatebot.com/diffs/npm/nx/22.7.0/22.7.1) |

---

### Release Notes

<details>
<summary>nrwl/nx (nx)</summary>

### [`v22.7.1`](https://github.com/nrwl/nx/releases/tag/22.7.1)

[Compare Source](https://github.com/nrwl/nx/compare/22.7.0...22.7.1)

#### 22.7.1 (2026-04-28)

##### 🩹 Fixes

- **core:** prevent spinner flicker when sync applying ([#&#8203;35445](https://github.com/nrwl/nx/pull/35445))
- **core:** exclude hyperfine env vars from daemon env reflection ([5095b4be7d](https://github.com/nrwl/nx/commit/5095b4be7d))
- **core:** provide actionable feedback when running migrations and pre-install fails with npm peer dep errors ([#&#8203;33961](https://github.com/nrwl/nx/pull/33961), [#&#8203;33942](https://github.com/nrwl/nx/issues/33942))
- **core:** consider virtual trees in multiGlobWithWorkspaceContext ([#&#8203;35447](https://github.com/nrwl/nx/pull/35447), [#&#8203;31805](https://github.com/nrwl/nx/issues/31805), [#&#8203;35373](https://github.com/nrwl/nx/issues/35373), [#&#8203;32588](https://github.com/nrwl/nx/issues/32588))
- **core:** surface ./nx --version stderr and force devDeps install ([#&#8203;35469](https://github.com/nrwl/nx/pull/35469))
- **core:** keep continuous children alive when nx:noop orchestrator completes ([#&#8203;35388](https://github.com/nrwl/nx/pull/35388))
- **core:** start TUI event reader synchronously in enter() to prevent stdin race ([#&#8203;35465](https://github.com/nrwl/nx/pull/35465), [#&#8203;34619](https://github.com/nrwl/nx/issues/34619), [#&#8203;34144](https://github.com/nrwl/nx/issues/34144))
- **core:** use require for global to local Nx handoff so Windows drive paths work ([#&#8203;35478](https://github.com/nrwl/nx/pull/35478))
- **core:** prevent daemon shutdown from cache-poisoned in-process nx loads ([#&#8203;35482](https://github.com/nrwl/nx/pull/35482), [#&#8203;35444](https://github.com/nrwl/nx/issues/35444), [#&#8203;34463](https://github.com/nrwl/nx/issues/34463), [#&#8203;34111](https://github.com/nrwl/nx/issues/34111))
- **detox:** generate valid JSON in .detoxrc for non-expo apps ([eb2fa8ced4](https://github.com/nrwl/nx/commit/eb2fa8ced4))
- **js:** include extended tsconfigs from project references in typecheck inputs ([#&#8203;35457](https://github.com/nrwl/nx/pull/35457))
- **linter:** detect root lint target added in same generator run ([#&#8203;35296](https://github.com/nrwl/nx/pull/35296), [#&#8203;23147](https://github.com/nrwl/nx/issues/23147), [#&#8203;34531](https://github.com/nrwl/nx/issues/34531))
- **misc:** exclude stories and specs from tailwind content scanning ([#&#8203;35470](https://github.com/nrwl/nx/pull/35470))
- **misc:** resolve pnpm catalog: refs in version lookups ([#&#8203;35459](https://github.com/nrwl/nx/pull/35459), [#&#8203;35453](https://github.com/nrwl/nx/issues/35453))
- **nextjs:** use cached project graph in withNx ([#&#8203;35475](https://github.com/nrwl/nx/pull/35475), [#&#8203;34518](https://github.com/nrwl/nx/issues/34518), [#&#8203;32880](https://github.com/nrwl/nx/issues/32880))
- **node:** include tsconfig input in node-app esbuild scaffold ([#&#8203;35466](https://github.com/nrwl/nx/pull/35466))
- **release:** handle short and full project names in commit scopes ([#&#8203;34219](https://github.com/nrwl/nx/pull/34219))
- **testing:** convert executor-based jest.config.ts and preserve type-only imports ([#&#8203;35286](https://github.com/nrwl/nx/pull/35286), [#&#8203;34593](https://github.com/nrwl/nx/issues/34593))

##### ❤️ Thank You

- Claude
- Craigory Coppola [@&#8203;AgentEnder](https://github.com/AgentEnder)
- Jack Hsu [@&#8203;jaysoo](https://github.com/jaysoo)
- Jason Jean [@&#8203;FrozenPandaz](https://github.com/FrozenPandaz)
- Leosvel Pérez Espinosa [@&#8203;leosvelperez](https://github.com/leosvelperez)
- ShwethaSundar

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/15
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 15:06:07 +02:00
APF Portal Bot c3d098502f chore(deps): update dependency postcss to v8.5.14 (#16)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 2m1s
CI / check (push) Successful in 2m24s
CI / a11y (push) Successful in 52s
CI / perf (push) Successful in 3m6s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [postcss](https://postcss.org/) ([source](https://github.com/postcss/postcss)) | devDependencies | patch | [`8.5.12` -> `8.5.14`](https://renovatebot.com/diffs/npm/postcss/8.5.12/8.5.14) |

---

### Release Notes

<details>
<summary>postcss/postcss (postcss)</summary>

### [`v8.5.14`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8514)

[Compare Source](https://github.com/postcss/postcss/compare/8.5.13...8.5.14)

- Fixed custom syntax regression (by [@&#8203;43081j](https://github.com/43081j)).

### [`v8.5.13`](https://github.com/postcss/postcss/blob/HEAD/CHANGELOG.md#8513)

[Compare Source](https://github.com/postcss/postcss/compare/8.5.12...8.5.13)

- Fixed `postcss-scss` commend regression.

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #16
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 14:59:53 +02:00
APF Portal Bot 4ee2409771 chore(deps): update pnpm to v10.33.3 (#17)
CI / check (push) Successful in 1m34s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 1m27s
CI / a11y (push) Successful in 1m42s
CI / perf (push) Successful in 2m34s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [pnpm](https://pnpm.io) ([source](https://github.com/pnpm/pnpm/tree/HEAD/pnpm)) | packageManager | patch | [`10.33.2` -> `10.33.3`](https://renovatebot.com/diffs/npm/pnpm/10.33.2/10.33.3) |

---

### Release Notes

<details>
<summary>pnpm/pnpm (pnpm)</summary>

### [`v10.33.3`](https://github.com/pnpm/pnpm/releases/tag/v10.33.3): pnpm 10.33.3

[Compare Source](https://github.com/pnpm/pnpm/compare/v10.33.2...v10.33.3)

#### Patch Changes

- When self-updating from v10's `@pnpm/exe` to v11+ on Intel macOS (darwin-x64), `pnpm self-update` now transparently switches to the JS-only `pnpm` package on npm instead of installing `@pnpm/exe@v11+` (which doesn't ship a working binary for Intel Macs because of an upstream Node.js SEA bug — see [#&#8203;11423](https://github.com/pnpm/pnpm/issues/11423) and [nodejs/node#62893](https://github.com/nodejs/node/issues/62893)). Without this, the self-update would silently leave the user with no working `pnpm` binary. The new install requires Node.js to be available on `PATH`; a warning is printed when the swap happens. All other host/version combinations are unchanged.
- `pnpm self-update` (with no version argument) no longer downgrades pnpm when the registry's `latest` dist-tag points to an older release than the currently active version. Run `pnpm self-update latest` to force a downgrade [#&#8203;11418](https://github.com/pnpm/pnpm/issues/11418).

<!-- sponsors -->

#### Platinum Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://bit.cloud/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/bit.svg" width="80" alt="Bit"></a>
      </td>
    </tr>
  </tbody>
</table>

#### Gold Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle">
        <a href="https://sanity.io/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/sanity.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/sanity_light.svg" />
            <img src="https://pnpm.io/img/users/sanity.svg" width="120" alt="Sanity" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://discord.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/discord.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/discord_light.svg" />
            <img src="https://pnpm.io/img/users/discord.svg" width="220" alt="Discord" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://vite.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank"><img src="https://pnpm.io/img/users/vitejs.svg" width="42" alt="Vite"></a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
        <a href="https://serpapi.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/serpapi_dark.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/serpapi_light.svg" />
            <img src="https://pnpm.io/img/users/serpapi_dark.svg" width="160" alt="SerpApi" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://coderabbit.ai/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/coderabbit.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/coderabbit_light.svg" />
            <img src="https://pnpm.io/img/users/coderabbit.svg" width="220" alt="CodeRabbit" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://stackblitz.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/stackblitz.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/stackblitz_light.svg" />
            <img src="https://pnpm.io/img/users/stackblitz.svg" width="190" alt="Stackblitz" />
          </picture>
        </a>
      </td>
    </tr>
    <tr>
      <td align="center" valign="middle">
        <a href="https://workleap.com/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/workleap.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/workleap_light.svg" />
            <img src="https://pnpm.io/img/users/workleap.svg" width="190" alt="Workleap" />
          </picture>
        </a>
      </td>
      <td align="center" valign="middle">
        <a href="https://nx.dev/?utm_source=pnpm&utm_medium=release_notes" target="_blank">
          <picture>
            <source media="(prefers-color-scheme: light)" srcset="https://pnpm.io/img/users/nx.svg" />
            <source media="(prefers-color-scheme: dark)" srcset="https://pnpm.io/img/users/nx_light.svg" />
            <img src="https://pnpm.io/img/users/nx.svg" width="50" alt="Nx" />
          </picture>
        </a>
      </td>
    </tr>
  </tbody>
</table>

<!-- sponsors end -->

</details>

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: https://git.unespace.com/julien/apf_portal/pulls/17
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 14:46:57 +02:00
APF Portal Bot 8769e697b6 chore(deps): update dependency @types/node to v20.19.39 (#14)
CI / commits (push) Has been skipped
CI / check (push) Successful in 2m20s
CI / scan (push) Failing after 2m9s
CI / a11y (push) Successful in 1m36s
CI / perf (push) Successful in 2m33s
This PR contains the following updates:

| Package | Type | Update | Change |
|---|---|---|---|
| [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node) ([source](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node)) | devDependencies | patch | [`20.19.9` -> `20.19.39`](https://renovatebot.com/diffs/npm/@types%2fnode/20.19.9/20.19.39) |

---

### Configuration

📅 **Schedule**: Branch creation - At any time (no schedule defined), Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update again.

---

 - [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check this box

---

This PR has been generated by [Renovate Bot](https://github.com/renovatebot/renovate).
<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiI0MC42Mi4xIiwidXBkYXRlZEluVmVyIjoiNDAuNjIuMSIsInRhcmdldEJyYW5jaCI6Im1haW4iLCJsYWJlbHMiOlsiZGVwZW5kZW5jaWVzIl19-->

Reviewed-on: #14
Co-authored-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
Co-committed-by: APF Portal Bot <jgautier.webdev+apf-portal-bot@gmail.com>
2026-05-05 14:07:26 +02:00
julien f58cf13e33 fix(ci): give Renovate a git identity and a github.com token (#13)
CI / check (push) Successful in 2m24s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 1m8s
CI / a11y (push) Successful in 1m32s
CI / perf (push) Successful in 2m52s
## Summary
First successful Renovate run (after the docker-image fix in #12) extracted 116 deps cleanly but every branch update failed with `fatal: empty ident name not allowed`, then the whole repo aborted on `Lock file error - aborting`. Two root causes:

- **No git identity** — the bot user had an email but no **Full Name** on its Gitea profile, so Renovate produced incomplete git authorship.
- **No github.com auth** — Renovate could not look up versions of GitHub-hosted Actions (`actions/checkout`, etc.) or `containerbase/node-prebuild` (the Node binary it dynamically fetches for lockfile maintenance) — anonymous rate limit (60 req/h) hit.

Fixes:

1. **`renovate.json`** — pin `gitAuthor` explicitly. The Full Name was also set on the bot's Gitea profile for UI consistency, but the override in config means we don't depend on out-of-band UI state.
2. **`.gitea/workflows/renovate.yml`** — pass `RENOVATE_GITHUB_COM_TOKEN` from the new `GITHUBCOM_TOKEN` repo secret (no underscore between GITHUB and COM — Gitea reserves the `GITHUB_*` namespace).
3. **`docs/development.md`** — onboarding procedure now covers both tokens + the Full Name step.

## Manual setup required after merge
Already done in this iteration:
- Bot's Full Name set in Gitea ("APF Portal Bot").
- `GITHUBCOM_TOKEN` repo secret created with a zero-scope github.com PAT.

(If the PAT was leaked during setup, regenerate before merging — the workflow only references the secret name, not the value.)

## Test plan
- [ ] After merge, trigger Renovate manually (Actions → Renovate → Run workflow).
- [ ] No `empty ident name` warning in the logs.
- [ ] No `Lock file error - aborting`; repo finishes with `INFO: Repository finished … "cloned": true`.
- [ ] Renovate creates the dependency dashboard issue + the first batch of grouped PRs (Angular, Nx, NestJS, Prisma, …) signed by `apf-portal-bot`.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #13
2026-05-05 13:47:30 +02:00
julien 399a14e0f4 fix(ci): run Renovate via official Docker image (#12)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 2m59s
CI / check (push) Successful in 3m12s
CI / a11y (push) Successful in 48s
CI / perf (push) Successful in 3m56s
## Summary
First Renovate run failed with `reference not found` on `renovatebot/github-action@v40` — act_runner's go-git clone couldn't resolve the major-rolling tag (whether the upstream tag is missing or it's a go-git tag-fetch quirk doesn't really matter — the wrapper action is the wrong layer to fight).

Switch to invoking the official `renovate/renovate:40` Docker image directly. The job container already has the host Docker socket mounted (per `ci-runners.compose.yml`), so the sibling `docker run` works out of the box. Renovate clones the target repo itself via API + token, so no `actions/checkout` or bind-mount is needed.

Net result:
- Decoupled from third-party action-tag resolution.
- Renovate runtime version explicitly pinned (reproducible).
- One fewer indirection to debug.

## Test plan
- [ ] After merge, trigger the workflow manually (Actions → Renovate → Run workflow).
- [ ] Job pulls `renovate/renovate:40` (~1 GB, one-time on this runner host) and runs without "reference not found".
- [ ] Renovate creates the onboarding PR ("Configure Renovate") visible in the repo's PR list, signed by `apf-portal-bot`.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #12
2026-05-05 11:42:03 +02:00
julien 82911f9319 chore(ci): set up Renovate dependency automation (#11)
CI / commits (push) Has been skipped
CI / check (push) Successful in 1m21s
CI / scan (push) Failing after 1m27s
CI / a11y (push) Successful in 44s
CI / perf (push) Successful in 2m28s
## Summary
Wire up Renovate to keep dependencies fresh without manual triage.

- **Workflow** — `.gitea/workflows/renovate.yml`: cron daily at 03:00 UTC + `workflow_dispatch`, runs on the existing self-hosted runners. Picked 03:00 specifically so Monday's tick sits inside Renovate's default `lockFileMaintenance.schedule` ("before 4am Monday") and triggers the weekly lockfile refresh in passing.
- **Config** — `renovate.json`: `config:recommended` baseline + groupings (Angular, Nx, NestJS, Prisma, Vitest, TypeScript tooling, ESLint, SWC, Tailwind), Conventional-Commits commit messages, OSV.dev as vulnerability source, dependency dashboard issue.
- **Docs** — new §5 in `docs/development.md` covering the bot onboarding (manual, one-shot), how to trigger Renovate manually, how to review its PRs. The placeholder roadmap entry is dropped from §8.

No ADR — Renovate is operational tooling, not an architectural decision (and on Gitea it's the only viable bot anyway, no real alternative to capture).

## Manual setup required after merge

The workflow is wired but inert until the bot is onboarded once on Gitea:

1. Create a non-admin Gitea user `apf-portal-bot`.
2. Add the bot as a **Write** collaborator on this repo.
3. Sign in as the bot, generate a PAT (scopes: read/write `repository`, read/write `issue`, read `user`).
4. Add the PAT as the repo secret `RENOVATE_TOKEN` (Settings → Actions → Secrets).

Detailed steps in [`docs/development.md`](docs/development.md) → "Dependency updates (Renovate)".

## Test plan
- [ ] After bot onboarding, trigger the workflow manually (Repo → Actions → Renovate → Run workflow).
- [ ] First run creates the "Renovate Dependency Dashboard" issue and a batch of grouped PRs (Angular, Nx, …).
- [ ] Each generated PR has CI green (`check`, `scan`, `commits`, `perf`, `a11y`).
- [ ] Commit subject matches `chore(deps): …` / `fix(deps): …` so the `commits` gate doesn't reject.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #11
2026-05-04 17:37:13 +02:00
julien efa660abab chore(infra): pin act_runner image pull policy (#10)
CI / check (push) Successful in 1m39s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 52s
CI / a11y (push) Successful in 51s
CI / perf (push) Successful in 1m53s
## Summary
`act_runner`'s default `container.force_pull: true` re-issues a `docker pull` at the start of every job, adding 10–30 s of registry round-trip even when every layer is already locally cached. With job images pinned to specific tags (`catthehacker/ubuntu:act-22.04` and `:full-22.04`), the implicit pull is pure overhead and contradicts the deliberate-upgrade policy ADR-0015 spells out for the runner image.

- Add `infra/runner-config.yaml` with `container.force_pull: false`.
- Mount it read-only into all three runners and point each at it via `CONFIG_FILE=/etc/runner/config.yaml`.
- Document the pre-pull procedure and image-upgrade playbook in `infra/README.md` → "Job image pinning and pre-pull".
- Fold the pre-pull into the "First-time registration" walkthrough so a fresh setup is correct end-to-end.

The trade-off: the runner host must hold the images locally before the runner is asked to use them. Documented.

## Roll-out (manual, on the runner host)
```bash
cd infra/

# 1. Pre-pull the job images (one-shot — pays the cold cost once).
docker pull catthehacker/ubuntu:act-22.04
docker pull catthehacker/ubuntu:full-22.04

# 2. Recreate the runners so the new mount + env var take effect.
docker compose -f ci-runners.compose.yml up -d --force-recreate

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #10
2026-05-04 15:55:17 +02:00
julien 7951908229 chore(prisma): point root postinstall to BFF schema (#9)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 1m52s
CI / a11y (push) Successful in 46s
CI / perf (push) Successful in 2m39s
CI / check (push) Failing after 11m41s
## Summary
`@prisma/client`'s postinstall hook runs `prisma generate` from the workspace root and didn't find a schema there, so the typed client was never generated. Fine today (schema has no models, no runtime usage), but a trap as soon as the first model lands.

Declare `package.json#prisma.schema` so the postinstall locates `apps/portal-bff/prisma/schema.prisma` and generates the typed client on every `pnpm install`.

Verified locally: postinstall now logs `✔ Generated Prisma Client (v6.19.3)`.

## Notes
- Prisma 6.19 emits a deprecation warning suggesting migration to `prisma.config.ts`. That format is freshly out of Early Access and the migration is small but non-trivial — folding it into the future Prisma 7 upgrade (which itself depends on `nestjs-prisma` catching up and will get its own ADR).

## Test plan
- [ ] CI green on this PR.
- [ ] In the `Run pnpm install --frozen-lockfile` log of the `check` job, the warning `prisma:warn We could not find your Prisma schema` is gone, replaced with `✔ Generated Prisma Client`.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #9
2026-05-04 15:33:40 +02:00
julien f2440fbf24 fix(ci): disable broken pnpm cache on actions/setup-node (#8)
CI / a11y (push) Successful in 45s
CI / perf (push) Successful in 2m40s
CI / commits (push) Failing after 12m17s
CI / scan (push) Failing after 12m18s
CI / check (push) Failing after 12m19s
## Summary
`act_runner`'s built-in GitHub-Actions-cache server binds inside the runner container on the compose-defined `apf-portal-act-runners` bridge. Jobs spawned via the mounted Docker socket land on Docker's default `bridge` network and can't reach it. Every job opting into `cache: 'pnpm'` ate ~2 min `ETIMEDOUT` on restore + another ~2 min on save — across the 5 jobs, ~20 min wasted per CI run for zero cache hits.

Drop `cache: 'pnpm'` everywhere. `pnpm install --frozen-lockfile` is fast on the warm store inside the job container, so removing the cache layer is a net gain today.

The proper fix (cross-container networking / fixed-port cache binding) is documented in `infra/README.md` → "Cache server (deferred)" so it can be picked up as an isolated infra spike later.

## Test plan
- [ ] CI run on this PR: every job's `Set up Node.js` step finishes in seconds (no ETIMEDOUT warning).
- [ ] `Complete job` step also finishes promptly (no `reserveCache failed` warning).
- [ ] Total wall-clock time for the run should drop by ~15-20 min vs. previous runs.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #8
2026-05-04 15:33:04 +02:00
julien b7adf2e308 fix(ci): post-runner-image cleanup (#7)
CI / commits (push) Has been skipped
CI / scan (push) Failing after 6m19s
CI / check (push) Successful in 11m43s
CI / perf (push) Successful in 12m0s
CI / a11y (push) Successful in 10m8s
## Summary
Three follow-up fixes uncovered by the first end-to-end CI run on the self-hosted act_runner image (smoke-test PR).

- **`check` job** — replace `nrwl/nx-set-shas@v4` (GitHub-API only, 404 on Gitea) with a manual shell step that derives `NX_BASE`/`NX_HEAD` from local git history (merge-base on `pull_request`, `HEAD~1` on `push`).
- **`perf` job** — pin to `catthehacker/ubuntu:full-22.04` so Lighthouse CI finds a real Chrome. The default act image (`act-22.04`) is the minimal variant, ships without browsers.
- **`package.json`** — declare `pnpm.onlyBuiltDependencies` to silence the "Ignored build scripts" warning and approve only the post-install hooks we actually rely on (Nx, Prisma, esbuild, swc, native watchers/resolvers).

No ADR change — these are purely operational adjustments.

## Test plan
- [ ] CI run on this PR: `check` and `perf` jobs both green.
- [ ] No "Ignored build scripts" warning in `pnpm install` step output.
- [ ] After merge, `push` event on `main` re-runs `check`, `scan`, `perf`, `a11y` cleanly (no `nx-set-shas` 404).

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #7
2026-05-04 14:55:14 +02:00
julien 25093db0b9 fix(ci): declare packageManager for pnpm/action-setup (#6)
CI / commits (push) Has been skipped
CI / check (push) Failing after 10s
CI / perf (push) Failing after 5m23s
CI / scan (push) Failing after 6m41s
CI / a11y (push) Successful in 9m51s
## Summary

- Add `"packageManager": "pnpm@10.33.2"` to root `package.json`.

## Motivation

The smoke-test CI run got past `actions/checkout@v4` (runner image fix from PR #4 working), but failed on `pnpm/action-setup@v3` with:

```
Error: No pnpm version is specified.
Please specify it by one of the following ways:
  - in the GitHub Action config with the key "version"
  - in the package.json with the key "packageManager"
```

The action looks at `package.json`'s `packageManager` field by default. Setting it there (rather than hardcoding `version:` in every workflow YAML) is the single-source-of-truth approach: corepack reads the same field locally, so dev environments and CI converge automatically.

## Implementation notes

- Pinned to `pnpm@10.33.2` (the exact version the workspace was bootstrapped with). Future bumps go through a dedicated `chore(deps): bump pnpm to X.Y.Z` PR that updates this field — keeps CI and local dev in lockstep.
- `corepack` will pick up this declaration on the next `corepack enable` or pnpm invocation. Devs already on 10.33.2 see no change; devs on a different version are nudged onto the canonical one.
- Workflow YAMLs (`.gitea/workflows/ci.yml`, `security-scheduled.yml`) untouched — `pnpm/action-setup@v3` reads `packageManager` directly.

## Verification

- [ ] Next CI run succeeds at `pnpm/action-setup@v3` (= the step that fails on smoke-test PR currently). Confirmed by re-pushing to the smoke-test branch (or any other PR) after this one merges.
- [x] `pnpm install` locally still works with the declaration (no change for someone already on 10.33.2).

## Related

- Follow-up to PR #4 (runner image fix). Together they unblock the CI gates.
- Smoke-test PR can be closed once a real PR (e.g. the upcoming "Local infra recipe") demonstrates green CI end to end.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #6
2026-05-04 12:36:38 +02:00
julien 02bdd43fa1 fix(ci): pin act_runner job image to catthehacker/ubuntu:act-22.04 (#4)
CI / commits (push) Has been skipped
CI / check (push) Failing after 3s
CI / scan (push) Failing after 9s
CI / a11y (push) Failing after 4s
CI / perf (push) Failing after 4s
## Summary

- Pin `act_runner`'s job container image to `catthehacker/ubuntu:act-22.04` via the `<label>:docker://<image>` format on the runner registration labels.
- Update `infra/ci-runners.compose.yml`'s `GITEA_RUNNER_LABELS` for all three runner services, with an inline comment explaining the format requirement.
- Amend ADR-0015 §"Runners" to specify the chosen image and explain the docker-suffix syntax trap.

## Motivation

The first real PR test of the CI pipeline failed at the very first step:

```
Run actions/checkout@v4
0s
Cannot find: node in PATH
 Failure - Main actions/checkout@v4
```

Root cause: `act_runner` registers labels (`self-hosted`, `on-prem`) without a `docker://` image suffix. Without that suffix, act spawns jobs in a minimal default container that has no Node. Every JavaScript action (`actions/checkout`, `actions/setup-node`, `nrwl/nx-set-shas`, the Trivy/gitleaks actions) crashes during the action's launch step. None of the five CI gates can run.

`catthehacker/ubuntu:act-22.04` is the de facto image used by `act` upstream and the standard recommendation for self-hosted Gitea Actions runners. It bundles Node, Python, git, common build tools, and the Docker CLI — exactly the assumed environment for GitHub Actions-compatible workflows.

## Implementation notes

- The fix lives in `GITEA_RUNNER_LABELS` because that's what `act_runner` reads at registration time. The label-to-image mapping is then persisted in the runner's `data/runner-N/.runner` credential.
- For runners **already registered** (i.e. the three currently-running `apf-portal-runner-N`), the persisted credential ignores the new env var. Their labels must be updated through Gitea's UI (Site Administration → Actions → Runners → each runner → edit `Labels`). This is documented in the commit message and is an operational follow-up to merging this PR.
- The compose-file change applies the next time a runner is re-registered (e.g. when `data/runner-N/` is wiped or a new fourth runner is added).
- ADR-0015 amendment is in-place, status remains `accepted`. The runner-image choice is an implementation detail under the existing decision; no new ADR.

## Verification

- [ ] `pnpm ci:check` — n/a, this PR only changes infra and ADR docs, no code paths.
- [ ] **Manual:** after merge + Gitea label updates, the next PR's `actions/checkout@v4` step runs without `Cannot find: node in PATH`.

## Related

- [ADR-0015 — CI/CD pipeline](docs/decisions/0015-cicd-gitea-actions.md). Amended in §"Runners".
- [`infra/README.md`](infra/README.md) — operational doc for the runners; mentions the registration workflow but predates this format requirement. A subsequent docs touch could mirror the new label format there too; deferred to keep this PR scoped to the actual fix.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #4
2026-05-04 11:06:56 +02:00
julien a0f6e594ba fix(portal-bff): downgrade Prisma to 6.x for nestjs-prisma compatibility (#3)
CI / commits (push) Has been skipped
CI / check (push) Failing after 4s
CI / scan (push) Failing after 6s
CI / a11y (push) Failing after 3s
CI / perf (push) Failing after 4s
## Summary

- Pin `prisma` and `@prisma/client` to `^6` (resolved 6.19.3) instead of the previous `^7`.
- Switch the generator in `apps/portal-bff/prisma/schema.prisma` from `prisma-client` to `prisma-client-js` (Prisma 6's default).
- Add the explicit `url = env("DATABASE_URL")` in the `datasource db` block (required by Prisma 6; was implicit in Prisma 7 via `prisma.config.ts`).
- Remove `apps/portal-bff/prisma.config.ts` (Prisma 7-only feature).
- Drop the now-irrelevant `/generated/prisma` entry from `apps/portal-bff/.gitignore`.

## Motivation

Two distinct Prisma 7 breaking changes surfaced as runtime errors in `pnpm nx serve portal-bff`:

1. **Generator output path:** Prisma 7's default `prisma-client` generator writes to a custom output dir declared in the schema. `@prisma/client/default.js`'s runtime stub still resolves `.prisma/client/default` in a sibling `node_modules/.prisma/client/`, which only the legacy `prisma-client-js` generator populates. Result: `ESM loader error: Cannot find module '.prisma/client/default'`.

2. **PrismaClientOptions API:** In Prisma 7, `PrismaClientOptions` no longer exposes `datasourceUrl` nor `datasources`. The connection must come through a driver adapter (e.g. `@prisma/adapter-pg`). `nestjs-prisma@0.27.0` calls `super(undefined)` when no `prismaServiceOptions` is passed, which Prisma 7 rejects with `PrismaClientInitializationError: PrismaClient needs to be constructed with a non-empty, valid PrismaClientOptions`.

Both issues are downstream of Prisma 7's "adapter-first" architecture being incompatible with `nestjs-prisma`'s still-Prisma-6-shaped wrapper. Working around each issue separately would lead into bespoke wiring (custom PrismaService, manual `@prisma/adapter-pg` install, hand-rolled DI). That's bricolage on a foundational layer.

Per CLAUDE.md ("default to stable, recognized, battle-tested choices; cutting-edge alternatives only when the trade-off is captured in an ADR"), the cheapest, cleanest fix is to use Prisma 6 — still actively maintained, fully aligned with `nestjs-prisma`'s design, supported by every tutorial and example in the wider ecosystem.

## Implementation notes

- ADR-0006 ("Persistence — PostgreSQL with Prisma") specifies "Prisma" without pinning a version. The version choice is a tactical detail. No ADR amendment.
- `apps/portal-bff/.env.example` is unchanged — the `DATABASE_URL` variable name is the same in Prisma 6 and 7.
- `prisma.config.ts` removed: it was a Prisma 7 file that Prisma 6 ignores; keeping it would only confuse a future contributor.
- The Prisma 7 `prisma-client` generator left a residual output dir at `apps/portal-bff/generated/` from the previous setup; removed locally and excluded from gitignore (no longer needed).
- Re-evaluate when `nestjs-prisma` releases an update aligned with Prisma 7's adapter model. The path back is symmetric: pin Prisma to `^7`, restore the schema's `prisma-client` generator, install `@prisma/adapter-pg`, and update `app.module.ts` to instantiate the adapter.

## Verification

- [x] `pnpm exec prisma generate` populates `node_modules/.../@prisma+client@6.19.3/.prisma/client/default.js` (no more 7.x in the active resolution).
- [x] `pnpm nx build portal-bff` green.
- [X] `pnpm nx serve portal-bff` boots cleanly (no `PrismaClientInitializationError`) — to be confirmed locally before merge. Connection to a real Postgres is out of scope of this PR; if Postgres is not running, an `ECONNREFUSED` is expected and unrelated.
- [ ] `pnpm ci:check` — runs in CI on PR open.

## Related

- [ADR-0006 — Persistence: PostgreSQL with Prisma](docs/decisions/0006-persistence-postgresql-prisma.md). Generator and version are tactical; no amendment.
- Future: revisit Prisma version when `nestjs-prisma` ships an update with first-class driver-adapter support.

---------

Co-authored-by: Julien Gautier <julien.gautier@apf.asso.fr>
Reviewed-on: #3
2026-05-04 10:46:12 +02:00
julien 52e75bcbc9 Merge pull request 'chore: add docker compose for self-hosted Gitea act_runners' (#2) from chore/ci-runners-infra into main
CI / check (push) Failing after 4s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 6s
CI / a11y (push) Failing after 3s
CI / perf (push) Failing after 3s
Reviewed-on: #2
2026-05-01 00:45:41 +02:00
julien f0b437bdc9 Merge pull request 'docs: add docs/architecture.md with C4 contexts, Nx boundaries, and CI/CD pipeline' (#1) from docs/architecture-diagrams into main
CI / check (push) Failing after 5s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 6s
CI / a11y (push) Failing after 2s
CI / perf (push) Failing after 3s
Reviewed-on: #1
2026-05-01 00:45:23 +02:00
Julien Gautier 644d3603d2 chore: add docker compose for self-hosted Gitea act_runners
CI / check (pull_request) Failing after 6s
CI / commits (pull_request) Failing after 2s
CI / scan (pull_request) Failing after 6s
CI / a11y (pull_request) Failing after 2s
CI / perf (pull_request) Failing after 3s
Set up the infrastructure-as-code recipe to bring up the three
self-hosted Gitea Actions runners required by ADR-0015. The compose
file launches three act_runner instances pinned to 0.2.13, registered
with the project's Gitea organisation, labelled self-hosted + on-prem
to match the runs-on selector in every job under .gitea/workflows/*.

Layout:
- infra/                         new top-level folder for IaC
- infra/README.md                explains the folder, registration
                                 flow, security implications, future
                                 placeholders (local/, prod/, runbooks/)
- infra/ci-runners.compose.yml   three act_runner services, networked
                                 together, persisting credentials to
                                 ./data/runner-N
- infra/.env.example             GITEA_INSTANCE_URL +
                                 GITEA_RUNNER_REGISTRATION_TOKEN; .env
                                 itself stays git-ignored (root rule)
- infra/data/.gitignore          tracks the dir, ignores runtime state

Security posture (documented in infra/README.md): mounting
/var/run/docker.sock gives the runner root-equivalent access to the
host Docker daemon. Mitigations rely on (a) repo-scope of the runner
in Gitea, (b) running the runner host outside the production trust
boundary, (c) no extra host filesystem mounts. Future hardening
(rootless Docker, DinD sidecar) is flagged as deferred.

The compose pins the runner image (0.2.13). Bumps go through a
dedicated chore(deps) PR per the convention; image upgrades roll one
runner at a time so CI is never starved (procedure documented in the
README).

Doc indexing (docs/README.md) deliberately not touched here to avoid
a conflict with the pending docs/architecture-diagrams branch which
also modifies that file. A small follow-up PR will add an index entry
once that branch is merged.
2026-05-01 00:00:28 +02:00
Julien Gautier 156e7ca2df chore: add PR template and document title/body convention
CI / check (push) Failing after 5s
CI / commits (push) Has been skipped
CI / scan (push) Failing after 6s
CI / perf (push) Failing after 3s
CI / a11y (push) Failing after 1s
Formalise the PR-flow conventions while we install the PR-flow itself.

.gitea/pull_request_template.md auto-populates the PR body in Gitea
with five sections: Summary / Motivation / Implementation notes /
Verification (with CI-gate checkboxes + ADR/diagram update flags) /
Related. Sections can be left blank when irrelevant; the template
guides without adding ceremony. Header HTML comment reminds the
contributor of the PR title format and links to the full convention.

docs/development.md §5 (Conventional commit cycle) gains a 'PR
conventions' subsection that:
- explains why the PR title format matters (squash-merge subject on
  main, validated by commitlint in the CI 'commits' job)
- separates feature-branch commit hygiene (exploratory OK) from PR
  title hygiene (must conform)
- documents the type vocabulary (feat/fix/docs/style/refactor/perf/
  test/build/ci/chore/revert)
- proposes an optional scope vocabulary (apps, libs, cross-cutting
  domains like decisions/docs/ci/deps)
- describes the body template

No new ADR. The PR title format is derived from ADR-0007 (Conventional
Commits at the commit-msg layer) plus ADR-0015 (squash-merge means PR
title becomes the commit subject on main). The body template is
tactical guidance, not architectural.
2026-04-30 23:03:13 +02:00
Julien Gautier 4b8d0789b1 docs: add inline OIDC sequence diagram to ADR-0009
CI / commits (pull_request) Failing after 2s
CI / check (pull_request) Failing after 3s
CI / scan (pull_request) Failing after 6s
CI / a11y (pull_request) Failing after 3s
CI / perf (pull_request) Failing after 3s
Render the OAuth 2.0 Authorization Code + PKCE flow as a Mermaid
sequence diagram at the top of the Decision Outcome section. Five
participants (user, SPA, BFF, Entra, Redis), thirteen autonumbered
steps covering the authorize redirect, the user-side authentication
(with the Conditional Access MFA enforcement annotated), the
callback, the state verification, the token exchange, the id_token
validation pipeline (signature, iss against the tenant allowlist,
aud, exp/nbf, amr sanity-check, audience-claim mapping), the
encrypted session write to Redis, and the cookie set.

Inline rather than in docs/architecture.md per the convention stated
at the top of architecture.md: cross-cutting diagrams live in the
architecture file, single-decision diagrams live inside the ADR they
visualise. ADR-0009 IS the auth flow decision; the sequence diagram
belongs here.

Cross-references the related ADRs (0010 sessions, 0011 MFA, 0008
audience model) so the diagram reads as the integration point of
the security stack rather than as an isolated picture.
2026-04-30 21:02:08 +02:00
Julien Gautier 312791b74e docs: add docs/architecture.md with C4 contexts, Nx boundaries, and CI/CD pipeline
Cross-cutting visual reference for the architecture, written in
Mermaid (text in markdown, rendered natively by Gitea / GitHub / IDE
viewers, diffable in PR). Four diagrams that summarise decisions
spread across multiple ADRs:

1. C4 level 1 - System Context. The portal as a black box with its
   workforce/customer/IT/RSSI actors and Entra ID + downstream APIs
   as external systems. Customer audience and Entra External ID are
   shown dashed (future scope per ADR-0008's dual-audience design).

2. C4 level 2 - Containers. Browser-side portal-shell, on-prem BFF,
   Postgres (public + audit schemas), Redis, local OTel Collector,
   plus external Entra ID and downstream APIs. Annotates the wire
   protocols (HTTPS + __Host- cookies, OIDC, OBO/signed assertion,
   OTLP, ioredis with AES-GCM at rest, traceparent end-to-end).

3. Nx module boundaries. The Project graph rendered with the
   depConstraints from ADR-0003 (scope axis: portal-shell /
   portal-bff / shared, plus type axis: app / feature / shared).
   Forbidden directions called out below the diagram.

4. CI/CD pipeline. Local hooks → push → PR → 5 parallel CI jobs
   (check / scan / commits / perf / a11y) → branch protection →
   squash-merge → tag → release. Includes the weekly scheduled
   security-scheduled.yml workflow (full-tree scan + prod
   Lighthouse).

Convention adopted at the top of architecture.md: cross-cutting
diagrams live here; single-ADR diagrams live inline in the ADR
itself (sequence flows, ERDs, lifecycle diagrams, etc.). The 'To be
added' section at the bottom maps each future diagram to where it
will land and what triggers its addition.

docs/README.md index updated with a new 'Architecture' section
linking to architecture.md, and the previous empty 'Architecture'
placeholder removed (the placeholder was a tick-the-box section
that violated the doc convention 'documentation when genuinely
useful, not just to tick a box').
2026-04-30 20:55:21 +02:00
Julien Gautier 7d27cd8773 docs: turn development.md §7 into a phase-mapped roadmap
CI / check (push) Failing after 2s
CI / commits (push) Has been skipped
CI / perf (push) Failing after 12s
CI / a11y (push) Failing after 3s
CI / scan (push) Failing after 1m33s
The section was a short bullet list of 'sections to be added' - it
underplayed how broad the future content really is, and gave no
visibility on what triggers each. Replace it with a structured table
that maps every planned section to (a) its ADR phase and (b) the
specific implementation work that unlocks it. A contributor reading
the doc today now sees:

- which dev-loops will exist (auth, sessions, MFA step-up, OTel,
  audit, downstream APIs, component patterns, a11y, perf debugging,
  Renovate, release, GitLab migration, architecture diagrams)
- under which ADR each lands
- what concrete event in the codebase makes each section real

Plus the explicit policy: each entry stays a subsection of this doc
until we have at least three substantial sub-topics, at which point
the file is split into docs/development/ with an index. Avoids
creating empty placeholder files (per CLAUDE.md: 'documentation when
genuinely useful, not just to tick a box') while signalling the
future structure clearly.

Cross-references each row to its triggering ADR so the table doubles
as a 'what's pending implementation' radar. Foreshadows the §7 → file
split that will happen once content density justifies it.
2026-04-30 20:11:01 +02:00
Julien Gautier b69d3a2206 docs: add development.md as the day-to-day reference for working on apf_portal
CI / check (push) Failing after 2s
CI / commits (push) Has been skipped
CI / perf (push) Failing after 12s
CI / a11y (push) Failing after 2s
CI / scan (push) Failing after 1m44s
A new contributor (or returning lead) opening the repo gets:
- the final repo layout, with one-line annotations per top-level dir
- the prerequisite tooling list (Node 24 LTS, pnpm 10, mkcert,
  optional local Trivy/gitleaks, Docker for Postgres)
- the fresh-clone setup steps (clone, pnpm install, prisma generate,
  sanity check)
- the daily commands organised by intent: serve, test (incl. single
  file), lint, build, generate (apps / libs / components), Prisma,
  the four ci:* scripts that mirror the CI gates
- the conventional commit cycle end-to-end (branch naming, hook
  enforcement, PR gates, squash-merge, release tagging)
- a 'where to look' table cross-linking the project rules
  (CLAUDE.md), the ADRs, the setup guides, and the personal notes
- an explicit 'to be added' section listing what the doc will grow
  into (local infra Docker Compose, auth dev-loop, component
  patterns, debugging tips, release workflow, Renovate policy)

The doc is intentionally non-exhaustive at v1 - it captures what a
contributor needs today and is structured to grow as the workflow
sharpens. Indexed in docs/README.md under a new 'Daily development'
section, separate from the one-off onboarding guides under
docs/setup/.
2026-04-30 19:58:37 +02:00
Julien Gautier be7187d5f2 chore: scaffold Gitea Actions pipelines per ADR-0015 / ADR-0017
CI / commits (push) Has been skipped
CI / check (push) Failing after 36s
CI / a11y (push) Failing after 2s
CI / perf (push) Failing after 38s
CI / scan (push) Failing after 2m15s
Wire the CI/CD pipeline scaffolding. Implements the level-2 (Gitea
Actions) part of ADR-0015 with the thin-YAML pattern, plus the perf
gate from ADR-0017. The level-1 decisions (gates list, branch model,
secrets policy) are unchanged.

Files:
- .nvmrc pins Node 24 (latest LTS major) for actions/setup-node.
- package.json gains four ci:* scripts that the workflows call:
  - ci:check  - 'nx affected -t format:check lint test build'
  - ci:audit  - 'pnpm audit --audit-level=moderate'
  - ci:commits- 'commitlint --from $COMMIT_LINT_FROM --to HEAD'
  - ci:perf   - 'nx build portal-shell --configuration=production
                 && lhci autorun --config=./lighthouserc.js'
  All four runnable locally; CI workflows are thin wrappers.
- @lhci/cli added as a dev dependency for ci:perf.
- lighthouserc.js encodes the Core Web Vitals thresholds from
  ADR-0017 (LCP <= 2500ms, CLS <= 0.1, TBT <= 200ms, server
  response <= 800ms, Performance >= 0.9). v1 measures only the
  static-served portal-shell bundle (Nx Welcome placeholder); the
  critical-routes list expands as real screens land.
- .gitea/workflows/ci.yml runs five jobs on PR + push to main:
  check, scan (audit + Trivy + gitleaks), commits (PR-only), perf,
  a11y. The a11y job is a placeholder that no-ops with a clear
  message; it wires up for real with the first Playwright e2e suite
  (ADR-0016). All gates are blocking - branch protection on main
  will require all five jobs green.
- .gitea/workflows/security-scheduled.yml runs weekly (Mon 04:00
  UTC) for full-tree Trivy + gitleaks (no severity filter, no
  skip-dirs - broader than per-PR) plus a Lighthouse run against
  the prod URL when vars.LHCI_PROD_URL is set.

Slight deviation from ADR-0015 §'Level 2': Trivy and gitleaks are
binaries (Go) and don't have clean npm wrappers, so they are
invoked through their official Gitea-Actions-compatible actions
inside the YAML rather than via 'pnpm ci:scan'. The high-level
decision (gates: audit + secret-scan + dep-scan) is unchanged; the
script/action boundary is shifted by one tool. Documented here for
traceability; no ADR amendment needed.

Operational TODOs (not blocking the scaffold):
- pnpm audit currently reports 6 moderate transitive vulnerabilities
  (ajv, brace-expansion, yaml, @hono/node-server, follow-redirects,
  uuid) in deep deps of Nx/Angular plugins. CI will fail on this
  gate until upstream updates land or Renovate bumps; expected and
  documented.
- act_runner self-hosted instances are not yet registered against
  the Gitea organisation; the workflows reference [self-hosted,
  on-prem] runner labels per ADR-0015. CI will not actually execute
  until the runners are up - that's an infra task.
- Branch protection rules on main (require all five jobs green) are
  configured in Gitea UI, not in this commit.
- Lighthouse-prod scheduled job runs only when vars.LHCI_PROD_URL
  is set - skipped silently otherwise. To be configured once a prod
  environment exists.
2026-04-30 19:48:20 +02:00
Julien Gautier 25a89bc8b0 docs: align CLAUDE.md UI stack note with the ADR-0016 spartan-ng deferral
Follow-up to the previous commit (ADR-0016 amendment). The CLAUDE.md
'Architecture' section's Accessibility line still mentioned spartan-ng
as part of the chosen UI stack; align it with the deferral note now in
ADR-0016. Phrasing matches: 'Angular CDK + TailwindCSS' as the v1
stack, with the spartan-ng philosophy applied in-house and the lib
itself revisited at 1.0.0.
2026-04-30 18:59:49 +02:00
Julien Gautier c66ef4c7a4 docs: amend ADR-0016 to defer the spartan-ng library, keep its philosophy
@spartan-ng/brain and @spartan-ng/cli are currently at 0.0.1-alpha.681
- pre-1.0, which trips the project rule against pre-1.0 dependencies
("Pre-1.0 dependencies and one-maintainer projects are rejected unless
an ADR justifies the exception", per CLAUDE.md). ADR-0016 originally
adopted spartan-ng with the copy-paste mitigation; the alpha state was
not anticipated when the ADR was written.

Amend ADR-0016 with a dated note: the spartan-ng *library* is
deferred until it reaches 1.0.0. The spartan-ng *philosophy* -
headless primitives on Angular CDK, Tailwind utility CSS, copy-paste
components owned in-source - is unchanged. Components for v1 are
written in-house in libs/shared/ui/, on Angular CDK directly. The
spartan-ng project is consulted for design inspiration (component
patterns, ARIA usage, theming) without taking the dependency.

CLAUDE.md Architecture section adjusted accordingly: 'Angular CDK +
TailwindCSS' (spartan-ng deferred), with the philosophy still in
effect.

The amendment is structured as an in-place '> Amended on YYYY-MM-DD'
block in the Component stack section, consistent with how ADR-0001's
recent path-relocation amendment was handled. Status remains
'accepted' - the design intent did not change, only the dependency
selection.

The argumentaire in notes/argumentaire-stack-ui-spartan-cdk-tailwind.md
is left as-is (gitignored, personal). It still serves to explain to
the dev team why we are NOT adopting React-side libs - the conclusion
section now reads as "we apply the same philosophy via CDK + Tailwind
in-house, deferring the lib until it stabilises".
2026-04-30 18:59:02 +02:00
Julien Gautier 0e58e32d29 chore: relocate ADRs from decisions/ to docs/decisions/ to consolidate documentation
Move the ADR folder under docs/ alongside the rest of the project
documentation. Convention (flat folder, globally-sequential 4-digit
numbering, tags-based categorization, MADR 4.0.0 format) is unchanged
- only the path moved.

- git mv decisions docs/decisions preserves history for all 18 ADRs +
  README + template (19 files renamed in this commit).
- ADR-0001 amended in-place with a dated note documenting the
  relocation. Status remains 'accepted' - the location detail
  changed, the decision did not.
- All cross-references updated:
  - CLAUDE.md (~17 ADR links + 3 mentions of decisions/ in the Project
    rules section)
  - docs/README.md (now references decisions/ as a sibling under docs/)
  - docs/setup/03-angular-nx-monorepo.md (paths shortened from
    ../../decisions/ to ../decisions/, since setup/ and decisions/ are
    now both inside docs/)
  - docs/decisions/0003 ../CLAUDE.md adjusted to ../../CLAUDE.md
    (one extra level of nesting)
  - docs/decisions/template.md mention of the README path
  - notes/asvs-level-decision-briefing-rssi.md mention of the index

Sanity verified: every ADR link in CLAUDE.md, docs/setup/03, and
docs/decisions/0001 resolves to an existing file. pnpm nx run-many
-t lint passes on 8 projects.
2026-04-30 18:57:59 +02:00
Julien Gautier bd8eefb44a chore: configure Tailwind 4 and align lib tsconfigs
Wire Tailwind CSS 4 in the portal-shell app per ADR-0016 (the future
host of spartan-ng components in libs/shared/ui will read from the
Tailwind tokens via the shared-tokens lib).

- pnpm add -D tailwindcss @tailwindcss/postcss postcss
- apps/portal-shell/postcss.config.js declares @tailwindcss/postcss
- apps/portal-shell/src/styles.scss renamed to styles.css and now
  contains a single @import 'tailwindcss' directive. Plain CSS for the
  global file avoids the Sass @import deprecation warning that fires
  when Tailwind directives sit inside SCSS. Component-level styles can
  still use SCSS.
- apps/portal-shell/project.json styles entry updated accordingly.

Side fix: align libs/shared/tokens and libs/shared/util tsconfigs from
module: commonjs to module: esnext. The Nx @nx/js:library --bundler=
tsc generator emits commonjs by default, but tsconfig.base.json
specifies moduleResolution: bundler, which TS only allows alongside
esnext or es2015+ modules. Without the alignment, those libs failed to
build (TS5095). All apps and libs now build green.

spartan-ng wiring is intentionally NOT in this commit. spartan-ng is
currently at 0.0.1-alpha.681 - clearly pre-1.0, which trips the
project rule against pre-1.0 dependencies. ADR-0016 chose spartan-ng
with the copy-paste mitigation, but the alpha state warrants an
explicit go/no-go decision before committing the workspace to it.
2026-04-30 17:50:35 +02:00
Julien Gautier d797becc2b chore: track Nx 22 AI tooling artefacts injected by generators
Nx 22 generators inject AI agent tooling into the repo via marked
sections and side files. Rather than re-deleting them after every
generator run, track the workspace-level ones and document why.

- CLAUDE.md gains a 'General Guidelines for working with Nx' section
  between Nx-managed markers; future Nx versions will update this
  section automatically without touching our project rules above.
  Pre-existing prettier-formatted blank lines added before code blocks
  are kept.
- .claude/settings.json (228 bytes) enables the nx-claude-plugins
  marketplace from nrwl/nx-ai-agents-config; tracked for contributor
  consistency. The personal .claude/settings.local.json stays
  gitignored.
- .github/ is the Nx AI skills/prompts/agents catalog. Kept despite
  being GitHub-named; it does not conflict with our Gitea workflows
  which will live under .gitea/workflows/ (per ADR-0015).
- .gitignore picks up Nx-managed transient dirs (.nx/polygraph,
  .claude/worktrees) and a trailing newline fix.

AGENTS.md is removed: it duplicated only the Nx auto-injected guidance
that CLAUDE.md already carries (CLAUDE.md is the strictly broader file
- project rules + Nx section). One source of truth for AI-agent
guidance.
2026-04-30 17:46:04 +02:00
Julien Gautier 3308fd6071 chore: configure local quality gates per ADR-0007
Wire Husky 9 + lint-staged + commitlint with @commitlint/config-
conventional - the local pair of git hooks defined in ADR-0007.

- package.json declares the prepare script ('husky') so the hooks
  install on every fresh pnpm install (no manual step).
- .husky/pre-commit runs 'pnpm exec lint-staged' which formats staged
  files via prettier (lint and tests stay in CI per ADR-0015 to keep
  commits fast).
- .husky/commit-msg runs 'pnpm exec commitlint --edit "$1"' to enforce
  Conventional Commits at commit time. Same check is repeated in CI
  for defense in depth.
- commitlint.config.cjs at the workspace root extends @commitlint
  /config-conventional.
- lint-staged config in package.json restricts to ts/tsx/js/jsx/html/
  scss/css/md/json/yml/yaml under prettier --write.

Verified: a 'feat: ...' commit message is accepted; a message without
a Conventional Commits type is rejected.
2026-04-30 17:43:49 +02:00
Julien Gautier 8de19320c5 chore: generate shared and feature libs with module boundaries per ADR-0003
Generate the four phase-4 libraries:

- libs/shared/tokens (project name shared-tokens) - plain TS lib via
  @nx/js:library; will host the a11y design tokens (palette,
  contrast tiers, spacing, motion) once Tailwind lands in phase 5;
  consumable by both apps; tagged scope:shared, type:shared.
- libs/shared/util (shared-util) - plain TS lib for cross-cutting
  utility code; tagged scope:shared, type:shared.
- libs/shared/ui (shared-ui) - Angular standalone library that will
  host the spartan-ng components copy-pasted in phase 5; Angular-only
  so tagged scope:portal-shell, type:shared. unitTestRunner=
  vitest-analog because vitest-angular requires a buildable lib.
- libs/feature/auth (feature-auth) - placeholder Angular standalone
  feature lib to demonstrate the type:feature pattern; tagged
  scope:portal-shell, type:feature.

@nx/enforce-module-boundaries depConstraints replaced (root
eslint.config.mjs) with the rules from ADR-0003:

  scope:portal-shell -> scope:portal-shell, scope:shared
  scope:portal-bff   -> scope:portal-bff,   scope:shared
  scope:shared       -> scope:shared
  type:app           -> type:feature, type:shared
  type:feature       -> type:feature, type:shared
  type:shared        -> type:shared

This forbids portal-shell from importing portal-bff code (and vice
versa) and prevents shared libs from depending on feature libs.

Project names follow the convention of ADR-0003 (feature-<name> /
shared-<scope>) by passing --name explicitly to the generator; the Nx
22 default takes only the last directory segment.

Sanity check: pnpm nx run-many -t lint and -t test pass for the 8
projects (4 apps/e2e + 4 libs).

Side effects from the generators: tsconfig.base.json paths populated
with the lib import aliases; nx.json gains vite/playwright plugin
entries; .gitignore picks up vitest.config.*.timestamp* (Vitest temp
files); package.json gains @analogjs/vitest-angular and related
devDeps; pnpm-lock.yaml regenerated. Two eslint-disable comments in
portal-bff-e2e support files were trimmed by lint --fix - those files
already lint clean without the directive.
2026-04-30 17:37:29 +02:00
Julien Gautier 2b0e20bd85 chore: wire PostgreSQL + Prisma per ADR-0006
Add Prisma 7 + nestjs-prisma. The schema lives at
apps/portal-bff/prisma/schema.prisma with provider postgresql; the new
prisma-client generator (Prisma 7 default) outputs the typed client to
apps/portal-bff/generated/prisma/ which is gitignored.

apps/portal-bff/src/app/app.module.ts imports PrismaModule.forRoot
({ isGlobal: true }) so PrismaService is injectable across the BFF
without per-module imports.

apps/portal-bff/.env.example documents DATABASE_URL with a local-dev
default, plus a forward list of env vars introduced by upcoming phases
and ADRs (auth, sessions, MFA, observability, audit, downstream APIs)
- catalog reference, not implementation. The actual .env stays
gitignored at both repo root and app levels.

prisma.config.ts (Prisma 7's TypeScript config) is committed; it loads
DATABASE_URL via dotenv. Schema and migrations paths are pinned to
prisma/ relative to the bff app.

PostgreSQL provisioning, RLS policies for the dual-audience design,
the dedicated audit schema with role grants (audit_owner / audit_writer
/ audit_reader / audit_archiver per ADR-0013), and column-level
encryption for L3-scoped data are out of scope of this commit -
they belong with the future on-prem infrastructure ADR.
2026-04-30 17:28:54 +02:00
Julien Gautier cd1d482aa8 fix(portal-shell): make 'nx test' run once by default, add watch configuration
The Angular 21 unit-test builder (@angular/build:unit-test) defaults
to watch mode. Without an explicit option, 'pnpm nx test portal-shell'
hangs on 'Waiting for task' indefinitely - unsuitable for CI and
surprising for ad-hoc invocations.

Pin watch=false as the default in the target options. Add a 'watch'
configuration so developers who want continuous test running can opt
in with 'pnpm nx test portal-shell --configuration=watch'. portal-bff
uses Jest which defaults to no-watch and needs no change.
2026-04-30 16:44:33 +02:00
Julien Gautier 0774014599 fix(portal-bff): use bracket notation for process.env access
The strict-TS option noPropertyAccessFromIndexSignature: true (set in
tsconfig.base.json per ADR-0004) forbids dot-notation access on index
signatures. process.env is typed as { [key: string]: string | undefined }
so process.env.PORT must be written process.env['PORT']. The Nx
generator wrote the dot form by default; fix to comply with the
project's strict-TS bar.

Touched: portal-bff main.ts and the three portal-bff-e2e support files
(global-setup, global-teardown, test-setup).
2026-04-30 16:34:17 +02:00
Julien Gautier bea5e1954f chore: generate portal-shell and portal-bff apps per ADR-0004 / ADR-0005
Add the @nx/angular, @nx/nest, @nx/vite, @nx/eslint plugins, then
generate the two apps. Adjust the empty-template tsconfig.base.json
to be Angular-compatible (drop project references and customConditions
that the empty-template defaults to but Angular doesn't support; keep
the strict-TS extensions from ADR-0004).

apps/portal-shell (Angular 21):
- standalone APIs, routing, SCSS, esbuild
- vitest-angular as unitTestRunner, playwright for e2e
- strict mode
- tags scope:portal-shell, type:app
- app.config.ts wired with provideZonelessChangeDetection() per
  ADR-0004 (Angular 21 + Nx 22 generates without zone.js by default)

apps/portal-bff (NestJS 11):
- Express adapter (default per ADR-0005)
- Jest as unitTestRunner
- tags scope:portal-bff, type:app
- main.ts wired with a global ValidationPipe configured
  whitelist + forbidNonWhitelisted + transform per ADR-0005
- Phase-2 security additions (helmet, CORS, sessions, CSRF, rate
  limit, auth guards, error filter) deferred to their respective
  ADRs - placeholder comment in main.ts

Workspace dependencies: class-validator + class-transformer added
(required by NestJS ValidationPipe at runtime). Nx-generated
.gitignore additions (.angular, __screenshots__) merged into ours.
.vscode/extensions.json and launch.json added by Nx are kept (do not
override our existing settings.json).
2026-04-30 16:12:42 +02:00
Julien Gautier 64ea72b321 chore: bootstrap Nx workspace per ADR-0002
Initialize the Nx 22 monorepo via copy-from-scratch (the
create-nx-workspace 'apps' preset is now mapped to nrwl/empty-template
in Nx 22). Workspace files extracted from a scratch generation and
adapted to the project:

- package.json: name 'apf-portal' (renamed from @org/source default)
- tsconfig.base.json: customConditions aligned to apf-portal; strict TS
  extended per ADR-0004 with noUncheckedIndexedAccess,
  exactOptionalPropertyTypes, noPropertyAccessFromIndexSignature
- nx.json: nxCloudId stripped (on-prem, no Nx Cloud SaaS)
- .prettierrc: project convention (singleQuote, semi, printWidth 100)
- pnpm-workspace.yaml: apps/* and libs/** for the integrated layout
- pnpm-lock.yaml committed

Plugins for Angular, NestJS, Vite, ESLint will be added in the next
phase when apps are generated. The auto-generated CLAUDE.md / AGENTS.md
/ .claude/ / .github/ from the bootstrap were intentionally not
carried over (we keep our own CLAUDE.md and use Gitea, not GitHub).
2026-04-30 16:07:11 +02:00
Julien Gautier a88fc1e8a1 docs: align CLAUDE.md narrative with phase-2 and phase-3a ADRs
The Architecture section title and the Repository status paragraph
still referred to 'phase-1 ADRs' as if that were the current state.
Update both to reflect that ADRs 0001-0017 (phase 1 + 2 + 3a) are
recorded, that the security baseline ADR is paused awaiting RSSI
input, and that docs/setup/03 has already been rewritten to align
with the ADRs.
2026-04-30 15:46:42 +02:00
Julien Gautier ea852b3239 docs: add ADR-0017 for performance budgets (Core Web Vitals + Lighthouse CI + Angular budgets + BFF SLOs)
Pin the perf framework. Front-end metrics tracked at Google Core Web
Vitals 'Good' thresholds (LCP <= 2.5s, INP <= 200ms, CLS <= 0.1, plus
TBT <= 200ms, TTFB <= 800ms) and Lighthouse Performance >= 90 on
critical routes. Lighthouse CI (@lhci/cli) enforces them in CI with
median-of-3 runs to mitigate runner variance, on a curated
critical-routes list (login, home, accessibility statement, flagship
features as they land). Wires into the perf gate slot from ADR-0015.

Bundle budgets enforced at nx build via Angular's project.json budgets
array, type 'error': initial <= 300 KB gzip, lazy chunks <= 100 KB
gzip, per-component CSS <= 6 KB. source-map-explorer wired as an Nx
analyze target for diagnosis on budget breaches.

Back-end SLOs documented per endpoint family (p95/p99) and observed
via the OpenTelemetry spans already shipped by ADR-0012 - advisory in
CI (load profile unrepresentative), alerting in production. Quarterly
review tightens budgets when achievable.

Scheduled weekly Lighthouse run on the prod env via the existing
security-scheduled.yml workflow extends coverage beyond PR-time.

Explicit a11y/perf trade-off rule: when they conflict, a11y wins (per
APF's mission, ADR-0016). The perf budget is then re-evaluated at the
next quarterly review.

No browser-side RUM SDK in v1 - the OTel browser tracing from ADR-0012
plus scheduled prod Lighthouse runs cover the gap. RUM revisited in
v2 if a real incident escapes the existing signal.

decisions/README.md index updated. CLAUDE.md gains an explicit
'Performance budgets' line pointing to ADR-0017.
2026-04-30 14:22:36 +02:00
Julien Gautier 98a8c78a31 docs: add ADR-0016 for accessibility baseline (WCAG 2.2 AA + targeted AAA, spartan-ng + CDK + Tailwind, APF panel)
Pin the a11y baseline given the host organisation context (APF France
Handicap, where accessibility is the core mission, not a compliance
checkbox):

- Conformance: WCAG 2.2 AA universal + AAA on criteria with high
  impact for the user base (1.4.6 Enhanced Contrast 7:1, 2.2.3 No
  Timing, 2.3.3 Animation from Interactions, 3.1.5 Reading Level,
  1.4.8 Visual Presentation, 2.4.9 Link Purpose, 3.3.5 Help). RGAA 4.1
  alignment for French audit context.

- User-preferences panel as a first-class feature: contrast (3 tiers),
  text size (up to 200%), motion, text spacing, cognitive
  simplification, reading focus. Persisted in session (ADR-0010).

- UI stack: Angular CDK + spartan-ng + TailwindCSS (not Angular
  Material; not React libs). Components copy-pasted into
  libs/shared/ui under our control. Design tokens with
  contrast-verified colour pairs in libs/shared/tokens.

- Tooling and CI gates: @angular-eslint/template/* a11y rules
  (blocking), @axe-core/playwright e2e blocking on critical/serious
  violations, design-token contrast verifier (blocking), touch-target
  size check (blocking on 44x44 min, default 48x48). Wires into the
  a11y gate slot from ADR-0015.

- Manual testing: keyboard and screen reader required on every UI PR
  via PR-template checklist; APF user-panel session before every major
  release covering visual / motor / cognitive / hearing categories.

- Documentation: public accessibility statement at /accessibility (EN)
  and /accessibilite (FR) - EAA legal requirement, generated from
  source-of-truth in the repo. Internal patterns library in
  docs/accessibility/.

decisions/README.md index updated. CLAUDE.md gains an explicit
'Accessibility' line pointing to ADR-0016 and the CI/CD line is
adjusted to mark the a11y gate as locked-in (no longer 'future').
2026-04-30 13:36:00 +02:00
Julien Gautier 880c7ded6b chore: rename project from adastra_portal to apf_portal
The host organisation - APF France Handicap - was confirmed on
2026-04-30. Update all in-repo references to use apf_portal
(snake_case in prose) and apf-portal (kebab-case workspace name and
repo URL). Touched: CLAUDE.md, ADRs 0001/0002/0003/0015, and the Nx
bootstrap setup guide.

The historical name is preserved as a single sentence in ADR-0003 as
a self-validating example of the function-prefixed naming convention
designed exactly for this scenario - the apps (portal-shell,
portal-bff) and the lib conventions (feature-<name>, shared-<scope>)
were unaffected by the rename, which was the explicit point of
ADR-0003.

Memory state aligned out-of-band: project_adastra.md retired,
project_apf_portal.md created with the expanded APF context (host
org, health + financial data scope, ASVS L3 pending RSSI input, UI
stack decision spartan-ng + CDK + Tailwind, expanded phase-3 status).

Pending follow-ups (user-side, not in this commit):
- rename the Gitea repo julien/adastra_portal -> julien/apf_portal
- git remote set-url origin gitea@git.unespace.com:julien/apf_portal.git
- optionally rename the local working directory ~/Works/adastra_portal/
  -> ~/Works/apf_portal/
2026-04-30 13:31:38 +02:00
Julien Gautier 49712d0bbf docs: add ADR-0015 for the CI/CD pipeline (Gitea Actions, trunk-based + squash-merge, thin YAML)
Pin the CI/CD shape with an explicit two-level structure, anticipating
the GitLab migration on the 6-18-month horizon:

Level 1 - vendor-neutral, survives the migration:
- Trunk-based with short-lived feature branches; squash-merge only.
- Branch protection on main: no direct push, no force push, linear
  history, required green CI, required reviewers = 0 in v1 (raised to
  >=1 when a second contributor joins), branch deletion after merge.
- Required CI gates (all blocking): format, lint, type-check, test,
  build (nx affected), audit (pnpm + Trivy), secret-scan (gitleaks),
  commit-lint (Conventional Commits on the PR commit range). Future
  a11y and perf gates land with their respective ADRs.
- Conventional Commits validated locally (hook from ADR-0007) and in
  CI as defense in depth.
- Signed commits recommended but not required in v1; revisited at the
  GitLab migration.
- Thin YAML: all orchestration logic lives in package.json scripts
  (ci:check, ci:scan, ci:commits) and Nx targets. Workflow files only
  do checkout, setup, cache, and call one script per job. The migration
  rewrites the YAML wrappers, never the gates.
- Secrets convention SCOPE_PURPOSE; gitleaks enforces no-secrets-in-code.
- Container images / deploy explicitly out of scope (deferred to the
  on-prem infrastructure ADR).

Level 2 - Gitea Actions specific, will be superseded by a GitLab
migration ADR:
- Engine: Gitea Actions (built-in, GitHub Actions-compatible syntax,
  partial portability hedge if the org pivots to GitHub).
- Runners: >=3 self-hosted act_runner instances on-prem, Debian image
  pinned by SHA, weekly rebuild via security-scheduled.yml.
- Three workflow files: ci.yml (PR + push to main), release.yml
  (stub for tag, populated by the deploy ADR), security-scheduled.yml
  (weekly Trivy + gitleaks full-tree scan + Renovate trigger).

Migration weight estimated at 3-5 days dev/ops when GitLab arrives:
the YAML is rewritten, the gates and scripts are unchanged. A future
ADR will explicitly supersede only the level-2 sections.

decisions/README.md index updated. CLAUDE.md gains an explicit 'CI/CD'
line pointing to ADR-0015 and noting the future GitLab supersession.
2026-04-30 11:21:30 +02:00
Julien Gautier a20330a474 docs: add ADR-0014 for downstream API access (OBO pattern + DownstreamApiClient framework)
Pin the framework for calls from the BFF to integrated downstream APIs.
The concrete list of downstream services is not yet known, but the
framework must exist so that the day a developer adds an integration the
answer is 'use the standard client', not 'invent something'.

A DownstreamApisModule exposes a DownstreamApiClientFactory that produces
typed clients from per-service DownstreamApiConfig blocks. Each config
declares the auth strategy, base URL, timeout, retry, circuit breaker,
bulkhead, and audienceConstraint.

Default auth strategy for Entra-protected downstreams is On-Behalf-Of
(MSAL Node acquireTokenOnBehalfOf). Downstream-scoped tokens are cached
in Redis under obo:{user_id_hash}:{resource}, encrypted with AES-256-GCM
using a dedicated key (OBO_CACHE_ENCRYPTION_KEY) distinct from the
session-encryption key so a cache compromise doesn't cascade into a
session compromise.

Fallback strategy for non-Entra downstreams is service credential +
signed user-assertion header (X-User-Assertion JWT signed by the BFF's
private key, verified by downstreams against the BFF JWKS at
/.well-known/jwks.json). Token relay is rejected as a default;
per-user credential mapping is rejected outright.

Resilience composes via cockatiel: timeout outermost, then retry (only
on idempotent verbs and retriable error classes), circuit breaker per
service, bulkhead per service. Each call opens a downstream.<service>
OpenTelemetry span; auth failures emit audit events. Downstream errors
are translated at the client boundary - never bubbled with raw payload.

Audience pre-check is enforced at the call site (not at controller
entry) - even a missing authorization guard upstream cannot bypass the
audience constraint.

The framework is forward-looking; concrete integrations land per-service
in code config (no per-integration ADR unless the integration deviates
non-trivially from the defaults). Strategy code is exercised by
mock-driven tests until the first real integration ships.

decisions/README.md index updated. CLAUDE.md gains an explicit
'Downstream API access' line pointing to ADR-0014.
2026-04-29 23:58:49 +02:00
Julien Gautier b35bf2b3de docs: add ADR-0013 for the audit trail (dedicated append-only Postgres schema)
Pin the audit-trail architecture: a dedicated 'audit' schema in the same
Postgres instance as business data, with three Postgres roles enforcing
append-only at the database layer - audit_writer (INSERT only),
audit_reader (SELECT only), audit_archiver (DELETE only on rows past the
retention threshold). No role anywhere holds UPDATE or TRUNCATE; the BFF
verifies this at startup with a deliberate failing UPDATE probe.

The audit stream is decoupled from the application logs (different sink,
different access controls, different retention) but cross-referenced via
trace_id (ADR-0012) and actor_id_hash, which uses the same salt as the
app logs so an investigator joins the two streams without re-hashing.

Events captured in v1 cover the auth and session lifecycle: sign_in
(success/failure), sign_out, session.expired, session.revoked,
token.validation.failed, mfa.assertion.failed, authz.deny. Hooks for
admin actions and sensitive data access are designed-in but inert until
v1+ features call them - kept alive by tests so they don't drift.

Failure semantics are blocking - if the audit INSERT fails, the
in-flight operation fails with 503. Trade-off acknowledged: the audit DB
is part of the trust path. Mitigation is HA Postgres in prod, deferred
to the infrastructure ADR.

Retention defaults to 365 days, env-overridable, enforced by a daily
purge running under audit_archiver. The retention default is engineering
prudence, not legal advice - the org-side legal review of the actual
applicable retention regime is explicitly owed and noted in the ADR.

Cryptographic chaining and WORM storage are deferred unless a compliance
regime demands them.

decisions/README.md index updated. CLAUDE.md gains an explicit
'Audit trail' line pointing to ADR-0013.
2026-04-29 23:32:35 +02:00