Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally

, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

Analytics Preference API

jjoonleo edited this page Jun 26, 2026 · 1 revision

Analytics Preference API

This document defines the frontend contract needed before implementing OnTime analytics preference sync. It covers only the account-scoped preference for signed-in users; pre-login installation-scoped preference remains local to the app.

Scope

  • The preference controls optional Product Usage Events for active Analytics Purposes.
  • The first release uses opt-out analytics and exposes the setting as Help Improve OnTime.
  • Disabled preference stops future optional Product Usage Events.
  • Marketing and personalization remain deferred and are not enabled by this API.

Endpoints

Get Analytics Preference

GET /users/me/analytics-preferenceAuthorization: Bearer <access token>

Successful response:

{
"data": {
"enabled": true,
"updatedAt": "2026-05-26T12:00:00Z"
}
}

Update Analytics Preference

PUT /users/me/analytics-preferenceAuthorization: Bearer <access token>Content-Type: application/json
{
"enabled": false
}

Successful response:

{
"data": {
"enabled": false,
"updatedAt": "2026-05-26T12:00:05Z"
}
}

Field Semantics

FieldTypeRequiredMeaning
enabledbooleanYesWhether optional Product Usage Events may be collected for the signed-in account.
updatedAtISO-8601 UTC stringYesServer time when the account-scoped preference was last changed.

Default Value

  • The backend default for existing and newly created signed-in accounts is config-gated.
  • The initial config default is enabled: false until privacy policy, hosted policy page, Google Play Data Safety, and release approval are complete.
  • After approval, the backend may flip the config default to enabled: true without changing the API contract.
  • An explicit user-saved enabled value always wins over the config default.
  • The frontend must still treat unknown or load-failed preference state as disabled for optional Product Usage Events.

Frontend Behavior

  1. Before sign-in, the app stores the Analytics Preference locally for the installation.
  2. After sign-in, the app loads GET /users/me/analytics-preference.
  3. After the user changes Help Improve OnTime, the app calls PUT /users/me/analytics-preference.
  4. If enabled is false, the app disables Firebase Analytics collection and does not emit future optional Product Usage Events.
  5. On sign-out, the app clears the Firebase Analytics user association and returns to the local installation-scoped preference.
  6. On account deletion, the app stops future user-linked Product Usage Events and clears the Firebase Analytics user association.

Failure Behavior

  • If loading the signed-in account preference fails, provider collection remains disabled until the preference is loaded successfully.
  • If updating the signed-in account preference fails, the app keeps the previous confirmed value and does not emit analytics_preference_changed.
  • If local installation preference and signed-in account preference conflict, the app uses the stricter value until the user explicitly changes the account preference.
  • Unknown preference state is treated as disabled for optional Product Usage Events.

Backend Handoff Scope

The backend task should be limited to account-scoped Analytics Preference sync:

  • Backend issue: DevKor-github/OnTime-back#318.
  • Add GET /users/me/analytics-preference.
  • Add PUT /users/me/analytics-preference.
  • Persist enabled and updatedAt for the signed-in account.
  • Define the default account value for existing and newly created users.
  • Confirm account deletion behavior for historical analytics as aggregate or de-identified retention.
  • Confirm privacy policy and Google Play Data Safety updates before release.

The backend task does not need to define Firebase event names, Flutter BLoC instrumentation, local pre-login preference storage, or UI copy.

Privacy And Release Requirements

  • Do not include email, name, OAuth identifiers, FCM token, schedule names, schedule notes, place names, preparation step names, request bodies, response bodies, raw exception strings, or free text in analytics events or preference API payloads.
  • Update the privacy policy and Google Play Data Safety worksheet before releasing Firebase Analytics.
  • Historical analytics after account deletion may be retained only in aggregate or de-identified form.
  • Production analytics is enabled by default only for production builds; debug, local development, tests, and Widgetbook collection require an explicit override.

Clone this wiki locally