Skip to content
Merged
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
79a58ef
fix: dept from path guard
AndlerRL Dec 2, 2025
da775f9
fix: workspace structure chk missing project in dept
AndlerRL Dec 2, 2025
235fe8e
Merge branch 'develop' into bugfix/workspace-structure
AndlerRL Dec 2, 2025
a2f3b80
fix: department n threads navigation
AndlerRL Dec 3, 2025
133cb74
fix: workspace active navigation persistent state
AndlerRL Dec 4, 2025
2c5d35f
style: header component clean up
AndlerRL Dec 4, 2025
1598bb3
fix: css build
AndlerRL Dec 4, 2025
379cc6b
fix: new proj among dept + thread refresh & filter
AndlerRL Dec 9, 2025
0a34914
chore: upt nextjs ver
AndlerRL Dec 9, 2025
47b7139
chore: upt react ver
AndlerRL Dec 9, 2025
264fe8c
Merge branch 'develop' into bugfix/workspace-structure
AndlerRL Dec 9, 2025
559553a
chore: rm legacy component
AndlerRL Dec 9, 2025
4aee8b7
chore: rm legacy component
AndlerRL Dec 9, 2025
29b9479
chore: rm legacy files
AndlerRL Dec 9, 2025
7778cb6
fix: project list, org list, thread list filter
AndlerRL Dec 11, 2025
8c81d60
Merge branch 'develop' into bugfix/workspace-navigation-v2
AndlerRL Dec 11, 2025
fb84c4a
Merge branch 'develop' into bugfix/workspace-navigation-v2
AndlerRL Dec 15, 2025
b8c8043
revert: fix sync merge
AndlerRL Dec 15, 2025
eabbf5c
fix: initial threads & count with latest org state
AndlerRL Dec 16, 2025
ccd6b28
fix: hasura org table rls
AndlerRL Dec 16, 2025
af0f6fe
fix: hasura pref table rls
AndlerRL Dec 16, 2025
7fe730e
fix: document save race condition + active state + navigation filter …
AndlerRL Dec 16, 2025
b9e701c
fix: default user pref at sign up
AndlerRL Dec 16, 2025
0dbfa66
fix: rm misplaced import
AndlerRL Dec 16, 2025
7e17ada
fix: create & save new document from draft
AndlerRL Dec 17, 2025
518347f
fix: new draft, doc & org upt & workspace doc nav pathname upt
AndlerRL Dec 18, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ object_relationships:
- name: complexityEnum
using:
foreign_key_constraint_on: default_complexity
- name: department
using:
foreign_key_constraint_on: department_id
- name: lengthEnum
using:
foreign_key_constraint_on: default_length
Expand Down Expand Up @@ -36,6 +39,13 @@ array_relationships:
table:
name: chatbot_domain
schema: public
- name: organization_chatbots
using:
foreign_key_constraint_on:
column: chatbot_id
table:
name: organization_chatbot
schema: public
- name: prompts
using:
foreign_key_constraint_on:
Expand All @@ -56,7 +66,6 @@ select_permissions:
columns:
- avatar
- chatbot_id
- chatbot_id
- created_by
- default_complexity
- default_length
Expand All @@ -75,20 +84,20 @@ select_permissions:
- role: moderator
permission:
columns:
- disabled
- is_pro
- pro_exclusive
- chatbot_id
- department_id
- order
- avatar
- chatbot_id
- created_by
- default_complexity
- default_length
- default_tone
- default_type
- department_id
- description
- disabled
- name
- order
filter: {}
allow_aggregations: true
comment: ""
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,15 @@ table:
name: organization
schema: public
object_relationships:
- name: organization_preference
using:
manual_configuration:
column_mapping:
name: latest_organization
insertion_order: null
remote_table:
name: preference
schema: public
Comment on lines +5 to +13
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion | 🟠 Major

Fragile relationship: references organization by name instead of ID.

