/** * Mandates store: governance mandates and their lifecycle steps. * * Maps to the backend /api/v1/mandates endpoints. */ export interface MandateStep { id: string mandate_id: string step_order: number step_type: string title: string | null description: string | null status: string vote_session_id: string | null outcome: string | null created_at: string } export interface Mandate { id: string title: string description: string | null mandate_type: string status: string mandatee_id: string | null decision_id: string | null starts_at: string | null ends_at: string | null created_at: string updated_at: string steps: MandateStep[] } export interface MandateCreate { title: string description?: string | null mandate_type: string decision_id?: string | null starts_at?: string | null ends_at?: string | null } export interface MandateUpdate { title?: string description?: string | null mandate_type?: string starts_at?: string | null ends_at?: string | null } export interface MandateStepCreate { step_type: string title?: string | null description?: string | null } interface MandatesState { list: Mandate[] current: Mandate | null loading: boolean error: string | null } export const useMandatesStore = defineStore('mandates', { state: (): MandatesState => ({ list: [], current: null, loading: false, error: null, }), getters: { byStatus: (state) => { return (status: string) => state.list.filter(m => m.status === status) }, activeMandates: (state): Mandate[] => { return state.list.filter(m => m.status === 'active') }, completedMandates: (state): Mandate[] => { return state.list.filter(m => m.status === 'completed') }, }, actions: { /** * Fetch all mandates with optional filters. */ async fetchAll(params?: { mandate_type?: string; status?: string }) { this.loading = true this.error = null try { const { $api } = useApi() const query: Record = {} if (params?.mandate_type) query.mandate_type = params.mandate_type if (params?.status) query.status = params.status this.list = await $api('/mandates/', { query }) } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des mandats' } finally { this.loading = false } }, /** * Fetch a single mandate by ID with all its steps. */ async fetchById(id: string) { this.loading = true this.error = null try { const { $api } = useApi() this.current = await $api(`/mandates/${id}`) } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Mandat introuvable' } finally { this.loading = false } }, /** * Create a new mandate. */ async create(payload: MandateCreate) { this.loading = true this.error = null try { const { $api } = useApi() const mandate = await $api('/mandates/', { method: 'POST', body: payload, }) this.list.unshift(mandate) return mandate } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de la creation du mandat' throw err } finally { this.loading = false } }, /** * Update an existing mandate. */ async update(id: string, data: MandateUpdate) { this.error = null try { const { $api } = useApi() const updated = await $api(`/mandates/${id}`, { method: 'PUT', body: data, }) if (this.current?.id === id) this.current = updated const idx = this.list.findIndex(m => m.id === id) if (idx >= 0) this.list[idx] = updated return updated } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de la mise a jour du mandat' throw err } }, /** * Delete a mandate. */ async delete(id: string) { this.error = null try { const { $api } = useApi() await $api(`/mandates/${id}`, { method: 'DELETE' }) this.list = this.list.filter(m => m.id !== id) if (this.current?.id === id) this.current = null } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de la suppression du mandat' throw err } }, /** * Advance the mandate to the next step in its workflow. */ async advance(id: string) { this.error = null try { const { $api } = useApi() const updated = await $api(`/mandates/${id}/advance`, { method: 'POST', }) if (this.current?.id === id) this.current = updated const idx = this.list.findIndex(m => m.id === id) if (idx >= 0) this.list[idx] = updated return updated } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de l\'avancement du mandat' throw err } }, /** * Add a step to a mandate. */ async addStep(id: string, step: MandateStepCreate) { this.error = null try { const { $api } = useApi() const newStep = await $api(`/mandates/${id}/steps`, { method: 'POST', body: step, }) if (this.current?.id === id) { this.current.steps.push(newStep) } return newStep } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de l\'ajout de l\'etape' throw err } }, /** * Assign a mandatee to the mandate. */ async assignMandatee(id: string, mandateeId: string) { this.error = null try { const { $api } = useApi() const updated = await $api(`/mandates/${id}/assign`, { method: 'POST', body: { mandatee_id: mandateeId }, }) if (this.current?.id === id) this.current = updated const idx = this.list.findIndex(m => m.id === id) if (idx >= 0) this.list[idx] = updated return updated } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de l\'assignation du mandataire' throw err } }, /** * Revoke the mandate. */ async revoke(id: string) { this.error = null try { const { $api } = useApi() const updated = await $api(`/mandates/${id}/revoke`, { method: 'POST', }) if (this.current?.id === id) this.current = updated const idx = this.list.findIndex(m => m.id === id) if (idx >= 0) this.list[idx] = updated return updated } catch (err: any) { this.error = err?.data?.detail || err?.message || 'Erreur lors de la revocation du mandat' throw err } }, /** * Clear the current mandate. */ clearCurrent() { this.current = null }, }, })