forked from yvv/decision
f56d84e76b
ci/woodpecker/push/woodpecker Pipeline was successful
- origin TEXT → origin_id UUID FK duniter_identities (migration e3f4a5b6c7d8) - GET /auth/identities?q= : recherche d'identités par nom/adresse - MandateCreate.nomination_mode : auto (auto-assign auteur), collective, postpone - Wizard new.vue : champ origine = picker identité, checkbox "Démarrer maintenant" - [id].vue : modal "Assigner" = search-picker (résout UUID vs adresse SS58), affiche origin_display_name + mandatee_display_name, inputs natifs (<input>/<textarea>) - Erreurs API visibles dans l'UI (plus de catch silencieux) - test_mandate_flows.py : 17 tests intégration SQLite réels (origin, nomination, assign, lifecycle, revocation, interactions croisées) — 241 tests total OK Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
220 lines
6.4 KiB
TypeScript
220 lines
6.4 KiB
TypeScript
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
|
|
origin_id: string | null
|
|
origin_display_name: string | null
|
|
description: string | null
|
|
mandate_type: string
|
|
status: string
|
|
mandatee_id: string | null
|
|
mandatee_display_name: 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
|
|
origin_id?: string | null
|
|
description?: string | null
|
|
mandate_type: string
|
|
nomination_mode?: string
|
|
decision_id?: string | null
|
|
starts_at?: string | null
|
|
ends_at?: string | null
|
|
}
|
|
|
|
export interface MandateUpdate {
|
|
title?: string
|
|
origin_id?: string | null
|
|
description?: string | null
|
|
mandate_type?: string
|
|
starts_at?: string | null
|
|
ends_at?: string | null
|
|
}
|
|
|
|
export interface MandateStepCreate {
|
|
step_order: number
|
|
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) => (status: string) => state.list.filter(m => m.status === status),
|
|
activeMandates: (state): Mandate[] => state.list.filter(m => m.status === 'active'),
|
|
completedMandates: (state): Mandate[] => state.list.filter(m => m.status === 'completed'),
|
|
},
|
|
|
|
actions: {
|
|
async fetchAll(params?: { mandate_type?: string; status?: string }) {
|
|
this.loading = true
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const query: Record<string, string> = {}
|
|
if (params?.mandate_type) query.mandate_type = params.mandate_type
|
|
if (params?.status) query.status = params.status
|
|
this.list = await $api<Mandate[]>('/mandates/', { query })
|
|
} catch (err: any) {
|
|
this.error = err?.data?.detail || err?.message || 'Erreur lors du chargement des mandats'
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async fetchById(id: string) {
|
|
this.loading = true
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
this.current = await $api<Mandate>(`/mandates/${id}`)
|
|
} catch (err: any) {
|
|
this.error = err?.data?.detail || err?.message || 'Mandat introuvable'
|
|
} finally {
|
|
this.loading = false
|
|
}
|
|
},
|
|
|
|
async create(payload: MandateCreate) {
|
|
this.loading = true
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const mandate = await $api<Mandate>('/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
|
|
}
|
|
},
|
|
|
|
async update(id: string, data: MandateUpdate) {
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const updated = await $api<Mandate>(`/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
|
|
}
|
|
},
|
|
|
|
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
|
|
}
|
|
},
|
|
|
|
async advance(id: string) {
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const updated = await $api<Mandate>(`/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
|
|
}
|
|
},
|
|
|
|
async addStep(id: string, step: MandateStepCreate) {
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const newStep = await $api<MandateStep>(`/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
|
|
}
|
|
},
|
|
|
|
async assignMandatee(id: string, mandateeId: string) {
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const updated = await $api<Mandate>(`/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
|
|
}
|
|
},
|
|
|
|
async revoke(id: string) {
|
|
this.error = null
|
|
try {
|
|
const { $api } = useApi()
|
|
const updated = await $api<Mandate>(`/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
|
|
}
|
|
},
|
|
|
|
clearCurrent() {
|
|
this.current = null
|
|
},
|
|
},
|
|
})
|