This relationship maps organization.name (text) to preference.latest_organization (text), which is fragile for the same reasons outlined in the migration review:

  • No referential integrity if names aren't constrained.
  • Name changes would break existing preferences.
  • Less performant than ID-based joins.

If you refactor the migration to use latest_organization_id instead of latest_organization, update this relationship accordingly:

   - name: organization_preference
     using:
       manual_configuration:
         column_mapping:
-          name: latest_organization
+          organization_id: latest_organization_id
         insertion_order: null
         remote_table:
           name: preference
           schema: public

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/hasura/metadata/databases/masterbots/tables/public_organization.yaml
around lines 5-13, the manual relationship maps organization.name to
preference.latest_organization (text) which is fragile; update the relationship
to map organization.id to preference.latest_organization_id instead. Change the
column_mapping to use id: latest_organization_id, ensure the remote_table column
name is updated to the new preference column, and confirm the preference table
has the latest_organization_id column with the correct type and a foreign key
constraint to public.organization.id (or add it if missing) so the Hasura
relationship is ID-based and consistent.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n apps/hasura/metadata/databases/masterbots/tables/public_organization.yaml

Repository: bitcashorg/masterbots

Length of output: 2115


🏁 Script executed:

find . -type f \( -name "*.sql" -o -name "*.yaml" \) | xargs grep -l "preference" | head -20

Repository: bitcashorg/masterbots

Length of output: 1729


🏁 Script executed:

cat -n apps/hasura/metadata/databases/masterbots/tables/public_preference.yaml

Repository: bitcashorg/masterbots

Length of output: 3958


🏁 Script executed:

head -100 apps/hasura/migrations/masterbots/1698804096149_init/up.sql | grep -A 30 "CREATE TABLE.*preference"

Repository: bitcashorg/masterbots

Length of output: 47


🏁 Script executed:

rg -n "CREATE TABLE.*preference" --type sql

Repository: bitcashorg/masterbots

Length of output: 261


🏁 Script executed:

sed -n '61,120p' packages/mb-drizzle/src/drizzle/0000_pink_lionheart.sql

Repository: bitcashorg/masterbots

Length of output: 2011


🏁 Script executed:

cat -n apps/hasura/metadata/databases/masterbots/tables/public_organization.yaml | head -20

Repository: bitcashorg/masterbots

Length of output: 672


🏁 Script executed:

rg -n "CREATE TABLE.*organization" --type sql

Repository: bitcashorg/masterbots

Length of output: 963


🏁 Script executed:

rg -n "latest_organization" --type sql

Repository: bitcashorg/masterbots

Length of output: 449


🏁 Script executed:

cat apps/hasura/migrations/masterbots/1765857892283_alter_table_public_preference_add_column_latest_organization/up.sql

Repository: bitcashorg/masterbots

Length of output: 143


Change organization_preference from object_relationship to array_relationship.

The latest_organization column in the preference table has no unique constraint, allowing multiple preference records to share the same organization name. This creates a one-to-many relationship from organization to preferences, which must be modeled as an array_relationship rather than object_relationship. An object_relationship will only return the first matching preference, silently omitting others.

Apply this change:

-object_relationships:
+array_relationships:
   - name: organization_preference
     using:
       manual_configuration:
         column_mapping:
           name: latest_organization
         insertion_order: null
         remote_table:
           name: preference
           schema: public

Committable suggestion skipped: line range outside the PR's diff.

🤖 Prompt for AI Agents
In apps/hasura/metadata/databases/masterbots/tables/public_organization.yaml
around lines 5-13, the relationship currently defined for
"organization_preference" is modeled as an object_relationship but must be an
array_relationship; change the relationship type from object_relationship to
array_relationship by moving this relationship entry under the
array_relationships section (preserving the existing name, manual_configuration,
column_mapping, insertion_order and remote_table fields) so the organization ->
preferences relation returns an array of matching preference rows instead of a
single object.

