Skip to content

feat(analytics): migrate from Umami to PostHog for SaaS product analytics - #203

Merged
ayoub3bidi merged 2 commits into
developfrom
feat/migrate-from-umami-to-posthog
Jul 18, 2026
Merged

feat(analytics): migrate from Umami to PostHog for SaaS product analytics#203
ayoub3bidi merged 2 commits into
developfrom
feat/migrate-from-umami-to-posthog

Conversation

@ayoub3bidi

@ayoub3bidi ayoub3bidi commented Jul 17, 2026

Copy link
Copy Markdown
Owner

Contribution workflow

  • Base branch is develop: This PR targets develop, not main.
  • Guidelines and docs: I have read CONTRIBUTING.md and the docs relevant to my change.
  • This template: I kept the PR template structure and filled in the sections below.

Description

Replace Umami with PostHog to enable product analytics, session replay, feature flags, and user identification for the upcoming Pro plan.

Type of Change

  • 🐛 Bug fix
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change
  • 📚 Documentation update
  • 🎨 Style/UI improvement
  • ⚡ Performance improvement
  • 🧪 Test addition or improvement
  • 🔧 Chore

Related Issues

Changes Made

  • Install posthog-js and @posthog/react packages
  • Create src/services/analytics.js — PostHog init, identify, reset, captureEvent with Do Not Track support
  • Create src/services/analyticsEvents.js — 20 event constants and 16 capture helper functions (algorithm_viewed, speed_changed, category_changed, sign_in_clicked, favorite_added, etc.)
  • Create src/providers/PostHogProvider.jsx — React provider wrapper
  • Create src/services/featureFlags.js — Feature flag architecture for future use
  • Create worker/posthog-proxy.js — Cloudflare Worker proxy via e.bayanflow.com for ad-blocker resilience
  • Integrate PostHog proxy into worker/index.js (routed via e.bayanflow.com hostname)
  • Update wrangler.jsonc with proxy routes for staging (e.dev.bayanflow.com) and production (e.bayanflow.com)
  • Remove Umami script from index.html
  • Update public/_headers CSP — replace cloud.umami.is/gateway.umami.is with *.posthog.com
  • Add assertAnalyticsCspDirectives() to scripts/cspHeaders.js and CSP test
  • Update .env.example with PostHog env vars
  • Add VITE_POSTHOG_API_KEY/VITE_POSTHOG_API_HOST to all 3 CI workflows
  • Instrument events in VisualizerApp.jsx — category, speed, sound, fullscreen, algorithm, steps, export, panels, completion
  • Add trackSignInClicked to SignInPromptModal.jsx (modal source) and UserMenu.jsx (navbar source)
  • Add trackFavoriteAdded/trackFavoriteRemoved to useFavorites.js
  • Add trackNoteSaved to useNoteAutosave.js
  • Add identifyUser/'resetUser'/'trackSignInCompleted' to AuthProvider.jsx on auth state changes
  • Update privacy policy (privacy.en.js, tests) — replace Umami with PostHog
  • Update SECURITY.md — reference PostHog analytics
  • Update main.jsx provider hierarchy (Theme → Auth → PostHog → Router)

Testing

  • All existing tests pass (pnpm test:run) — 1834 passed, 7 pre-existing worker test failures
  • New tests updated for privacy policy and CSP assertions
  • ESLint passes (pnpm lint) — 0 errors, 3 pre-existing warnings
  • Build passes (pnpm build) — successful

Test Results

Test Files  2 failed | 154 passed (156)
     Tests  8 failed | 1834 passed (1842)
     Errors  1 error

The 7 worker/index.test.js failures are pre-existing (URL constructor not available in test env).
The 1 AuthProvider test failure was fixed in the final commit.

Code Quality

  • Code follows the project's coding standards
  • ESLint passes
  • Prettier formatting applied
  • No console errors or warnings
  • Code is properly documented with JSDoc

Performance Impact

  • No performance impact — PostHog loads asynchronously, proxy is zero-overhead

Breaking Changes

  • None

