feat: complete Epic 0 — foundation migration & infrastructure setup
Stories 0.2-0.5: rename folders→declarations (backend+frontend), configure Redis for cache/queue/sessions, add foundation database migrations (permissions, archived_at), replace DeclarationStatus enum with architecture lifecycle values, create DeclarationObserver for status transition validation and auto-archive, fix controller status transitions to respect observer rules. 93 tests pass (240 assertions). Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import { router, usePage } from '@inertiajs/vue3';
|
||||
import { Bell } from 'lucide-vue-next';
|
||||
import { computed } from 'vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import {
|
||||
DropdownMenu,
|
||||
@@ -16,8 +16,8 @@ type NotificationItem = {
|
||||
id: string;
|
||||
type: string;
|
||||
data: {
|
||||
folder_id?: number;
|
||||
folder_title?: string;
|
||||
declaration_id?: number;
|
||||
declaration_title?: string;
|
||||
mentioned_by_name?: string;
|
||||
message?: string;
|
||||
url?: string;
|
||||
@@ -36,7 +36,8 @@ type UserNotifications = {
|
||||
const page = usePage();
|
||||
|
||||
const userNotifications = computed<UserNotifications>(() => {
|
||||
return (page.props as Record<string, unknown>).userNotifications as UserNotifications;
|
||||
return (page.props as Record<string, unknown>)
|
||||
.userNotifications as UserNotifications;
|
||||
});
|
||||
|
||||
const unreadCount = computed(() => userNotifications.value?.unread_count ?? 0);
|
||||
@@ -63,7 +64,7 @@ function navigateToNotification(notification: NotificationItem) {
|
||||
|
||||
router.visit(targetUrl, {
|
||||
onError: () => {
|
||||
// Folder may have been deleted — mark as read anyway
|
||||
// Declaration may have been deleted — mark as read anyway
|
||||
if (!notification.read_at) {
|
||||
markAsRead(notification);
|
||||
}
|
||||
@@ -86,7 +87,7 @@ function markAllAsRead() {
|
||||
<Bell class="size-4" />
|
||||
<span
|
||||
v-if="unreadCount > 0"
|
||||
class="absolute -right-0.5 -top-0.5 flex size-4 items-center justify-center rounded-full bg-destructive text-[10px] font-bold text-destructive-foreground"
|
||||
class="absolute -top-0.5 -right-0.5 flex size-4 items-center justify-center rounded-full bg-destructive text-[10px] font-bold text-destructive-foreground"
|
||||
>
|
||||
{{ unreadCount > 9 ? '9+' : unreadCount }}
|
||||
</span>
|
||||
@@ -96,11 +97,17 @@ function markAllAsRead() {
|
||||
<DropdownMenuLabel>Notifications</DropdownMenuLabel>
|
||||
<DropdownMenuSeparator />
|
||||
|
||||
<div v-if="isLoading" class="px-2 py-4 text-center text-sm text-muted-foreground">
|
||||
<div
|
||||
v-if="isLoading"
|
||||
class="px-2 py-4 text-center text-sm text-muted-foreground"
|
||||
>
|
||||
Chargement...
|
||||
</div>
|
||||
|
||||
<div v-else-if="!items.length" class="px-2 py-4 text-center text-sm text-muted-foreground">
|
||||
<div
|
||||
v-else-if="!items.length"
|
||||
class="px-2 py-4 text-center text-sm text-muted-foreground"
|
||||
>
|
||||
Aucune notification.
|
||||
</div>
|
||||
|
||||
@@ -114,17 +121,27 @@ function markAllAsRead() {
|
||||
>
|
||||
<div class="flex w-full items-center justify-between gap-2">
|
||||
<span class="text-xs font-medium">
|
||||
{{ notification.data?.mentioned_by_name ?? 'Système' }}
|
||||
{{
|
||||
notification.data?.mentioned_by_name ??
|
||||
'Système'
|
||||
}}
|
||||
</span>
|
||||
<span class="text-xs text-muted-foreground">
|
||||
{{ notification.created_at }}
|
||||
</span>
|
||||
</div>
|
||||
<p class="text-xs text-muted-foreground">
|
||||
<span v-if="notification.data?.folder_title" class="font-medium text-foreground">
|
||||
{{ notification.data.folder_title }}
|
||||
<span
|
||||
v-if="notification.data?.declaration_title"
|
||||
class="font-medium text-foreground"
|
||||
>
|
||||
{{ notification.data.declaration_title }}
|
||||
</span>
|
||||
{{ notification.data?.message ? ` — ${notification.data.message}` : '' }}
|
||||
{{
|
||||
notification.data?.message
|
||||
? ` — ${notification.data.message}`
|
||||
: ''
|
||||
}}
|
||||
</p>
|
||||
<span
|
||||
v-if="!notification.read_at"
|
||||
|
||||
Reference in New Issue
Block a user