feat: add multi-tenant system with properties, organizations, and public booking

Implement complete multi-property architecture:
- Properties (groups of spaces) with public/private visibility
- Property managers (many-to-many) with role-based permissions
- Organizations with member management
- Anonymous/guest booking support via public API (/api/public/*)
- Property-scoped spaces, bookings, and settings
- Frontend: property selector, organization management, public booking views
- Migration script and updated seed data

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Claude Agent
2026-02-15 00:17:21 +00:00
parent d637513d92
commit e21cf03a16
51 changed files with 6324 additions and 273 deletions

View File

@@ -1,10 +1,10 @@
<template>
<div id="app">
<AppSidebar v-if="authStore.isAuthenticated" />
<AppSidebar v-if="showSidebar" />
<div class="app-main" :class="{ 'with-sidebar': authStore.isAuthenticated, 'sidebar-collapsed': collapsed }">
<div class="app-main" :class="{ 'with-sidebar': showSidebar, 'sidebar-collapsed': collapsed }">
<!-- Mobile header bar -->
<div v-if="authStore.isAuthenticated" class="mobile-header">
<div v-if="showSidebar" class="mobile-header">
<button class="mobile-hamburger" @click="toggleMobile" aria-label="Open menu">
<Menu :size="22" />
</button>
@@ -59,7 +59,7 @@
<script setup lang="ts">
import { ref, computed, onMounted, onUnmounted } from 'vue'
import { useAuthStore } from '@/stores/auth'
import { useRouter } from 'vue-router'
import { useRouter, useRoute } from 'vue-router'
import { notificationsApi } from '@/services/api'
import { useSidebar } from '@/composables/useSidebar'
import type { Notification } from '@/types'
@@ -68,6 +68,10 @@ import { Menu, Bell, X } from 'lucide-vue-next'
const authStore = useAuthStore()
const router = useRouter()
const route = useRoute()
const isPublicRoute = computed(() => route.meta.isPublic === true)
const showSidebar = computed(() => authStore.isAuthenticated && !isPublicRoute.value)
const { collapsed, toggleMobile } = useSidebar()
const notifications = ref<Notification[]>([])