diff --git a/apps/accounts/admin.py b/apps/accounts/admin.py index 7dbfc73..8e3269d 100644 --- a/apps/accounts/admin.py +++ b/apps/accounts/admin.py @@ -37,11 +37,11 @@ class OrganizationAdmin(ModelAdmin): @admin.register(Invite) class InviteAdmin(ModelAdmin): - list_display = ('token', 'organization', 'created_by', 'is_active', 'uses', 'max_uses', 'expires_at') - search_fields = ('token', 'organization__name', 'created_by__email_address') + list_display = ('uuid', 'organization', 'created_by', 'is_active', 'uses', 'max_uses', 'expires_at') + search_fields = ('uuid', 'organization__name', 'created_by__email_address') list_filter = ('is_active', 'expires_at') raw_id_fields = ('organization', 'created_by') - readonly_fields = ('token', 'created_at') + readonly_fields = ('uuid', 'created_at') @admin.register(Role) class RoleAdmin(ModelAdmin): diff --git a/apps/accounts/migrations/0001_initial.py b/apps/accounts/migrations/0001_initial.py index 4f11c86..a954d13 100644 --- a/apps/accounts/migrations/0001_initial.py +++ b/apps/accounts/migrations/0001_initial.py @@ -1,7 +1,8 @@ -import django.db.models.deletion -import uuid +import uuid + from django.conf import settings from django.db import migrations, models +import django.db.models.deletion class Migration(migrations.Migration): @@ -61,17 +62,16 @@ class Migration(migrations.Migration): ('uuid', models.UUIDField(default=uuid.uuid4, editable=False, verbose_name='UUID')), ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), - ('token', models.UUIDField(default=uuid.uuid4, editable=False, unique=True, verbose_name='Token')), ('expires_at', models.DateTimeField(verbose_name='Expires At')), ('uses', models.IntegerField(default=0, verbose_name='Uses')), ('max_uses', models.IntegerField(default=1, verbose_name='Max Uses')), ('is_active', models.BooleanField(default=True, verbose_name='Is Active')), ('created_by', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='created_invites', to=settings.AUTH_USER_MODEL)), - ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invite_tokens', to='accounts.organization')), + ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invites', to='accounts.organization')), ], options={ - 'verbose_name': 'Invite Token', - 'verbose_name_plural': 'Invite Tokens', + 'verbose_name': 'Invite', + 'verbose_name_plural': 'Invites', }, ), migrations.CreateModel( diff --git a/apps/accounts/migrations/0002_alter_invite_options_alter_invite_organization.py b/apps/accounts/migrations/0002_alter_invite_options_alter_invite_organization.py deleted file mode 100644 index a1c3baa..0000000 --- a/apps/accounts/migrations/0002_alter_invite_options_alter_invite_organization.py +++ /dev/null @@ -1,23 +0,0 @@ - - -import django.db.models.deletion -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('accounts', '0001_initial'), - ] - - operations = [ - migrations.AlterModelOptions( - name='invite', - options={'verbose_name': 'Invite', 'verbose_name_plural': 'Invites'}, - ), - migrations.AlterField( - model_name='invite', - name='organization', - field=models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='invites', to='accounts.organization'), - ), - ] diff --git a/apps/accounts/models.py b/apps/accounts/models.py index d3f73f6..c203808 100644 --- a/apps/accounts/models.py +++ b/apps/accounts/models.py @@ -64,8 +64,7 @@ class Organization(IdentifierMixin, TimeStampMixin, Model): return self.name class Invite(IdentifierMixin, TimeStampMixin, Model): - - token = UUIDField(verbose_name = _("Token"), default = uuid4, unique = True, editable = False) + organization = ForeignKey(Organization, on_delete = CASCADE, related_name = "invites") created_by = ForeignKey(User, on_delete = CASCADE, related_name = "created_invites") expires_at = DateTimeField(verbose_name=_("Expires At")) diff --git a/apps/accounts/serializers.py b/apps/accounts/serializers.py index a7028b5..e477df4 100644 --- a/apps/accounts/serializers.py +++ b/apps/accounts/serializers.py @@ -32,14 +32,14 @@ class InviteSerializer(ModelSerializer): class Meta: model = Invite - fields = ['id', 'token', 'organization', 'created_by', 'expires_at', 'uses', 'max_uses', 'is_active', 'created_at', 'updated_at', 'invite_url', 'is_valid'] - read_only_fields = ['id', 'token', 'organization', 'created_by', 'created_at', 'updated_at'] + fields = ['id', 'uuid', 'organization', 'created_by', 'expires_at', 'uses', 'max_uses', 'is_active', 'created_at', 'updated_at', 'invite_url', 'is_valid'] + read_only_fields = ['id', 'uuid', 'organization', 'created_by', 'created_at', 'updated_at'] def get_invite_url(self, obj: Invite) -> str: request = self.context.get('request') if request: - return request.build_absolute_uri(f'/invite/{obj.token}') - return f'/invite/{obj.token}' + return request.build_absolute_uri(f'/invite/{obj.uuid}') + return f'/invite/{obj.uuid}' def get_is_valid(self, obj: Invite) -> bool: return obj.is_valid() diff --git a/apps/accounts/viewsets.py b/apps/accounts/viewsets.py index 0e09747..c16a4fe 100644 --- a/apps/accounts/viewsets.py +++ b/apps/accounts/viewsets.py @@ -140,30 +140,30 @@ class OrganizationViewSet(ModelViewSet): ) return Response(InviteSerializer(invitation, context={'request': request}).data) - @action(detail=True, methods=['delete'], url_path=r'revoke-invite/(?P[0-9a-f-]{36})') - def revoke_invite(self, request, uuid=None, token=None): + @action(detail=True, methods=['delete'], url_path=r'revoke-invite/(?P[0-9a-f-]{36})') + def revoke_invite(self, request, uuid=None, invite_uuid=None): organization = self.get_object() if not request.user.is_manager: return Response({'error': 'Only managers can revoke invites'}, status=HTTP_403_FORBIDDEN) - invite = organization.invites.filter(token=token).first() + invite = organization.invites.filter(uuid=invite_uuid).first() if not invite: - return Response({'error': 'Invalid invitation token or not found in this organization'}, status=HTTP_404_NOT_FOUND) + return Response({'error': 'Invalid invitation uuid or not found in this organization'}, status=HTTP_404_NOT_FOUND) invite.is_active = False invite.save() return Response({'message': 'Invitation successfully revoked'}, status=HTTP_200_OK) - @action(detail=False, methods=['post'], url_path='join/(?P[0-9a-f-]{36})') - def join(self, request, token=None): + @action(detail=False, methods=['post'], url_path='join/(?P[0-9a-f-]{36})') + def join(self, request, invite_uuid=None): try: - invitation = Invite.objects.get(token=token) + invitation = Invite.objects.get(uuid=invite_uuid) except Invite.DoesNotExist: return Response({'error': 'Not Found'}, status=HTTP_404_NOT_FOUND) if not invitation.is_valid(): - return Response({'error': 'Invalid or expired token'}, status=HTTP_400_BAD_REQUEST) + return Response({'error': 'Invalid or expired invitation'}, status=HTTP_400_BAD_REQUEST) organization = invitation.organization - if organization.members.filter(id=request.user.id).exists(): + if organization.members.filter(uuid=request.user.uuid).exists(): return Response({'error': 'Already a member'}, status=HTTP_403_FORBIDDEN) organization.members.add(request.user) @@ -184,7 +184,7 @@ class OrganizationViewSet(ModelViewSet): if organization.owner == request.user: return Response({'error': 'Owner cannot leave'}, status=HTTP_403_FORBIDDEN) - if not organization.members.filter(id=request.user.id).exists(): + if not organization.members.filter(uuid=request.user.uuid).exists(): return Response({'error': 'Not a member'}, status=HTTP_400_BAD_REQUEST) organization.members.remove(request.user) @@ -196,16 +196,16 @@ class OrganizationViewSet(ModelViewSet): serializer = UserSerializer(organization.members.all(), many=True) return Response(serializer.data) - @action(detail=True, methods=['post'], url_path=r'member/(?P\d+)/remove') - def remove_member(self, request, uuid=None, user_id=None): + @action(detail=True, methods=['post'], url_path=r'member/(?P[0-9a-f-]{36})/remove') + def remove_member(self, request, uuid=None, user_uuid=None): if not request.user.is_manager: return Response({'error': 'Forbidden'}, status=HTTP_403_FORBIDDEN) organization = self.get_object() - if str(organization.owner.id) == str(user_id): + if str(organization.owner.uuid) == str(user_uuid): return Response({'error': 'Cannot remove owner'}, status=HTTP_403_FORBIDDEN) - user_to_remove = organization.members.filter(id=user_id).first() + user_to_remove = organization.members.filter(uuid=user_uuid).first() if not user_to_remove: return Response({'error': 'Not found'}, status=HTTP_404_NOT_FOUND) diff --git a/apps/knowledge/migrations/0001_initial.py b/apps/knowledge/migrations/0001_initial.py index e288c21..e6ca4c4 100644 --- a/apps/knowledge/migrations/0001_initial.py +++ b/apps/knowledge/migrations/0001_initial.py @@ -1,9 +1,9 @@ -import django.db.models.deletion -import pgvector.django import uuid + from django.conf import settings from django.db import migrations, models -from pgvector.django import VectorExtension +import django.db.models.deletion +import pgvector.django.vector class Migration(migrations.Migration): @@ -15,7 +15,7 @@ class Migration(migrations.Migration): ] operations = [ - VectorExtension(), + pgvector.django.VectorExtension(), migrations.CreateModel( name='TrainingFile', fields=[ @@ -48,7 +48,7 @@ class Migration(migrations.Migration): ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), ('content', models.TextField()), ('content_hash', models.CharField(db_index=True, max_length=64)), - ('embedding', pgvector.django.VectorField(blank=True, dimensions=1536, null=True)), + ('embedding', pgvector.django.vector.VectorField(blank=True, dimensions=1536, null=True)), ('metadata', models.JSONField(blank=True, default=dict)), ('chunk_index', models.IntegerField(default=0)), ('is_active', models.BooleanField(default=True)), diff --git a/apps/onboarding/migrations/0001_initial.py b/apps/onboarding/migrations/0001_initial.py index 0ac9fe7..8f56aff 100644 --- a/apps/onboarding/migrations/0001_initial.py +++ b/apps/onboarding/migrations/0001_initial.py @@ -22,9 +22,9 @@ class Migration(migrations.Migration): ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), ('name', models.CharField(max_length=255, verbose_name='Agent Name')), ('agent_type', models.CharField(choices=[('curriculum', 'Curriculum Agent (CA)'), ('knowledge', 'Knowledge Agent (KA)'), ('assessment', 'Assessment Agent (AA)'), ('monitor', 'Progress Monitor Agent (PMA)')], max_length=40, verbose_name='Agent Type')), - ('llm_config', models.JSONField(default=dict, verbose_name='LLM Configuration')), - ('system_prompt', models.TextField(verbose_name='System Prompt')), - ('tool_permissions', models.JSONField(default=list, verbose_name='Tool Permissions')), + ('llm_config', models.JSONField(blank=True, default=dict, null=True, verbose_name='LLM Configuration')), + ('system_prompt', models.TextField(blank=True, default='', verbose_name='System Prompt')), + ('tool_permissions', models.JSONField(blank=True, default=list, null=True, verbose_name='Tool Permissions')), ('organization', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='agent_configs', to='accounts.organization', verbose_name='Organization')), ], options={ @@ -40,6 +40,7 @@ class Migration(migrations.Migration): ('created_at', models.DateTimeField(auto_now_add=True, verbose_name='Created At')), ('updated_at', models.DateTimeField(auto_now=True, verbose_name='Updated At')), ('title', models.CharField(max_length=255, verbose_name='Flow Title')), + ('structure', models.JSONField(blank=True, default=list, verbose_name='Flow Structure')), ('is_active', models.BooleanField(default=True, verbose_name='Is Active')), ('role', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='flows', to='accounts.role', verbose_name='Role')), ], diff --git a/apps/onboarding/migrations/0002_alter_agentconfig_llm_config_and_more.py b/apps/onboarding/migrations/0002_alter_agentconfig_llm_config_and_more.py deleted file mode 100644 index 4cc07bb..0000000 --- a/apps/onboarding/migrations/0002_alter_agentconfig_llm_config_and_more.py +++ /dev/null @@ -1,28 +0,0 @@ - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('onboarding', '0001_initial'), - ] - - operations = [ - migrations.AlterField( - model_name='agentconfig', - name='llm_config', - field=models.JSONField(blank=True, default=dict, null=True, verbose_name='LLM Configuration'), - ), - migrations.AlterField( - model_name='agentconfig', - name='system_prompt', - field=models.TextField(blank=True, default='', verbose_name='System Prompt'), - ), - migrations.AlterField( - model_name='agentconfig', - name='tool_permissions', - field=models.JSONField(blank=True, default=list, null=True, verbose_name='Tool Permissions'), - ), - ] diff --git a/apps/onboarding/migrations/0003_onboardingflow_structure.py b/apps/onboarding/migrations/0003_onboardingflow_structure.py deleted file mode 100644 index 69f02a9..0000000 --- a/apps/onboarding/migrations/0003_onboardingflow_structure.py +++ /dev/null @@ -1,18 +0,0 @@ - - -from django.db import migrations, models - - -class Migration(migrations.Migration): - - dependencies = [ - ('onboarding', '0002_alter_agentconfig_llm_config_and_more'), - ] - - operations = [ - migrations.AddField( - model_name='onboardingflow', - name='structure', - field=models.JSONField(blank=True, default=list, verbose_name='Flow Structure'), - ), - ] diff --git a/site/src/router/api.ts b/site/src/router/api.ts index 4048d61..3d95c63 100644 --- a/site/src/router/api.ts +++ b/site/src/router/api.ts @@ -94,8 +94,8 @@ export const API = { byId: (uuid: string) => `organization/${uuid}/`, members: { list: (uuid: string) => `organization/${uuid}/members/`, - remove: (uuid: string, userId: number) => - `organization/${uuid}/member/${userId}/remove/`, + remove: (uuid: string, userUuid: string) => + `organization/${uuid}/member/${userUuid}/remove/`, }, invites: { list: (uuid: string) => `organization/${uuid}/invite/`, @@ -103,7 +103,7 @@ export const API = { `organization/${uuid}/create-invite/?max_uses=${maxUses}`, revoke: (uuid: string, inviteUuid: string) => `organization/${uuid}/revoke-invite/${inviteUuid}/`, - join: (token: string) => `organization/join/${token}/`, + join: (inviteUuid: string) => `organization/join/${inviteUuid}/`, }, leave: (uuid: string) => `organization/${uuid}/leave/`, roles: { diff --git a/site/src/router/index.ts b/site/src/router/index.ts index a1ebd85..e658bce 100644 --- a/site/src/router/index.ts +++ b/site/src/router/index.ts @@ -39,19 +39,19 @@ const router = createRouter({ meta: { requiresAuth: true }, }, { - path: '/organization/:id', + path: '/organization/:organizationUuid', name: 'organization-detail', component: () => import('../views/OrganizationView.vue'), meta: { requiresAuth: true }, }, { - path: '/organization/:id/manage', + path: '/organization/:organizationUuid/manage', name: 'organization-manage', component: () => import('../views/OrganizationManage.vue'), meta: { requiresAuth: true, requiresManager: true }, }, { - path: '/invite/:token', + path: '/invite/:inviteUuid', name: 'invite-accept', component: () => import('../views/InviteAccept.vue'), }, @@ -62,7 +62,7 @@ const router = createRouter({ meta: { requiresAuth: true, requiresManager: true }, }, { - path: '/agents/:id', + path: '/agents/:agentUuid', name: 'agent-detail', component: () => import('../views/AgentDetailView.vue'), meta: { requiresAuth: true, requiresManager: true }, diff --git a/site/src/types/organization.ts b/site/src/types/organization.ts index 3cdc732..a58ec36 100644 --- a/site/src/types/organization.ts +++ b/site/src/types/organization.ts @@ -1,7 +1,6 @@ import { User } from './user' export interface Organization { - id: number uuid: string name: string description: string @@ -13,7 +12,6 @@ export interface Organization { } export interface Role { - id: number uuid: string name: string description?: string @@ -24,8 +22,7 @@ export interface Role { } export interface InviteToken { - id: number - token: string + uuid: string invite_url: string created_by: User organization: Organization @@ -36,7 +33,6 @@ export interface InviteToken { uses?: number } export interface TrainingFile { - id: number uuid: string role: Role uploaded_by: User diff --git a/site/src/types/user.ts b/site/src/types/user.ts index 41a79c0..f16792d 100644 --- a/site/src/types/user.ts +++ b/site/src/types/user.ts @@ -1,5 +1,4 @@ export interface User { - id: number uuid: string email_address: string first_name: string diff --git a/site/src/views/InviteAccept.vue b/site/src/views/InviteAccept.vue index 9138dc9..ccde24a 100644 --- a/site/src/views/InviteAccept.vue +++ b/site/src/views/InviteAccept.vue @@ -7,7 +7,7 @@ import { apiClient, isAxiosError, API } from '../router/api' const route = useRoute() const router = useRouter() -const token = route.params.token as string +const inviteUuid = route.params.inviteUuid as string const loading = ref(false) const accepting = ref(false) const accepted = ref(false) @@ -18,7 +18,7 @@ const acceptInvite = async () => { error.value = null try { const response = await apiClient.post<{ message: string; success: boolean; uuid: string }>( - API.organization.invites.join(token), + API.organization.invites.join(inviteUuid), ) message.success(response.data?.message || 'Successfully joined organization') accepted.value = true diff --git a/site/src/views/OrganizationManage.vue b/site/src/views/OrganizationManage.vue index e625725..1bab784 100644 --- a/site/src/views/OrganizationManage.vue +++ b/site/src/views/OrganizationManage.vue @@ -26,7 +26,7 @@ const route = useRoute() const router = useRouter() const auth = useUserStore() -const orgId = route.params.id as string +const organizationUuid = route.params.organizationUuid as string const organization = ref(null) const members = ref([]) const invites = ref([]) @@ -48,7 +48,7 @@ const newDescription = ref('') const fetchOrganization = async () => { loading.value = true try { - const response = await apiClient.get(API.organization.byId(orgId)) + const response = await apiClient.get(API.organization.byId(organizationUuid)) organization.value = response.data newDescription.value = response.data.description } catch (error) { @@ -61,7 +61,7 @@ const fetchOrganization = async () => { const fetchMembers = async () => { try { - const response = await apiClient.get(API.organization.members.list(orgId)) + const response = await apiClient.get(API.organization.members.list(organizationUuid)) members.value = response.data } catch (error) { console.error('Failed to fetch members:', error) @@ -70,7 +70,7 @@ const fetchMembers = async () => { const fetchInvites = async () => { try { - const response = await apiClient.get(API.organization.invites.list(orgId)) + const response = await apiClient.get(API.organization.invites.list(organizationUuid)) invites.value = response.data } catch (error) { console.error('Failed to fetch invites:', error) @@ -79,7 +79,7 @@ const fetchInvites = async () => { const fetchRoles = async () => { try { - const response = await apiClient.get(API.organization.roles.list(orgId)) + const response = await apiClient.get(API.organization.roles.list(organizationUuid)) Roles.value = response.data as unknown as Role[] } catch (error) { console.error('Failed to fetch Roles:', error) @@ -109,7 +109,7 @@ const createRole = async () => { creatingRole.value = true try { - await apiClient.post(API.organization.roles.list(orgId), { name, description }) + await apiClient.post(API.organization.roles.list(organizationUuid), { name, description }) message.success('Role created successfully') roleModalVisible.value = false resetRoleForm() @@ -136,7 +136,7 @@ const deleteRole = async (role: Role) => { onOk: async () => { deletingRoleUuid.value = role.uuid try { - await apiClient.delete(API.organization.roles.remove(orgId, role.uuid)) + await apiClient.delete(API.organization.roles.remove(organizationUuid, role.uuid)) message.success('Role deleted successfully') await fetchRoles() } catch (error) { @@ -156,7 +156,7 @@ const deleteRole = async (role: Role) => { const createInvite = async () => { try { const response = await apiClient.post( - API.organization.invites.create(orgId, newInviteMaxUses.value), + API.organization.invites.create(organizationUuid, newInviteMaxUses.value), ) newInviteUrl.value = response.data.invite_url inviteModalVisible.value = true @@ -177,9 +177,9 @@ const copyUrl = (url: string) => { message.success('Copied to clipboard') } -const revokeInvite = async (token: string) => { +const revokeInvite = async (inviteUuid: string) => { try { - await apiClient.delete(API.organization.invites.revoke(orgId, token)) + await apiClient.delete(API.organization.invites.revoke(organizationUuid, inviteUuid)) message.success('Invite revoked') fetchInvites() } catch (error) { @@ -188,9 +188,9 @@ const revokeInvite = async (token: string) => { } } -const removeMember = async (userId: number) => { +const removeMember = async (userUuid: string) => { try { - await apiClient.post(API.organization.members.remove(orgId, userId)) + await apiClient.post(API.organization.members.remove(organizationUuid, userUuid)) message.success('Member removed') fetchMembers() } catch (error) { @@ -203,7 +203,7 @@ const removeMember = async (userId: number) => { const saveDescription = async () => { try { - await apiClient.patch(API.organization.byId(orgId), { + await apiClient.patch(API.organization.byId(organizationUuid), { description: newDescription.value, }) message.success('Description updated') @@ -221,14 +221,14 @@ onMounted(async () => { await fetchInvites() await fetchRoles() - const currentUserId = auth.user?.id - const isOwner = organization.value?.owner?.id === currentUserId - const myMembership = members.value.find((m) => m.id === currentUserId) + const currentUserUuid = auth.user?.uuid + const isOwner = organization.value?.owner?.uuid === currentUserUuid + const myMembership = members.value.find((member) => member.uuid === currentUserUuid) const isEmployer = myMembership?.is_manager if (!isOwner && !isEmployer) { message.error('You do not have permission to manage this organization') - router.replace(`/organization/${orgId}`) + router.replace(`/organization/${organizationUuid}`) } }) @@ -239,7 +239,7 @@ onMounted(async () => {
Manage {{ organization.name }} -
@@ -289,10 +289,10 @@ onMounted(async () => { /> @@ -343,7 +343,7 @@ onMounted(async () => { diff --git a/site/src/views/OrganizationView.vue b/site/src/views/OrganizationView.vue index 81afeb5..e1514d8 100644 --- a/site/src/views/OrganizationView.vue +++ b/site/src/views/OrganizationView.vue @@ -23,11 +23,11 @@ import type { Role, Organization, TrainingFile } from '../types/organization' const router = useRouter() const route = useRoute() -const orgId = route.params.id as string +const organizationUuid = route.params.organizationUuid as string const organization = ref(null) const roles = ref([]) -const members = ref>([]) +const members = ref>([]) const trainingFiles = ref([]) const loading = ref(false) const uploading = ref(false) @@ -38,14 +38,14 @@ const isManager = computed(() => { if (!auth.user || !organization.value) return false if ((organization.value as Organization & { is_manager?: boolean }).is_manager === true) return true - if (organization.value.owner?.id === auth.user.id) return true - return members.value.some((m) => m.user?.id === auth.user?.id && m.role === 'employer') + if (organization.value.owner?.uuid === auth.user.uuid) return true + return members.value.some((member) => member.uuid === auth.user?.uuid && member.is_manager) }) const fetchOrganization = async () => { loading.value = true try { - const response = await apiClient.get(API.organization.byId(orgId)) + const response = await apiClient.get(API.organization.byId(organizationUuid)) organization.value = response.data } catch (error) { console.error('Failed to fetch organization:', error) @@ -86,7 +86,7 @@ const isRoleJoined = (roleUuid: string | undefined) => { const fetchMembers = async () => { if (!organization.value?.uuid) return try { - const response = await apiClient.get>( + const response = await apiClient.get>( API.organization.members.list(organization.value.uuid), ) members.value = response.data @@ -100,7 +100,7 @@ const selectRole = async (roleUuid: string) => { message.error('Organization not loaded') return } - if (!auth.user?.id) { + if (!auth.user?.uuid) { try { await auth.fetchSession(true) } catch { @@ -315,7 +315,7 @@ const trainingFileColumns = [ title: 'Action', key: 'action', customRender: ({ record }: { record: TrainingFile }) => { - if (isManager.value || auth.user?.id === record.uploaded_by?.id) { + if (isManager.value || auth.user?.uuid === record.uploaded_by?.uuid) { return h( Button, { diff --git a/site/src/views/OrganizationsView.vue b/site/src/views/OrganizationsView.vue index e9e67a3..fbc1a64 100644 --- a/site/src/views/OrganizationsView.vue +++ b/site/src/views/OrganizationsView.vue @@ -25,8 +25,7 @@ const fetchOrganizations = async () => { if (organizations.value.length === 1 && !auth.isGeneralManager) { const onlyOrg = organizations.value[0] - const id = onlyOrg.uuid || String(onlyOrg.id) - await router.replace(`/organization/${id}`) + await router.replace(`/organization/${onlyOrg.uuid}`) } } catch (err: unknown) { console.error('Failed to fetch organizations:', err) @@ -52,8 +51,7 @@ onMounted(() => { }) const openOrg = (org: Organization) => { - const id = org.uuid || String(org.id) - router.push(`/organization/${id}`) + router.push(`/organization/${org.uuid}`) } const resetCreateOrganizationForm = () => {