Additional Notes

  • PostHog is configured with person_profiles: 'identified_only' — anonymous users stay anonymous
  • Session replay is enabled for all users with text/media/input masking for privacy
  • The reverse proxy at e.bayanflow.com is integrated into the existing Cloudflare Worker

Summary by CodeRabbit

  • New Features

    • Added PostHog analytics to track sign-ins, algorithm interactions, favorites, notes, navigation, and feature usage.
    • Added feature-flag support for controlled product experiences.
    • Added a custom analytics proxy for improved privacy and first-party delivery.
    • Non-production environments are now excluded from search engine indexing.
  • Documentation

    • Updated privacy and security documentation to describe PostHog analytics and data handling.
  • Chores

    • Configured analytics across local, preview, staging, and production builds.

…tics

- Replace Umami with PostHog SDK (posthog-js, @posthog/react)
- Add PostHog reverse proxy via e.bayanflow.com (ad-blocker resilient)
- Instrument 20+ custom events across VisualizerApp, UserMenu, SignInPromptModal, useFavorites, useNoteAutosave
- Implement user identification on sign-in/sign-out via AuthProvider
- Add first-party session replay (text/media masked, inputs masked)
- Respect Do Not Track header
- Add feature flag architecture for future use
- Update CSP headers for PostHog domains
- Update privacy policy, SECURITY.md to reference PostHog
- Add VITE_POSTHOG_API_KEY/VITE_POSTHOG_API_HOST to CI workflows
@github-actions github-actions Bot added documentation Improvements or additions to documentation style Improve styling, design, and animation ci Workflows dependencies tests labels Jul 17, 2026
@coderabbitai

coderabbitai Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@ayoub3bidi, you've reached your PR review limit, so we couldn't start this review.

Next review available in: 37 minutes

Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available.
You're only billed for reviews past your plan's rate limits ($0.25/file).

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: ccd2b00b-b097-441d-bd2b-20795ba30315

📥 Commits

Reviewing files that changed from the base of the PR and between 3e2f556 and c21c046.

📒 Files selected for processing (8)
  • .env.example
  • .github/workflows/deploy-cloudflare.yml
  • public/_headers
  • scripts/cspHeaders.js
  • src/contexts/AuthProvider.jsx
  • src/services/analytics.js
  • worker/index.js
  • worker/posthog-proxy.js
📝 Walkthrough

Walkthrough

The PR replaces Umami with PostHog analytics, adds event and feature-flag helpers, instruments application interactions, proxies PostHog traffic through Cloudflare Workers, updates build configuration and CSP validation, and revises privacy and security disclosures.

Changes

PostHog analytics integration

Layer / File(s) Summary
Analytics foundation and provider wiring
package.json, src/services/..., src/providers/PostHogProvider.jsx, src/main.jsx
Adds PostHog dependencies, initialization, event wrappers, feature-flag helpers, provider context, and application bootstrap integration.
Application event instrumentation
src/components/..., src/contexts/AuthProvider.jsx, src/hooks/..., src/pages/VisualizerApp.jsx
Tracks sign-in, authentication identity changes, favorites, note saves, algorithm activity, controls, exports, panels, and category changes.
PostHog proxy and deployment wiring
worker/..., wrangler.jsonc, .github/workflows/..., .env.example
Routes PostHog API and asset requests through Cloudflare Workers, caches static responses, adds custom domains, and supplies build-time environment variables.
CSP and environment security updates
public/_headers, scripts/cspHeaders.js, src/security/..., index.html, SECURITY.md
Removes Umami origins, validates PostHog CSP directives, updates security text, and applies noindex metadata to non-production hosts.
Privacy policy updates
src/content/legal/privacy.en.js, src/content/legal/privacy.en.test.js, src/pages/PrivacyPolicy.test.jsx
Replaces Umami disclosures with PostHog analytics, retention, processor, and session-replay descriptions and updates related tests.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related PRs

Suggested labels: config

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: migrating analytics from Umami to PostHog.
Docstring Coverage ✅ Passed Docstring coverage is 91.89% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/migrate-from-umami-to-posthog

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@socket-security

