Adapting to recent model version

Co-authored-by: jas <jas@tutao.de>
This commit is contained in:
and 2025-12-05 13:25:26 +01:00
parent b047d63637
commit 808250f189
16 changed files with 76 additions and 307 deletions

View file

@ -618,6 +618,7 @@ function getContents(eventObjects: ICalObject[], zone: string) {
hashedUid: null,
invitedConfidentially: null,
alarmInfos: [],
pendingInvitation: null, // FIXME
}) as Require<"uid", CalendarEvent>
let alarms: AlarmInfoTemplate[] = []

View file

@ -501,6 +501,7 @@ export function assembleCalendarEventEditResult(models: CalendarEventEditModels)
// fields related to the event instance's identity are excluded.
// reminders. will be set up separately.
alarmInfos: [],
pendingInvitation: null,
},
newAlarms: alarmResult.alarms,
sendModels: whoResult,
@ -574,6 +575,7 @@ function makeEmptyCalendarEvent(): StrippedEntity<CalendarEvent> {
attendees: [],
organizer: null,
sequence: "",
pendingInvitation: null,
}
}

View file

@ -95,7 +95,6 @@ import { EntityUpdateData, isUpdateFor, isUpdateForTypeRef } from "../../../comm
import {
AlarmInterval,
assignEventId,
assignPendingEventId,
CalendarEventValidity,
CalendarType,
checkEventValidity,
@ -320,11 +319,13 @@ export class CalendarModel {
newEvent.startTime.getTime() !== existingEvent.startTime.getTime() ||
(await didLongStateChange(newEvent, existingEvent, zone))
) {
if (this.isDefaultCalendar(groupRoot._id) && isSameId(groupRoot.pendingEvents?.list ?? null, listIdPart(existingEvent._id))) {
await this.createPendingEvent(newEvent, groupRoot, newAlarms, existingEvent)
} else {
// FIXME come back when deciding about strategies and etc
// if (this.isDefaultCalendar(groupRoot._id) && isSameId(groupRoot.pendingEvents?.list ?? null, listIdPart(existingEvent._id))) {
// await this.createPendingEvent(newEvent, groupRoot, newAlarms, existingEvent)
// }
await this.doCreate(newEvent, zone, groupRoot, newAlarms, existingEvent)
}
// We should reload the instance here because session key and permissions are updated when we recreate event.
return await this.entityClient.load<CalendarEvent>(CalendarEventTypeRef, newEvent._id)
} else {
@ -689,19 +690,11 @@ export class CalendarModel {
const userSettingsGroupRoot = this.logins.getUserController().userSettingsGroupRoot
const isInternalUser = this.logins.isInternalUserLoggedIn()
if (!isInternalUser) {
if (!isInternalUser || firstPrivateCalendar) {
return calendarInfos
}
if (firstPrivateCalendar) {
if (userSettingsGroupRoot.defaultCalendar === null) {
await this.calendarFacade.setCalendarAsDefault(firstPrivateCalendar.id, userSettingsGroupRoot)
}
return calendarInfos
}
const newCalendarGroup = await this.createCalendar("", null, [], null)
await this.calendarFacade.setCalendarAsDefault(newCalendarGroup._id, userSettingsGroupRoot)
await this.createCalendar("", null, [], null)
// Reload calendar infos to include the newly created calendar
return await this.loadCalendarInfos(progressMonitor)
@ -756,17 +749,12 @@ export class CalendarModel {
return await this.calendarFacade.saveCalendarEvent(event, alarmInfos, existingEvent ?? null).then(this.requestWidgetRefresh)
}
private async createPendingEvent(
event: CalendarEvent,
groupRoot: CalendarGroupRoot,
alarmInfos: ReadonlyArray<AlarmInfoTemplate> = [],
existingEvent: CalendarEvent | null = null,
): Promise<void> {
private async createPendingEvent(event: CalendarEvent, groupRoot: CalendarGroupRoot, existingEvent: CalendarEvent | null = null): Promise<void> {
// If the event was copied it might still carry some fields for re-encryption. We can't reuse them.
removeTechnicalFields(event)
const { assignPendingEventId } = await import("../../../common/calendar/date/CalendarUtils")
assignPendingEventId(event, groupRoot)
const { assignEventId } = await import("../../../common/calendar/date/CalendarUtils")
assignEventId(event, getTimeZone(), groupRoot)
// Reset ownerEncSessionKey because it cannot be set for new entity, it will be assigned by the CryptoFacade
event._ownerEncSessionKey = null
@ -778,7 +766,7 @@ export class CalendarModel {
downcast(event)._permissions = null
event._ownerGroup = groupRoot._id
return await this.calendarFacade.saveCalendarEvent(event, alarmInfos, existingEvent)
return await this.calendarFacade.saveCalendarEvent(event, [], existingEvent)
}
async deleteEvent(event: CalendarEvent): Promise<void> {
@ -985,8 +973,12 @@ export class CalendarModel {
if (dbEvents == null) {
// Create pending events when processing calendar invites.
const defaultCalendarGroupRoot = await this.getDefaultCalendarGroupRoot()
return await this.handleNewCalendarInvitation(sender, calendarData, defaultCalendarGroupRoot)
const calendarInfos = await this.loadOrCreateCalendarInfo(this.readProgressMonitor.next().value)
const firstCalendar = findFirstPrivateCalendar(calendarInfos)
if (firstCalendar == null) {
throw new Error("Missing private calendar")
}
return await this.handleNewCalendarInvitation(sender, calendarData, firstCalendar.groupRoot)
}
const method = calendarData.method
@ -999,37 +991,11 @@ export class CalendarModel {
}
}
/**
* Loads default calendar.
* If the user still haven't been assigned one, it calls {@link loadOrCreateCalendarInfo} to get the most recent
* list of calendars and assign the default;
*
* Throws an error if it fails to find a valid calendar after one retry
*
* @return {CalendarGroupRoot}
* @throws if Can not create or find a default calendar
*/
async getDefaultCalendarGroupRoot(): Promise<CalendarGroupRoot> {
const storedDefaultCalendarGroupRoot = this.logins.getUserController().userSettingsGroupRoot.defaultCalendar
if (storedDefaultCalendarGroupRoot) {
return await this.entityClient.load(CalendarGroupRootTypeRef, storedDefaultCalendarGroupRoot)
}
const calendarInfos = await this.loadOrCreateCalendarInfo(this.readProgressMonitor.next().value)
const firstCalendar = findFirstPrivateCalendar(calendarInfos)
if (!firstCalendar) {
throw new Error(`Could not find a default calendar for user ${this.logins.getUserController().user._id}`)
}
return firstCalendar.groupRoot
}
/**
* Handles new Calendar Invitations, creating an entry for them in the pendingEventsList of the default
* CalendarGroupRoot. The server takes care of inserting an index entry into CalendarEventUidIndexTypeRef
*/
async handleNewCalendarInvitation(sender: string, calendarData: ParsedCalendarData, defaultCalendarGroupRoot: CalendarGroupRoot) {
async handleNewCalendarInvitation(sender: string, calendarData: ParsedCalendarData, destinationCalendarGroupRoot: CalendarGroupRoot) {
if (calendarData.method !== CalendarMethod.REQUEST) {
return // We don't handle anything different from an invitation
}
@ -1040,7 +1006,7 @@ export class CalendarModel {
sender,
}
return this.createPendingEvent(calendarEvent, defaultCalendarGroupRoot)
return this.createPendingEvent(calendarEvent, destinationCalendarGroupRoot)
})
await Promise.all(eventsPromises)
@ -1284,7 +1250,7 @@ export class CalendarModel {
}
async deleteCalendar(calendar: CalendarInfo): Promise<void> {
await this.calendarFacade.deleteCalendar(calendar.groupRoot._id, this.isDefaultCalendar(calendar.id))
await this.calendarFacade.deleteCalendar(calendar.groupRoot._id)
this.deviceConfig.removeLastSync(calendar.group._id)
}
@ -1475,14 +1441,6 @@ export class CalendarModel {
getGroupSettings(): GroupSettings[] {
return this.logins.getUserController().userSettingsGroupRoot.groupSettings
}
private isDefaultCalendar(calendar: Id) {
return isSameId(this.logins.getUserController().userSettingsGroupRoot.defaultCalendar, calendar)
}
get defaultCalendar() {
return this.logins.getUserController().userSettingsGroupRoot.defaultCalendar
}
}
/** return false when the given events (representing the new and old version of the same event) are both long events

View file

@ -1,5 +1,5 @@
const modelInfo = {
version: 36,
version: 37,
}
export default modelInfo

View file

@ -9,7 +9,7 @@ export const typeModels = {
"12": {
"name": "ReadCounterData",
"app": "monitor",
"version": 36,
"version": 37,
"since": 1,
"type": "DATA_TRANSFER_TYPE",
"id": 12,
@ -56,7 +56,7 @@ export const typeModels = {
"16": {
"name": "ReadCounterReturn",
"app": "monitor",
"version": 36,
"version": 37,
"since": 1,
"type": "DATA_TRANSFER_TYPE",
"id": 16,
@ -97,7 +97,7 @@ export const typeModels = {
"49": {
"name": "WriteCounterData",
"app": "monitor",
"version": 36,
"version": 37,
"since": 4,
"type": "DATA_TRANSFER_TYPE",
"id": 49,
@ -152,7 +152,7 @@ export const typeModels = {
"221": {
"name": "ApprovalMail",
"app": "monitor",
"version": 36,
"version": 37,
"since": 14,
"type": "LIST_ELEMENT_TYPE",
"id": 221,
@ -233,7 +233,7 @@ export const typeModels = {
"300": {
"name": "CounterValue",
"app": "monitor",
"version": 36,
"version": 37,
"since": 22,
"type": "AGGREGATED_TYPE",
"id": 300,
@ -272,7 +272,7 @@ export const typeModels = {
"305": {
"name": "ErrorReportFile",
"app": "monitor",
"version": 36,
"version": 37,
"since": 23,
"type": "AGGREGATED_TYPE",
"id": 305,
@ -311,7 +311,7 @@ export const typeModels = {
"316": {
"name": "ErrorReportData",
"app": "monitor",
"version": 36,
"version": 37,
"since": 23,
"type": "AGGREGATED_TYPE",
"id": 316,
@ -406,7 +406,7 @@ export const typeModels = {
"335": {
"name": "ReportErrorIn",
"app": "monitor",
"version": 36,
"version": 37,
"since": 23,
"type": "DATA_TRANSFER_TYPE",
"id": 335,

View file

@ -4564,13 +4564,21 @@ export const typeModels = {
"cardinality": "ZeroOrOne",
"encrypted": false
},
"1788": {
"1783": {
"final": false,
"name": "sender",
"id": 1788,
"id": 1783,
"type": "String",
"cardinality": "ZeroOrOne",
"encrypted": true
},
"1784": {
"final": false,
"name": "pendingInvitation",
"id": 1784,
"type": "Boolean",
"cardinality": "ZeroOrOne",
"encrypted": true
}
},
"associations": {
@ -4700,15 +4708,6 @@ export const typeModels = {
"cardinality": "ZeroOrOne",
"refTypeId": 1100,
"dependency": null
},
"1786": {
"final": false,
"name": "pendingEvents",
"id": 1786,
"type": "AGGREGATION",
"cardinality": "ZeroOrOne",
"refTypeId": 1783,
"dependency": null
}
}
},
@ -5010,15 +5009,6 @@ export const typeModels = {
"cardinality": "Any",
"refTypeId": 968,
"dependency": null
},
"1787": {
"final": false,
"name": "defaultCalendar",
"id": 1787,
"type": "ELEMENT_ASSOCIATION",
"cardinality": "ZeroOrOne",
"refTypeId": 947,
"dependency": null
}
}
},
@ -5041,14 +5031,6 @@ export const typeModels = {
"type": "Number",
"cardinality": "One",
"encrypted": false
},
"1789": {
"final": false,
"name": "deleteEventsOnly",
"id": 1789,
"type": "Boolean",
"cardinality": "One",
"encrypted": false
}
},
"associations": {
@ -9734,38 +9716,5 @@ export const typeModels = {
"dependency": null
}
}
},
"1783": {
"name": "CalendarEventsRef",
"app": "tutanota",
"version": 99,
"since": 99,
"type": "AGGREGATED_TYPE",
"id": 1783,
"rootId": "CHR1dGFub3RhAAb3",
"versioned": false,
"encrypted": false,
"isPublic": true,
"values": {
"1784": {
"final": true,
"name": "_id",
"id": 1784,
"type": "CustomId",
"cardinality": "One",
"encrypted": false
}
},
"associations": {
"1785": {
"final": true,
"name": "list",
"id": 1785,
"type": "LIST_ASSOCIATION",
"cardinality": "One",
"refTypeId": 933,
"dependency": null
}
}
}
}

View file

@ -1148,6 +1148,7 @@ export type CalendarEvent = {
recurrenceId: null | Date;
_ownerKeyVersion: null | NumberString;
sender: null | string;
pendingInvitation: null | boolean;
repeatRule: null | CalendarRepeatRule;
alarmInfos: IdTuple[];
@ -1175,7 +1176,6 @@ export type CalendarGroupRoot = {
shortEvents: Id;
longEvents: Id;
index: null | CalendarEventIndexRef;
pendingEvents: null | CalendarEventsRef;
}
export const UserAreaGroupDataTypeRef: TypeRef<UserAreaGroupData> = new TypeRef("tutanota", 956)
@ -1254,7 +1254,6 @@ export type UserSettingsGroupRoot = {
birthdayCalendarColor: null | string;
groupSettings: GroupSettings[];
defaultCalendar: null | Id;
}
export const CalendarDeleteInTypeRef: TypeRef<CalendarDeleteIn> = new TypeRef("tutanota", 982)
@ -1267,7 +1266,6 @@ export type CalendarDeleteIn = {
_original?: CalendarDeleteIn
_format: NumberString;
deleteEventsOnly: boolean;
groupRootId: Id;
}
@ -2721,17 +2719,3 @@ export type PopulateClientSpamTrainingDataPostIn = {
populateClientSpamTrainingDatum: PopulateClientSpamTrainingDatum[];
}
export const CalendarEventsRefTypeRef: TypeRef<CalendarEventsRef> = new TypeRef("tutanota", 1783)
export function createCalendarEventsRef(values: StrippedEntity<CalendarEventsRef>): CalendarEventsRef {
return Object.assign(create(typeModels[CalendarEventsRefTypeRef.typeId], CalendarEventsRefTypeRef), values)
}
export type CalendarEventsRef = {
_type: TypeRef<CalendarEventsRef>;
_original?: CalendarEventsRef
_id: Id;
list: Id;
}

View file

@ -394,7 +394,6 @@ export async function initUserController({
groupSettings: [],
usageDataOptedIn: null,
birthdayCalendarColor: null,
defaultCalendar: null,
}),
)
.then(() => entityClient.load(UserSettingsGroupRootTypeRef, user.userGroup.group)),

View file

@ -36,7 +36,7 @@ import {
} from "@tutao/tutanota-utils"
import { CryptoFacade } from "../../crypto/CryptoFacade.js"
import { GroupType, OperationType } from "../../../common/TutanotaConstants.js"
import type { CalendarEvent, CalendarEventUidIndex, CalendarRepeatRule, UserSettingsGroupRoot } from "../../../entities/tutanota/TypeRefs.js"
import type { CalendarEvent, CalendarEventUidIndex, CalendarRepeatRule } from "../../../entities/tutanota/TypeRefs.js"
import { CalendarEventTypeRef, CalendarEventUidIndexTypeRef, CalendarGroupRootTypeRef, createCalendarDeleteIn } from "../../../entities/tutanota/TypeRefs.js"
import { DefaultEntityRestCache } from "../../rest/DefaultEntityRestCache.js"
import { ConnectionError, NotAuthorizedError, NotFoundError, PayloadTooLargeError } from "../../../common/error/RestError.js"
@ -62,7 +62,6 @@ import {
generateCalendarInstancesInRange,
hasAlarmsForTheUser,
isBirthdayCalendar,
isLongEvent,
} from "../../../../calendar/date/CalendarUtils.js"
import { CalendarInfo } from "../../../../../calendar-app/calendar/model/CalendarModel.js"
import { geEventElementMaxId, getEventElementMinId } from "../../../common/utils/CommonCalendarUtils.js"
@ -131,7 +130,6 @@ export class CalendarFacade {
calendarInfos: ReadonlyMap<Id, CalendarInfo>,
daysToEvents: DaysToEvents,
zone: string,
defaultCalendarId: Id | null,
): Promise<DaysToEvents> {
// Because of the timezones and all day events, we might not load an event which we need to display.
// So we add a margin on 24 hours to be sure we load everything we need. We will filter matching
@ -152,12 +150,6 @@ export class CalendarFacade {
const shortEventsResult = await this.cachingEntityClient.loadReverseRangeBetween(CalendarEventTypeRef, groupRoot.shortEvents, endId, startId, 200)
const longEventsResult = await this.cachingEntityClient.loadAll(CalendarEventTypeRef, groupRoot.longEvents)
const pendingEventListId = groupRoot.pendingEvents?.list
let pendingEventsResult: Array<CalendarEvent> = []
if (pendingEventListId && isSameId(defaultCalendarId, groupRoot._id)) {
pendingEventsResult = await this.cachingEntityClient.loadAll(CalendarEventTypeRef, pendingEventListId)
}
const shortEvents: Array<EventWrapper> = shortEventsResult.elements.map((e) => ({
event: e,
flags: {
@ -175,25 +167,6 @@ export class CalendarFacade {
color,
}))
const pendingEvents: Array<EventWrapper> = pendingEventsResult.map((e) => ({
event: e,
flags: {
isGhost: true,
hasAlarms: false,
isAlteredInstance: !!e.recurrenceId,
},
color,
}))
for (const ev of pendingEvents) {
const isLongEvents = isLongEvent(ev.event, zone)
if (isLongEvents) {
longEvents.push(ev)
} else {
shortEvents.push(ev)
}
}
calendars.push({
short: shortEvents,
long: longEvents,
@ -387,14 +360,8 @@ export class CalendarFacade {
return await this.groupManagementFacade.createCalendar(name)
}
async deleteCalendar(groupRootId: Id, deleteEventsOnly: boolean = false): Promise<void> {
await this.serviceExecutor.delete(CalendarService, createCalendarDeleteIn({ groupRootId, deleteEventsOnly }))
}
async setCalendarAsDefault(groupRootId: Id, userSettingsGroupRoot: UserSettingsGroupRoot): Promise<void> {
console.log(`Assigning default calendar: ${groupRootId}`)
userSettingsGroupRoot.defaultCalendar = groupRootId
await this.entityRestCache.update(userSettingsGroupRoot)
async deleteCalendar(groupRootId: Id): Promise<void> {
await this.serviceExecutor.delete(CalendarService, createCalendarDeleteIn({ groupRootId }))
}
async scheduleAlarmsForNewDevice(pushIdentifier: PushIdentifier): Promise<void> {

View file

@ -118,13 +118,7 @@ export class CalendarEventsRepository {
this.loadedMonths.set(monthRange.start, Array.from(calendarInfos.keys()))
}
const eventsMap = await this.calendarFacade.updateEventMap(
monthRange,
calendarInfos,
this.daysToEvents(),
this.zone,
this.calendarModel.defaultCalendar,
)
const eventsMap = await this.calendarFacade.updateEventMap(monthRange, calendarInfos, this.daysToEvents(), this.zone)
this.replaceEvents(eventsMap)
this.addBirthdaysEventsIfNeeded(dayInMonth, monthRange)
} catch (e) {
@ -163,13 +157,7 @@ export class CalendarEventsRepository {
calendarInfos = new Map<string, CalendarInfo>([[calendarToLoad, calendarToLoadInfo]])
}
const eventsMap = await this.calendarFacade.updateEventMap(
monthRange,
calendarInfos,
this.daysToEvents(),
this.zone,
this.calendarModel.defaultCalendar,
)
const eventsMap = await this.calendarFacade.updateEventMap(monthRange, calendarInfos, this.daysToEvents(), this.zone)
this.replaceEvents(eventsMap)
this.addBirthdaysEventsIfNeeded(dayInMonth, monthRange)
} catch (e) {
@ -337,7 +325,7 @@ export class CalendarEventsRepository {
const wrapper: EventWrapper = {
event,
flags: {
isGhost: calendarInfos.get(eventOwnerGroupId)?.groupRoot.pendingEvents?.list === update.instanceListId,
isGhost: !!event.pendingInvitation,
hasAlarms: isNotEmpty(event.alarmInfos),
isAlteredInstance: Boolean(event.recurrenceId),
},
@ -416,6 +404,7 @@ export class CalendarEventsRepository {
invitedConfidentially: null,
repeatRule: createRepeatRuleWithValues(RepeatPeriod.ANNUALLY, 1),
uid,
pendingInvitation: null,
})
newEvent._id = [calendarId, `${generateLocalEventElementId(newEvent.startTime.getTime(), contact._id.join("/"))}#${encodedContactId}`]

View file

@ -898,14 +898,6 @@ export function assignEventId(event: CalendarEvent, zone: string, groupRoot: Cal
event._id = [listId, generateEventElementId(event.startTime.getTime())]
}
/** Create a pending event id depending on the default calendar assigned to this user */
export function assignPendingEventId(event: CalendarEvent, groupRoot: CalendarGroupRoot): void {
if (!groupRoot.pendingEvents?.list) {
throw Error(`Group ${groupRoot._id} is missing its pending list`)
}
event._id = [groupRoot.pendingEvents.list, generateEventElementId(event.startTime.getTime())]
}
/** predicate that tells us if two CalendarEvent objects refer to the same instance or different ones.*/
export function isSameEventInstance(left: EventWrapper, right: EventWrapper): boolean {
// in addition to the id we compare the start time equality to be able to distinguish repeating events. They have the same id but different start time.

View file

@ -1724,6 +1724,7 @@ impl EventFacade {
attendees: vec![],
invitedConfidentially: None,
repeatRule: None,
pendingInvitation: None,
uid: Some(uid),
_id: Some(IdTupleCustom {
list_id: birthday_calendar_id.clone(),

View file

@ -1885,8 +1885,10 @@ pub struct CalendarEvent {
pub recurrenceId: Option<DateTime>,
#[serde(rename = "1401")]
pub _ownerKeyVersion: Option<i64>,
#[serde(rename = "1788")]
#[serde(rename = "1783")]
pub sender: Option<String>,
#[serde(rename = "1784")]
pub pendingInvitation: Option<bool>,
#[serde(rename = "945")]
pub repeatRule: Option<CalendarRepeatRule>,
#[serde(rename = "946")]
@ -1933,8 +1935,6 @@ pub struct CalendarGroupRoot {
pub longEvents: GeneratedId,
#[serde(rename = "1103")]
pub index: Option<CalendarEventIndexRef>,
#[serde(rename = "1786")]
pub pendingEvents: Option<CalendarEventsRef>,
#[serde(default)]
pub _errors: Errors,
@ -2065,8 +2065,6 @@ pub struct UserSettingsGroupRoot {
pub birthdayCalendarColor: Option<String>,
#[serde(rename = "979")]
pub groupSettings: Vec<GroupSettings>,
#[serde(rename = "1787")]
pub defaultCalendar: Option<GeneratedId>,
#[serde(default)]
pub _errors: Errors,
@ -2088,8 +2086,6 @@ impl Entity for UserSettingsGroupRoot {
pub struct CalendarDeleteIn {
#[serde(rename = "983")]
pub _format: i64,
#[serde(rename = "1789")]
pub deleteEventsOnly: bool,
#[serde(rename = "984")]
pub groupRootId: GeneratedId,
}
@ -4323,21 +4319,3 @@ impl Entity for PopulateClientSpamTrainingDataPostIn {
}
}
}
#[derive(uniffi::Record, Clone, Serialize, Deserialize)]
#[cfg_attr(any(test, feature = "testing"), derive(PartialEq, Debug))]
pub struct CalendarEventsRef {
#[serde(rename = "1784")]
pub _id: Option<CustomId>,
#[serde(rename = "1785")]
pub list: GeneratedId,
}
impl Entity for CalendarEventsRef {
fn type_ref() -> TypeRef {
TypeRef {
app: AppName::Tutanota,
type_id: TypeId::from(1783),
}
}
}

View file

@ -11,12 +11,12 @@ use crate::entities::generated::monitor::ReadCounterReturn;
use crate::entities::generated::monitor::ReportErrorIn;
pub struct CounterService;
crate::service_impl!(declare, CounterService, "monitor/counterservice", 36);
crate::service_impl!(declare, CounterService, "monitor/counterservice", 37);
crate::service_impl!(POST, CounterService, WriteCounterData, ());
crate::service_impl!(GET, CounterService, ReadCounterData, ReadCounterReturn);
pub struct ReportErrorService;
crate::service_impl!(declare, ReportErrorService, "monitor/reporterrorservice", 36);
crate::service_impl!(declare, ReportErrorService, "monitor/reporterrorservice", 37);
crate::service_impl!(POST, ReportErrorService, ReportErrorIn, ());

View file

@ -2,7 +2,7 @@
"12": {
"name": "ReadCounterData",
"app": "monitor",
"version": 36,
"version": 37,
"since": 1,
"type": "DATA_TRANSFER_TYPE",
"id": 12,
@ -49,7 +49,7 @@
"16": {
"name": "ReadCounterReturn",
"app": "monitor",
"version": 36,
"version": 37,
"since": 1,
"type": "DATA_TRANSFER_TYPE",
"id": 16,
@ -90,7 +90,7 @@
"49": {
"name": "WriteCounterData",
"app": "monitor",
"version": 36,
"version": 37,
"since": 4,
"type": "DATA_TRANSFER_TYPE",
"id": 49,
@ -145,7 +145,7 @@
"221": {
"name": "ApprovalMail",
"app": "monitor",
"version": 36,
"version": 37,
"since": 14,
"type": "LIST_ELEMENT_TYPE",
"id": 221,
@ -226,7 +226,7 @@
"300": {
"name": "CounterValue",
"app": "monitor",
"version": 36,
"version": 37,
"since": 22,
"type": "AGGREGATED_TYPE",
"id": 300,
@ -265,7 +265,7 @@
"305": {
"name": "ErrorReportFile",
"app": "monitor",
"version": 36,
"version": 37,
"since": 23,
"type": "AGGREGATED_TYPE",
"id": 305,
@ -304,7 +304,7 @@
"316": {
"name": "ErrorReportData",
"app": "monitor",
"version": 36,
"version": 37,
"since": 23,
"type": "AGGREGATED_TYPE",
"id": 316,
@ -399,7 +399,7 @@
"335": {
"name": "ReportErrorIn",
"app": "monitor",
"version": 36,
"version": 37,
"since": 23,
"type": "DATA_TRANSFER_TYPE",
"id": 335,

View file

@ -4557,13 +4557,21 @@
"cardinality": "ZeroOrOne",
"encrypted": false
},
"1788": {
"1783": {
"final": false,
"name": "sender",
"id": 1788,
"id": 1783,
"type": "String",
"cardinality": "ZeroOrOne",
"encrypted": true
},
"1784": {
"final": false,
"name": "pendingInvitation",
"id": 1784,
"type": "Boolean",
"cardinality": "ZeroOrOne",
"encrypted": true
}
},
"associations": {
@ -4693,15 +4701,6 @@
"cardinality": "ZeroOrOne",
"refTypeId": 1100,
"dependency": null
},
"1786": {
"final": false,
"name": "pendingEvents",
"id": 1786,
"type": "AGGREGATION",
"cardinality": "ZeroOrOne",
"refTypeId": 1783,
"dependency": null
}
}
},
@ -5003,15 +5002,6 @@
"cardinality": "Any",
"refTypeId": 968,
"dependency": null
},
"1787": {
"final": false,
"name": "defaultCalendar",
"id": 1787,
"type": "ELEMENT_ASSOCIATION",
"cardinality": "ZeroOrOne",
"refTypeId": 947,
"dependency": null
}
}
},
@ -5034,14 +5024,6 @@
"type": "Number",
"cardinality": "One",
"encrypted": false
},
"1789": {
"final": false,
"name": "deleteEventsOnly",
"id": 1789,
"type": "Boolean",
"cardinality": "One",
"encrypted": false
}
},
"associations": {
@ -9727,38 +9709,5 @@
"dependency": null
}
}
},
"1783": {
"name": "CalendarEventsRef",
"app": "tutanota",
"version": 99,
"since": 99,
"type": "AGGREGATED_TYPE",
"id": 1783,
"rootId": "CHR1dGFub3RhAAb3",
"versioned": false,
"encrypted": false,
"isPublic": true,
"values": {
"1784": {
"final": true,
"name": "_id",
"id": 1784,
"type": "CustomId",
"cardinality": "One",
"encrypted": false
}
},
"associations": {
"1785": {
"final": true,
"name": "list",
"id": 1785,
"type": "LIST_ASSOCIATION",
"cardinality": "One",
"refTypeId": 933,
"dependency": null
}
}
}
}