- name: user
using:
foreign_key_constraint_on: user_id
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ insert_permissions:
- favorite
- font_size
- lang
- latest_organization
- preferred_complexity
- preferred_length
- preferred_tone
Expand All @@ -38,13 +39,14 @@ insert_permissions:
check:
user_id:
_eq: X-Hasura-User-Id
set:
user_id: X-Hasura-User-Id
set:
user_id: X-Hasura-User-Id
columns:
- deep_expertise
- favorite
- font_size
- lang
- latest_organization
- preferred_complexity
- preferred_length
- preferred_tone
Expand All @@ -56,17 +58,7 @@ select_permissions:
- role: anonymous
permission:
columns:
- deep_expertise
- favorite
- font_size
- lang
- preference_id
- preferred_complexity
- preferred_length
- preferred_tone
- preferred_type
- user_id
- web_search
filter: {}
comment: ""
- role: moderator
Expand All @@ -76,6 +68,7 @@ select_permissions:
- favorite
- font_size
- lang
- latest_organization
- preference_id
- preferred_complexity
- preferred_length
Expand All @@ -92,14 +85,17 @@ select_permissions:
- favorite
- font_size
- lang
- latest_organization
- preference_id
- preferred_complexity
- preferred_length
- preferred_tone
- preferred_type
- user_id
- web_search
filter: {}
filter:
user_id:
_eq: X-Hasura-User-Id
comment: ""
update_permissions:
- role: moderator
Expand All @@ -109,10 +105,12 @@ update_permissions:
- favorite
- font_size
- lang
- latest_organization
- preferred_complexity
- preferred_length
- preferred_tone
- preferred_type
- user_id
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Critical: Allowing user_id updates creates a security vulnerability.

Permitting user_id to be updated in both moderator and user roles allows preferences to be reassigned to different users. This could enable:

  • Users modifying the user_id on their preferences to associate them with other users
  • Potential privilege escalation or data corruption
  • Breaking the integrity of user-preference ownership

The user_id foreign key should be immutable after creation.

Remove user_id from the updatable columns:

  - role: moderator
    permission:
      columns:
        - deep_expertise
        - favorite
        - font_size
        - lang
        - latest_organization
        - preferred_complexity
        - preferred_length
        - preferred_tone
        - preferred_type
-       - user_id
        - web_search
  - role: user
    permission:
      columns:
        - deep_expertise
        - favorite
        - font_size
        - lang
        - latest_organization
        - preferred_complexity
        - preferred_length
        - preferred_tone
        - preferred_type
-       - user_id
        - web_search

Also applies to: 130-130

🤖 Prompt for AI Agents
In apps/hasura/metadata/databases/masterbots/tables/public_preference.yaml
around lines 113 and 130, remove "user_id" from the list of updatable columns
for roles (both moderator and user) so the foreign key cannot be changed after
creation; ensure "user_id" remains allowed for inserts (creation) but is omitted
from any update permission blocks and related computed/update checks so
ownership cannot be reassigned.

- web_search
filter: {}
check: null
Expand All @@ -124,10 +122,12 @@ update_permissions:
- favorite
- font_size
- lang
- latest_organization
- preferred_complexity
- preferred_length
- preferred_tone
- preferred_type
- user_id
- web_search
filter:
user_id:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,13 @@ array_relationships:
table:
name: social_following
schema: public
- name: organizations
using:
foreign_key_constraint_on:
column: user_id
table:
name: organization
schema: public
- name: preferences
using:
foreign_key_constraint_on:
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Could not auto-generate a down migration.
-- Please write an appropriate down migration for the SQL below:
-- alter table "public"."preference" add column "latest_organization" text
-- null;
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
alter table "public"."preference" add column "latest_organization" text
null;
Comment on lines +1 to +2
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

Add foreign key constraint to ensure referential integrity.

The latest_organization column lacks a foreign key constraint to public.organization, allowing insertion of invalid organization names and creating orphaned references if organizations are deleted or renamed.

Apply this diff to add the constraint:

 alter table "public"."preference" add column "latest_organization" text
- null;
+ null constraint fk_preference_latest_organization 
+ references "public"."organization"("name") on delete set null;