socket-security Bot commented Jul 17, 2026

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedposthog-js@​1.404.06610081100100
Added@​posthog/​react@​1.10.31001007799100

View full report

@socket-security

socket-security Bot commented Jul 17, 2026

Copy link
Copy Markdown

Warning

Review the following alerts detected in dependencies.

According to your organization's Security Policy, it is recommended to resolve "Warn" alerts. Learn more about Socket for GitHub.

Action Severity Alert  (click "▶" to expand/collapse)
Warn High
Obfuscated code: npm web-vitals is 90.0% likely obfuscated

Confidence: 0.90

Location: Package overview

From: pnpm-lock.yamlnpm/posthog-js@1.404.0npm/web-vitals@5.3.0

ℹ Read more on: This package | This alert | What is obfuscated code?

Next steps: Take a moment to review the security alert above. Review the linked package source code to understand the potential risk. Ensure the package is not malicious before proceeding. If you're unsure how to proceed, reach out to your security team or ask the Socket team for help at support@socket.dev.

Suggestion: Packages should not obfuscate their code. Consider not using packages with obfuscated code.

Mark the package as acceptable risk. To ignore this alert only in this pull request, reply with the comment @SocketSecurity ignore npm/web-vitals@5.3.0. You can also ignore all packages with @SocketSecurity ignore-all. To ignore an alert for all future pull requests, use Socket's Dashboard to change the triage state of this alert.

View full report

@github-actions

Copy link
Copy Markdown

Preview for Bayan Flow Staging ready!

Name Link
🔨 Latest commit 3e2f556
🔍 Latest deploy log https://github.com/ayoub3bidi/bayan-flow/actions/runs/29608439756
😎 Deploy Preview https://pr-203-bayan-flow-staging.ayoub3bidi.workers.dev
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

Preview alias pr-203 on the staging worker. Updates automatically with new commits.

@codecov

codecov Bot commented Jul 17, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.22535% with 59 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
worker/posthog-proxy.js 2.32% 42 Missing ⚠️
src/services/featureFlags.js 12.50% 7 Missing ⚠️
src/providers/PostHogProvider.jsx 14.28% 6 Missing ⚠️
src/pages/VisualizerApp.jsx 88.88% 3 Missing ⚠️
src/contexts/AuthProvider.jsx 94.44% 1 Missing ⚠️

📢 Thoughts on this report? Let us know!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🧹 Nitpick comments (4)
src/contexts/AuthProvider.jsx (1)

182-194: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Sync user properties more reliably by identifying outside of SIGNED_IN.

Currently, identifyUser is only called when the SIGNED_IN event fires. This has two drawbacks:

  1. When a returning user opens the app, Supabase fires an INITIAL_SESSION event instead. If their local storage was cleared or they are using a cross-domain/embedded browser setup, their identity won't be consistently synced to PostHog for that session.
  2. The user's plan is hardcoded to null here because the profile row hasn't been fetched yet. If a user upgrades their plan, PostHog won't see the new plan until they explicitly sign out and back in.

Consider additionally calling identifyUser inside evaluateAccess once refreshProfile(activeUser) resolves. This ensures the user is accurately identified on every session load and immediately reflects database-backed billing plan updates.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/contexts/AuthProvider.jsx` around lines 182 - 194, Update evaluateAccess
to call identifyUser after refreshProfile(activeUser) resolves, using the
refreshed profile data and current user details so identity and billing plan
properties are synchronized on every session load. Keep the existing SIGNED_IN
identification flow intact unless needed to avoid duplication, and ensure the
plan comes from the fetched profile rather than the hardcoded null.
src/services/analytics.js (2)

29-36: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Prevent event queueing when analytics are bypassed in development.

When initPostHog() returns early without calling posthog.init(), any subsequent calls to tracking functions will cause the PostHog SDK to continuously queue events in memory.

To prevent this internal queue from growing indefinitely during long local development sessions, consider either overriding the exported SDK wrapper functions with no-ops when bypassed, or call posthog.init() but disable capturing using opt_out_capturing_by_default: true.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/analytics.js` around lines 29 - 36, Update initPostHog’s
local-development bypass so subsequent exported tracking calls cannot queue
events in the PostHog SDK. Either replace the exported SDK wrapper functions
with no-ops when the localhost/127.0.0.1 condition matches, or initialize
PostHog with opt_out_capturing_by_default enabled while preserving the
bypassed-capture behavior.

