feat(multi-tenancy): implement critical fixes for orphaned users and permissions

- Simplified HasTenantAccess permission logic to ensure every authenticated user has an account.
- Added fallback to system account for OpenAI settings in AI configuration.
- Allowed any authenticated user to check task progress in IntegrationSettingsViewSet.
- Created a script to identify and fix orphaned users without accounts.
- Updated error response handling in business endpoints for clarity.
This commit is contained in:
IGNY8 VPS (Salman)
2025-12-10 09:51:06 +00:00
parent 5fb3687854
commit 7a35981038
11 changed files with 573 additions and 38 deletions

View File

@@ -148,18 +148,16 @@ export default function WorkflowGuide({ onSiteAdded }: WorkflowGuideProps) {
try {
setIsCreatingSite(true);
// Create site with user-provided name and domain
// Create site with user-provided name, domain, and industry
const newSite = await createSite({
name: siteName.trim(),
domain: websiteAddress.trim() || undefined,
is_active: true,
hosting_type: 'wordpress',
industry: selectedIndustry.id, // Include industry ID - required by backend
});
// Set industry for the site (if API supports it during creation, otherwise update)
// For now, we'll set it via selectSectorsForSite which also sets industry
// Select sectors for the site (this also sets the industry)
// Select sectors for the site
await selectSectorsForSite(
newSite.id,
selectedIndustry.slug,

View File

@@ -49,6 +49,7 @@ export default function Sites() {
domain: '',
description: '',
is_active: true, // Default to true to match backend model default
industry: undefined as number | undefined, // Industry ID - required by backend
});
// Load sites and industries
@@ -145,6 +146,7 @@ export default function Sites() {
domain: site.domain || '',
description: site.description || '',
is_active: site.is_active || false,
industry: site.industry,
});
setShowDetailsModal(true);
};
@@ -177,6 +179,7 @@ export default function Sites() {
domain: '',
description: '',
is_active: true, // Default to true to match backend model default
industry: undefined,
});
setShowSiteModal(true);
};
@@ -188,6 +191,7 @@ export default function Sites() {
domain: site.domain || '',
description: site.description || '',
is_active: site.is_active || false,
industry: site.industry,
});
setShowSiteModal(true);
};
@@ -247,6 +251,7 @@ export default function Sites() {
domain: '',
description: '',
is_active: false,
industry: undefined,
});
await loadSites();
} catch (error: any) {
@@ -313,6 +318,22 @@ export default function Sites() {
required: true,
placeholder: 'Enter site name',
},
{
key: 'industry',
label: 'Industry',
type: 'select',
value: formData.industry?.toString() || '',
onChange: (value: any) => setFormData({ ...formData, industry: value ? parseInt(value) : undefined }),
required: true,
placeholder: 'Select an industry',
options: [
{ value: '', label: 'Select an industry...' },
...industries.map(industry => ({
value: industry.id.toString(),
label: industry.name,
})),
],
},
{
key: 'domain',
label: 'Domain',
@@ -428,6 +449,7 @@ export default function Sites() {
domain: '',
description: '',
is_active: false,
industry: undefined,
});
}}
onSubmit={handleSaveSite}

View File

@@ -1395,6 +1395,7 @@ export interface Site {
export interface SiteCreateData {
name: string;
industry?: number; // Industry ID - required by backend
slug?: string;
domain?: string;
description?: string;
@@ -1403,6 +1404,7 @@ export interface SiteCreateData {
wp_url?: string;
wp_username?: string;
wp_app_password?: string;
hosting_type?: string;
}
export interface SitesResponse {