Note: This assumes organization.name is unique. If not, see the next comment about using organization_id instead.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
alter table "public"."preference" add column "latest_organization" text
null;
alter table "public"."preference" add column "latest_organization" text
null constraint fk_preference_latest_organization
references "public"."organization"("name") on delete set null;
🤖 Prompt for AI Agents
In
apps/hasura/migrations/masterbots/1765857892283_alter_table_public_preference_add_column_latest_organization/up.sql
around lines 1-2, the new latest_organization text column has no foreign key
constraint to public.organization, allowing invalid/orphaned values; add a
foreign key constraint referencing public.organization(name) (ensuring
organization.name is unique) or, if name is not unique, change to storing
organization_id and add a foreign key to public.organization(id); alter the
migration to ALTER TABLE public.preference ADD CONSTRAINT
fk_preference_latest_org FOREIGN KEY (latest_organization) REFERENCES
public.organization(name) or the equivalent organization_id-based constraint and
ensure any existing data respects the constraint (or add a safe data
migration/cleanup step before applying).

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# First, find all migration files to understand the schema
echo "=== Finding migration files ==="
find apps/hasura/migrations/masterbots -type f -name "*.sql" | head -20

echo -e "\n=== Checking organization table definition ==="
# Look for organization table creation
find apps/hasura/migrations/masterbots -type f -name "*.sql" -exec grep -l "create.*table.*organization" -i {} \;

echo -e "\n=== Searching for unique constraints on organization.name ==="
find apps/hasura/migrations/masterbots -type f -name "*.sql" -exec rg -l "unique.*name|unique.*constraint" {} \; | head -10

Repository: bitcashorg/masterbots

Length of output: 2602


🏁 Script executed:

#!/bin/bash
# Search for references to organization in migration files
echo "=== Looking for foreign keys and references to organization ==="
find apps/hasura/migrations/masterbots -type f -name "*.sql" -exec rg -H "organization_id|references.*organization" {} \;

echo -e "\n=== Checking the preference table related migrations ==="
find apps/hasura/migrations/masterbots -type f -name "*preference*" | sort

Repository: bitcashorg/masterbots

Length of output: 1081


🏁 Script executed:

#!/bin/bash
# Examine the migration file in question and surrounding files
echo "=== Migration file content ==="
cat apps/hasura/migrations/masterbots/1765857892283_alter_table_public_preference_add_column_latest_organization/up.sql

echo -e "\n=== Checking down migration ==="
cat apps/hasura/migrations/masterbots/1765857892283_alter_table_public_preference_add_column_latest_organization/down.sql 2>/dev/null || echo "No down migration found"

echo -e "\n=== Looking at preference table definition ==="
find apps/hasura/migrations/masterbots -type f -name "*preference*" | while read f; do echo "File: $f"; cat "$f"; echo "---"; done

Repository: bitcashorg/masterbots

Length of output: 450


🏁 Script executed:

#!/bin/bash
# Check for unique constraints on organization table specifically
echo "=== Organization table creation ==="
cat apps/hasura/migrations/masterbots/1761768880712_create_table_public_organization/up.sql

echo -e "\n=== Check for any constraints added to organization.name ==="
find apps/hasura/migrations/masterbots -type f -name "*.sql" -exec rg -H "organization.*name|alter.*organization" -A3 -B1 {} \;

echo -e "\n=== Search for all columns named 'organization' to see common patterns ==="
find apps/hasura/migrations/masterbots -type f -name "*.sql" -exec rg -H "\"organization\"" {} \; | head -30

echo -e "\n=== Check if latest_organization is used elsewhere ==="
rg -r "latest_organization" apps/hasura/migrations/masterbots

Repository: bitcashorg/masterbots

Length of output: 3134


Use organization_id instead of storing organization by name.

The organization.name column has no UNIQUE constraint, making name-based references fragile. Additionally, the codebase follows the pattern of using organization_id (UUID) for organization relationships, as seen in the organization_chatbot table. Storing the latest organization as a text column without a foreign key constraint introduces data integrity risks.