29-36: 🩺 Stability & Availability | 🔵 Trivial | 💤 Low value

Prevent event queueing when analytics are bypassed in development.

When initPostHog() returns early without calling posthog.init(), any subsequent calls to tracking functions will cause the PostHog SDK to continuously queue events in memory.

To prevent this internal queue from growing indefinitely during long local development sessions, consider either overriding the exported SDK wrapper functions with no-ops when bypassed, or call posthog.init() but disable capturing using opt_out_capturing_by_default: true.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/services/analytics.js` around lines 29 - 36, Update initPostHog’s
local-development bypass so subsequent exported tracking calls cannot queue
events: either replace the SDK wrapper functions with no-ops when returning
early, or initialize PostHog with capturing disabled by default via
opt_out_capturing_by_default. Preserve analytics behavior outside localhost and
127.0.0.1 development environments.
.env.example (1)

10-14: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Maintain alphabetical ordering of environment variables.

As suggested by the dotenv-linter, VITE_POSTHOG_API_HOST should appear before VITE_POSTHOG_API_KEY to maintain alphabetical order.

🧹 Proposed fix
 # PostHog analytics (optional — skip in local dev)
+VITE_POSTHOG_API_HOST=https://us.i.posthog.com
 VITE_POSTHOG_API_KEY=phc_your_project_token
-VITE_POSTHOG_API_HOST=https://us.i.posthog.com
 # For production with reverse proxy: VITE_POSTHOG_API_HOST=https://e.bayanflow.com
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.env.example around lines 10 - 14, Reorder the PostHog environment variables
in .env.example so VITE_POSTHOG_API_HOST appears before VITE_POSTHOG_API_KEY,
preserving their values and comments.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/deploy-cloudflare.yml:
- Around line 54-55: Update the VITE_POSTHOG_API_HOST value in the deployment
workflow to select the proxy host based on the deployed branch: use the
production host for main and the staging host e.dev.bayanflow.com for develop.
Keep VITE_POSTHOG_API_KEY unchanged.

In `@public/_headers`:
- Line 8: Add https://e.bayanflow.com to connect-src in public/_headers while
preserving the existing Supabase and other resource sources. Update the
analytics CSP assertion in scripts/cspHeaders.js, including its relevant
validation symbols, to require the same proxy origin alongside the existing
PostHog origin checks; both sites must remain aligned.

In `@scripts/cspHeaders.js`:
- Around line 92-100: Update the script-src and connect-src validation in the
CSP checking logic to split each directive value on whitespace and require an
exact https://*.posthog.com token match, rather than using substring includes
checks. Preserve the existing error behavior and messages for directives missing
the exact token.

In `@worker/index.js`:
- Around line 49-52: Update the hostname condition in the request routing logic
around handlePostHogProxy to accept both the production and staging PostHog
proxy domains configured in wrangler.jsonc, e.bayanflow.com and
e.dev.bayanflow.com, while preserving the existing proxy handling for either
hostname.
- Around line 36-40: Restrict the static-asset cache guards to GET requests by
adding request.method === 'GET' alongside the existing host and status checks in
worker/index.js (lines 36-40) and worker/posthog-proxy.js (lines 69-74).

---

Nitpick comments:
In @.env.example:
- Around line 10-14: Reorder the PostHog environment variables in .env.example
so VITE_POSTHOG_API_HOST appears before VITE_POSTHOG_API_KEY, preserving their
values and comments.

In `@src/contexts/AuthProvider.jsx`:
- Around line 182-194: Update evaluateAccess to call identifyUser after
refreshProfile(activeUser) resolves, using the refreshed profile data and
current user details so identity and billing plan properties are synchronized on
every session load. Keep the existing SIGNED_IN identification flow intact
unless needed to avoid duplication, and ensure the plan comes from the fetched
profile rather than the hardcoded null.

In `@src/services/analytics.js`:
- Around line 29-36: Update initPostHog’s local-development bypass so subsequent
exported tracking calls cannot queue events in the PostHog SDK. Either replace
the exported SDK wrapper functions with no-ops when the localhost/127.0.0.1
condition matches, or initialize PostHog with opt_out_capturing_by_default
enabled while preserving the bypassed-capture behavior.
- Around line 29-36: Update initPostHog’s local-development bypass so subsequent
exported tracking calls cannot queue events: either replace the SDK wrapper
functions with no-ops when returning early, or initialize PostHog with capturing
disabled by default via opt_out_capturing_by_default. Preserve analytics
behavior outside localhost and 127.0.0.1 development environments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 19bd8f06-d805-44cc-9212-9db48291f988

📥 Commits

Reviewing files that changed from the base of the PR and between 636d1ea and 3e2f556.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (27)
  • .env.example
  • .github/workflows/ci.yml
  • .github/workflows/deploy-cloudflare.yml
  • .github/workflows/preview-cloudflare.yml
  • SECURITY.md
  • index.html
  • package.json
  • public/_headers
  • scripts/cspHeaders.js
  • src/components/SignInPromptModal.jsx
  • src/components/UserMenu.jsx
  • src/content/legal/privacy.en.js
  • src/content/legal/privacy.en.test.js
  • src/contexts/AuthProvider.jsx
  • src/hooks/useFavorites.js
  • src/hooks/useNoteAutosave.js
  • src/main.jsx
  • src/pages/PrivacyPolicy.test.jsx
  • src/pages/VisualizerApp.jsx
  • src/providers/PostHogProvider.jsx
  • src/security/cspHeaders.test.js
  • src/services/analytics.js
  • src/services/analyticsEvents.js
  • src/services/featureFlags.js
  • worker/index.js
  • worker/posthog-proxy.js
  • wrangler.jsonc
💤 Files with no reviewable changes (1)
  • index.html

Comment thread .github/workflows/deploy-cloudflare.yml Outdated
Comment thread public/_headers Outdated
Permissions-Policy: camera=(), microphone=(), geolocation=(), identity-credentials-get=(self "https://accounts.google.com")
# Pyodide CDN origins: jsDelivr below; custom VITE_PYODIDE_CDN_BASE origins appended at build (vite.config.js)
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' blob: https://cloud.umami.is https://static.cloudflareinsights.com https://cdn.jsdelivr.net https://accounts.google.com; connect-src 'self' blob: https://cloud.umami.is https://gateway.umami.is https://cloudflareinsights.com https://api.github.com https://cdn.jsdelivr.net https://www.remotion.pro https://qketsapzqpzmccljfjcm.supabase.co https://accounts.google.com https://oauth2.googleapis.com; img-src 'self' data: blob: https://api.producthunt.com https://lh3.googleusercontent.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; font-src 'self' data:; worker-src 'self' blob:; media-src 'self' blob:; frame-src https://www.youtube-nocookie.com https://accounts.google.com; object-src 'none'; base-uri 'self'; form-action 'self'
Content-Security-Policy: default-src 'self'; script-src 'self' 'unsafe-inline' 'wasm-unsafe-eval' blob: https://*.posthog.com https://static.cloudflareinsights.com https://cdn.jsdelivr.net https://accounts.google.com; connect-src 'self' blob: https://*.posthog.com https://cloudflareinsights.com https://api.github.com https://cdn.jsdelivr.net https://www.remotion.pro https://qketsapzqpzmccljfjcm.supabase.co https://accounts.google.com https://oauth2.googleapis.com; img-src 'self' data: blob: https://api.producthunt.com https://lh3.googleusercontent.com; style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net; font-src 'self' data:; worker-src 'self' blob:; media-src 'self' blob:; frame-src https://www.youtube-nocookie.com https://accounts.google.com; object-src 'none'; base-uri 'self'; form-action 'self'

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Keep the runtime CSP and build-time assertion aligned for the first-party proxy.

PostHog traffic is routed through https://e.bayanflow.com, but the runtime header omits that origin and the assertion only validates *.posthog.com. This blocks proxy requests in browsers while allowing the CSP test to pass.

  • public/_headers#L8-L8: add https://e.bayanflow.com to connect-src.
  • scripts/cspHeaders.js#L89-L106: require the same proxy origin in the analytics CSP assertion.

As per coding guidelines: “Preserve the CSP requirements for Supabase, Google profile images, and Google Identity Services resources; CSP is asserted by scripts/cspHeaders.js at build time.”

📍 Affects 2 files
  • public/_headers#L8-L8 (this comment)
  • scripts/cspHeaders.js#L89-L106
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@public/_headers` at line 8, Add https://e.bayanflow.com to connect-src in
public/_headers while preserving the existing Supabase and other resource
sources. Update the analytics CSP assertion in scripts/cspHeaders.js, including
its relevant validation symbols, to require the same proxy origin alongside the
existing PostHog origin checks; both sites must remain aligned.

