Skip to content

fix(analytics): PostHog api_host bug + identify/group on login#3772

Merged
PierreBrisorgueil merged 7 commits intomasterfrom
fix/analytics-posthog-identify-group
Mar 25, 2026
Merged

fix(analytics): PostHog api_host bug + identify/group on login#3772
PierreBrisorgueil merged 7 commits intomasterfrom
fix/analytics-posthog-identify-group

Conversation

@PierreBrisorgueil
Copy link
Copy Markdown
Collaborator

@PierreBrisorgueil PierreBrisorgueil commented Mar 25, 2026

Summary

  • Bug fix: api_host in PostHog plugin was set to config.analytics.posthog.key instead of .host — analytics events were sent to the wrong endpoint
  • Identify on login: call posthog.identify(userId, {email, name}) after successful signin
  • Group on org switch: call posthog.group('company', orgId, {name, plan}) after org switch
  • Reset on logout: call posthog.reset() on signout to clear user identity
  • All PostHog calls guarded by posthog.__loaded — no-op when PostHog is not configured

Test plan

  • PostHog plugin test now asserts exact { api_host: host } object (not expect.any)
  • Auth store tests: identify called on signin when loaded, skipped when not loaded, _id fallback + partial name
  • Auth store tests: reset called on signout when loaded, skipped when not loaded
  • Org store tests: group called on switch when loaded, skipped when not loaded, skipped when org not found
  • All 703 tests pass, lint clean

Closes #3769

Summary by CodeRabbit

  • Documentation

    • Added downstream configuration patterns guide covering config layering, post-login redirects, and custom home pages.
  • Bug Fixes

    • Corrected PostHog analytics endpoint configuration.
  • New Features

    • Integrated PostHog analytics tracking for user authentication and organization switching.

Add downstream config patterns section to CLAUDE.md covering post-login
redirect, custom home page, and config layering conventions.

Closes #3753
…eset

The PostHog plugin was passing the API key as api_host instead of the
configured host URL. Additionally, integrate PostHog identity tracking:
- identify(userId, {email, name}) on successful signin
- group('company', orgId, {name, plan}) on org switch
- reset() on signout
All calls are guarded by posthog.__loaded to no-op when unconfigured.

Closes #3769
Copilot AI review requested due to automatic review settings March 25, 2026 07:59
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Mar 25, 2026

Warning

Rate limit exceeded

@PierreBrisorgueil has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 25 minutes and 59 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 6db06885-ca2b-43b5-834a-5ac60279ae0d

📥 Commits

Reviewing files that changed from the base of the PR and between d3e8242 and bb882be.

📒 Files selected for processing (7)
  • CLAUDE.md
  • src/modules/analytics/composables/analytics.useFeatureFlag.js
  • src/modules/analytics/composables/analytics.usePostHog.js
  • src/modules/analytics/tests/analytics.useFeatureFlag.unit.tests.js
  • src/modules/analytics/tests/analytics.usePostHog.unit.tests.js
  • src/modules/auth/stores/auth.store.js
  • src/modules/auth/tests/auth.store.unit.tests.js

Walkthrough

Fixes a PostHog plugin configuration bug where api_host was incorrectly set to the API key value. Integrates PostHog analytics by identifying authenticated users on login, grouping by organization on organization switch, and resetting session data on logout.

Changes

