Skip to content

Commit bb09c24

Browse files
committed
fix(cloudkit): sync the project start date through a text field so iCloud stops rejecting every save (Atomic failure)
1 parent b5200e0 commit bb09c24

4 files changed

Lines changed: 9 additions & 6 deletions

File tree

apps/desktop/src-tauri/src/macos_cloudkit_bridge.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -232,7 +232,7 @@ typedef NS_ENUM(NSInteger, MWFieldKind) {
232232
{"updatedAt", "updatedAt", MWFieldKindDate},
233233
{"deletedAt", "deletedAt", MWFieldKindDate},
234234
{"purgedAt", "purgedAt", MWFieldKindDate},
235-
{"startDate", "startDate", MWFieldKindDate},
235+
{"startDate", "startDateText", MWFieldKindDate}, // Production "startDate" is a Date field; strings never fit it
236236
};
237237
static const size_t kProjectFieldsCount = sizeof(kProjectFields) / sizeof(kProjectFields[0]);
238238

apps/mobile/modules/cloudkit-sync/ios/CloudKitRecordMapper.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ enum CloudKitRecordMapper {
177177
FieldSpec(jsKey: "updatedAt", ckKey: "updatedAt", kind: .date),
178178
FieldSpec(jsKey: "deletedAt", ckKey: "deletedAt", kind: .date),
179179
FieldSpec(jsKey: "purgedAt", ckKey: "purgedAt", kind: .date),
180-
FieldSpec(jsKey: "startDate", ckKey: "startDate", kind: .date),
180+
FieldSpec(jsKey: "startDate", ckKey: "startDateText", kind: .date), // "startDate" exists in Production as a Date field; date kinds are written as strings, so it can never be used
181181
]
182182

183183
// MARK: - Section Fields

docs/release-notes/unreleased.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,5 @@ Changes collected after `v1.2.7` and before the next version tag.
1717
- Self-hosted server: a new capture webhook, `POST /v1/capture`, turns a posted transcription and optional audio recording into an Inbox task with the recording attached. Send it as a form upload, as JSON, or as plain text, with your sync token as the bearer token. It matches the format the Pebble Index watch already posts, so that watch can send straight to your own server, and so can any shortcut, script, or automation that can make a web request. (#1148)
1818

1919
- iCloud sync (iOS and macOS): when CloudKit refused a save, the Sync screen showed "Atomic failure" for a bystander record instead of the record and reason that actually failed, so the cause could not be read from the shared log. The screen and the log now name the failing record's real error. (Discord report, App Store 1.2.7)
20+
21+
- iCloud sync (iOS and macOS): after 1.2.7, iCloud sync failed on every attempt with "Atomic failure" for anyone whose library held a project with a start date. The new project start date was created in the iCloud schema as a date field, while the app stores every date as text, so CloudKit refused the record and the whole batch with it. The start date now syncs through a text field like the other dates. (Discord report, App Store 1.2.7)

packages/core/src/cloudkit-production-schema.json

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
{
2-
"comment": "CloudKit Production container schema state by record type. 'deployed' is the repository assertion for keys already exercised by stable releases or explicitly confirmed in the Production dashboard. New keys stay in 'pendingProduction' until that dashboard check is complete; stable releases fail while any pending key remains.",
2+
"comment": "CloudKit Production container schema state by record type. 'deployed' is the repository assertion for keys already exercised by stable releases or explicitly confirmed in the Production dashboard. New keys stay in 'pendingProduction' until that dashboard check is complete; stable releases fail while any pending key remains. MindwtrProject.startDate exists in Production as a Date/Time field by mistake (1.2.7); every date kind is written as a String, so that key is retired and the start date lives in startDateText (String).",
33
"records": {
44
"MindwtrTask": {
55
"deployed": [
@@ -71,10 +71,11 @@
7171
"createdAt",
7272
"updatedAt",
7373
"deletedAt",
74-
"purgedAt",
75-
"startDate"
74+
"purgedAt"
7675
],
77-
"pendingProduction": []
76+
"pendingProduction": [
77+
"startDateText"
78+
]
7879
},
7980
"MindwtrSection": {
8081
"deployed": [

0 commit comments

Comments
 (0)