Refactor to use an ID-based foreign key instead:

alter table "public"."preference" add column "latest_organization_id" uuid
 null constraint fk_preference_latest_organization 
 references "public"."organization"("organization_id") on delete set null;
🤖 Prompt for AI Agents
In
apps/hasura/migrations/masterbots/1765857892283_alter_table_public_preference_add_column_latest_organization/up.sql
around lines 1-2, the migration adds latest_organization as text which is
fragile and not referentially safe; replace this with a UUID foreign key column
latest_organization_id that references public.organization(organization_id) with
an ON DELETE SET NULL behavior and a named constraint (e.g.,
fk_preference_latest_organization), and remove or avoid adding the text column
so the preference table stores an organization_id relation consistent with the
rest of the schema.

This file was deleted.

This file was deleted.

This file was deleted.

3 changes: 0 additions & 3 deletions apps/hasura/seeds/masterbots/1738179687443_init_tag_enum.sql

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { isProAuthorized } from '@/lib/auth-utils'
import { botNames } from '@/lib/constants/bots-names'
import { WHITELIST_USERS } from '@/lib/constants/config'
import { PAGE_SIZE } from '@/lib/constants/hasura'
import { getChatbot, getThreads } from '@/services/hasura'
import { getChatbot, getThreads, getUserPreferences } from '@/services/hasura'
import { isTokenExpired } from 'mb-lib'
import { getServerSession } from 'next-auth'
import dynamic from 'next/dynamic'
Expand Down Expand Up @@ -61,11 +61,23 @@ export default async function BotThreadPopUpQuestionPage(props: {
throw new Error('User ID is missing.')
}

const { data: userPreferences } = await getUserPreferences(
userId,
jwt as string,
)
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
chatbotName,
jwt: jwt as string,
userId,
limit: PAGE_SIZE,
...latestOrganization,
})

// if (!isProAuthorized(session.user)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { isProAuthorized } from '@/lib/auth-utils'
import { botNames } from '@/lib/constants/bots-names'
import { WHITELIST_USERS } from '@/lib/constants/config'
import { PAGE_SIZE } from '@/lib/constants/hasura'
import { getChatbot, getThreads } from '@/services/hasura'
import { getChatbot, getThreads, getUserPreferences } from '@/services/hasura'
import { isTokenExpired } from 'mb-lib'
import { getServerSession } from 'next-auth'
import dynamic from 'next/dynamic'
Expand Down Expand Up @@ -61,11 +61,23 @@ export default async function BotThreadPopUpPage(props: {
throw new Error('User ID is missing.')
}

const { data: userPreferences } = await getUserPreferences(
userId,
jwt as string,
)
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
chatbotName,
jwt: jwt as string,
userId,
limit: PAGE_SIZE,
...latestOrganization,
})

// if (!isProAuthorized(session.user)) {
Expand Down
14 changes: 13 additions & 1 deletion apps/pro-web/app/(pro)/[category]/[domain]/[chatbot]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { botNames } from '@/lib/constants/bots-names'
import { WHITELIST_USERS } from '@/lib/constants/config'
import { PAGE_SIZE } from '@/lib/constants/hasura'
import { generateMetadataFromSEO } from '@/lib/metadata'
import { getChatbot, getThreads } from '@/services/hasura'
import { getChatbot, getThreads, getUserPreferences } from '@/services/hasura'
import { isTokenExpired } from 'mb-lib'
import type { Metadata } from 'next'
import { getServerSession } from 'next-auth'
Expand Down Expand Up @@ -62,11 +62,23 @@ export default async function BotThreadsPage(props: {
throw new Error('User ID is missing.')
}

const { data: userPreferences } = await getUserPreferences(
userId,
jwt as string,
)
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
chatbotName,
jwt: jwt as string,
userId,
limit: PAGE_SIZE,
...latestOrganization,
})

