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,42 +1,53 @@
|
||||
<script setup lang="ts">
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-vue-next';
|
||||
import { computed, ref } from 'vue';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { ChevronLeft, ChevronRight } from 'lucide-vue-next';
|
||||
|
||||
type Folder = {
|
||||
type Declaration = {
|
||||
id: number;
|
||||
due_date: string | null;
|
||||
};
|
||||
|
||||
type Props = {
|
||||
folders: Folder[];
|
||||
declarations: Declaration[];
|
||||
};
|
||||
|
||||
const props = defineProps<Props>();
|
||||
|
||||
const monthNames = [
|
||||
'Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin',
|
||||
'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre',
|
||||
'Janvier',
|
||||
'Février',
|
||||
'Mars',
|
||||
'Avril',
|
||||
'Mai',
|
||||
'Juin',
|
||||
'Juillet',
|
||||
'Août',
|
||||
'Septembre',
|
||||
'Octobre',
|
||||
'Novembre',
|
||||
'Décembre',
|
||||
];
|
||||
const dayNames = ['Lun', 'Mar', 'Mer', 'Jeu', 'Ven', 'Sam', 'Dim'];
|
||||
|
||||
const current = ref(new Date());
|
||||
|
||||
const monthLabel = computed(() =>
|
||||
`${monthNames[current.value.getMonth()]} ${current.value.getFullYear()}`,
|
||||
const monthLabel = computed(
|
||||
() =>
|
||||
`${monthNames[current.value.getMonth()]} ${current.value.getFullYear()}`,
|
||||
);
|
||||
|
||||
const datesWithFolders = computed(() => {
|
||||
const datesWithDeclarations = computed(() => {
|
||||
const set = new Set<string>();
|
||||
props.folders.forEach((f) => {
|
||||
props.declarations.forEach((f) => {
|
||||
if (f.due_date) set.add(f.due_date);
|
||||
});
|
||||
return set;
|
||||
});
|
||||
|
||||
const foldersByDate = computed(() => {
|
||||
const declarationsByDate = computed(() => {
|
||||
const map = new Map<string, number>();
|
||||
props.folders.forEach((f) => {
|
||||
props.declarations.forEach((f) => {
|
||||
if (f.due_date) {
|
||||
map.set(f.due_date, (map.get(f.due_date) ?? 0) + 1);
|
||||
}
|
||||
@@ -52,7 +63,11 @@ const calendarDays = computed(() => {
|
||||
const startDay = (first.getDay() + 6) % 7;
|
||||
const daysInMonth = last.getDate();
|
||||
|
||||
const days: Array<{ date: Date | null; dateStr: string | null; count: number }> = [];
|
||||
const days: Array<{
|
||||
date: Date | null;
|
||||
dateStr: string | null;
|
||||
count: number;
|
||||
}> = [];
|
||||
|
||||
for (let i = 0; i < startDay; i++) {
|
||||
days.push({ date: null, dateStr: null, count: 0 });
|
||||
@@ -63,18 +78,24 @@ const calendarDays = computed(() => {
|
||||
days.push({
|
||||
date,
|
||||
dateStr,
|
||||
count: foldersByDate.value.get(dateStr) ?? 0,
|
||||
count: declarationsByDate.value.get(dateStr) ?? 0,
|
||||
});
|
||||
}
|
||||
return days;
|
||||
});
|
||||
|
||||
function prevMonth() {
|
||||
current.value = new Date(current.value.getFullYear(), current.value.getMonth() - 1);
|
||||
current.value = new Date(
|
||||
current.value.getFullYear(),
|
||||
current.value.getMonth() - 1,
|
||||
);
|
||||
}
|
||||
|
||||
function nextMonth() {
|
||||
current.value = new Date(current.value.getFullYear(), current.value.getMonth() + 1);
|
||||
current.value = new Date(
|
||||
current.value.getFullYear(),
|
||||
current.value.getMonth() + 1,
|
||||
);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -111,11 +132,8 @@ function nextMonth() {
|
||||
>
|
||||
<template v-if="cell.date">
|
||||
{{ cell.date.getDate() }}
|
||||
<span
|
||||
v-if="cell.count > 0"
|
||||
class="mt-0.5 text-[10px]"
|
||||
>
|
||||
{{ cell.count }} dossier{{ cell.count > 1 ? 's' : '' }}
|
||||
<span v-if="cell.count > 0" class="mt-0.5 text-[10px]">
|
||||
{{ cell.count }} décl.
|
||||
</span>
|
||||
</template>
|
||||
</div>
|
||||
Reference in New Issue
Block a user