diff --git a/.env.mobile b/.env.mobile
index 33e24dc8..f3831533 100644
--- a/.env.mobile
+++ b/.env.mobile
@@ -1 +1,5 @@
-PLATFORM=mobile 
\ No newline at end of file
+PLATFORM=mobile
+VITE_ENDORSER_API_URL=https://test-api.endorser.ch/api/v2/claim
+VITE_PARTNER_API_URL=https://test-api.partner.ch/api/v2
+VITE_IMAGE_API_URL=https://test-api.images.ch/api/v2
+VITE_PUSH_SERVER_URL=https://test-api.push.ch/api/v2 
\ No newline at end of file
diff --git a/.eslintrc.js b/.eslintrc.js
index 0a908a2e..02ecf15f 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -26,6 +26,10 @@ module.exports = {
     "no-debugger": process.env.NODE_ENV === "production" ? "error" : "warn",
     "@typescript-eslint/no-explicit-any": "warn",
     "@typescript-eslint/explicit-function-return-type": "off",
-    "@typescript-eslint/no-unnecessary-type-constraint": "off"
+    "@typescript-eslint/no-unnecessary-type-constraint": "off",
+    "@typescript-eslint/no-unused-vars": ["error", {
+      "argsIgnorePattern": "^_",
+      "varsIgnorePattern": "^_"
+    }]
   },
 };
diff --git a/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock b/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock
index 6f5da8a4..6316cbbe 100644
Binary files a/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock and b/android/.gradle/buildOutputCleanup/buildOutputCleanup.lock differ
diff --git a/android/.gradle/buildOutputCleanup/cache.properties b/android/.gradle/buildOutputCleanup/cache.properties
index 1cb74a9a..e0d365f0 100644
--- a/android/.gradle/buildOutputCleanup/cache.properties
+++ b/android/.gradle/buildOutputCleanup/cache.properties
@@ -1,2 +1,2 @@
-#Fri Mar 21 07:27:50 UTC 2025
-gradle.version=8.2.1
+#Thu Apr 03 08:01:00 UTC 2025
+gradle.version=8.11.1
diff --git a/android/.gradle/file-system.probe b/android/.gradle/file-system.probe
index d0da6143..c967c2ff 100644
Binary files a/android/.gradle/file-system.probe and b/android/.gradle/file-system.probe differ
diff --git a/android/app/capacitor.build.gradle b/android/app/capacitor.build.gradle
index 151fee42..e3e02249 100644
--- a/android/app/capacitor.build.gradle
+++ b/android/app/capacitor.build.gradle
@@ -10,6 +10,8 @@ android {
 apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
 dependencies {
     implementation project(':capacitor-app')
+    implementation project(':capacitor-filesystem')
+    implementation project(':capacitor-share')
 
 }
 
diff --git a/android/app/src/main/assets/capacitor.plugins.json b/android/app/src/main/assets/capacitor.plugins.json
index 21a0521e..83bccb09 100644
--- a/android/app/src/main/assets/capacitor.plugins.json
+++ b/android/app/src/main/assets/capacitor.plugins.json
@@ -2,5 +2,13 @@
 	{
 		"pkg": "@capacitor/app",
 		"classpath": "com.capacitorjs.plugins.app.AppPlugin"
+	},
+	{
+		"pkg": "@capacitor/filesystem",
+		"classpath": "com.capacitorjs.plugins.filesystem.FilesystemPlugin"
+	},
+	{
+		"pkg": "@capacitor/share",
+		"classpath": "com.capacitorjs.plugins.share.SharePlugin"
 	}
 ]
diff --git a/android/app/src/main/assets/public/index.html b/android/app/src/main/assets/public/index.html
index 9a2af5b2..b8bc11e2 100644
--- a/android/app/src/main/assets/public/index.html
+++ b/android/app/src/main/assets/public/index.html
@@ -6,7 +6,7 @@
     <meta name="viewport" content="width=device-width,initial-scale=1.0">
     <link rel="icon" href="/favicon.ico">
     <title>TimeSafari</title>
-    <script type="module" crossorigin src="/assets/index-CZMUlUNO.js"></script>
+    <script type="module" crossorigin src="/assets/index-CxCVZqQa.js"></script>
   </head>
   <body>
     <noscript>
