#### PR Dependency Tree
* **PR #14783** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Configurable request timeout for calendar integrations.
* Calendar polling now enqueues per-subscription sync jobs (larger
batch) for improved throughput.
* **Bug Fixes / Improvements**
* Persisted next-sync timestamps and retry counts for more reliable
scheduling and retry behavior.
* Exponential backoff and webhook renewal now update scheduling
consistently.
* **Refactor**
* Calendar sync flow moved to a job-queue-driven design for better
concurrency and observability.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #14779** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Added conditional init checks to service deployments and jobs to wait
for the database proxy before starting
* Exposed a new health port (9801) for the database proxy to enable
readiness probing
* **Tests**
* Minor test reordering and formatting changes (no behavioral changes)
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #14770** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
## Release Notes
* **New Features**
* Implemented batch processing for calendar synchronization to improve
performance and resource utilization.
* Added distributed locking to prevent concurrent operations in
multi-instance environments.
* **Bug Fixes**
* Improved reliability by preventing duplicate synchronization attempts.
* **Tests**
* Enhanced test coverage for batch processing and locking mechanisms.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
fixes#14696
iCloud was returning 400 Bad Request for /.well-known/caldav, which
caused AFFiNE to fail before reaching the actual CalDAV endpoints. This
change makes discovery fall back to the base CalDAV URL for that case,
which lets the iCloud account link flow continue successfully.
This also adds a GraphQL field resolver for
CalendarAccountObjectType.calendarsCount. The field is requested by the
frontend, but some mutation return paths were returning a raw account
object without that computed value, which caused GraphQL to fail on a
non-null field.
---
### Why this was needed
iCloud rejected the standard well-known discovery probe with 400, even
though the rest of the CalDAV flow worked.
calendarsCount is a computed field used by the frontend, so it should be
resolved by GraphQL rather than manually attached in individual service
methods.
---
### How to test
Generate an Apple app-specific password: [Apple
Support](https://support.apple.com/en-gb/102654)
In AFFiNE, add an iCloud CalDAV account using:
your Apple Account email
the new app-specific password
Confirm the account links successfully and calendars load without the
previous GraphQL error.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Calendar accounts now display the total number of calendars.
* **Bug Fixes**
* Enhanced calendar discovery process to handle additional HTTP error
conditions.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
## 📝 Summary
This PR fixes a regression that caused the following error during GitHub
OAuth login:
> Unable to parse JSON response from
[https://github.com/login/oauth/access_token](https://github.com/login/oauth/access_token)
Related issue:
[https://github.com/toeverything/AFFiNE/issues/14334](https://github.com/toeverything/AFFiNE/issues/14334)
Regression introduced in:
[https://github.com/toeverything/AFFiNE/pull/14061](https://github.com/toeverything/AFFiNE/pull/14061)
---
## 🎯 Background
GitHub’s OAuth access token endpoint returns different response formats
depending on the request headers.
To receive a JSON response, the request must include:
```
Accept: application/json
```
If the `Accept` header is missing, GitHub responds with:
```
application/x-www-form-urlencoded
```
The current implementation assumes a JSON response and parses it
directly.
When a non-JSON response is returned, JSON parsing fails,
breaking the OAuth login flow.
---
## 🔍 Traffic Analysis (tcpdump)
Network path:
affine-graphql → (HTTPS) → envoy → (HTTP, tcpdump) → envoy → GitHub
### Observed Request
```
POST /login/oauth/access_token HTTP/1.1
host: github-proxy.com
content-type: application/x-www-form-urlencoded
accept: */*
...
```
### Observed Response
```
HTTP/1.1 200 OK
date: Sat, 28 Feb 2026 14:47:43 GMT
content-type: application/x-www-form-urlencoded; charset=utf-8
...
```
The `Accept` header was `*/*` instead of `application/json`,
causing GitHub to return a form-urlencoded response.
---
## 🐛 Root Cause
PR #14061 introduced a side effect in the request configuration.
Although the `Accept` header was initially defined,
the request options were later overwritten by the `init` parameter.
Because `init.headers` replaced the previously defined headers object,
the required header was lost.
Resulting in:
* Missing `Accept: application/json`
* GitHub returning `application/x-www-form-urlencoded`
* JSON parsing failure
* OAuth login failure
---
## 🔧 Changes
### 1️⃣ Fix header overwrite order
* Process the incoming `init` parameter first
* Explicitly overwrite required headers afterward
* Ensure `Accept: application/json` is always enforced
---
## 💥 Breaking Changes
None.
---
## 🧪 How to Test
1. Configure GitHub OAuth.
2. Attempt login via GitHub.
3. Verify that:
* The request contains `Accept: application/json`
* The response content-type is `application/json`
* No JSON parsing error occurs
* OAuth login completes successfully
---
## 📌 Notes
This change restores correct OAuth behavior and prevents regression
caused by header overwriting introduced in #14061.
The same header overwrite pattern identified in this issue
was also found in the calendar module and has been corrected there as
well.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Refactor**
* Improved backend HTTP header handling for external integrations to
avoid unintended header overrides, ensuring content-type and encoding
hints are applied consistently and improving reliability of service
requests.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
#### PR Dependency Tree
* **PR #14510** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved calendar sync reliability with exponential backoff for
repeated failures.
* Better handling of token refresh failures with automatic account
invalidation and cleanup when needed.
* Subscriptions are now automatically disabled and related events
removed when the calendar provider reports missing resources.
* **Tests**
* Added comprehensive tests covering sync failures, backoff behavior,
token refresh handling, skipping retries during backoff, and recovery.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Chores**
* Upgraded TypeScript toolchain to v5.9.3 across packages and tooling.
* Removed legacy ts-node and migrated developer tooling to newer
runtimes (tsx/SWC) where applicable.
* **Documentation**
* Updated developer CLI docs and runtime behavior notes to reflect the
new loader/runtime for running TypeScript files; no changes to public
APIs or end-user behavior.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #14452** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **Bug Fixes**
* Improved null-safety, dependency tracking, upload validation, and
error logging for more reliable uploads, clipboard, calendar linking,
telemetry, PDF/theme printing, and preview/zoom behavior.
* Tightened handling of all-day calendar events (missing date now
reported).
* **Deprecations**
* Removed deprecated RadioButton and RadioButtonGroup; use RadioGroup.
* **Chores**
* Unified and upgraded linting/config, reorganized imports, and
standardized binary handling for more consistent builds and tooling.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
fix#13531
#### PR Dependency Tree
* **PR #14372** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* CalDAV calendar integration: link and sync CalDAV-compatible calendars
(discovery, listing, event sync).
* New UI flow and dialog to link CalDAV accounts with provider
selection, credentials, and display name.
* **API / Config**
* Server exposes CalDAV provider presets in config and new GraphQL
mutation to link CalDAV accounts.
* New calendar config section for CalDAV with validation and defaults.
* **Tests**
* Comprehensive CalDAV integration test suite added.
* **Chores**
* Removed analytics tokens from build configuration and reduced Cloud
E2E test shards.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #14251** 👈
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Current user profile now exposes access tokens, revealed tokens, and
detailed calendar accounts/subscriptions.
* Workspace now exposes permissions, calendars, calendar events, and a
workspace-scoped blob upload part URL.
* New document-update mutation for applying doc updates.
* **API Changes**
* validateAppConfig is now a query (mutation deprecated).
* Several legacy top-level calendar/blob endpoints deprecated in favor
of user/workspace fields.
* **Refactor**
* Calendar, blob-upload and access-token surfaces reorganized to use
user/workspace-centric fields.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
#### PR Dependency Tree
* **PR #14247** 👈
* **PR #14248**
This tree was auto-generated by
[Charcoal](https://github.com/danerwilliams/charcoal)
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Google Calendar integration (disabled by default): link/unlink
accounts, OAuth flow, webhooks, real-time push, background sync,
workspace calendars with customizable items and date-range event
viewing.
* **GraphQL / Client**
* New queries & mutations for accounts, subscriptions, events,
providers, and workspace calendar management.
* **Localization**
* Added localized error message for calendar provider request failures.
* **Tests**
* Backend tests covering sync, webhook renewal, and error/error-recovery
scenarios.
<sub>✏️ Tip: You can customize this high-level summary in your review
settings.</sub>
<!-- end of auto-generated comment: release notes by coderabbit.ai -->