Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the You can disable this status message by setting the WalkthroughThis PR consolidates project creation into a modal-driven flow within the Dashboard component, removing the dedicated Changes
Sequence DiagramsequenceDiagram
actor User
participant Dashboard
participant Modal as Project Modal
participant API
participant DB
participant Toast
User->>Dashboard: Click "New Project" button
Dashboard->>Modal: Open modal (newProjectModalOpen = true)
User->>Modal: Enter project name & organisation
User->>Modal: Click Create button
Modal->>Dashboard: Trigger onCreateProject()
Dashboard->>Dashboard: Validate project name
Dashboard->>Dashboard: Set loading state
Dashboard->>API: POST createProject(name, organisationId)
API->>DB: Insert new project
DB-->>API: Project created
API-->>Dashboard: Return success
Dashboard->>API: Refetch projects list
API->>DB: Query projects
DB-->>API: Projects list
API-->>Dashboard: Updated projects
Dashboard->>Toast: Show success message
Dashboard->>Dashboard: Track analytics (trackCustom)
Dashboard->>Dashboard: Reset modal state & close
Estimated code review effort🎯 4 (Complex) | ⏱️ ~45 minutes
Poem
Pre-merge checks and finishing touches❌ Failed checks (1 warning, 1 inconclusive)
✅ Passed checks (1 passed)
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. Comment |
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (15)
web/app/pages/Onboarding/Onboarding.tsx (1)
27-27: Project name length handling is consistent but now locally definedUsing
MAX_PROJECT_NAME_LENGTHfor both validation andmaxLengthkeeps this form self-consistent, but defining the limit locally risks divergence from any shared project-name constraints used elsewhere.Consider reusing a shared constant (or adding a small comment here referencing the canonical limit) so onboarding and project settings stay in sync if the allowed length ever changes.
Also applies to: 151-165, 389-399
web/app/pages/UserSettings/UserSettings.tsx (1)
41-41: Headings migrated toTextcorrectly; consider future alignment for remaining headersThe new
Textusages for the main title and shared-projects heading look correct and preserve the existing semantics. For longer-term consistency, you might eventually migrate the remaining<h3>headings in this file toTextas well, but this is not blocking.Also applies to: 385-388, 432-434
web/app/pages/UserSettings/components/NoOrganisations.tsx (1)
3-4: Adjust heading level to avoid nestedh2under anh3This message is rendered inside the “Organisations” section, which already has an
<h3>heading inUserSettings.tsx. UsingText as='h2'here creates a heading level jump. Consider using a less prominent level or body text, e.g.:- <Text as='h2' size='2xl' className='mb-4 text-center leading-snug'> + <Text as='p' size='lg' className='mb-4 text-center leading-snug'>(or
as='h4'if you still want it treated as a subheading).Also applies to: 10-13
web/app/pages/Project/View/Panels.tsx (2)
35-36: Error boundary text migrated toTextcomponent; consider i18n laterUsing
Textfor the error copy inExtensionErrorBoundarystandardizes styling and keeps semantics (as='p',colour='error'). When you revisit this area, consider moving the hard‑coded English strings into the i18n layer to align with the rest of the UI.Also applies to: 94-105
755-773: Good use ofTextin metadata tab; consider tooltip for truncated valuesThe switch to
Textfor the “no param data” message, column headers, and row labels looks consistent and non‑breaking. For the event/property label:<Text size='sm' truncate> {ev} </Text>users may lose access to long names once truncated. Adding a tooltip via
titlewould preserve readability:- <Text size='sm' truncate> - {ev} - </Text> + <Text size='sm' truncate title={ev}> + {ev} + </Text>Also applies to: 805-823
web/app/pages/Project/View/components/Errors.tsx (1)
12-13: Typography refactor looks good; remove redundant font weight on wrapperMigrating the error name, filename, message, and count to
Textstandardizes styling and keeps semantics. The wrapper<p>around the name still hasfont-semiboldwhile the inner<Text>usesweight='bold', so the wrapper weight class is redundant. You can safely drop it:- <p className='flex items-center gap-x-2 leading-6 font-semibold'> + <p className='flex items-center gap-x-2 leading-6'>Also applies to: 75-83, 88-91, 106-110
web/app/ui/Text.tsx (1)
1-66:Textimplementation is solid; consider a generic polymorphic typing for better DXThe component correctly centralizes typography concerns (size/weight/colour/truncation) and forwards arbitrary props to the rendered element. From a type-safety/ergonomics perspective, you might want to evolve this to a generic polymorphic component so DOM props are inferred from
as, e.g.:type TextElement = keyof JSX.IntrinsicElements type TextOwnProps<C extends TextElement> = { as?: C size?: TextSize weight?: TextWeight colour?: TextColour truncate?: boolean className?: string children: React.ReactNode } type TextProps<C extends TextElement = 'span'> = TextOwnProps<C> & Omit<React.ComponentPropsWithoutRef<C>, keyof TextOwnProps<C>> export const Text = <C extends TextElement = 'span'>({ as, children, size = 'base', weight = 'normal', colour = 'primary', truncate, className, ...props }: TextProps<C>) => { const Component = as || 'span' return ( <Component className={cn(sizeClasses[size], weightClasses[weight], colourClasses[colour], { truncate }, className)} {...props} > {children} </Component> ) }This keeps the current runtime behavior but gives consumers proper IntelliSense and type‑checked attributes for the chosen element.
web/app/pages/Project/View/components/MetricCards.tsx (1)
13-14: Metric cards typography refactor is fine; consider label colour and a11y tweakThe move to
Textfor metric values and labels (including the select dropdown) is consistent and keeps layout intact. Two optional refinements:
Label colour parity – if the previous labels were using a more muted grey, you might want to explicitly set:
<Text size='sm' weight='bold' colour='secondary'>(or
colour='muted') to preserve that visual hierarchy instead of defaulting to the primary colour.Clickable select label – the select trigger is still a
<span>withonClick. For keyboard/a11y, consider making it a<button>with appropriate focus styles andaria-expandedinstead of a plain span.Also applies to: 76-82, 88-91, 121-127, 139-140, 147-149, 165-169
web/app/pages/Project/View/ViewProject.tsx (2)
3230-3250: MobileTabSelector tab switching logic looks sound, but consider undefined active label edge caseThe selector correctly special‑cases the
settingspseudo‑tab and delegates the rest tosetDashboardTab, so navigation stays in sync with URL state. One minor edge case: whenprojectQueryTabsfilters out the currentactiveTab,activeTabLabelandselectedItemwill beundefined, so the dropdown renders without a selected value until the user picks a tab. That’s acceptable, but if you want a slightly smoother UX you could defaulttitle/selectedItemback to the first available tab when no match is found.
3274-3297: Sidebar + main-content layout is duplicated across several branchesThe new desktop
ProjectSidebar+ main content structure is repeated in the locked, “no data yet”, “no error data”, and main render branches. This works functionally, but it will be easy to miss one branch when tweaking layout or padding later.Consider extracting a small wrapper (e.g.
ProjectLayout) that takeschildrenfor the main content and reuses the sidebar wiring (tabs,activeTab,setDashboardTab, etc.). That keeps all layout changes in one place without altering behavior.Also applies to: 3308-3331, 3346-3368, 3410-3425
web/app/pages/Project/View/components/ProjectSidebar.tsx (3)
70-79: Simplify the expand-on-active effect to avoid disabling exhaustive-depsThe
useEffectcurrently depends only onhasActiveTaband suppresses the exhaustive‑deps rule, even though it readsisExpanded:React.useEffect(() => { if (hasActiveTab && !isExpanded) { setIsExpanded(true) } }, [hasActiveTab]) // eslint-disable-line react-hooks/exhaustive-depsYou can drop the
!isExpandedcheck and rely on React’s no‑op state update behavior, which lets you remove the lint disable entirely:- React.useEffect(() => { - if (hasActiveTab && !isExpanded) { - setIsExpanded(true) - } - }, [hasActiveTab]) // eslint-disable-line react-hooks/exhaustive-deps + React.useEffect(() => { + if (hasActiveTab) { + setIsExpanded(true) + } + }, [hasActiveTab])This keeps the intent (“ensure the active group is open”) while staying hook‑lint‑clean.
114-157: Link handling and loading state in CollapsibleGroup are correct; consider small a11y enhancementsThe pattern of:
- Building
tabUrlfromsearchParamsfor analytics tabs,- Letting the
settingstab navigate directly toroutes.project_settings,- Short‑circuiting
onTabChangewhendataLoadingis true,all looks consistent and should avoid accidental tab switches mid‑load.
Two optional improvements:
- Add
aria-expandedto the group toggle button andaria-controlslinking it to the collapsible<nav>for better screen‑reader support.- Since
settingsis not currently in anyTabGroup, the special‑case logic fortab.id === 'settings'insideCollapsibleGroupis unused; you can either keep it as future‑proofing or remove it until a group actually includes that tab.
176-209: Grouping tabs into web/product analytics is straightforward but tightly coupled to PROJECT_TABSThe grouping logic correctly partitions the incoming
tabsintowebAnalyticsandproductAnalyticsusingPROJECT_TABS.*values. This works with the current tab set, but it does mean any new tab IDs will be invisible in the sidebar until this switch is updated.If you expect more categories later, consider encoding the group ID alongside each tab in the calling code and building
tabGroupsfrom that metadata instead of hard‑coding membership here. For now, behavior is fine as‑is.web/app/pages/Dashboard/Dashboard.tsx (2)
47-49: Project name validation mostly mirrors settings, but consider trimming and aligning with DEFAULT_PROJECT_NAME behaviorThe new constants and
validateProjectNamecover “required” and max‑length constraints, which is good. A couple of minor inconsistencies to watch:
submitDisabled={!newProjectName}means the user can’t submit when the input is empty, so theDEFAULT_PROJECT_NAMEfallback is effectively unreachable. Either drop the fallback or relaxsubmitDisabledif you genuinely want unnamed projects to default to “Untitled Project”.validateProjectNamechecks_isEmpty(newProjectName)and_size(newProjectName)without trimming. A name of just spaces will pass validation and bypass the fallback. Trimming before validation and before passing the value tocreateProjectwould give cleaner data.Both are easy to adjust and keep the dashboard modal behavior in line with project settings.
Also applies to: 111-131
643-685: New project Modal wiring is solid; consider clearing errors on input changeThe modal is wired correctly:
isLoading/onSubmit/submitDisabledall point at the new creation flow.Inputshows validation/server errors only after the first submit vianewProjectBeenSubmitted.- Organisation
Selectis shown only when there are multiple eligible orgs, with a “not set” option.One small UX improvement: clear
newProjectErrorwhen the user editsnewProjectNameor changes organisation, so stale server errors disappear as soon as they adjust the form:onChange={(e) => { - setNewProjectName(e.target.value) + setNewProjectName(e.target.value) + if (newProjectError) setNewProjectError(null) }}Not required for correctness but makes the form feel less “stuck” after a failed attempt.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (31)
web/app/modals/NewFunnel.tsx(2 hunks)web/app/pages/Dashboard/AddProject.tsx(3 hunks)web/app/pages/Dashboard/Dashboard.tsx(9 hunks)web/app/pages/Dashboard/NoProjects.tsx(2 hunks)web/app/pages/Dashboard/ProjectCard.tsx(3 hunks)web/app/pages/NotFound/index.tsx(2 hunks)web/app/pages/Onboarding/Onboarding.tsx(1 hunks)web/app/pages/Organisations/NoOrganisations.tsx(2 hunks)web/app/pages/Organisations/OrganisationCard.tsx(2 hunks)web/app/pages/Organisations/Organisations.tsx(4 hunks)web/app/pages/Project/New/index.tsx(0 hunks)web/app/pages/Project/View/Panels.tsx(6 hunks)web/app/pages/Project/View/ViewProject.tsx(9 hunks)web/app/pages/Project/View/components/CurrentTime.tsx(3 hunks)web/app/pages/Project/View/components/Errors.tsx(3 hunks)web/app/pages/Project/View/components/FunnelsList.tsx(3 hunks)web/app/pages/Project/View/components/MetricCards.tsx(4 hunks)web/app/pages/Project/View/components/NoErrorDetails.tsx(2 hunks)web/app/pages/Project/View/components/NoEvents.tsx(3 hunks)web/app/pages/Project/View/components/NoSessionDetails.tsx(2 hunks)web/app/pages/Project/View/components/ProjectSidebar.tsx(1 hunks)web/app/pages/Project/View/components/WaitingForAnEvent.tsx(3 hunks)web/app/pages/UserSettings/UserSettings.tsx(3 hunks)web/app/pages/UserSettings/components/NoOrganisations.tsx(1 hunks)web/app/pages/UserSettings/components/NoSharedProjects.tsx(1 hunks)web/app/routes/projects.new.tsx(0 hunks)web/app/ui/Input.tsx(1 hunks)web/app/ui/Text.tsx(1 hunks)web/app/utils/routes.ts(0 hunks)web/app/utils/server.ts(0 hunks)web/public/locales/en.json(1 hunks)
💤 Files with no reviewable changes (4)
- web/app/routes/projects.new.tsx
- web/app/utils/server.ts
- web/app/utils/routes.ts
- web/app/pages/Project/New/index.tsx
🧰 Additional context used
🧬 Code graph analysis (23)
web/app/pages/Project/View/components/NoSessionDetails.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/NoErrorDetails.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/UserSettings/components/NoOrganisations.tsx (2)
web/app/pages/Organisations/NoOrganisations.tsx (1)
NoOrganisations(10-33)web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Dashboard/ProjectCard.tsx (2)
web/app/ui/Text.tsx (1)
Text(50-66)web/app/utils/generic.ts (1)
nFormatter(20-24)
web/app/modals/NewFunnel.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Organisations/NoOrganisations.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Dashboard/NoProjects.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/WaitingForAnEvent.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/Errors.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/NoEvents.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/ui/Text.tsx (1)
web/app/utils/generic.ts (1)
cn(150-152)
web/app/pages/Project/View/components/CurrentTime.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/UserSettings/components/NoSharedProjects.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/NotFound/index.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/FunnelsList.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Organisations/Organisations.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/UserSettings/UserSettings.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/MetricCards.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/ViewProject.tsx (2)
web/app/lib/constants/index.ts (1)
PROJECT_TABS(490-492)web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Dashboard/Dashboard.tsx (4)
web/app/lib/constants/index.ts (1)
isSelfhosted(399-399)web/app/api/index.ts (1)
createProject(410-416)web/app/utils/analytics.ts (1)
trackCustom(181-190)web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/components/ProjectSidebar.tsx (2)
web/app/lib/constants/index.ts (1)
PROJECT_TABS(490-492)web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Organisations/OrganisationCard.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
web/app/pages/Project/View/Panels.tsx (1)
web/app/ui/Text.tsx (1)
Text(50-66)
🔇 Additional comments (25)
web/app/ui/Input.tsx (1)
39-49: Input ring styling change looks goodAdding
ring-insetis a safe, purely visual tweak and keeps the rest of the input behavior unchanged.web/public/locales/en.json (1)
840-842: New analytics dashboard labels are well-placedThe added
webAnalytics,productAnalytics, andrevenueAnalyticskeys are consistent with existing dashboard copy and JSON structure.web/app/pages/Project/View/components/NoSessionDetails.tsx (1)
4-5: Typography migration to Text is cleanReplacing the raw
h1/pwithTextkeeps semantics and styles aligned while standardising typography on the shared component.Also applies to: 16-21
web/app/modals/NewFunnel.tsx (1)
13-14: Funnel steps label now uses shared Text componentUsing
Texthere aligns the modal’s steps label with the new typography system without affecting validation or submit logic.Also applies to: 92-94
web/app/pages/Dashboard/ProjectCard.tsx (1)
23-24: Dashboard card typography refactor is safe and consistentUsing
Textfor metric labels, totals, and project name centralises styling while preserving truncation and layout; the surrounding logic and data handling remain unchanged.Also applies to: 51-63, 229-232
web/app/pages/Organisations/OrganisationCard.tsx (1)
17-18: Organisation name rendering updated to TextSwitching the organisation name to
Textmaintains truncation and semantics while aligning with the shared typography component used elsewhere.Also applies to: 130-132
web/app/pages/Organisations/NoOrganisations.tsx (1)
4-5: Empty state now uses shared Text componentThe NoOrganisations empty state correctly delegates heading and body styling to
Text, keeping layout intact and centralising typography.Also applies to: 14-23
web/app/pages/Project/View/components/NoErrorDetails.tsx (1)
4-5: Typography refactor is semantically safe and consistentUsing
Textwithas='h1'/as='p', explicitsize/weightandcolour='secondary'preserves heading semantics and improves consistency without changing behavior.Also applies to: 16-21
web/app/pages/Project/View/components/NoEvents.tsx (1)
5-5: No-events layout now usesTextconsistently; behavior unchangedTitle and body copy are correctly migrated to
Textwith appropriateas,size, andweightprops in both branches, and the sharedmax-w-7xlwrapper keeps the two states visually aligned. Looks good from a semantics and layout perspective.Also applies to: 23-29, 41-47
web/app/pages/Project/View/components/WaitingForAnEvent.tsx (1)
7-7: Waiting-for-event copy migrated cleanly toTextThe refactor to
Textfor the title and description keeps the structure andTransbehavior intact while delegating typography and theming to the shared component. No functional or accessibility regressions spotted.Also applies to: 17-25
web/app/pages/Project/View/components/FunnelsList.tsx (1)
10-10: Funnel labels now useTextwith correct semantics and truncationUsing
Textforfunnel.name(withas='p',weight='semibold',truncate) and for the “New Funnel” label (as aspan) preserves previous behavior while centralizing typography. The surrounding navigation and click handlers remain unchanged.Also applies to: 51-53, 110-112
web/app/pages/NotFound/index.tsx (1)
5-5: 404 page typography refactor keeps semantics and layout intactThe 404 label, title, and description are correctly migrated to
Textwith appropriateas,size, andweightvalues. Usingcolour='muted'for the description is a good fit, assuming it’s wired incolourClasses/TextProps; otherwise no behavioral changes are introduced.Also applies to: 17-27
web/app/pages/Project/View/components/CurrentTime.tsx (1)
10-10: Current-time tooltip now leveragesTextwithout altering logicWrapping the timezone line, helper hint, and trigger text in
Textcomponents (with appropriatesize,weight, andcolour) keeps the tooltip behavior andTransmarkup intact while standardizing typography.Also applies to: 31-36, 40-62
web/app/pages/UserSettings/components/NoSharedProjects.tsx (1)
3-13: Consistent adoption ofTextfor the empty‑state headingUsing
<Text as='h2' size='2xl'>here keeps the semantic heading while centralizing typography in the shared component; layout and i18n usage remain unchanged.web/app/pages/Organisations/Organisations.tsx (2)
24-25: Title rewritten to useTextwithout changing behaviorThe main organisations heading now uses
<Text as='h2' size='3xl' weight='bold'>, which matches the previous semantics while routing typography through the shared component; surrounding search toggle logic and layout remain intact.Also applies to: 184-219
344-347: Error message usesTextwith the correct semantic and colourRendering
newOrganisationErrorvia<Text as='p' size='sm' weight='medium' colour='error'>cleanly replaces the previous styled paragraph while preserving spacing and clearly signalling the error state.web/app/pages/Project/View/Panels.tsx (2)
179-183: Panel header correctly usesTextfor semantics and style
<Text as='h3' size='lg' weight='semibold'>preserves the heading level and prior visual weight while delegating colours and font sizing to the shared typography system; theiconandnamecomposition is unchanged.
439-444: KV table “no data” message now uses shared typographyReturning a
<Text as='p' size='base' colour='secondary'>for the empty state keeps the same UX while aligning with the new text system.web/app/pages/Dashboard/AddProject.tsx (1)
7-8: Button-based trigger is appropriate; verify Tailwind class and call sitesSwitching
AddProjectto a<button type='button'>withonClick: () => voidmatches the new modal‑driven flow and improves semantics over a link.Two things to double‑check:
- Call sites – ensure all usages of
AddProjecthave been updated to pass a zero‑arg callback (no longer rely on the click event).- Tailwind class –
lg:min-h-autoisn’t part of core Tailwind; if you don’t have a custom utility for it, consider reverting tomin-h-[auto]or another supported value to avoid the class being dropped at build time.Also applies to: 16-18, 24-25, 39-39
web/app/pages/Dashboard/NoProjects.tsx (1)
6-7: Empty-state text and create-project trigger align with new patterns; confirmonClickusageBoth branches now render their copy via
Text(as='h3'/as='p'with appropriate sizes/colours), and the “create project” action uses a semantic<button type='button'>, which fits the modal-based flow.As with
AddProject, please just confirm:
- All
NoProjectsconsumers have been updated to pass a zero‑argumentonClickhandler.- Any navigation previously handled via routing is now correctly wired in that handler.
Also applies to: 23-25, 32-41, 43-45, 50-50
web/app/pages/Project/View/ViewProject.tsx (1)
3447-3453: Text component usage for funnel heading and “no segments” label is consistentUsing
Text as='h2'for the active funnel name andText colour='secondary'for the non‑clickable “no segments yet” entry aligns with the new typography system and preserves semantics. Just ensurecolour='secondary'is covered bycolourClassesin~/ui/Text(it appears to be, based on other usages in the PR).Also applies to: 3517-3518
web/app/pages/Project/View/components/ProjectSidebar.tsx (1)
212-259: Project header and bottom settings link are wired correctlyUsing
Tooltip+Text as='h2'for the project name header and a separate sticky bottomSettingslink (guarded byallowedToManage) keeps the sidebar focused and avoids mixing settings into the analytics groups. The icon color mapping viaICON_COLORS.settingsis also consistent.No functional issues spotted here.
web/app/pages/Dashboard/Dashboard.tsx (3)
189-211: New project trigger preserves email-activation gate and cleanly opens the modal
onNewProjectstill blocks inactive cloud users viashowActivateEmailModaland otherwise only togglesnewProjectModalOpen. This reuses the existing activation flow and avoids route-based navigation, which is exactly what you want with the new modal approach.No issues here.
248-258: closeNewProjectModal correctly guards against closing mid-submit and resets stateThe close handler’s early return when
isNewProjectLoadingis true plus the full reset of name, organisation, error, and “beenSubmitted” flag should prevent mid-flight closures and stale errors in subsequent opens.This looks good.
425-461: Dashboard title refactor to Text is consistent with the new typography systemReplacing the raw
<h2>withText as='h2' size='3xl' weight='bold'keeps existing semantics while aligning this header with the shared typography component used elsewhere in the PR. The surrounding search-toggle controls are unchanged functionally.No further changes needed here.
Changes
Community Edition support
Database migrations
Documentation
Summary by CodeRabbit
New Features
Refactor
✏️ Tip: You can customize this high-level summary in your review settings.