diff --git a/android/build.gradle b/android/build.gradle
index 85a5dda2..3995fb3d 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -7,7 +7,7 @@ buildscript {
         mavenCentral()
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:8.2.1'
+        classpath 'com.android.tools.build:gradle:8.9.0'
         classpath 'com.google.gms:google-services:4.4.0'
 
         // NOTE: Do not place your application dependencies here; they belong
diff --git a/android/capacitor.settings.gradle b/android/capacitor.settings.gradle
index 2085c863..79e75364 100644
--- a/android/capacitor.settings.gradle
+++ b/android/capacitor.settings.gradle
@@ -4,3 +4,9 @@ project(':capacitor-android').projectDir = new File('../node_modules/@capacitor/
 
 include ':capacitor-app'
 project(':capacitor-app').projectDir = new File('../node_modules/@capacitor/app/android')
+
+include ':capacitor-filesystem'
+project(':capacitor-filesystem').projectDir = new File('../node_modules/@capacitor/filesystem/android')
+
+include ':capacitor-share'
+project(':capacitor-share').projectDir = new File('../node_modules/@capacitor/share/android')
diff --git a/android/gradle/wrapper/gradle-wrapper.properties b/android/gradle/wrapper/gradle-wrapper.properties
index c747538f..c1d5e018 100644
--- a/android/gradle/wrapper/gradle-wrapper.properties
+++ b/android/gradle/wrapper/gradle-wrapper.properties
@@ -1,6 +1,6 @@
 distributionBase=GRADLE_USER_HOME
 distributionPath=wrapper/dists
-distributionUrl=https\://services.gradle.org/distributions/gradle-8.2.1-all.zip
+distributionUrl=https\://services.gradle.org/distributions/gradle-8.11.1-all.zip
 networkTimeout=10000
 validateDistributionUrl=true
 zipStoreBase=GRADLE_USER_HOME
diff --git a/package-lock.json b/package-lock.json
index 4f1c9854..25b24bfa 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -11,7 +11,7 @@
         "@capacitor/android": "^6.2.0",
         "@capacitor/app": "^6.0.0",
         "@capacitor/cli": "^6.2.0",
-        "@capacitor/core": "^6.2.0",
+        "@capacitor/core": "^6.2.1",
         "@capacitor/filesystem": "^6.0.3",
         "@capacitor/ios": "^6.2.0",
         "@capacitor/share": "^6.0.3",
@@ -13208,9 +13208,9 @@
       }
     },
     "node_modules/caniuse-lite": {
-      "version": "1.0.30001707",
-      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001707.tgz",
-      "integrity": "sha512-3qtRjw/HQSMlDWf+X79N206fepf4SOOU6SQLMaq/0KkZLmSjPxAkBOQQ+FxbHKfHmYLZFfdWsO3KA90ceHPSnw==",
+      "version": "1.0.30001709",
+      "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001709.tgz",
+      "integrity": "sha512-NgL3vUTnDrPCZ3zTahp4fsugQ4dc7EKTSzwQDPEel6DMoMnfH2jhry9n2Zm8onbSR+f/QtKHFOA+iAQu4kbtWA==",
       "devOptional": true,
       "funding": [
         {
@@ -15612,9 +15612,9 @@
       }
     },
     "node_modules/electron-to-chromium": {
-      "version": "1.5.129",
-      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.129.tgz",
-      "integrity": "sha512-JlXUemX4s0+9f8mLqib/bHH8gOHf5elKS6KeWG3sk3xozb/JTq/RLXIv8OKUWiK4Ah00Wm88EFj5PYkFr4RUPA==",
+      "version": "1.5.130",
+      "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.5.130.tgz",
+      "integrity": "sha512-Ou2u7L9j2XLZbhqzyX0jWDj6gA8D3jIfVzt4rikLf3cGBa0VdReuFimBKS9tQJA4+XpeCxj1NoWlfBXzbMa9IA==",
       "devOptional": true,
       "license": "ISC"
     },
@@ -16037,14 +16037,14 @@
       }
     },
     "node_modules/eslint-plugin-prettier": {
-      "version": "5.2.5",
-      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.5.tgz",
-      "integrity": "sha512-IKKP8R87pJyMl7WWamLgPkloB16dagPIdd2FjBDbyRYPKo93wS/NbCOPh6gH+ieNLC+XZrhJt/kWj0PS/DFdmg==",
+      "version": "5.2.6",
+      "resolved": "https://registry.npmjs.org/eslint-plugin-prettier/-/eslint-plugin-prettier-5.2.6.tgz",
+      "integrity": "sha512-mUcf7QG2Tjk7H055Jk0lGBjbgDnfrvqjhXh9t2xLMSCjZVcw9Rb1V6sVNXO0th3jgeO7zllWPTNRil3JW94TnQ==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
         "prettier-linter-helpers": "^1.0.0",
-        "synckit": "^0.10.2"
+        "synckit": "^0.11.0"
       },
       "engines": {
         "node": "^14.18.0 || >=16.0.0"
@@ -18568,9 +18568,9 @@
       }
     },
     "node_modules/image-size": {
-      "version": "1.2.0",
-      "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.0.tgz",
-      "integrity": "sha512-4S8fwbO6w3GeCVN6OPtA9I5IGKkcDMPcKndtUlpJuCwu7JLjtj7JZpwqLuyY2nrmQT3AWsCJLSKPsc2mPBSl3w==",
+      "version": "1.2.1",
+      "resolved": "https://registry.npmjs.org/image-size/-/image-size-1.2.1.tgz",
+      "integrity": "sha512-rH+46sQJ2dlwfjfhCyNx5thzrv+dtmBIhPHk0zgRUukHzZ/kRueTJXoYYsclBaKcSMBWuGbOFXtioLpzTb5euw==",
       "license": "MIT",
       "optional": true,
       "peer": true,
@@ -23520,9 +23520,9 @@
       }
     },
     "node_modules/nostr-tools": {
-      "version": "2.11.1",
-      "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.11.1.tgz",
-      "integrity": "sha512-+Oj5t+behIkU9kh3go5wg8Aa5oR7euBU9gOItUNapJe5Gaa+KPzMuTIN+rMRK3DaZ4Zt6RM4kR/ddwstzGKf7g==",
+      "version": "2.12.0",
+      "resolved": "https://registry.npmjs.org/nostr-tools/-/nostr-tools-2.12.0.tgz",
+      "integrity": "sha512-pUWEb020gTvt1XZvTa8AKNIHWFapjsv2NKyk43Ez2nnvz6WSXsrTFE0XtkNLSRBjPn6EpxumKeNiVzLz74jNSA==",
       "license": "Unlicense",
       "dependencies": {
         "@noble/ciphers": "^0.5.1",
@@ -28778,9 +28778,9 @@
       }
     },
     "node_modules/synckit": {
-      "version": "0.10.3",
-      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.10.3.tgz",
-      "integrity": "sha512-R1urvuyiTaWfeCggqEvpDJwAlDVdsT9NM+IP//Tk2x7qHCkSvBk/fwFgw/TLAHzZlrAnnazMcRw0ZD8HlYFTEQ==",
+      "version": "0.11.1",
+      "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.11.1.tgz",
+      "integrity": "sha512-fWZqNBZNNFp/7mTUy1fSsydhKsAKJ+u90Nk7kOK5Gcq9vObaqLBLjWFDBkyVU9Vvc6Y71VbOevMuGhqv02bT+Q==",
       "dev": true,
       "license": "MIT",
       "dependencies": {
@@ -28791,7 +28791,7 @@
         "node": "^14.18.0 || >=16.0.0"
       },
       "funding": {
-        "url": "https://opencollective.com/unts"
+        "url": "https://opencollective.com/synckit"
       }
     },
     "node_modules/synckit/node_modules/tslib": {
diff --git a/package.json b/package.json
index 68ad0aa1..acc99052 100644
--- a/package.json
+++ b/package.json
@@ -45,7 +45,7 @@
     "@capacitor/android": "^6.2.0",
     "@capacitor/app": "^6.0.0",
     "@capacitor/cli": "^6.2.0",
-    "@capacitor/core": "^6.2.0",
+    "@capacitor/core": "^6.2.1",
     "@capacitor/filesystem": "^6.0.3",
     "@capacitor/ios": "^6.2.0",
     "@capacitor/share": "^6.0.3",
diff --git a/src/components/EntityIcon.vue b/src/components/EntityIcon.vue
index 9c3a083a..8c3ad58a 100644
--- a/src/components/EntityIcon.vue
+++ b/src/components/EntityIcon.vue
@@ -7,10 +7,11 @@ import { createAvatar, StyleOptions } from "@dicebear/core";
 import { avataaars } from "@dicebear/collection";
 import { Vue, Component, Prop } from "vue-facing-decorator";
 import { Contact } from "../db/tables/contacts";
+import { logger } from "../utils/logger";
 
 @Component
 export default class EntityIcon extends Vue {
-  @Prop contact: Contact;
+  @Prop({ required: false }) contact?: Contact;
   @Prop entityId = ""; // overridden by contact.did or profileImageUrl
   @Prop iconSize = 0;
   @Prop profileImageUrl = ""; // overridden by contact.profileImageUrl
@@ -22,7 +23,8 @@ export default class EntityIcon extends Vue {
     } else {
       const identifier = this.contact?.did || this.entityId;
       if (!identifier) {
-        return `<img src="../src/assets/blank-square.svg" class="rounded" width="${this.iconSize}" height="${this.iconSize}" />`;
+        const baseUrl = import.meta.env.VITE_BASE_URL || '/';
+        return `<img src="${baseUrl}assets/blank-square.svg" class="rounded" width="${this.iconSize}" height="${this.iconSize}" />`;
       }
       // https://api.dicebear.com/8.x/avataaars/svg?seed=
       // ... does not render things with the same seed as this library.
@@ -37,6 +39,12 @@ export default class EntityIcon extends Vue {
       return svgString;
     }
   }
+
+  mounted() {
+    logger.log('EntityIcon mounted, profileImageUrl:', this.profileImageUrl);
+    logger.log('EntityIcon mounted, entityId:', this.entityId);
+    logger.log('EntityIcon mounted, iconSize:', this.iconSize);
+  }
 }
 </script>
 <style scoped></style>
diff --git a/src/db/index.ts b/src/db/index.ts
index 839094c3..5f9645a5 100644
--- a/src/db/index.ts
+++ b/src/db/index.ts
@@ -1,5 +1,6 @@
 import BaseDexie, { Table } from "dexie";
 import { encrypted, Encryption } from "@pvermeer/dexie-encrypted-addon";
+import { exportDB } from "dexie-export-import";
 import * as R from "ramda";
 
 import { Account, AccountsSchema } from "./tables/accounts";
@@ -26,19 +27,21 @@ type NonsensitiveTables = {
 };
 
 // Using 'unknown' instead of 'any' for stricter typing and to avoid TypeScript warnings
-export type SecretDexie<T extends unknown = SecretTable> = BaseDexie & T;
-export type SensitiveDexie<T extends unknown = SensitiveTables> = BaseDexie & T;
-export type NonsensitiveDexie<T extends unknown = NonsensitiveTables> =
-  BaseDexie & T;
+export type SecretDexie<T extends unknown = SecretTable> = BaseDexie & T & { export: (options?: any) => Promise<Blob> };
+export type SensitiveDexie<T extends unknown = SensitiveTables> = BaseDexie & T & { export: (options?: any) => Promise<Blob> };
+export type NonsensitiveDexie<T extends unknown = NonsensitiveTables> = BaseDexie & T & { export: (options?: any) => Promise<Blob> };
 
 //// Initialize the DBs, starting with the sensitive ones.
 
 // Initialize Dexie database for secret, which is then used to encrypt accountsDB
 export const secretDB = new BaseDexie("TimeSafariSecret") as SecretDexie;
 secretDB.version(1).stores(SecretSchema);
+secretDB.export = (options) => exportDB(secretDB, options);
 
 // Initialize Dexie database for accounts
 const accountsDexie = new BaseDexie("TimeSafariAccounts") as SensitiveDexie;
+accountsDexie.version(1).stores(AccountsSchema);
+accountsDexie.export = (options) => exportDB(accountsDexie, options);
 
 // Instead of accountsDBPromise, use libs/util retrieveAccountMetadata or retrieveFullyDecryptedAccount
 // so that it's clear whether the usage needs the private key inside.
@@ -54,8 +57,15 @@ export const accountsDBPromise = useSecretAndInitializeAccountsDB(
 
 //// Now initialize the other DB.
 
-// Initialize Dexie databases for non-sensitive data
+// Initialize Dexie database for non-sensitive data
 export const db = new BaseDexie("TimeSafari") as NonsensitiveDexie;
+db.version(1).stores({
+  contacts: ContactSchema.contacts,
+  logs: LogSchema.logs,
+  settings: SettingsSchema.settings,
+  temp: TempSchema.temp,
+});
+db.export = (options) => exportDB(db, options);
 
 // Only the tables with index modifications need listing. https://dexie.org/docs/Tutorial/Design#database-versioning
 
diff --git a/src/interfaces/identifier.ts b/src/interfaces/identifier.ts
index 969a7928..7c373227 100644
--- a/src/interfaces/identifier.ts
+++ b/src/interfaces/identifier.ts
@@ -15,8 +15,20 @@ export interface IKey {
   meta?: KeyMeta;
 }
 
+export interface IService {
+  id: string;
+  type: string;
+  serviceEndpoint: string;
+  description?: string;
+  metadata?: {
+    version?: string;
+    capabilities?: string[];
+    config?: Record<string, unknown>;
+  };
+}
+
 export interface IIdentifier {
   did: string;
   keys: IKey[];
-  services: any[];
+  services: IService[];
 }
diff --git a/src/interfaces/service.ts b/src/interfaces/service.ts
new file mode 100644
index 00000000..2059a415
--- /dev/null
+++ b/src/interfaces/service.ts
@@ -0,0 +1,288 @@
+/**
+ * @file service.ts
+ * @description Service interfaces for Decentralized Identifiers (DIDs)
+ *
+ * This module defines the service interfaces used in the TimeSafari application.
+ * Services are associated with DIDs to provide additional functionality and endpoints.
+ *
+ * Architecture:
+ * 1. Base IService interface defines common service properties
+ * 2. Specialized interfaces extend IService for specific service types
+ * 3. Services are stored in IIdentifier.services array
+ * 4. Services are loaded and managed by PlatformServiceFactory
+ *
+ * Service Types:
+ * - EndorserService: Handles claims and endorsements
+ * - PushNotificationService: Manages web push notifications
+ * - ProfileService: Handles user profiles and settings
+ * - BackupService: Manages data backup and restore
+ *
+ * @see IIdentifier
+ * @see PlatformServiceFactory
+ * @see DatabaseBackupService
+ */
+
+/**
+ * Base interface for all DID services
+ *
+ * This interface defines the core properties that all services must implement.
+ * It follows the W3C DID specification for service endpoints.
+ *
+ * @example
+ * const service: IService = {
+ *   id: 'endorser-service',
+ *   type: 'EndorserService',
+ *   serviceEndpoint: 'https://api.endorser.ch',
+ *   description: 'Endorser service for claims and endorsements',
+ *   metadata: {
+ *     version: '1.0.0',
+ *     capabilities: ['claims', 'endorsements'],
+ *     config: { apiServer: 'https://api.endorser.ch' }
+ *   }
+ * };
+ */
+export interface IService {
+  /**
+   * Unique identifier for the service
+   * @example 'endorser-service'
+   * @example 'push-notification-service'
+   */
+  id: string;
+
+  /**
+   * Type of service
+   * @example 'EndorserService'
+   * @example 'PushNotificationService'
+   */
+  type: string;
+
+  /**
+   * Endpoint URL for the service
+   * @example 'https://api.endorser.ch'
+   * @example 'https://push.timesafari.app'
+   */
+  serviceEndpoint: string;
+
+  /**
+   * Optional human-readable description of the service
+   * @example 'Service for handling claims and endorsements'
+   */
+  description?: string;
+
+  /**
+   * Optional metadata for service configuration
+   */
+  metadata?: {
+    /**
+     * Service version in semantic versioning format
+     * @example '1.0.0'
+     */
+    version?: string;
+
+    /**
+     * Array of service capabilities
+     * @example ['claims', 'endorsements']
+     * @example ['notifications', 'alerts']
+     */
+    capabilities?: string[];
+
+    /**
+     * Service-specific configuration
+     * @example { apiServer: 'https://api.endorser.ch' }
+     */
+    config?: Record<string, unknown>;
+  };
+}
+
+/**
+ * Service for handling claims and endorsements
+ *
+ * This service provides endpoints for:
+ * - Submitting claims
+ * - Managing endorsements
+ * - Checking rate limits
+ *
+ * @example
+ * const endorserService: IEndorserService = {
+ *   id: 'endorser-service',
+ *   type: 'EndorserService',
+ *   serviceEndpoint: 'https://api.endorser.ch',
+ *   metadata: {
+ *     version: '1.0.0',
+ *     capabilities: ['claims', 'endorsements'],
+ *     config: {
+ *       apiServer: 'https://api.endorser.ch',
+ *       rateLimits: {
+ *         claimsPerDay: 100,
+ *         endorsementsPerDay: 1000
+ *       }
+ *     }
+ *   }
+ * };
+ */
+export interface IEndorserService extends IService {
+  /** @override */
+  type: "EndorserService";
+
+  /** @override */
+  metadata: {
+    version: string;
+    capabilities: ["claims", "endorsements"];
+    config: {
+      /**
+       * API server URL
+       * @example 'https://api.endorser.ch'
+       */
+      apiServer: string;
+
+      /**
+       * Optional rate limits
+       */
+      rateLimits?: {
+        /**
+         * Maximum claims per day
+         * @default 100
+         */
+        claimsPerDay: number;
+
+        /**
+         * Maximum endorsements per day
+         * @default 1000
+         */
+        endorsementsPerDay: number;
+      };
+    };
+  };
+}
+
+/**
+ * Service for managing web push notifications
+ *
+ * This service provides endpoints for:
+ * - Registering push subscriptions
+ * - Sending push notifications
+ * - Managing notification preferences
+ *
+ * @example
+ * const pushService: IPushNotificationService = {
+ *   id: 'push-service',
+ *   type: 'PushNotificationService',
+ *   serviceEndpoint: 'https://push.timesafari.app',
+ *   metadata: {
+ *     version: '1.0.0',
+ *     capabilities: ['notifications'],
+ *     config: {
+ *       pushServer: 'https://push.timesafari.app',
+ *       vapidPublicKey: '...'
+ *     }
+ *   }
+ * };
+ */
+export interface IPushNotificationService extends IService {
+  /** @override */
+  type: "PushNotificationService";
+
+  /** @override */
+  metadata: {
+    version: string;
+    capabilities: ["notifications"];
+    config: {
+      /**
+       * Push server URL
+       * @example 'https://push.timesafari.app'
+       */
+      pushServer: string;
+
+      /**
+       * Optional VAPID public key for push notifications
+       */
+      vapidPublicKey?: string;
+    };
+  };
+}
+
+/**
+ * Service for managing user profiles and settings
+ *
+ * This service provides endpoints for:
+ * - Managing user profiles
+ * - Updating user settings
+ * - Retrieving user preferences
+ *
+ * @example
+ * const profileService: IProfileService = {
+ *   id: 'profile-service',
+ *   type: 'ProfileService',
+ *   serviceEndpoint: 'https://partner-api.endorser.ch',
+ *   metadata: {
+ *     version: '1.0.0',
+ *     capabilities: ['profile', 'settings'],
+ *     config: {
+ *       partnerApiServer: 'https://partner-api.endorser.ch'
+ *     }
+ *   }
+ * };
+ */
+export interface IProfileService extends IService {
+  /** @override */
+  type: "ProfileService";
+
+  /** @override */
+  metadata: {
+    version: string;
+    capabilities: ["profile", "settings"];
+    config: {
+      /**
+       * Partner API server URL
+       * @example 'https://partner-api.endorser.ch'
+       */
+      partnerApiServer: string;
+    };
+  };
+}
+
+/**
+ * Service for managing data backup and restore operations
+ *
+ * This service provides endpoints for:
+ * - Creating backups
+ * - Restoring from backups
+ * - Managing backup storage
+ *
+ * @example
+ * const backupService: IBackupService = {
+ *   id: 'backup-service',
+ *   type: 'BackupService',
+ *   serviceEndpoint: 'https://backup.timesafari.app',
+ *   metadata: {
+ *     version: '1.0.0',
+ *     capabilities: ['backup', 'restore'],
+ *     config: {
+ *       storageType: 'cloud',
+ *       encryptionKey: '...'
+ *     }
+ *   }
+ * };
+ */
+export interface IBackupService extends IService {
+  /** @override */
+  type: "BackupService";
+
+  /** @override */
+  metadata: {
+    version: string;
+    capabilities: ["backup", "restore"];
+    config: {
+      /**
+       * Storage type for backups
+       * @default 'local'
+       */
+      storageType: "local" | "cloud";
+
+      /**
+       * Optional encryption key for backups
+       */
+      encryptionKey?: string;
+    };
+  };
+}
diff --git a/src/platforms/capacitor/DatabaseBackupService.ts b/src/platforms/capacitor/DatabaseBackupService.ts
new file mode 100644
index 00000000..09326a75
--- /dev/null
+++ b/src/platforms/capacitor/DatabaseBackupService.ts
@@ -0,0 +1,69 @@
+/**
+ * @file DatabaseBackupService.ts
+ * @description Capacitor-specific implementation of DatabaseBackupService
+ *
+ * This implementation handles database backup operations specifically for Capacitor
+ * platforms (Android/iOS). It uses the Filesystem and Share plugins to save and
+ * share the backup file.
+ */
+
+import { DatabaseBackupService as BaseDatabaseBackupService } from "../../services/DatabaseBackupService";
+import { Filesystem, Directory } from "@capacitor/filesystem";
+import { Share } from "@capacitor/share";
+import { log, error } from "../../utils/logger";
+
+export class DatabaseBackupService extends BaseDatabaseBackupService {
+  /**
+   * Handles the backup process for Capacitor platforms
+   * 
+   * @param base64Data - Backup data in base64 format
+   * @param arrayBuffer - Backup data as ArrayBuffer
+   * @param blob - Backup data as Blob
+   */
+  protected async handleBackup(
+    base64Data: string,
+    arrayBuffer: ArrayBuffer,
+    blob: Blob
+  ): Promise<void> {
+    try {
+      log("Starting Capacitor backup process");
+      
+      // Create a temporary file
+      const fileName = `timesafari-backup-${new Date().toISOString()}.json`;
+      const filePath = `backups/${fileName}`;
+      
+      log("Writing backup file");
+      const result = await Filesystem.writeFile({
+        path: filePath,
+        data: base64Data,
+        directory: Directory.Cache,
+        recursive: true
+      });
+      
+      log("Getting file path");
+      const fileInfo = await Filesystem.stat({
+        path: filePath,
+        directory: Directory.Cache
+      });
+      
+      log("Sharing backup file");
+      await Share.share({
+        title: "TimeSafari Backup",
+        text: "Your TimeSafari backup file",
+        url: fileInfo.uri,
+        dialogTitle: "Share TimeSafari Backup"
+      });
+      
+      log("Backup shared successfully");
+
+      // Clean up the temporary file
+      await Filesystem.deleteFile({
+        path: filePath,
+        directory: Directory.Cache
+      });
+    } catch (err) {
+      error("Error during Capacitor backup:", err);
+      throw err;
+    }
+  }
+} 
\ No newline at end of file
diff --git a/src/services/DatabaseBackupService.ts b/src/services/DatabaseBackupService.ts
index 9f92a8b7..e0867d89 100644
--- a/src/services/DatabaseBackupService.ts
+++ b/src/services/DatabaseBackupService.ts
@@ -1,26 +1,95 @@
 /**
  * @file DatabaseBackupService.ts
  * @description Base service class for handling database backup operations
- * @author Matthew Raymer
- * @version 1.0.0
+ *
+ * This service implements the Template Method pattern to provide a common interface
+ * for database backup operations across different platforms. It defines the structure
+ * of backup operations while delegating platform-specific implementations to subclasses.
+ *
+ * Build Process Integration:
+ * 1. Platform-Specific Implementation:
+ *    - Each platform (web, electron, capacitor) has its own implementation
+ *    - Implementations are loaded dynamically via PlatformServiceFactory
+ *    - Located in ./platforms/{platform}/DatabaseBackupService.ts
+ *
+ * 2. Build Configuration:
+ *    - Vite config files (vite.config.*.mts) set VITE_PLATFORM
+ *    - PlatformServiceFactory uses this to load correct implementation
+ *    - Build process creates separate chunks for each platform
+ *
+ * 3. Data Handling:
+ *    - Supports multiple data formats (base64, ArrayBuffer, Blob)
+ *    - Platform implementations handle format conversion
+ *    - Ensures consistent backup format across platforms
+ *
+ * Usage:
+ * - Create backup: DatabaseBackupService.createAndShareBackup(data)
+ * - Platform-specific: new WebDatabaseBackupService().handleBackup()
+ *
+ * @see PlatformServiceFactory.ts
+ * @see vite.config.web.mts
+ * @see vite.config.electron.mts
+ * @see vite.config.capacitor.mts
  */
 
 import { PlatformServiceFactory } from "./PlatformServiceFactory";
+import { log, error } from "../utils/logger";
 
 export class DatabaseBackupService {
-  protected async handleBackup(): Promise<void> {
+  /**
+   * Template method that must be implemented by platform-specific services
+   * @param base64Data - Backup data in base64 format
+   * @param arrayBuffer - Backup data as ArrayBuffer
+   * @param blob - Backup data as Blob
+   * @throws Error if not implemented by subclass
+   */
+  protected async handleBackup(
+    _base64Data: string,
+    _arrayBuffer: ArrayBuffer,
+    _blob: Blob,
+  ): Promise<void> {
     throw new Error(
       "handleBackup must be implemented by platform-specific service",
     );
   }
 
+  /**
+   * Factory method to create and share a backup
+   * Uses PlatformServiceFactory to get platform-specific implementation
+   *
+   * @param base64Data - Backup data in base64 format
+   * @param arrayBuffer - Backup data as ArrayBuffer
+   * @param blob - Backup data as Blob
+   * @returns Promise that resolves when backup is complete
+   */
   public static async createAndShareBackup(
     base64Data: string,
     arrayBuffer: ArrayBuffer,
-    blob: Blob,
+    blob: Blob
   ): Promise<void> {
+    try {
+      log('Creating platform-specific backup service');
+      const backupService = await this.getPlatformSpecificBackupService();
+      log('Backup service created successfully');
+
+      log('Executing platform-specific backup');
+      await backupService.handleBackup(base64Data, arrayBuffer, blob);
+      log('Backup completed successfully');
+    } catch (err) {
+      error('Error during backup creation:', err);
+      if (err instanceof Error) {
+        error('Error details:', {
+          name: err.name,
+          message: err.message,
+          stack: err.stack
+        });
+      }
+      throw err;
+    }
+  }
+
+  private static async getPlatformSpecificBackupService(): Promise<DatabaseBackupService> {
     const factory = PlatformServiceFactory.getInstance();
-    const service = await factory.createDatabaseBackupService();
-    await service.handleBackup(base64Data, arrayBuffer, blob);
+    return await factory.createDatabaseBackupService();
   }
 }
diff --git a/src/services/PlatformServiceFactory.ts b/src/services/PlatformServiceFactory.ts
index 9c0c1646..e537e1fd 100644
--- a/src/services/PlatformServiceFactory.ts
+++ b/src/services/PlatformServiceFactory.ts
@@ -1,20 +1,102 @@
 /**
  * @file PlatformServiceFactory.ts
  * @description Factory for creating platform-specific service implementations
- * @author Matthew Raymer
- * @version 1.0.0
+ *
+ * This factory implements the Abstract Factory pattern to create platform-specific
+ * implementations of services. It uses Vite's dynamic import feature to load the
+ * appropriate implementation based on the current platform (web, electron, etc.).
+ *
+ * Architecture:
+ * 1. Singleton Pattern:
+ *    - Ensures only one factory instance exists
+ *    - Manages platform-specific service instances
+ *    - Maintains consistent state across the application
+ *
+ * 2. Dynamic Loading:
+ *    - Uses Vite's dynamic import for platform-specific code
+ *    - Loads services on-demand based on platform
+ *    - Handles platform detection and service instantiation
+ *
+ * 3. Platform Detection:
+ *    - Uses VITE_PLATFORM environment variable
+ *    - Supports web, electron, and capacitor platforms
+ *    - Falls back to 'web' if platform is not specified
+ *
+ * Usage:
+ * ```typescript
+ * // Get factory instance
+ * const factory = PlatformServiceFactory.getInstance();
+ *
+ * // Create platform-specific service
+ * const backupService = await factory.createDatabaseBackupService();
+ * ```
+ *
+ * @see vite.config.web.mts
+ * @see vite.config.electron.mts
+ * @see vite.config.capacitor.mts
+ * @see DatabaseBackupService
  */
 
 import { DatabaseBackupService } from "./DatabaseBackupService";
+import { logger } from "../utils/logger";
 
+/**
+ * Factory class for creating platform-specific service implementations
+ *
+ * This class manages the creation and instantiation of platform-specific
+ * service implementations. It uses the Abstract Factory pattern to provide
+ * a consistent interface for creating services across different platforms.
+ *
+ * @example
+ * ```typescript
+ * // Get factory instance
+ * const factory = PlatformServiceFactory.getInstance();
+ *
+ * // Create platform-specific service
+ * const backupService = await factory.createDatabaseBackupService();
+ *
+ * // Use the service
+ * await backupService.handleBackup(data);
+ * ```
+ */
 export class PlatformServiceFactory {
+  /**
+   * Singleton instance of the factory
+   * @private
+   */
   private static instance: PlatformServiceFactory;
+
+  /**
+   * Current platform identifier
+   * @private
+   */
   private platform: string;
 
+  /**
+   * Private constructor to enforce singleton pattern
+   *
+   * Initializes the factory with the current platform from environment variables.
+   * Falls back to 'web' if no platform is specified.
+   *
+   * @private
+   */
   private constructor() {
     this.platform = import.meta.env.VITE_PLATFORM || "web";
   }
 
+  /**
+   * Gets the singleton instance of the factory
+   *
+   * Creates a new instance if one doesn't exist, otherwise returns
+   * the existing instance.
+   *
+   * @returns {PlatformServiceFactory} The singleton factory instance
+   *
+   * @example
+   * ```typescript
+   * const factory = PlatformServiceFactory.getInstance();
+   * ```
+   */
   public static getInstance(): PlatformServiceFactory {
     if (!PlatformServiceFactory.instance) {
       PlatformServiceFactory.instance = new PlatformServiceFactory();
@@ -22,19 +104,75 @@ export class PlatformServiceFactory {
     return PlatformServiceFactory.instance;
   }
 
+  /**
+   * Creates a platform-specific database backup service
+   *
+   * Dynamically loads and instantiates the appropriate implementation
+   * based on the current platform. The implementation is loaded from
+   * the platforms/{platform}/DatabaseBackupService.js file.
+   *
+   * @returns {Promise<DatabaseBackupService>} A promise that resolves to a platform-specific backup service
+   * @throws {Error} If the service fails to load or instantiate
+   *
+   * @example
+   * ```typescript
+   * const factory = PlatformServiceFactory.getInstance();
+   * try {
+   *   const backupService = await factory.createDatabaseBackupService();
+   *   await backupService.handleBackup(data);
+   * } catch (error) {
+   *   logger.error('Failed to create backup service:', error);
+   * }
+   * ```
+   */
   public async createDatabaseBackupService(): Promise<DatabaseBackupService> {
     try {
-      // Use Vite's dynamic import for platform-specific implementation
-      const { default: PlatformService } = await import(
-        `./platforms/${this.platform}/DatabaseBackupService`
+      logger.log(`Loading platform-specific service for ${this.platform}`);
+      // Update the import path to point to the correct location
+      const { DatabaseBackupService: PlatformService } = await import(
+        `../platforms/${this.platform}/DatabaseBackupService`
       );
+      logger.log('Platform service loaded successfully');
       return new PlatformService();
     } catch (error) {
-      console.error(
+      logger.error(
         `Failed to load platform-specific service for ${this.platform}:`,
         error,
       );
       throw error;
     }
   }
+
+  /**
+   * Gets the current platform identifier
+   *
+   * @returns {string} The current platform identifier
+   *
+   * @example
+   * ```typescript
+   * const factory = PlatformServiceFactory.getInstance();
+   * logger.log(factory.getPlatform()); // 'web', 'electron', or 'capacitor'
+   * ```
+   */
+  public getPlatform(): string {
+    return this.platform;
+  }
+
+  /**
+   * Sets the current platform identifier
+   *
+   * This method is primarily used for testing purposes to override
+   * the platform detection. Use with caution in production code.
+   *
+   * @param {string} platform - The platform identifier to set
+   *
+   * @example
+   * ```typescript
+   * const factory = PlatformServiceFactory.getInstance();
+   * factory.setPlatform('electron'); // For testing purposes only
+   * ```
+   */
+  public setPlatform(platform: string): void {
+    this.platform = platform;
+  }
 }
diff --git a/src/services/RateLimitsService.ts b/src/services/RateLimitsService.ts
index 1ac5f1b7..6a95c156 100644
--- a/src/services/RateLimitsService.ts
+++ b/src/services/RateLimitsService.ts
@@ -8,32 +8,40 @@
 import { logger } from "../utils/logger";
 import { getHeaders } from "../libs/endorserServer";
 import type { EndorserRateLimits, ImageRateLimits } from "../interfaces/limits";
+import axios from "axios";
 
 export class RateLimitsService {
   /**
    * Fetches rate limits for a given DID
    * @param apiServer - The API server URL
-   * @param activeDid - The user's active DID
+   * @param did - The user's DID
    * @returns Promise<EndorserRateLimits>
    */
-  static async fetchRateLimits(
-    apiServer: string,
-    activeDid: string,
-  ): Promise<EndorserRateLimits> {
+  static async fetchRateLimits(apiServer: string, did: string): Promise<EndorserRateLimits> {
+    logger.log('Fetching rate limits for DID:', did);
+    logger.log('Using API server:', apiServer);
+    
     try {
-      const headers = await getHeaders(activeDid);
-      const response = await fetch(
-        `${apiServer}/api/endorser/rateLimits/${activeDid}`,
-        { headers },
-      );
-
-      if (!response.ok) {
-        throw new Error(`Failed to fetch rate limits: ${response.statusText}`);
-      }
-
-      return await response.json();
+      const headers = await getHeaders(did);
+      const response = await axios.get(`${apiServer}/api/v2/rate-limits/${did}`, { headers });
+      logger.log('Rate limits response:', response.data);
+      return response.data;
     } catch (error) {
-      logger.error("Error fetching rate limits:", error);
+      if (axios.isAxiosError(error) && (error.response?.status === 400 || error.response?.status === 404)) {
+        const errorData = error.response.data as { error?: { message?: string, code?: string } };
+        if (errorData.error?.code === 'UNREGISTERED_USER' || error.response?.status === 404) {
+          logger.log('User is not registered, returning default limits');
+          return {
+            doneClaimsThisWeek: "0",
+            maxClaimsPerWeek: "0",
+            nextWeekBeginDateTime: new Date().toISOString(),
+            doneRegistrationsThisMonth: "0",
+            maxRegistrationsPerMonth: "0",
+            nextMonthBeginDateTime: new Date().toISOString()
+          };
+        }
+      }
+      logger.error('Error fetching rate limits:', error);
       throw error;
     }
   }
diff --git a/src/services/platforms/mobile/DatabaseBackupService.ts b/src/services/platforms/mobile/DatabaseBackupService.ts
index 6f962ee0..b18d136c 100644
--- a/src/services/platforms/mobile/DatabaseBackupService.ts
+++ b/src/services/platforms/mobile/DatabaseBackupService.ts
@@ -10,7 +10,11 @@ import { Filesystem } from "@capacitor/filesystem";
 import { Share } from "@capacitor/share";
 
 export default class MobileDatabaseBackupService extends DatabaseBackupService {
-  protected async handleBackup(base64Data: string): Promise<void> {
+  protected async handleBackup(
+    base64Data: string,
+    _arrayBuffer: ArrayBuffer,
+    _blob: Blob,
+  ): Promise<void> {
     // Mobile platform handling
     const fileName = `database-backup-${new Date().toISOString()}.json`;
     const path = `backups/${fileName}`;
diff --git a/src/services/platforms/web/DatabaseBackupService.ts b/src/services/platforms/web/DatabaseBackupService.ts
index f0f41942..4da346dd 100644
--- a/src/services/platforms/web/DatabaseBackupService.ts
+++ b/src/services/platforms/web/DatabaseBackupService.ts
@@ -6,17 +6,28 @@
  */
 
 import { DatabaseBackupService } from "../../DatabaseBackupService";
+import { log, error } from "../../../utils/logger";
 
 export default class WebDatabaseBackupService extends DatabaseBackupService {
-  protected async handleBackup(blob: Blob): Promise<void> {
-    // Web platform handling
-    const url = URL.createObjectURL(blob);
-    const a = document.createElement("a");
-    a.href = url;
-    a.download = `database-backup-${new Date().toISOString()}.json`;
-    document.body.appendChild(a);
-    a.click();
-    document.body.removeChild(a);
-    URL.revokeObjectURL(url);
+  protected async handleBackup(
+    _base64Data: string,
+    _arrayBuffer: ArrayBuffer,
+    blob: Blob
+  ): Promise<void> {
+    try {
+      log('Starting web platform backup');
+      const url = URL.createObjectURL(blob);
+      const a = document.createElement("a");
+      a.href = url;
+      a.download = `database-backup-${new Date().toISOString()}.json`;
+      document.body.appendChild(a);
+      a.click();
+      document.body.removeChild(a);
+      URL.revokeObjectURL(url);
+      log('Web platform backup completed');
+    } catch (err) {
+      error('Error during web platform backup:', err);
+      throw err;
+    }
   }
 }
diff --git a/src/types/interfaces.ts b/src/types/interfaces.ts
index c751e7d8..950d65d8 100644
--- a/src/types/interfaces.ts
+++ b/src/types/interfaces.ts
@@ -1,28 +1,286 @@
 /**
- * Type declarations for custom interfaces used in the application.
- * @author Matthew Raymer
+ * @file interfaces.ts
+ * @description Core type declarations for the TimeSafari application
+ * 
+ * This module defines the core interfaces and types used throughout the application.
+ * It serves as the central location for type definitions that are shared across
+ * multiple components and services.
+ * 
+ * Architecture:
+ * 1. DID (Decentralized Identifier) Types:
+ *    - IIdentifier: Core DID structure
+ *    - IKey: Cryptographic key information
+ *    - IService: Service endpoints and capabilities
+ * 
+ * 2. Verifiable Credential Types:
+ *    - GenericCredWrapper: Base wrapper for all credentials
+ *    - GiveVerifiableCredential: Gift-related credentials
+ *    - OfferVerifiableCredential: Offer-related credentials
+ *    - RegisterVerifiableCredential: Registration credentials
+ * 
+ * 3. Service Types:
+ *    - EndorserService: Claims and endorsements
+ *    - PushNotificationService: Web push notifications
+ *    - ProfileService: User profiles
+ *    - BackupService: Data backup
+ * 
+ * @see src/interfaces/identifier.ts
+ * @see src/interfaces/claims.ts
+ * @see src/interfaces/limits.ts
  */
 
 import { GiveVerifiableCredential } from "../interfaces";
 
+/**
+ * Interface for a Decentralized Identifier (DID)
+ * 
+ * This interface defines the structure of a DID, which is a unique identifier
+ * that can be used to look up a DID document containing information associated
+ * with the DID, such as public keys and service endpoints.
+ * 
+ * @example
+ * ```typescript
+ * const identifier: IIdentifier = {
+ *   did: 'did:ethr:0x123...',
+ *   provider: 'ethr',
+ *   keys: [{
+ *     kid: 'keys-1',
+ *     kms: 'local',
+ *     type: 'Secp256k1',
+ *     publicKeyHex: '0x...',
+ *     meta: { derivationPath: "m/44'/60'/0'/0/0" }
+ *   }],
+ *   services: [{
+ *     id: 'endorser-service',
+ *     type: 'EndorserService',
+ *     serviceEndpoint: 'https://api.endorser.ch'
+ *   }]
+ * };
+ * ```
+ */
 export interface IIdentifier {
+  /**
+   * The DID string in the format 'did:method:identifier'
+   * @example 'did:ethr:0x123...'
+   */
   did: string;
+
+  /**
+   * The DID method provider
+   * @example 'ethr'
+   */
   provider: string;
+
+  /**
+   * Array of cryptographic keys associated with the DID
+   */
   keys: Array<{
+    /**
+     * Key identifier
+     * @example 'keys-1'
+     */
     kid: string;
+
+    /**
+     * Key management system
+     * @example 'local'
+     */
     kms: string;
+
+    /**
+     * Key type
+     * @example 'Secp256k1'
+     */
     type: string;
+
+    /**
+     * Public key in hexadecimal format
+     * @example '0x...'
+     */
     publicKeyHex: string;
+
+    /**
+     * Optional metadata about the key
+     */
     meta?: any;
   }>;
+
+  /**
+   * Array of service endpoints associated with the DID
+   */
   services: Array<{
+    /**
+     * Service identifier
+     * @example 'endorser-service'
+     */
     id: string;
+
+    /**
+     * Service type
+     * @example 'EndorserService'
+     */
     type: string;
+
+    /**
+     * Service endpoint URL
+     * @example 'https://api.endorser.ch'
+     */
     serviceEndpoint: string;
+
+    /**
+     * Optional service description
+     */
     description?: string;
   }>;
 }
 
+/**
+ * Interface for a cryptographic key
+ * 
+ * This interface defines the structure of a cryptographic key used in the
+ * DID system. It includes both public and private key information, along
+ * with metadata about the key's purpose and derivation.
+ * 
+ * @example
+ * ```typescript
+ * const key: IKey = {
+ *   id: 'did:ethr:0x123...#keys-1',
+ *   type: 'Secp256k1VerificationKey2018',
+ *   controller: 'did:ethr:0x123...',
+ *   ethereumAddress: '0x123...',
+ *   publicKeyHex: '0x...',
+ *   privateKeyHex: '0x...',
+ *   meta: {
+ *     derivationPath: "m/44'/60'/0'/0/0"
+ *   }
+ * };
+ * ```
+ */
+export interface IKey {
+  /**
+   * Unique identifier for the key
+   * @example 'did:ethr:0x123...#keys-1'
+   */
+  id: string;
+
+  /**
+   * Key type specification
+   * @example 'Secp256k1VerificationKey2018'
+   */
+  type: string;
+
+  /**
+   * DID that controls this key
+   * @example 'did:ethr:0x123...'
+   */
+  controller: string;
+
+  /**
+   * Associated Ethereum address
+   * @example '0x123...'
+   */
+  ethereumAddress: string;
+
+  /**
+   * Public key in hexadecimal format
+   * @example '0x...'
+   */
+  publicKeyHex: string;
+
+  /**
+   * Private key in hexadecimal format
+   * @example '0x...'
+   */
+  privateKeyHex: string;
+
+  /**
+   * Optional metadata about the key
+   */
+  meta?: {
+    /**
+     * HD wallet derivation path
+     * @example "m/44'/60'/0'/0/0"
+     */
+    derivationPath?: string;
+
+    /**
+     * Additional key metadata
+     */
+    [key: string]: unknown;
+  };
+}
+
+/**
+ * Interface for a service endpoint
+ * 
+ * This interface defines the structure of a service endpoint that can be
+ * associated with a DID. Services provide additional functionality and
+ * endpoints for DID operations.
+ * 
+ * @example
+ * ```typescript
+ * const service: IService = {
+ *   id: 'endorser-service',
+ *   type: 'EndorserService',
+ *   serviceEndpoint: 'https://api.endorser.ch',
+ *   description: 'Service for handling claims and endorsements',
+ *   metadata: {
+ *     version: '1.0.0',
+ *     capabilities: ['claims', 'endorsements'],
+ *     config: {
+ *       apiServer: 'https://api.endorser.ch'
+ *     }
+ *   }
+ * };
+ * ```
+ */
+export interface IService {
+  /**
+   * Unique identifier for the service
+   * @example 'endorser-service'
+   */
+  id: string;
+
+  /**
+   * Type of service
+   * @example 'EndorserService'
+   */
+  type: string;
+
+  /**
+   * Service endpoint URL
+   * @example 'https://api.endorser.ch'
+   */
+  serviceEndpoint: string;
+
+  /**
+   * Optional human-readable description
+   */
+  description?: string;
+
+  /**
+   * Optional service metadata
+   */
+  metadata?: {
+    /**
+     * Service version
+     * @example '1.0.0'
+     */
+    version?: string;
+
+    /**
+     * Array of service capabilities
+     * @example ['claims', 'endorsements']
+     */
+    capabilities?: string[];
+
+    /**
+     * Service-specific configuration
+     */
+    config?: Record<string, unknown>;
+  };
+}
+
 export interface ExportProgress {
   status: "preparing" | "exporting" | "complete" | "error";
   message?: string;
diff --git a/src/utils/logger.ts b/src/utils/logger.ts
index fcf0847a..f081b055 100644
--- a/src/utils/logger.ts
+++ b/src/utils/logger.ts
@@ -19,28 +19,55 @@ function safeStringify(obj: unknown) {
   });
 }
 
+function formatMessage(message: string, ...args: unknown[]): string {
+  const prefix = '[TimeSafari]';
+  const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
+  return `${prefix} ${message}${argsString}`;
+}
+
 export const logger = {
   log: (message: string, ...args: unknown[]) => {
     if (process.env.NODE_ENV !== "production") {
-      // eslint-disable-next-line no-console
-      console.log(message, ...args);
-      const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
-      logToDb(message + argsString);
+      const formattedMessage = formatMessage(message, ...args);
+      console.log(formattedMessage);
+      logToDb(message + (args.length > 0 ? " - " + safeStringify(args) : ""));
     }
   },
   warn: (message: string, ...args: unknown[]) => {
     if (process.env.NODE_ENV !== "production") {
-      // eslint-disable-next-line no-console
-      console.warn(message, ...args);
-      const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
-      logToDb(message + argsString);
+      const formattedMessage = formatMessage(message, ...args);
+      console.warn(formattedMessage);
+      logToDb(message + (args.length > 0 ? " - " + safeStringify(args) : ""));
     }
   },
   error: (message: string, ...args: unknown[]) => {
-    // Errors will always be logged
-    // eslint-disable-next-line no-console
-    console.error(message, ...args);
-    const argsString = args.length > 0 ? " - " + safeStringify(args) : "";
-    logToDb(message + argsString);
+    const formattedMessage = formatMessage(message, ...args);
+    console.error(formattedMessage);
+    logToDb(message + (args.length > 0 ? " - " + safeStringify(args) : ""));
   },
 };
+
+export function log(...args: any[]) {
+  const message = formatMessage(args[0], ...args.slice(1));
+  console.log(message);
+}
+
+export function error(...args: any[]) {
+  const message = formatMessage(args[0], ...args.slice(1));
+  console.error(message);
+}
+
+export function warn(...args: any[]) {
+  const message = formatMessage(args[0], ...args.slice(1));
+  console.warn(message);
+}
+
+export function info(...args: any[]) {
+  const message = formatMessage(args[0], ...args.slice(1));
+  console.info(message);
+}
+
+export function debug(...args: any[]) {
+  const message = formatMessage(args[0], ...args.slice(1));
+  console.debug(message);
+}
diff --git a/src/views/AccountViewView.vue b/src/views/AccountViewView.vue
index 072cf6ce..2b21010d 100644
--- a/src/views/AccountViewView.vue
+++ b/src/views/AccountViewView.vue
@@ -836,7 +836,7 @@ import "leaflet/dist/leaflet.css";
 import { AxiosError } from "axios";
 import { Buffer } from "buffer/";
 import Dexie from "dexie";
-import "dexie-export-import";
+import { exportDB } from "dexie-export-import";
 import * as R from "ramda";
 import type { IIdentifier, UserProfile } from "@/types/interfaces";
 import { ref } from "vue";
@@ -889,6 +889,7 @@ import { DatabaseBackupService } from "../services/DatabaseBackupService";
 import { ProfileService } from "../services/ProfileService";
 import { RateLimitsService } from "../services/RateLimitsService";
 import ProfileSection from "../components/ProfileSection.vue";
+import { log, error } from '../utils/logger';
 
 const inputImportFileNameRef = ref<Blob>();
 
@@ -943,6 +944,8 @@ export default class AccountViewView extends Vue {
   DEFAULT_IMAGE_API_SERVER = DEFAULT_IMAGE_API_SERVER;
   DEFAULT_PARTNER_API_SERVER = DEFAULT_PARTNER_API_SERVER;
 
+  private db = db;
+
   activeDid = "";
   apiServer = "";
   apiServerInput = "";
@@ -1400,42 +1403,52 @@ export default class AccountViewView extends Vue {
    */
   async exportDatabase() {
     try {
-      // Generate database blob
-      const blob = await (Dexie as any).export(db, {
-        prettyJson: true,
+      logger.log("Starting database export process");
+      
+      const db = await this.getDatabase();
+      logger.log("Database instance:", {
+        name: db.name,
+        version: db.verno,
+        tables: db.tables.map((t: { name: string }) => t.name)
       });
 
-      // Convert blob to base64 for mobile platforms
-      const arrayBuffer = await blob.arrayBuffer();
-      const base64Data = Buffer.from(arrayBuffer).toString("base64");
+      if (!db.export) {
+        logger.error("Database export method not available");
+        return;
+      }
 
-      await DatabaseBackupService.createAndShareBackup(
-        base64Data,
-        arrayBuffer,
-        blob,
-      );
+      logger.log("Creating export blob");
+      const blob = await db.export();
+      logger.log("Blob created:", {
+        type: blob.type,
+        size: blob.size
+      });
 
-      this.$notify(
-        {
-          group: "alert",
-          type: "success",
-          title: "Export Complete",
-          text: "Your database has been exported successfully.",
-        },
-        5000,
-      );
-    } catch (error: unknown) {
-      if (error instanceof Error) {
-        const errorMessage = error.message;
-        this.limitsMessage = errorMessage || "Bad server response.";
-        logger.error("Got bad response retrieving limits:", error);
-      } else {
-        this.limitsMessage = "Got an error retrieving limits.";
-        logger.error("Got some error retrieving limits:", error);
-      }
+      logger.log("Converting blob to base64");
+      const base64Data = await new Promise<string>((resolve, reject) => {
+        const reader = new FileReader();
+        reader.onload = () => resolve(reader.result as string);
+        reader.onerror = reject;
+        reader.readAsDataURL(blob);
+      });
+      logger.log("Base64 data length:", base64Data.length);
+
+      logger.log("Converting blob to ArrayBuffer");
+      const arrayBuffer = await blob.arrayBuffer();
+      logger.log("ArrayBuffer size:", arrayBuffer.byteLength);
+
+      logger.log("Creating and sharing backup");
+      await this.createAndShareBackup(base64Data, arrayBuffer, blob);
+      logger.log("Backup creation and sharing completed");
+    } catch (error) {
+      logger.error("Error during database export:", error);
     }
   }
 
+  async createAndShareBackup(base64Data: string, arrayBuffer: ArrayBuffer, blob: Blob) {
+    await DatabaseBackupService.createAndShareBackup(base64Data, arrayBuffer, blob);
+  }
+
   async uploadImportFile(event: Event) {
     const target = event.target as HTMLInputElement;
     if (target.files) {
@@ -1942,5 +1955,9 @@ export default class AccountViewView extends Vue {
     this.userProfileLongitude = updatedProfile.location?.lng || 0;
     this.includeUserProfileLocation = !!updatedProfile.location;
   }
+
+  async getDatabase() {
+    return await db;
+  }
 }
 </script>
diff --git a/src/views/ContactGiftingView.vue b/src/views/ContactGiftingView.vue
index aa48f796..4c111d4f 100644
--- a/src/views/ContactGiftingView.vue
+++ b/src/views/ContactGiftingView.vue
@@ -21,7 +21,7 @@
         <h2 class="text-base flex gap-4 items-center">
           <span class="grow">
             <img
-              src="../assets/blank-square.svg"
+              src="@/assets/blank-square.svg"
               width="32"
               class="inline-block align-middle border border-slate-300 rounded-md mr-1"
             />
diff --git a/src/views/HelpView.vue b/src/views/HelpView.vue
index fe4d9555..0ce0c1e3 100644
--- a/src/views/HelpView.vue
+++ b/src/views/HelpView.vue
@@ -484,13 +484,13 @@
         <a href="http://creativecommons.org/publicdomain/zero/1.0?ref=chooser-v1" target="_blank" rel="license noopener noreferrer">
           <span class="text-blue-500 mr-1">CC0 1.0</span>
           <img
-              src="../assets/help/creative-commons-circle.svg"
+              src="@/assets/help/creative-commons-circle.svg"
               alt="CC circle"
               width="20"
               class="display: inline"
           />
           <img
-              src="../assets/help/creative-commons-zero.svg"
+              src="@/assets/help/creative-commons-zero.svg"
               alt="CC zero"
               width="20"
               style="display: inline"
diff --git a/src/views/HomeView.vue b/src/views/HomeView.vue
index a685b0e1..9dd159b1 100644
--- a/src/views/HomeView.vue
+++ b/src/views/HomeView.vue
@@ -135,7 +135,7 @@ Raymer * @version 1.0.0 */
             >
               <li @click="openDialog()">
                 <img
-                  src="../assets/blank-square.svg"
+                  src="@/assets/blank-square.svg"
                   class="mx-auto border border-blue-500 rounded-md mb-1 cursor-pointer"
                 />
                 <h3
diff --git a/src/views/ProjectViewView.vue b/src/views/ProjectViewView.vue
index 2cad3d86..fe0b078e 100644
--- a/src/views/ProjectViewView.vue
+++ b/src/views/ProjectViewView.vue
@@ -220,7 +220,7 @@
         </li>
         <li @click="openGiftDialogToProject()">
           <img
-            src="../assets/blank-square.svg"
+            src="@/assets/blank-square.svg"
             class="mx-auto border border-blue-300 rounded-md mb-1 cursor-pointer"
           />
           <h3
diff --git a/vite.config.common.mts b/vite.config.common.mts
index 1e288f5f..82ae373b 100644
--- a/vite.config.common.mts
+++ b/vite.config.common.mts
@@ -36,7 +36,15 @@ export async function createBuildConfig(mode: string) {
       assetsDir: 'assets',
       chunkSizeWarningLimit: 1000,
       rollupOptions: {
-        external: isCapacitor ? ['@capacitor/app'] : []
+        external: isCapacitor ? ['@capacitor/app'] : [],
+        output: {
+          assetFileNames: (assetInfo) => {
+            if (assetInfo.name?.endsWith('.svg')) {
+              return 'assets/[name][extname]';
+            }
+            return 'assets/[name]-[hash][extname]';
+          }
+        }
       }
     },
     define: {
@@ -44,6 +52,8 @@ export async function createBuildConfig(mode: string) {
       'process.env.VITE_PLATFORM': JSON.stringify(mode),
       'process.env.VITE_PWA_ENABLED': JSON.stringify(!(isElectron || isPyWebView || isCapacitor)),
       __dirname: isElectron ? JSON.stringify(process.cwd()) : '""',
+      'process.env.VITE_ASSET_URL': JSON.stringify(isCapacitor ? './assets/' : '/assets/'),
+      'process.env.VITE_BASE_URL': JSON.stringify(isCapacitor ? './' : '/')
     },
     resolve: {
       alias: {
diff --git a/vite.config.web.mts b/vite.config.web.mts
index d27befaa..d69a7384 100644
--- a/vite.config.web.mts
+++ b/vite.config.web.mts
@@ -1,20 +1,92 @@
-import { defineConfig, mergeConfig } from "vite";
+/**
+ * @file vite.config.web.mts
+ * @description Vite configuration for web platform builds
+ * 
+ * This configuration file defines how the application is built for web platforms.
+ * It extends the base configuration with web-specific settings and optimizations.
+ * 
+ * Build Process Integration:
+ * 1. Configuration Loading:
+ *    - Loads environment variables based on build mode
+ *    - Merges base configuration from vite.config.common.mts
+ *    - Loads application-specific configuration
+ * 
+ * 2. Platform Definition:
+ *    - Sets VITE_PLATFORM environment variable to 'web'
+ *    - Used by PlatformServiceFactory to load web-specific implementations
+ * 
+ * 3. Build Output:
+ *    - Outputs to 'dist/web' directory
+ *    - Creates vendor chunk for Vue-related dependencies
+ *    - Enables PWA features with auto-update capability
+ * 
+ * 4. Development vs Production:
+ *    - Development: Enables source maps and development features
+ *    - Production: Optimizes chunks and enables PWA features
+ * 
+ * Usage:
+ * - Development: npm run dev
+ * - Production: npm run build:web
+ * 
+ * @see vite.config.common.mts
+ * @see vite.config.utils.mts
+ * @see PlatformServiceFactory.ts
+ */
+
+import { defineConfig, mergeConfig, loadEnv } from "vite";
 import { VitePWA } from "vite-plugin-pwa";
 import { createBuildConfig } from "./vite.config.common.mts";
 import { loadAppConfig } from "./vite.config.utils.mts";
 
-export default defineConfig(async () => {
+export default defineConfig(async ({ mode }) => {
+  // Load environment variables based on build mode
+  const env = loadEnv(mode, process.cwd(), '');
+  
+  // Load base configuration for web platform
   const baseConfig = await createBuildConfig('web');
+  
+  // Load application-specific configuration
   const appConfig = await loadAppConfig();
 
+  // Merge configurations with web-specific settings
   return mergeConfig(baseConfig, {
+    // Define platform-specific environment variables
+    define: {
+      'import.meta.env.VITE_PLATFORM': JSON.stringify('web'),
+    },
+    
+    // Build output configuration
+    build: {
+      // Output directory for web builds
+      outDir: 'dist/web',
+      
+      // Rollup-specific options
+      rollupOptions: {
+        output: {
+          // Create separate vendor chunk for Vue-related dependencies
+          manualChunks: {
+            vendor: ['vue', 'vue-router', 'pinia'],
+          }
+        }
+      }
+    },
+    
+    // Vite plugins configuration
     plugins: [
+      // Progressive Web App configuration
       VitePWA({
+        // Auto-update service worker
         registerType: 'autoUpdate',
+        
+        // PWA manifest configuration
         manifest: appConfig.pwaConfig?.manifest,
+        
+        // Development options
         devOptions: {
           enabled: false
         },
+        
+        // Workbox configuration for service worker
         workbox: {
           cleanupOutdatedCaches: true,
           skipWaiting: true,
diff --git a/vite.config.web.ts b/vite.config.web.ts
deleted file mode 100644
index f7376975..00000000
--- a/vite.config.web.ts
+++ /dev/null
@@ -1,27 +0,0 @@
-import { defineConfig, loadEnv } from "vite";
-import baseConfig from "./vite.config.base";
-
-export default defineConfig(({ mode }) => {
-  const env = loadEnv(mode, process.cwd(), '');
-  
-  return {
-    ...baseConfig,
-    define: {
-      'import.meta.env.VITE_PLATFORM': JSON.stringify('web'),
-    },
-    build: {
-      ...baseConfig.build,
-      outDir: 'dist/web',
-      rollupOptions: {
-        ...baseConfig.build.rollupOptions,
-        output: {
-          ...baseConfig.build.rollupOptions.output,
-          manualChunks: {
-            // Web-specific chunk splitting
-            vendor: ['vue', 'vue-router', 'pinia'],
-          }
-        }
-      }
-    }
-  };
-}); 
\ No newline at end of file