// if (!isProAuthorized(session.user)) {
Expand Down
18 changes: 17 additions & 1 deletion apps/pro-web/app/(pro)/[category]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ import { isProAuthorized } from '@/lib/auth-utils'
import { WHITELIST_USERS } from '@/lib/constants/config'
import { PAGE_SIZE } from '@/lib/constants/hasura'
import { generateMetadataFromSEO } from '@/lib/metadata'
import { getDepartments, getThreads } from '@/services/hasura'
import {
getDepartments,
getThreads,
getUserPreferences,
} from '@/services/hasura'
import type { PageProps } from '@/types'
import { isTokenExpired, toSlug } from 'mb-lib'
import type { Metadata } from 'next'
Expand Down Expand Up @@ -37,11 +41,23 @@ export default async function ChatCategoryPage(props: PageProps) {
const department = departments.find(
(department) => toSlug(department.name) === params.category,
)
const { data: userPreferences } = await getUserPreferences(
session.user.id,
jwt,
)
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
jwt,
userId: session?.user.id,
departmentId: department?.departmentId,
limit: PAGE_SIZE,
...latestOrganization,
})

// if (!isProAuthorized(session.user)) {
Expand Down
14 changes: 13 additions & 1 deletion apps/pro-web/app/(pro)/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { isProAuthorized } from '@/lib/auth-utils'
import { PAGE_SIZE } from '@/lib/constants/hasura'
import { generateMetadataFromSEO } from '@/lib/metadata'
import { type RoleTypes, isAdminOrModeratorRole } from '@/lib/utils'
import { getThreads } from '@/services/hasura'
import { getThreads, getUserPreferences } from '@/services/hasura'
import type { PageProps } from '@/types'
import { isTokenExpired } from 'mb-lib'
import type { Metadata } from 'next'
Expand Down Expand Up @@ -36,10 +36,22 @@ export default async function IndexPage() {
redirect('/auth/signin')
}

const { data: userPreferences } = await getUserPreferences(
session.user.id,
jwt,
)
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
jwt,
userId: session?.user.id,
limit: PAGE_SIZE,
...latestOrganization,
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Missing error handling for getUserPreferences.

The error returned by getUserPreferences is destructured but never used. If the preferences fetch fails, the error is silently ignored, and threads will load without organization filtering. Consider logging the error for debugging purposes.

Apply this diff to add error logging:

 	const { data: userPreferences, error } = await getUserPreferences(
 		session.user.id,
 		jwt,
 	)
+	if (error) {
+		console.error('Failed to fetch user preferences:', error)
+	}
 	const latestOrganization = userPreferences?.latestOrganization

Consider extracting repeated getUserPreferences logic.

This pattern of fetching user preferences and deriving latestOrganization is repeated across multiple page files. Consider extracting it into a shared helper function to reduce duplication and ensure consistent behavior.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const { data: userPreferences } = await getUserPreferences(
session.user.id,
jwt,
)
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
jwt,
userId: session?.user.id,
limit: PAGE_SIZE,
...latestOrganization,
const { data: userPreferences, error } = await getUserPreferences(
session.user.id,
jwt,
)
if (error) {
console.error('Failed to fetch user preferences:', error)
}
const latestOrganization = userPreferences?.latestOrganization
? {
organizationData: {
organization: userPreferences.latestOrganization,
},
}
: {}
const { threads, count } = await getThreads({
jwt,
userId: session?.user.id,
limit: PAGE_SIZE,
...latestOrganization,

})

// if (!isProAuthorized(session.user)) {
Expand Down
2 changes: 1 addition & 1 deletion apps/pro-web/app/actions/thread.actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -722,7 +722,7 @@ export async function getUserWorkspaceInitialState(
const activeDepartment = activeOrganization
? (() => {
const deptName = departmentsByOrgArray[activeOrganization]?.[0]
if (!deptName) return ['General', 1] as [string, number] // Default to General
if (!deptName) return null

// Get department ID from our chatbot-based mapping
const deptMap = departmentsByOrgFromChatbots[activeOrganization]
Expand Down
Loading