{
  "application": {
    "universalIdentifier": "05ce64a4-c1ee-4f4e-885c-bc1f7123a25b",
    "displayName": "Viginti Mobile Push",
    "description": "Registers iOS and iPadOS devices for Viginti remote push notifications and relays task assignment events through a Cloudflare Worker to Firebase Cloud Messaging.",
    "author": "Thomas Entner",
    "category": "Productivity",
    "websiteUrl": "https://github.com/entttom/Viginti-Twenty-CRM-Public",
    "termsUrl": "https://github.com/entttom/Viginti-Twenty-CRM-Public",
    "emailSupport": "support@example.com",
    "applicationVariables": {
      "RELAY_BASE_URL": {
        "universalIdentifier": "06000b38-8fe0-413c-9b19-22afb1974ff5",
        "description": "Base URL of the Cloudflare push relay.",
        "value": "https://twenty-push-relay.entner-tom.workers.dev",
        "isSecret": false
      }
    },
    "defaultRoleUniversalIdentifier": "4c8246e5-0a05-4155-816c-9ec4cb79c04b",
    "yarnLockChecksum": null,
    "packageJsonChecksum": "9945429e2d9022d558e5179792974a1b",
    "postInstallLogicFunction": {
      "universalIdentifier": "f9791ee7-af73-41e2-81aa-08bd9e29c876",
      "shouldRunOnVersionUpgrade": true,
      "shouldRunSynchronously": false
    }
  },
  "objects": [
    {
      "universalIdentifier": "9b8388f0-36f5-4cfc-8d4f-aaac5f358c05",
      "nameSingular": "pushDevice",
      "namePlural": "pushDevices",
      "labelSingular": "Push Device",
      "labelPlural": "Push Devices",
      "description": "A registered iOS device that can receive Viginti push notifications.",
      "icon": "IconDeviceMobile",
      "isSearchable": false,
      "isUICreatable": false,
      "isUIEditable": false,
      "labelIdentifierFieldMetadataUniversalIdentifier": "11672460-4bc9-4adc-9815-3a1e4580e4f7",
      "fields": [
        {
          "universalIdentifier": "11672460-4bc9-4adc-9815-3a1e4580e4f7",
          "type": "TEXT",
          "name": "installationId",
          "label": "Installation ID",
          "description": "Stable per-install UUID from the mobile app."
        },
        {
          "universalIdentifier": "ea864f90-59e2-4f09-8be5-b431416731d5",
          "type": "TEXT",
          "name": "workspaceMemberId",
          "label": "Workspace Member ID",
          "description": "Authenticated Twenty workspace member that owns this device."
        },
        {
          "universalIdentifier": "91d5f03f-5fcc-417c-a97e-5d0ebf689564",
          "type": "TEXT",
          "name": "fcmToken",
          "label": "FCM Token",
          "description": "Firebase registration token. Sensitive; never expose in UI."
        },
        {
          "universalIdentifier": "7fa4054d-dd2e-4c10-b8fd-91318d1833c9",
          "type": "TEXT",
          "name": "tokenHash",
          "label": "Token Fingerprint",
          "description": "Safe SHA-256 fingerprint prefix of the FCM token."
        },
        {
          "universalIdentifier": "35fde69d-4fcd-4b6d-b560-00f9bebd0d9d",
          "type": "TEXT",
          "name": "platform",
          "label": "Platform",
          "description": "Device platform, for example ios."
        },
        {
          "universalIdentifier": "07e09c4a-d328-42fc-a0ef-d7f74c70262b",
          "type": "TEXT",
          "name": "environment",
          "label": "APNs Environment",
          "description": "sandbox or production."
        },
        {
          "universalIdentifier": "4c8c1a24-36d8-4ec5-a983-8468be33f7e6",
          "type": "TEXT",
          "name": "bundleIdentifier",
          "label": "Bundle Identifier",
          "description": "Mobile app bundle identifier."
        },
        {
          "universalIdentifier": "ef80c428-1a95-4532-94be-bdbedea30fcc",
          "type": "TEXT",
          "name": "appVersion",
          "label": "App Version",
          "description": "Mobile app marketing version."
        },
        {
          "universalIdentifier": "220a51d3-a7aa-4ead-822b-7eaa0a8f0e39",
          "type": "TEXT",
          "name": "buildNumber",
          "label": "Build Number",
          "description": "Mobile app build number."
        },
        {
          "universalIdentifier": "88e14f0c-511e-4671-bfb3-bd938965f893",
          "type": "TEXT",
          "name": "deviceLocale",
          "label": "Device Locale",
          "description": "BCP-47 locale, for example de-AT."
        },
        {
          "universalIdentifier": "33469cde-22f6-47ca-818c-b4a4485c90d0",
          "type": "TEXT",
          "name": "timeZone",
          "label": "Time Zone",
          "description": "IANA time zone, for example Europe/Vienna."
        },
        {
          "universalIdentifier": "081b6f77-1083-4d73-aff5-f210bf8e001a",
          "type": "BOOLEAN",
          "name": "notificationsEnabled",
          "label": "Notifications Enabled",
          "description": "Master push switch for this device.",
          "defaultValue": true
        },
        {
          "universalIdentifier": "0996e12d-a6c1-4eef-a797-0d0646033736",
          "type": "BOOLEAN",
          "name": "taskAssignedEnabled",
          "label": "Task Assigned",
          "description": "Notify when a task is assigned to the owner.",
          "defaultValue": true
        },
        {
          "universalIdentifier": "30c399a9-2fd4-4c17-a98a-e1368f614c7e",
          "type": "BOOLEAN",
          "name": "taskDueDateChangedEnabled",
          "label": "Due Date Changed",
          "description": "Reserved for a later event type.",
          "defaultValue": false
        },
        {
          "universalIdentifier": "e0689b0a-95fd-4117-9c48-326e02830772",
          "type": "BOOLEAN",
          "name": "taskCompletedEnabled",
          "label": "Task Completed",
          "description": "Reserved for a later event type.",
          "defaultValue": false
        },
        {
          "universalIdentifier": "4a91a20a-199f-4f31-8e84-7f00b29e92fc",
          "type": "BOOLEAN",
          "name": "taskUnassignedEnabled",
          "label": "Task Unassigned",
          "description": "Reserved for a later event type.",
          "defaultValue": false
        },
        {
          "universalIdentifier": "1f29217a-9bf6-4694-bed6-9f318941ead0",
          "type": "DATE_TIME",
          "name": "lastSeenAt",
          "label": "Last Seen",
          "description": "Last successful registration sync.",
          "isNullable": true
        },
        {
          "universalIdentifier": "d9970b6e-ce54-4e4a-a66d-28b9ec8351d5",
          "type": "DATE_TIME",
          "name": "disabledAt",
          "label": "Disabled At",
          "description": "When the device was deactivated.",
          "isNullable": true
        },
        {
          "universalIdentifier": "cebc6621-f35a-4694-8f11-f04155d3081c",
          "type": "TEXT",
          "name": "lastDeliveryError",
          "label": "Last Delivery Error",
          "description": "Non-sensitive code of the last delivery failure.",
          "isNullable": true
        },
        {
          "name": "id",
          "label": "Id",
          "description": "Id",
          "icon": "Icon123",
          "isNullable": false,
          "defaultValue": "uuid",
          "type": "UUID",
          "universalIdentifier": "668d1067-2cc6-510a-be70-0334e7f5409b"
        },
        {
          "name": "name",
          "label": "Name",
          "description": "Name",
          "icon": "IconAbc",
          "isNullable": true,
          "defaultValue": null,
          "type": "TEXT",
          "universalIdentifier": "9197ce43-8032-583b-8a86-0755da75243a"
        },
        {
          "name": "createdAt",
          "label": "Creation date",
          "description": "Creation date",
          "icon": "IconCalendar",
          "isNullable": false,
          "defaultValue": "now",
          "type": "DATE_TIME",
          "universalIdentifier": "f227747e-d000-5b22-8963-5156abb7e935"
        },
        {
          "name": "updatedAt",
          "label": "Last update",
          "description": "Last time the record was changed",
          "icon": "IconCalendarClock",
          "isNullable": false,
          "defaultValue": "now",
          "type": "DATE_TIME",
          "universalIdentifier": "bb3c4af2-5ddc-5929-ab65-0581b6d5291c"
        },
        {
          "name": "deletedAt",
          "label": "Deleted at",
          "description": "Deletion date",
          "icon": "IconCalendarClock",
          "isNullable": true,
          "defaultValue": null,
          "type": "DATE_TIME",
          "universalIdentifier": "0865a5c0-1515-51ae-a34a-ee2ca726ceb5"
        },
        {
          "name": "createdBy",
          "label": "Created by",
          "description": "The creator of the record",
          "icon": "IconCreativeCommonsSa",
          "isNullable": false,
          "defaultValue": {
            "name": "''",
            "source": "'MANUAL'"
          },
          "type": "ACTOR",
          "universalIdentifier": "7a8e1adb-975e-5ec7-9614-a4918db88495"
        },
        {
          "name": "updatedBy",
          "label": "Updated by",
          "description": "The workspace member who last updated the record",
          "icon": "IconUserCircle",
          "isNullable": false,
          "defaultValue": {
            "name": "''",
            "source": "'MANUAL'"
          },
          "type": "ACTOR",
          "universalIdentifier": "7fe67583-5507-539a-abae-998df64e7486"
        },
        {
          "name": "position",
          "label": "Position",
          "description": "Position",
          "icon": "IconHierarchy2",
          "isNullable": false,
          "defaultValue": 0,
          "type": "POSITION",
          "universalIdentifier": "d5f1b662-f846-559e-a943-fa3251679f1e"
        },
        {
          "name": "searchVector",
          "label": "Search vector",
          "icon": "IconSearch",
          "description": "Search vector",
          "isNullable": true,
          "defaultValue": null,
          "type": "TS_VECTOR",
          "universalIdentifier": "1833502b-af59-5028-800e-1be8217482ff"
        },
        {
          "name": "timelineActivities",
          "label": "Timeline Activities",
          "description": "Push Devices tied to the PushDevice",
          "icon": "IconBuildingSkyscraper",
          "isNullable": true,
          "type": "RELATION",
          "universalSettings": {
            "relationType": "ONE_TO_MANY"
          },
          "universalIdentifier": "8c73d6b3-5fbf-59a5-9cec-d2ff6a5a025e",
          "relationTargetFieldMetadataUniversalIdentifier": "6d5ee806-c94e-5eb0-a677-41eb299f2230",
          "relationTargetObjectMetadataUniversalIdentifier": "20202020-6736-4337-b5c4-8b39fae325a5"
        },
        {
          "name": "attachments",
          "label": "Attachments",
          "description": "Push Devices tied to the PushDevice",
          "icon": "IconBuildingSkyscraper",
          "isNullable": true,
          "type": "RELATION",
          "universalSettings": {
            "relationType": "ONE_TO_MANY"
          },
          "universalIdentifier": "8263c479-7b90-50a1-8534-2f8f516d94ef",
          "relationTargetFieldMetadataUniversalIdentifier": "73887b21-a47b-5d56-9fed-eacf5f7efe3e",
          "relationTargetObjectMetadataUniversalIdentifier": "20202020-bd3d-4c60-8dca-571c71d4447a"
        },
        {
          "name": "noteTargets",
          "label": "Note Targets",
          "description": "Push Devices tied to the PushDevice",
          "icon": "IconBuildingSkyscraper",
          "isNullable": true,
          "type": "RELATION",
          "universalSettings": {
            "relationType": "ONE_TO_MANY"
          },
          "universalIdentifier": "0fedc93d-3135-57c0-a81e-b542bf839664",
          "relationTargetFieldMetadataUniversalIdentifier": "dc6700c7-f192-5228-8781-7c557ec9b175",
          "relationTargetObjectMetadataUniversalIdentifier": "20202020-fff0-4b44-be82-bda313884400"
        },
        {
          "name": "taskTargets",
          "label": "Task Targets",
          "description": "Push Devices tied to the PushDevice",
          "icon": "IconBuildingSkyscraper",
          "isNullable": true,
          "type": "RELATION",
          "universalSettings": {
            "relationType": "ONE_TO_MANY"
          },
          "universalIdentifier": "40412572-3f22-5118-8478-af6e46458119",
          "relationTargetFieldMetadataUniversalIdentifier": "26be4cb5-43e1-5231-8f2b-bd6cf2a9042f",
          "relationTargetObjectMetadataUniversalIdentifier": "20202020-5a9a-44e8-95df-771cd06d0fb1"
        }
      ]
    }
  ],
  "fields": [
    {
      "name": "targetPushDevice",
      "label": "PushDevice",
      "description": "PushDevice Push Device",
      "icon": "IconCheckbox",
      "isNullable": true,
      "universalSettings": {
        "relationType": "MANY_TO_ONE",
        "onDelete": "SET_NULL",
        "joinColumnName": "targetPushDeviceId"
      },
      "universalIdentifier": "26be4cb5-43e1-5231-8f2b-bd6cf2a9042f",
      "objectUniversalIdentifier": "20202020-5a9a-44e8-95df-771cd06d0fb1",
      "relationTargetFieldMetadataUniversalIdentifier": "40412572-3f22-5118-8478-af6e46458119",
      "relationTargetObjectMetadataUniversalIdentifier": "9b8388f0-36f5-4cfc-8d4f-aaac5f358c05",
      "type": "MORPH_RELATION",
      "morphId": "20202020-f636-435d-ab8d-e1168b375c71"
    },
    {
      "name": "targetPushDevice",
      "label": "PushDevice",
      "description": "PushDevice Push Device",
      "icon": "IconTimelineEvent",
      "isNullable": true,
      "universalSettings": {
        "relationType": "MANY_TO_ONE",
        "onDelete": "SET_NULL",
        "joinColumnName": "targetPushDeviceId"
      },
      "universalIdentifier": "6d5ee806-c94e-5eb0-a677-41eb299f2230",
      "objectUniversalIdentifier": "20202020-6736-4337-b5c4-8b39fae325a5",
      "relationTargetFieldMetadataUniversalIdentifier": "8c73d6b3-5fbf-59a5-9cec-d2ff6a5a025e",
      "relationTargetObjectMetadataUniversalIdentifier": "9b8388f0-36f5-4cfc-8d4f-aaac5f358c05",
      "type": "MORPH_RELATION",
      "morphId": "20202020-9a2b-4c3d-a4e5-f6a7b8c9d0e1"
    },
    {
      "name": "targetPushDevice",
      "label": "PushDevice",
      "description": "PushDevice Push Device",
      "icon": "IconFileImport",
      "isNullable": true,
      "universalSettings": {
        "relationType": "MANY_TO_ONE",
        "onDelete": "SET_NULL",
        "joinColumnName": "targetPushDeviceId"
      },
      "universalIdentifier": "73887b21-a47b-5d56-9fed-eacf5f7efe3e",
      "objectUniversalIdentifier": "20202020-bd3d-4c60-8dca-571c71d4447a",
      "relationTargetFieldMetadataUniversalIdentifier": "8263c479-7b90-50a1-8534-2f8f516d94ef",
      "relationTargetObjectMetadataUniversalIdentifier": "9b8388f0-36f5-4cfc-8d4f-aaac5f358c05",
      "type": "MORPH_RELATION",
      "morphId": "20202020-f634-435d-ab8d-e1168b375c69"
    },
    {
      "name": "targetPushDevice",
      "label": "PushDevice",
      "description": "PushDevice Push Device",
      "icon": "IconCheckbox",
      "isNullable": true,
      "universalSettings": {
        "relationType": "MANY_TO_ONE",
        "onDelete": "SET_NULL",
        "joinColumnName": "targetPushDeviceId"
      },
      "universalIdentifier": "dc6700c7-f192-5228-8781-7c557ec9b175",
      "objectUniversalIdentifier": "20202020-fff0-4b44-be82-bda313884400",
      "relationTargetFieldMetadataUniversalIdentifier": "0fedc93d-3135-57c0-a81e-b542bf839664",
      "relationTargetObjectMetadataUniversalIdentifier": "9b8388f0-36f5-4cfc-8d4f-aaac5f358c05",
      "type": "MORPH_RELATION",
      "morphId": "20202020-f635-435d-ab8d-e1168b375c70"
    }
  ],
  "indexes": [
    {
      "universalIdentifier": "995bdfe7-9d9b-4e81-a8e3-f738e2ab5ded",
      "objectUniversalIdentifier": "9b8388f0-36f5-4cfc-8d4f-aaac5f358c05",
      "isUnique": true,
      "fields": [
        {
          "universalIdentifier": "e4537d65-5d5a-48fb-8ba6-cf091946d5cf",
          "fieldUniversalIdentifier": "ea864f90-59e2-4f09-8be5-b431416731d5"
        },
        {
          "universalIdentifier": "bd243a0c-5cab-4061-9d08-1d2c1c8009f7",
          "fieldUniversalIdentifier": "11672460-4bc9-4adc-9815-3a1e4580e4f7"
        }
      ]
    }
  ],
  "permissionFlags": [],
  "roles": [
    {
      "universalIdentifier": "4c8246e5-0a05-4155-816c-9ec4cb79c04b",
      "label": "Viginti Mobile Push default function role",
      "description": "Viginti Mobile Push default function role",
      "canReadAllObjectRecords": true,
      "canUpdateAllObjectRecords": true,
      "canSoftDeleteAllObjectRecords": false,
      "canDestroyAllObjectRecords": false,
      "objectPermissions": [],
      "fieldPermissions": [],
      "permissionFlagUniversalIdentifiers": []
    }
  ],
  "skills": [],
  "agents": [],
  "connectionProviders": [],
  "logicFunctions": [
    {
      "universalIdentifier": "5b32dcbd-86dc-4f3b-adb6-e98eea298b69",
      "name": "push-preferences",
      "description": "Updates the authenticated member's mobile push preferences.",
      "timeoutSeconds": 10,
      "httpRouteTriggerSettings": {
        "path": "/push/preferences",
        "httpMethod": "POST",
        "isAuthRequired": true,
        "forwardedRequestHeaders": [
          "authorization"
        ]
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/preferences.logic-function.ts",
      "builtHandlerPath": "src/preferences.logic-function.mjs",
      "builtHandlerChecksum": "fcc1f365a899df7172abd347184612d6"
    },
    {
      "universalIdentifier": "806f4f64-9676-4af1-825c-bef656ab0fab",
      "name": "push-register",
      "description": "Registers or updates the authenticated member's mobile push device.",
      "timeoutSeconds": 10,
      "httpRouteTriggerSettings": {
        "path": "/push/register",
        "httpMethod": "POST",
        "isAuthRequired": true,
        "forwardedRequestHeaders": [
          "authorization"
        ]
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/register.logic-function.ts",
      "builtHandlerPath": "src/register.logic-function.mjs",
      "builtHandlerChecksum": "71a84dddaaadee683246bc19047be9e4"
    },
    {
      "universalIdentifier": "b768f8c5-e660-49ba-a302-e7b7cb7bb2c1",
      "name": "push-unregister",
      "description": "Disables the authenticated member's mobile push device.",
      "timeoutSeconds": 10,
      "httpRouteTriggerSettings": {
        "path": "/push/unregister",
        "httpMethod": "POST",
        "isAuthRequired": true,
        "forwardedRequestHeaders": [
          "authorization"
        ]
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/unregister.logic-function.ts",
      "builtHandlerPath": "src/unregister.logic-function.mjs",
      "builtHandlerChecksum": "c81458a436cd24c9c8d91a0e20e76411"
    },
    {
      "universalIdentifier": "b845b39b-aaad-42eb-82aa-97ac6742b8b4",
      "name": "task-created-push",
      "description": "Sends a push notification when a newly created task is assigned.",
      "timeoutSeconds": 20,
      "databaseEventTriggerSettings": {
        "eventName": "task.created"
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/task-created.logic-function.ts",
      "builtHandlerPath": "src/task-created.logic-function.mjs",
      "builtHandlerChecksum": "866bd1d21977c4ceef19435045f88500"
    },
    {
      "universalIdentifier": "c80d22cf-ce36-485b-8bd3-07d9caf0ba33",
      "name": "push-status",
      "description": "Reports Viginti mobile push installation and relay readiness.",
      "timeoutSeconds": 2,
      "httpRouteTriggerSettings": {
        "path": "/push/status",
        "httpMethod": "GET",
        "isAuthRequired": true
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/status.logic-function.ts",
      "builtHandlerPath": "src/status.logic-function.mjs",
      "builtHandlerChecksum": "c1da5633ca946b7aaa25045e71bf198a"
    },
    {
      "universalIdentifier": "ce6343cd-24f0-4faf-8c34-6ea5f5af4bda",
      "name": "push-test",
      "description": "Sends a test push notification to the authenticated member's active devices.",
      "timeoutSeconds": 20,
      "httpRouteTriggerSettings": {
        "path": "/push/test",
        "httpMethod": "POST",
        "isAuthRequired": true,
        "forwardedRequestHeaders": [
          "authorization"
        ]
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/test.logic-function.ts",
      "builtHandlerPath": "src/test.logic-function.mjs",
      "builtHandlerChecksum": "b612a9153df16314f29fa8e2c2761046"
    },
    {
      "universalIdentifier": "f7fda668-8229-427f-92f0-fb1521d2a067",
      "name": "task-updated-push",
      "description": "Sends push notifications for task assignment, due date, completion, and unassignment updates.",
      "timeoutSeconds": 20,
      "databaseEventTriggerSettings": {
        "eventName": "task.updated",
        "updatedFields": [
          "assignee",
          "assigneeId",
          "dueAt",
          "status"
        ]
      },
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/task-updated.logic-function.ts",
      "builtHandlerPath": "src/task-updated.logic-function.mjs",
      "builtHandlerChecksum": "9e0f1ca0f99151f929d7677d4a7f0366"
    },
    {
      "universalIdentifier": "f9791ee7-af73-41e2-81aa-08bd9e29c876",
      "name": "provision-relay-installation",
      "description": "Registers this Twenty app installation with the Viginti push relay.",
      "timeoutSeconds": 20,
      "shouldRunOnVersionUpgrade": true,
      "shouldRunSynchronously": false,
      "handlerName": "default.config.handler",
      "sourceHandlerPath": "src/post-install.ts",
      "builtHandlerPath": "src/post-install.mjs",
      "builtHandlerChecksum": "1905ba16b1a588994128a0292d39d532"
    }
  ],
  "frontComponents": [],
  "publicAssets": [],
  "views": [],
  "viewFields": [],
  "navigationMenuItems": [],
  "pageLayouts": [],
  "pageLayoutTabs": [],
  "commandMenuItems": []
}