Source: Coding guidelines

Comment thread scripts/cspHeaders.js Outdated
Comment thread worker/index.js Outdated
Comment on lines +36 to +40
// Cache static assets
if (targetHost === POSTHOG_ASSETS_HOST && response.status === 200) {
const cache = caches.default;
ctx.waitUntil(cache.put(request, response.clone()));
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🌐 Web query:

Does Cloudflare Workers caches.default.put throw an error if the request method is not GET?

💡 Result:

Yes, Cloudflare Workers' caches.default.put method will throw an error if the request provided as the cache key has a method other than GET [1][2][3]. According to the official Cloudflare Workers documentation, the cache.put method explicitly throws an error if the request passed to it is a method other than GET [1][2][3]. This is a documented constraint of the Cache API within the Cloudflare Workers runtime [1][4]. If you need to cache a request that is not a GET request, or if you want to force a request to be treated as a GET request for caching purposes, you can use the ignoreMethod option in the cache.match method [3], but for cache.put, the method constraint remains strict [1][2]. Developers typically handle this by ensuring only GET requests are passed to cache.put [5][6].

Citations:


Only cache GET requests. caches.default.put() throws when the request method is not GET, so HEAD/OPTIONS traffic can fail here. Add request.method === 'GET' to both cache guards in worker/index.js and worker/posthog-proxy.js.

📍 Affects 2 files
  • worker/index.js#L36-L40 (this comment)
  • worker/posthog-proxy.js#L69-L74
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@worker/index.js` around lines 36 - 40, Restrict the static-asset cache guards
to GET requests by adding request.method === 'GET' alongside the existing host
and status checks in worker/index.js (lines 36-40) and worker/posthog-proxy.js
(lines 69-74).

Comment thread worker/index.js Outdated
…cache guards, dev bypass

- deploy-cloudflare.yml: use branch-conditional proxy host (e.bayanflow.com for main, e.dev.bayanflow.com for develop)
- public/_headers: add e.bayanflow.com and e.dev.bayanflow.com to connect-src
- scripts/cspHeaders.js: exact token matching instead of substring includes; add proxy origin check
- worker/index.js: accept both staging and production proxy domains; restrict static-asset cache to GET
- worker/posthog-proxy.js: restrict static-asset cache to GET
- src/services/analytics.js: set isBypassed flag to prevent SDK event queueing in dev
- src/contexts/AuthProvider.jsx: identifyUser after profile fetch with accurate plan
- .env.example: alphabetical ordering of PostHog env vars
@ayoub3bidi
ayoub3bidi merged commit 2d6e8d3 into develop Jul 18, 2026
14 of 15 checks passed
@ayoub3bidi
ayoub3bidi deleted the feat/migrate-from-umami-to-posthog branch July 18, 2026 13:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ci Workflows dependencies documentation Improvements or additions to documentation style Improve styling, design, and animation tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant