feat(enterprise): cloud whitelabeling for enterprise orgs#4047
feat(enterprise): cloud whitelabeling for enterprise orgs#4047waleedlatif1 merged 20 commits intostagingfrom
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
PR SummaryMedium Risk Overview Updates the workspace UI to consume org branding dynamically: a new Reviewed by Cursor Bugbot for commit ebe7e5c. Configure here. |
Greptile SummaryThis PR adds a cloud whitelabeling feature for enterprise orgs, storing per-org branding config (logo, colors, brand name, links, hide-powered-by toggle) in a new Confidence Score: 5/5Safe to merge — all previously flagged issues have been resolved and the two remaining findings are minor P2 suggestions. The critical concerns from prior review rounds (enterprise plan scope check, onSuccess→onSettled, auth layering) have all been addressed. The two new findings — a serial fetch waterfall causing a brief flash of default branding, and redundant CSS variable declarations in generateOrgThemeCSS — are both P2 style suggestions that do not affect correctness or data integrity. The migration is purely additive (nullable column), the API guards are correctly layered, and color values are strictly validated before CSS injection. apps/sim/ee/whitelabeling/components/branding-provider.tsx (waterfall fetch), apps/sim/ee/whitelabeling/org-branding-utils.ts (duplicate CSS declarations)
|
| Filename | Overview |
|---|---|
| apps/sim/app/api/organizations/[id]/whitelabel/route.ts | New GET/PUT API route for org whitelabel settings; enterprise plan check correctly scoped to target org, membership + role guards in place, audit logging wired |
| apps/sim/ee/whitelabeling/components/branding-provider.tsx | Client-side context provider merging instance and org branding; serial fetch waterfall (orgs → whitelabel) can cause brief flash of default colors |
| apps/sim/ee/whitelabeling/components/whitelabeling-settings.tsx | Settings form with logo upload, color pickers, link fields; render-phase setState pattern is consistent with other forms; enterprise/role guards applied behind billing flag |
| apps/sim/ee/whitelabeling/hooks/whitelabel.ts | React Query hooks for fetching and mutating whitelabel settings; correctly uses onSettled for cache invalidation, signal forwarded, staleTime set |
| apps/sim/ee/whitelabeling/org-branding-utils.ts | Merge helpers and CSS variable generator; duplicate CSS declarations when both primaryColor and primaryHoverColor are set (functionally correct but redundant) |
| apps/sim/ee/whitelabeling/org-branding.ts | Server-side org branding fetch utility, correctly logs errors and returns null on failure |
| apps/sim/lib/branding/types.ts | Adds OrganizationWhitelabelSettings interface as the shared source of truth for org branding fields |
| packages/db/schema.ts | Adds whitelabel_settings JSON column to the organization table; inline type is consistent with cross-package boundary constraints |
| packages/db/migrations/0188_short_luke_cage.sql | Additive migration: ALTER TABLE adds nullable json column — safe to run on live data |
| apps/sim/app/workspace/[workspaceId]/layout.tsx | Wraps workspace in BrandingProvider; correct placement ensures sidebar and all child components can consume org brand config |
| apps/sim/app/workspace/[workspaceId]/settings/navigation.ts | Adds whitelabeling nav item under enterprise section, correctly gated with requiresHosted and requiresEnterprise flags |
Sequence Diagram
sequenceDiagram
participant Browser
participant BrandingProvider
participant OrgQuery as useOrganizations()
participant WLQuery as useWhitelabelSettings()
participant API as /api/organizations/[id]/whitelabel
Browser->>BrandingProvider: Mount workspace layout
BrandingProvider->>OrgQuery: fetch active org
OrgQuery-->>BrandingProvider: { activeOrganization: { id } }
BrandingProvider->>WLQuery: fetch whitelabel settings (orgId)
WLQuery->>API: GET /api/organizations/:id/whitelabel
API-->>WLQuery: { data: OrganizationWhitelabelSettings }
WLQuery-->>BrandingProvider: orgSettings
BrandingProvider->>Browser: inject CSS vars + provide BrandConfig context
Note over Browser: Sidebar reads useOrgBrandConfig() → org logo & brand name
Browser->>API: PUT /api/organizations/:id/whitelabel
Note over API: Checks: session → member → admin/owner → enterprise plan
API-->>Browser: { data: updated settings }
Note over Browser: onSettled invalidates whitelabelKeys + organizationKeys.detail
Reviews (3): Last reviewed commit: "fix(enterprise): remove webp from logo a..." | Re-trigger Greptile
…mpty update result
|
@greptile |
|
@cursor review |
apps/sim/ee/whitelabeling/components/whitelabeling-settings.tsx
Outdated
Show resolved
Hide resolved
…ad hook validation
|
@greptile |
|
@cursor review |
|
@greptile |
|
@cursor review |
There was a problem hiding this comment.
✅ Bugbot reviewed your changes and found no new issues!
Comment @cursor review or bugbot run to trigger another review on this PR
Reviewed by Cursor Bugbot for commit ebe7e5c. Configure here.
…on non-hosted environments
…eturns /api/files/serve/ paths
…lash on repeat visits
…o flash before paint
…rg settings resolve
… remove mutation from useCallback deps
…sh on all page loads
… injection React Query returns isLoading: false with data: undefined during SSR, so the previous brandingLoading condition was always false on the server — initialCache was never injected into brandConfig. Changing to !orgSettings correctly applies the cookie cache both during SSR and while the client-side query loads, eliminating the logo flash on hard refresh.
Summary
whitelabel_settingsJSON column on theorganizationtableBrandingProviderReact context in the workspace layoutuseOrgBrandConfig()to reflect org branding liveGET/PUT/api/organizations/[id]/whitelabel) with session, membership, role, and enterprise plan checks + audit loggingprofile-picturesstorage context — no new bucket neededType of Change
Testing
Tested manually
Checklist