feat: consolidate frontend API layer, add query-client, and harden backend Fase 1

Frontend:
- Consolidate duplicate API layers into single src/lib/axios.ts per app
- Remove src/lib/api-client.ts and src/utils/api.ts (admin)
- Add src/lib/query-client.ts with TanStack Query config per app
- Update all imports and auto-import config

Backend:
- Fix organisations.billing_status default to 'trial'
- Fix user_invitations.invited_by_user_id to nullOnDelete
- Add MeResource with separated app_roles and pivot-based org roles
- Add cross-org check to EventPolicy view() and update()
- Restrict EventPolicy create/update to org_admin/event_manager (not org_member)
- Attach creator as org_admin on organisation store
- Add query scopes to Event and UserInvitation models
- Improve factories with Dutch test data
- Expand test suite from 29 to 41 tests (90 assertions)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 17:35:34 +02:00
parent 611c311854
commit 0d24506c89
36 changed files with 454 additions and 118 deletions

View File

@@ -375,7 +375,6 @@ import { UnwrapRef } from 'vue'
declare module 'vue' {
interface GlobalComponents {}
interface ComponentCustomProperties {
readonly $api: UnwrapRef<typeof import('./src/utils/api')['$api']>
readonly COOKIE_MAX_AGE_1_YEAR: UnwrapRef<typeof import('./src/utils/constants')['COOKIE_MAX_AGE_1_YEAR']>
readonly EffectScope: UnwrapRef<typeof import('vue')['EffectScope']>
readonly acceptHMRUpdate: UnwrapRef<typeof import('pinia')['acceptHMRUpdate']>
@@ -527,7 +526,6 @@ declare module 'vue' {
readonly useAbs: UnwrapRef<typeof import('@vueuse/math')['useAbs']>
readonly useActiveElement: UnwrapRef<typeof import('@vueuse/core')['useActiveElement']>
readonly useAnimate: UnwrapRef<typeof import('@vueuse/core')['useAnimate']>
readonly useApi: UnwrapRef<typeof import('./src/composables/useApi')['useApi']>
readonly useArrayDifference: UnwrapRef<typeof import('@vueuse/core')['useArrayDifference']>
readonly useArrayEvery: UnwrapRef<typeof import('@vueuse/core')['useArrayEvery']>
readonly useArrayFilter: UnwrapRef<typeof import('@vueuse/core')['useArrayFilter']>

View File

@@ -0,0 +1,12 @@
import type { VueQueryPluginOptions } from '@tanstack/vue-query'
export const queryClientConfig: VueQueryPluginOptions = {
queryClientConfig: {
defaultOptions: {
queries: {
staleTime: 1000 * 60 * 5, // 5 minutes
retry: 1,
},
},
},
}

View File

@@ -1,5 +1,6 @@
import { createApp } from 'vue'
import { VueQueryPlugin } from '@tanstack/vue-query'
import { queryClientConfig } from '@/lib/query-client'
import App from '@/App.vue'
import { registerPlugins } from '@core/utils/plugins'
@@ -14,13 +15,7 @@ const app = createApp(App)
// Register plugins
registerPlugins(app)
app.use(VueQueryPlugin, {
queryClientConfig: {
defaultOptions: {
queries: { staleTime: 1000 * 60 * 5, retry: 1 },
},
},
})
app.use(VueQueryPlugin, queryClientConfig)
// Mount vue app
app.mount('#app')