refactor: align codebase with EventCrew domain and trim legacy band stack
- Update API: events, users, policies, routes, resources, migrations - Remove deprecated models/resources (customers, setlists, invitations, etc.) - Refresh admin app and docs; remove apps/band Made-with: Cursor
This commit is contained in:
@@ -1,49 +1,40 @@
|
||||
import { ofetch } from 'ofetch'
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
import { apiClient } from '@/lib/api-client'
|
||||
|
||||
export const $api = ofetch.create({
|
||||
baseURL: import.meta.env.VITE_API_URL || '/api',
|
||||
async onRequest({ options }) {
|
||||
options.headers = options.headers || new Headers()
|
||||
type ApiOptions = {
|
||||
method?: string
|
||||
body?: unknown
|
||||
query?: Record<string, string | number | boolean | undefined>
|
||||
onResponseError?: (ctx: { response: { status: number; _data?: { errors?: Record<string, string[]>; message?: string } } }) => void
|
||||
}
|
||||
|
||||
const accessToken = useCookie('accessToken').value
|
||||
if (accessToken) {
|
||||
if (options.headers instanceof Headers) {
|
||||
options.headers.set('Authorization', `Bearer ${accessToken}`)
|
||||
}
|
||||
/**
|
||||
* Thin ofetch-style wrapper around the single axios client (lib/axios).
|
||||
* Use apiClient from @/lib/axios directly in new code; $api remains for Vuexy template compatibility.
|
||||
*/
|
||||
export async function $api<T = unknown>(url: string, options: ApiOptions = {}): Promise<T> {
|
||||
const { method = 'GET', body, query, onResponseError } = options
|
||||
|
||||
const config: AxiosRequestConfig = {
|
||||
method: method.toLowerCase() as AxiosRequestConfig['method'],
|
||||
url,
|
||||
params: query,
|
||||
data: body,
|
||||
}
|
||||
|
||||
try {
|
||||
const response = await apiClient.request<T>(config)
|
||||
return response.data
|
||||
}
|
||||
catch (error: any) {
|
||||
if (onResponseError && error.response) {
|
||||
onResponseError({
|
||||
response: {
|
||||
status: error.response.status,
|
||||
_data: error.response.data,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
// Set default headers
|
||||
if (options.headers instanceof Headers) {
|
||||
options.headers.set('Accept', 'application/json')
|
||||
options.headers.set('Content-Type', 'application/json')
|
||||
}
|
||||
},
|
||||
async onResponseError({ response }) {
|
||||
// Handle 401 by redirecting to login
|
||||
if (response.status === 401) {
|
||||
if (import.meta.env.DEV) {
|
||||
console.error('❌ API 401 Error:', {
|
||||
url: response.url,
|
||||
pathname: window.location.pathname,
|
||||
willRedirect: window.location.pathname !== '/login',
|
||||
})
|
||||
}
|
||||
|
||||
// Clear auth data
|
||||
useCookie('accessToken').value = null
|
||||
useCookie('userData').value = null
|
||||
useCookie('userAbilityRules').value = null
|
||||
|
||||
// Only redirect if not already on login page
|
||||
// Add a small delay to prevent redirect loops
|
||||
if (window.location.pathname !== '/login') {
|
||||
// Use setTimeout to break any potential redirect loops
|
||||
setTimeout(() => {
|
||||
if (window.location.pathname !== '/login') {
|
||||
window.location.href = '/login'
|
||||
}
|
||||
}, 100)
|
||||
}
|
||||
}
|
||||
},
|
||||
})
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
23
apps/admin/src/utils/auth-ability.ts
Normal file
23
apps/admin/src/utils/auth-ability.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import type { Rule } from '@/plugins/casl/ability'
|
||||
|
||||
/**
|
||||
* CASL rules from Spatie role names returned by the API (`/auth/login`, etc.).
|
||||
*/
|
||||
export function getUserAbilityRules(roles: string[]): Rule[] {
|
||||
if (roles.includes('super_admin')) {
|
||||
return [{ action: 'manage', subject: 'all' }]
|
||||
}
|
||||
|
||||
if (roles.includes('org_admin')) {
|
||||
return [
|
||||
{ action: 'read', subject: 'all' },
|
||||
{ action: 'manage', subject: 'Event' },
|
||||
{ action: 'manage', subject: 'Organisation' },
|
||||
]
|
||||
}
|
||||
|
||||
return [
|
||||
{ action: 'read', subject: 'Event' },
|
||||
{ action: 'read', subject: 'Organisation' },
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user