Cohort / File(s) Summary
PostHog Plugin Configuration Fix
src/lib/plugins/posthog.js, src/lib/plugins/tests/posthog.unit.tests.js
Fixed api_host initialization to use config.analytics.posthog.host instead of incorrectly using the API key. Updated test assertion to verify explicit config object with correct host.
Auth Store PostHog Integration
src/modules/auth/stores/auth.store.js, src/modules/auth/tests/auth.store.unit.tests.js
Added conditional posthog.identify() call on successful signin with user ID and traits (email, name). Added conditional posthog.reset() call on signout. Updated tests to mock PostHog, validate analytics calls, and use configurable cookie prefix for localStorage keys instead of hardcoded values.
Organizations Store PostHog Integration
src/modules/organizations/stores/organizations.store.js, src/modules/organizations/tests/organizations.store.unit.tests.js
Added conditional posthog.group() call in switchOrganization with company grouping, organization ID, name, and plan. Extended tests to validate group calls under various conditions (loaded state, org existence).
Documentation
CLAUDE.md
Added "Downstream config patterns" section describing config layering rules, post-login redirect via sign.route, and custom home page router implementation.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant AuthStore
    participant OrgStore
    participant PostHog
    participant LocalStorage

    User->>AuthStore: signin(credentials)
    AuthStore->>LocalStorage: store auth token
    AuthStore->>AuthStore: refresh navigation & abilities
    alt PostHog loaded
        AuthStore->>PostHog: identify(userId, {email, name})
    end

    User->>OrgStore: switchOrganization(orgId)
    OrgStore->>LocalStorage: update organization & JWT
    OrgStore->>OrgStore: refresh navigation & abilities
    alt PostHog loaded & org exists
        OrgStore->>PostHog: group('company', orgId, {name, plan})
    end

    User->>AuthStore: signout()
    AuthStore->>LocalStorage: clear abilities
    alt PostHog loaded
        AuthStore->>PostHog: reset()
    end
    AuthStore->>LocalStorage: remove auth entries
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The PR title clearly and concisely identifies the main changes: fixing the PostHog api_host bug and adding identify/group analytics calls on login, which aligns with the primary objectives.
Description check ✅ Passed The PR description covers the main changes (bug fix, identify on login, group on org switch, reset on logout) and includes test validation results, but omits several template sections including modules impacted, risk level, guardrails checklist, and rollback plan.
Linked Issues check ✅ Passed All coding requirements from issue #3769 are addressed: api_host bug fixed, identify() called on signin, group() called on org switch, reset() called on logout, all guarded by posthog.__loaded, and unit tests updated accordingly.
Out of Scope Changes check ✅ Passed All changes are directly related to the PostHog analytics integration requirements. Documentation additions (CLAUDE.md) provide helpful context on config patterns but are not out of scope.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/analytics-posthog-identify-group

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 and usage tips.

@codecov
Copy link
Copy Markdown

codecov Bot commented Mar 25, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.20%. Comparing base (dce0267) to head (bb882be).
⚠️ Report is 5 commits behind head on master.

Additional details and impacted files
@@            Coverage Diff             @@
##           master    #3772      +/-   ##
==========================================
+ Coverage   99.19%   99.20%   +0.01%     
==========================================
  Files          26       26              
  Lines         873      886      +13     
  Branches      223      230       +7     
==========================================
+ Hits          866      879      +13     
  Misses          7        7              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

Fixes PostHog configuration and adds user/org analytics hooks in the auth and organizations stores so PostHog identity/group context is kept in sync with login/logout and org switching.

Changes:

  • Fix PostHog plugin api_host to use config.analytics.posthog.host (not the key).
  • Add PostHog identify() on signin, reset() on signout, and group() on org switch (guarded by posthog.__loaded).
  • Extend unit tests to assert the corrected plugin config and the new analytics calls.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
src/lib/plugins/posthog.js Fixes api_host wiring so events go to the correct PostHog endpoint.
src/lib/plugins/tests/posthog.unit.tests.js Tightens the assertion to validate { api_host: host } exactly.
src/modules/auth/stores/auth.store.js Adds PostHog identify on signin and reset on signout.
src/modules/auth/tests/auth.store.unit.tests.js Adds PostHog analytics tests and updates localStorage key expectations to use config.cookie.prefix.
src/modules/organizations/stores/organizations.store.js Adds PostHog group('company', ...) call when switching organizations.
src/modules/organizations/tests/organizations.store.unit.tests.js Mocks posthog-js and adds coverage for group() behavior on org switch.
CLAUDE.md Documents downstream config override patterns relevant to stack consumers.

Comment thread src/modules/auth/stores/auth.store.js
Comment thread src/modules/auth/tests/auth.store.unit.tests.js
Comment thread src/modules/auth/stores/auth.store.js Outdated
Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/lib/plugins/posthog.js (1)

9-20: 🛠️ Refactor suggestion | 🟠 Major

Add JSDoc header to the install method.

The install method is missing the required JSDoc documentation with @param and @returns tags. As per coding guidelines for src/**/*.{js,ts,vue}, every function should have JSDoc headers.

📝 Proposed JSDoc addition
 export default {
+  /**
+   * `@desc` Install PostHog analytics plugin when configured.
+   * `@param` {Object} app - Vue application instance
+   * `@returns` {void}
+   */
   install(app) {
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/lib/plugins/posthog.js` around lines 9 - 20, The install method in the
default export lacks the required JSDoc header; add a JSDoc block above the
install(app) function that documents the app parameter with `@param`
{import('vue').App} app (or appropriate type) and includes an `@returns` {void}
tag, and briefly describes the method's purpose and behavior (initializing
posthog via posthog.init and attaching to app.config.globalProperties.$posthog)
so the install function, app param, and return value are properly documented.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Outside diff comments:
In `@src/lib/plugins/posthog.js`:
- Around line 9-20: The install method in the default export lacks the required
JSDoc header; add a JSDoc block above the install(app) function that documents
the app parameter with `@param` {import('vue').App} app (or appropriate type) and
includes an `@returns` {void} tag, and briefly describes the method's purpose and
behavior (initializing posthog via posthog.init and attaching to
app.config.globalProperties.$posthog) so the install function, app param, and
return value are properly documented.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: b4d2e61e-d78b-46b2-9635-c1bbd11dbb8f

📥 Commits

Reviewing files that changed from the base of the PR and between 3320349 and d3e8242.

📒 Files selected for processing (7)
  • CLAUDE.md
  • src/lib/plugins/posthog.js
  • src/lib/plugins/tests/posthog.unit.tests.js
  • src/modules/auth/stores/auth.store.js
  • src/modules/auth/tests/auth.store.unit.tests.js
  • src/modules/organizations/stores/organizations.store.js
  • src/modules/organizations/tests/organizations.store.unit.tests.js

Reactive composables for PostHog feature flags and direct SDK access.
useFeatureFlag returns a ref that auto-updates via onFeatureFlags callback.
Both gracefully return false/null when PostHog is not configured.

Closes #3771
…ierreb-devkit/Vue into fix/analytics-posthog-identify-group
- useFeatureFlag now delegates to usePostHog() instead of duplicating
  getCurrentInstance() logic, keeping the access pattern consistent
- Moved onFeatureFlags registration from onMounted to setup phase to
  eliminate timing window between initial sync and callback registration
- Added explicit assertion for the unconfigured PostHog test case
…onal identify name

- Add JSDoc header to signout action
- Mock config service in auth store tests (avoid reliance on generated config/index.js)
- Build PostHog identify name conditionally: omit when empty, fallback to deduceNamesFromEmail
- Add tests for name deduction fallback and empty-name omission
@PierreBrisorgueil PierreBrisorgueil merged commit 534fdf3 into master Mar 25, 2026
6 checks passed
@PierreBrisorgueil PierreBrisorgueil deleted the fix/analytics-posthog-identify-group branch March 25, 2026 11:45
PierreBrisorgueil pushed a commit that referenced this pull request Apr 1, 2026
# [1.5.0](v1.4.0...v1.5.0) (2026-04-01)

### Bug Fixes

* **analytics:** PostHog api_host bug + identify/group on login ([#3772](#3772)) ([534fdf3](534fdf3)), closes [#3753](#3753) [#3766](#3766) [#3769](#3769) [#3771](#3771)
* **auth,admin:** move mailer warning to admin page, fix verify-email routing, align invite button ([0d195c4](0d195c4))
* **auth:** add missing $route.query mock in verifyEmail tests ([b2732f6](b2732f6))
* **auth:** address CodeRabbit review feedback ([1d14b06](1d14b06))
* **auth:** address review feedback from pass 1 ([bd27d2f](bd27d2f))
* **auth:** address review feedback from pass 1 ([a87fdb1](a87fdb1))
* **auth:** address review feedback from pass 2 — prevent form flash on load ([a6afeca](a6afeca))
* **auth:** fix runtime deprecation warnings and add auth view unit tests ([1901dad](1901dad)), closes [#3592](#3592)
* **auth:** persist snackbar dismissal on implicit close ([5e464c3](5e464c3))
* **auth:** resolve lint errors and update test mocks for fetchServerConfig ([a642001](a642001))
* **billing:** add store unit tests and fix view import paths ([e370272](e370272))
* **billing:** address CodeRabbit review — guards, tests, JSDoc, price fallback ([f0f6657](f0f6657))
* **billing:** address CodeRabbit review feedback ([b195d2d](b195d2d))
* **billing:** address CodeRabbit review feedback ([8435d1c](8435d1c))
* **billing:** address CodeRabbit review feedback ([4187771](4187771))
* **billing:** address review — tier comparison, graceful failure, tests, naming ([7b00b91](7b00b91))
* **billing:** address review feedback — pricing card, fetch guard, router tests ([34cbda9](34cbda9))
* **billing:** address UI review findings ([b281a8a](b281a8a))
* **billing:** address UI review findings ([ead3eb0](ead3eb0))
* **billing:** address UI review findings ([b2d3897](b2d3897))
* **billing:** address UI review findings ([a756cd9](a756cd9))
* **billing:** align CASL guard subject with backend policy ([7e8287b](7e8287b))
* **billing:** align CASL guard subject with backend policy ([8e9b768](8e9b768))
* **billing:** correct plan field name, add enterprise badge, store cleanup ([#3733](#3733)) ([9b6e30d](9b6e30d)), closes [#3729](#3729) [#3730](#3730) [#3731](#3731) [#3732](#3732) [#3729](#3729) [#3730](#3730) [#3731](#3731) [#3732](#3732)
* **billing:** correct test URL assertions to match store checkout URLs ([cd64628](cd64628))
* **billing:** correct view import paths to match lowercase filenames ([e2646dd](e2646dd))
* **billing:** default free plan display + E2E security tests ([#3751](#3751)) ([025534a](025534a))
* **billing:** fix branch coverage and E2E auth guard test ([2864cf7](2864cf7))
* **billing:** fix branch coverage and harden E2E auth test ([7b91edb](7b91edb))
* **billing:** fix error-handling tests and restore CASL guard on /billing route ([bcb15a6](bcb15a6))
* **billing:** fix plan merge — match by planId/name and build price objects ([1c1c765](1c1c765))
* **billing:** gate fetchSubscription behind org check and add missing [@returns](https://github.com/returns) JSDoc ([9dd15a7](9dd15a7))
* **billing:** harden URL validation, test assertions, and error handling ([44d9cc2](44d9cc2))
* **billing:** include canceled query param in checkout cancel URL ([9e28636](9e28636))
* **billing:** propagate errors, add CASL route metadata, rename views ([39343ba](39343ba))
* **billing:** remove duplicate import in E2E test ([02576f5](02576f5))
* **billing:** rename views, fix test assertions, address review feedback ([cb72130](cb72130))
* **billing:** separate checkout error from fetch error in pricing view ([78db8b1](78db8b1))
* **billing:** update store cancel URL to include canceled query param ([ca5f1a3](ca5f1a3))
* **billing:** validate portal URL and catch fetchSubscription rejection ([7534b6c](7534b6c))
* **ci:** ensure coverage thresholds pass with all modules ([8e0c970](8e0c970)), closes [#3710](#3710)
* **ci:** remove ARC-specific conditionals from CI.yml ([#3806](#3806)) ([48747f3](48747f3)), closes [#3805](#3805)
* **config:** add missing api section to config.test.js ([#3679](#3679)) ([fff9ffc](fff9ffc)), closes [#3676](#3676)
* **config:** address review — use lodash-es, drop glob dep, add env warning ([1ec84fa](1ec84fa))
* **config:** address review feedback from pass 1 ([3336f09](3336f09))
* **config:** align app_title default between Dockerfile and hooks/build ([b08dbf3](b08dbf3))
* **config:** backward-compat fallback for sucessColor and improve warning ([1965557](1965557))
* **config:** fail fast when config is missing in production builds ([#3671](#3671)) ([c660ba4](c660ba4)), closes [#3669](#3669)
* **config:** generateConfig ignores module env-specific configs ([#3827](#3827)) ([1ffd80e](1ffd80e)), closes [#3826](#3826)
* **config:** remove [@desc](https://github.com/desc) tag from deepMerge JSDoc ([7c4b613](7c4b613))
* **config:** remove duplicate vuetify.theme block from app config merge ([5a583a7](5a583a7))
* **config:** remove unused imports and fix typo in generateConfig ([7b0c006](7b0c006))
* **config:** replace _.merge with deepMerge to fix array handling ([4e91025](4e91025)), closes [#3628](#3628)
* **config:** skip undefined values and guard against prototype pollution in deepMerge ([ffc574e](ffc574e))
* **config:** use pathToFileURL for cross-platform dynamic imports ([acad44e](acad44e))
* **core:** address review feedback from pass 1 ([0f6e3af](0f6e3af))
* **core:** make datatable generic via fetchAction prop ([e3a4926](e3a4926)), closes [#3596](#3596)
* **coverage:** exclude bootstrapper files with 0% coverage from collection ([4dfde5a](4dfde5a))
* **datatable:** increase per page select width to 100px ([#3779](#3779)) ([ff65d6f](ff65d6f)), closes [#3778](#3778)
* **docker:** add DEVKIT_NODE_api_port to docker-compose.test.yml ([#3815](#3815)) ([0f06402](0f06402)), closes [#3809](#3809)
* **docker:** make docker-compose.test.yml work for downstream projects ([#3790](#3790)) ([838aec1](838aec1)), closes [#3789](#3789)
* **docs:** add src/ prefix and use <env> placeholder in merge order table ([5af5d5b](5af5d5b))
* **docs:** mark global env override config files as optional ([7459d0f](7459d0f))
* **e2e:** read ports from project config instead of hardcoding ([#3777](#3777)) ([ec56d20](ec56d20)), closes [#3775](#3775)
* **header:** address review feedback from pass 1 ([b05d210](b05d210))
* **home,config:** address review feedback from pass 1 ([709ccbe](709ccbe))
* **home:** add JSDoc for tabs colorMode validator and tabStyle method ([a7fb5e3](a7fb5e3))
* **home:** add JSDoc to created() hook in home.team.view ([7548c15](7548c15))
* **home:** address CodeRabbit review feedback ([9990286](9990286))
* **home:** hero vertical centering, overlap prop, and Vuetify 4 typography migration ([4c26b25](4c26b25)), closes [#3587](#3587)
* **home:** pass colorMode to tabs component so forced text color applies to tab items ([50256d8](50256d8))
* **lodash:** use lodash-es imports for proper tree-shaking ([50570cf](50570cf))
* **nav:** fix organizations ghost item icon in sidenav ([bca4237](bca4237)), closes [#3706](#3706)
* **pull-request skill:** add consecutive_zero guard and re-check pending review checks ([18c70f8](18c70f8))
* **pull-request skill:** address review feedback — clarity and consistency ([2dd1ce2](2dd1ce2))
* **pull-request skill:** reply and resolve all threads including non-actionable ([ff776c8](ff776c8))
* **security:** harden auth views against XSS and weak validation ([#3735](#3735)) ([c3b844d](c3b844d))
* **seo-inject:** add JSON-LD structured data injection ([#3670](#3670)) ([5b36e5c](5b36e5c)), closes [#3664](#3664)
* **seo:** improve heading hierarchy and alt text for accessibility ([#3661](#3661)) ([918f9bd](918f9bd))
* **seo:** puppeteer prerender Docker support + minor plugin fixes ([#3673](#3673)) ([8ac241b](8ac241b))
* **seo:** skip runtime JSON-LD when seo-inject handles schema ([#3677](#3677)) ([#3680](#3680)) ([b0d90ac](b0d90ac))
* **skill:** add merge conflict check in pull-request convergence loop ([ef136ed](ef136ed)), closes [#3707](#3707)
* **skill:** address review feedback from pass 1 ([4020b82](4020b82))
* **skill:** handle CHANGES_REQUESTED, UNKNOWN mergeable, and standardize $PR usage ([13cb3cf](13cb3cf))
* **skill:** pull-request skill should ignore stack-level CodeRabbit comments for downstream projects ([97d2cb2](97d2cb2)), closes [#3604](#3604)
* **skills:** clarify feature Phase 0 completeness check ([#3773](#3773)) ([8ac6b1b](8ac6b1b))
* **skills:** match coderabbitai[bot] login in monitoring jq filter ([aae850f](aae850f))
* **update-stack:** add concrete gh issue create command and resolution guidance ([6092368](6092368))
* **update-stack:** add downstream-only new files rule to conflict table ([4a15e39](4a15e39))
* **update-stack:** address review feedback from pass 1 ([f7ed820](f7ed820))
* **update-stack:** address review feedback from pass 2 ([2bef8a3](2bef8a3))
* **update-stack:** clarify failure origin criteria in step 3bis ([a71515e](a71515e))

### Features

* add /frontend design skill + migrate Vuetify 3 patterns to V4 ([#3644](#3644)) ([2f2a8ff](2f2a8ff))
* **analytics:** add useFeatureFlag and usePostHog composables ([#3774](#3774)) ([2506a4f](2506a4f)), closes [#3771](#3771)
* **auth:** add email verification gate UI for org setup ([999aa60](999aa60))
* **auth:** add password visibility toggle ([#3752](#3752)) ([ea3b0a0](ea3b0a0)), closes [#336](#336)
* **auth:** display server-side auth status on signin/signup pages ([0f4276d](0f4276d))
* **billing:** add billing page with plan badge and subscription management ([e9a1fc5](e9a1fc5)), closes [#3715](#3715)
* **billing:** add BillingUsageBar component and enhance UpgradePrompt ([#3744](#3744)) ([0e9ca7f](0e9ca7f))
* **billing:** add checkout flow with auth/org guards and Stripe redirect ([ce17d67](ce17d67)), closes [#3714](#3714)
* **billing:** add checkout flow with auth/org guards and Stripe redirect ([f762d91](f762d91)), closes [#3714](#3714)
* **billing:** add feature gates — composable, upgrade prompt, router guard ([207c022](207c022)), closes [#3716](#3716)
* **billing:** add homepage pricing section ([a8ced6d](a8ced6d)), closes [#3717](#3717)
* **billing:** add pricing page with plan cards and billing toggle ([abb1d4a](abb1d4a)), closes [#3713](#3713)
* **billing:** add pricing page with plan cards and billing toggle ([0881a9f](0881a9f)), closes [#3713](#3713)
* **billing:** add useQuota composable for plan-based feature gating ([#3743](#3743)) ([85e2984](85e2984))
* **billing:** move pricing to dedicated page, update topnav ([eaab6f3](eaab6f3))
* **billing:** scaffold billing module with store, router, and views ([7b08b12](7b08b12)), closes [#3712](#3712)
* **ci:** skip setup-node and playwright install on self-hosted runner ([#3803](#3803)) ([104d4f8](104d4f8)), closes [#3802](#3802)
* **ci:** support configurable runner via RUNNER variable ([#3794](#3794)) ([1151d02](1151d02)), closes [#3792](#3792)
* **ci:** use APP_ENV variable for generateConfig in CI ([#3801](#3801)) ([e384c7c](e384c7c)), closes [#3795](#3795)
* **config:** migrate WAOS_VUE_* env prefix to DEVKIT_VUE_* ([7ad1a7f](7ad1a7f)), closes [#3614](#3614)
* **header:** add float scroll behavior and document all config options ([d1d4891](d1d4891))
* **home:** add dedicated 404 Not Found page ([#3655](#3655)) ([ac73739](ac73739))
* **home:** add FAQ accordion component with JSON-LD schema ([#3821](#3821)) ([444e62c](444e62c)), closes [#3819](#3819)
* **nav:** liquid glass sidenav with Apple-style inset mode ([#3737](#3737)) ([8203f2c](8203f2c))
* **pageHeader:** add tabs slot as alternative to icon + title ([#3781](#3781)) ([763d814](763d814)), closes [#3780](#3780)
* phase 2 organizations ([#3702](#3702)) ([71c6a5c](71c6a5c)), closes [#3674](#3674) [#3675](#3675) [#3684](#3684) [#3686](#3686) [#3681](#3681) [#3682](#3682) [#3683](#3683) [#3684](#3684) [#3685](#3685) [#3686](#3686) [#3675](#3675) [#3674](#3674)
* rename /frontend to /ui, add workflow rules ([#3704](#3704)) ([3d8259e](3d8259e))
* **sentry:** add Sentry error tracking and ErrorBoundary component ([#3788](#3788)) ([b5463d7](b5463d7)), closes [#3787](#3787)
* **seo-inject:** add noscript fallback, preconnect hints, and theme-color ([#3663](#3663)) ([261a3a8](261a3a8))
* **seo:** add pre-rendering of home page at build time ([#3660](#3660)) ([39d9414](39d9414))
* **seo:** add seo-static Vite plugin for robots.txt, sitemap.xml, manifest.json ([#3658](#3658)) ([0a50388](0a50388))
* **update-stack:** report upstream issues when verify fails on stack code ([71dbecc](71dbecc))
* **verify:** add coverage enforcement to verify skill ([#3776](#3776)) ([63301f9](63301f9))

### Performance Improvements

* **ci:** optimize GitHub Actions ([#3793](#3793)) ([e31287e](e31287e)), closes [#3791](#3791)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(analytics): PostHog plugin api_host bug + identify/group on login

2 participants