gigafibre-fsm/apps/ops/src/composables/usePaymentActions.js
louispaulb 607ea54b5c refactor: reduce token count, DRY code, consolidate docs
Backend services:
- targo-hub: extract deepGetValue to helpers.js, DRY disconnect reasons
  lookup map, compact CAPABILITIES, consolidate vision.js prompts/schemas,
  extract dispatch scoring weights, trim section dividers across 9 files
- modem-bridge: extract getSession() helper (6 occurrences), resetIdleTimer(),
  consolidate DM query factory, fix duplicate username fill bug, trim headers
  (server.js -36%, tplink-session.js -47%, docker-compose.yml -57%)

Frontend:
- useWifiDiagnostic: extract THRESHOLDS const, split processDiagnostic into
  6 focused helpers (processOnlineStatus, processWanIPs, processRadios,
  processMeshNodes, processClients, checkRadioIssues)
- EquipmentDetail: merge duplicate ROLE_LABELS, remove verbose comments

Documentation (17 → 13 files, -1,400 lines):
- New consolidated README.md (architecture, services, dependencies, auth)
- Merge ECOSYSTEM-OVERVIEW into ARCHITECTURE.md
- Merge MIGRATION-PLAN + ARCHITECTURE-COMPARE + FIELD-GAP + CHANGELOG → MIGRATION.md
- Merge COMPETITIVE-ANALYSIS into PLATFORM-STRATEGY.md
- Update ROADMAP.md with current phase status
- Delete CONTEXT.md (absorbed into README)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-04-13 08:39:58 -04:00

177 lines
5.4 KiB
JavaScript

/**
* Payment actions composable — agent-facing payment operations via targo-hub
*/
import { ref } from 'vue'
import { Notify } from 'quasar'
import { HUB_SSE_URL } from 'src/config/dispatch'
const HUB = HUB_SSE_URL
async function hubFetch (path, opts = {}) {
const res = await fetch(HUB + path, {
method: opts.method || 'GET',
headers: { 'Content-Type': 'application/json', ...opts.headers },
...(opts.body ? { body: JSON.stringify(opts.body) } : {}),
})
if (!res.ok) {
const err = await res.json().catch(() => ({ error: 'Request failed' }))
throw new Error(err.error || `HTTP ${res.status}`)
}
return res.json()
}
export function usePaymentActions (customer) {
const loading = ref(false)
const sendingLink = ref(false)
const chargingCard = ref(false)
const togglingPpa = ref(false)
async function fetchBalance () {
if (!customer.value?.name) return null
try {
return await hubFetch(`/payments/balance/${encodeURIComponent(customer.value.name)}`)
} catch (e) {
console.error('Balance fetch error:', e)
return null
}
}
async function fetchMethods () {
if (!customer.value?.name) return []
try {
const res = await hubFetch(`/payments/methods/${encodeURIComponent(customer.value.name)}`)
return res.methods || []
} catch (e) {
console.error('Methods fetch error:', e)
return []
}
}
async function sendPaymentLink (channel = 'both') {
sendingLink.value = true
try {
const res = await hubFetch('/payments/send-link', {
method: 'POST',
body: { customer: customer.value.name, channel },
})
const sentVia = res.sent?.join(' + ') || 'aucun'
Notify.create({ type: 'positive', message: `Lien de paiement envoyé (${sentVia}) — ${res.amount}$`, position: 'top' })
return res
} catch (e) {
Notify.create({ type: 'negative', message: `Erreur: ${e.message}`, position: 'top' })
} finally {
sendingLink.value = false
}
}
async function chargeCard (amount) {
chargingCard.value = true
try {
const res = await hubFetch('/payments/charge', {
method: 'POST',
body: { customer: customer.value.name, ...(amount ? { amount } : {}) },
})
if (res.ok) {
Notify.create({ type: 'positive', message: `Paiement de ${res.amount}$ prélevé avec succès`, position: 'top' })
} else {
Notify.create({ type: 'warning', message: `Statut: ${res.status} — vérifier Stripe`, position: 'top' })
}
return res
} catch (e) {
Notify.create({ type: 'negative', message: `Erreur prélèvement: ${e.message}`, position: 'top' })
} finally {
chargingCard.value = false
}
}
async function togglePpa (enabled) {
togglingPpa.value = true
try {
await hubFetch('/payments/toggle-ppa', {
method: 'POST',
body: { customer: customer.value.name, enabled },
})
Notify.create({
type: 'positive',
message: enabled ? 'PPA activé' : 'PPA désactivé',
position: 'top',
})
return true
} catch (e) {
Notify.create({ type: 'negative', message: `Erreur PPA: ${e.message}`, position: 'top' })
return false
} finally {
togglingPpa.value = false
}
}
async function openPortal () {
loading.value = true
try {
const res = await hubFetch('/payments/portal', {
method: 'POST',
body: { customer: customer.value.name },
})
if (res.url) window.open(res.url, '_blank')
} catch (e) {
Notify.create({ type: 'negative', message: `Erreur: ${e.message}`, position: 'top' })
} finally {
loading.value = false
}
}
async function createCheckout () {
loading.value = true
try {
const res = await hubFetch('/payments/checkout', {
method: 'POST',
body: { customer: customer.value.name },
})
// Copy URL to clipboard for the agent to share
if (res.url) {
await navigator.clipboard?.writeText(res.url)
Notify.create({ type: 'info', message: `Lien copié — ${res.amount}$. Ouvre dans un nouvel onglet.`, position: 'top', timeout: 4000 })
window.open(res.url, '_blank')
}
return res
} catch (e) {
Notify.create({ type: 'negative', message: `Erreur: ${e.message}`, position: 'top' })
} finally {
loading.value = false
}
}
const refunding = ref(false)
async function refundPayment (paymentEntry, amount, reason) {
refunding.value = true
try {
const res = await hubFetch('/payments/refund', {
method: 'POST',
body: { payment_entry: paymentEntry, amount: amount || undefined, reason },
})
if (res.ok) {
const msg = res.stripe_refund
? `Remboursement Stripe ${res.amount}$ (${res.stripe_refund.id})`
: `Remboursement ${res.amount}$ enregistré`
Notify.create({ type: 'positive', message: msg, position: 'top' })
if (res.warning) {
Notify.create({ type: 'warning', message: res.warning, position: 'top', timeout: 8000 })
}
}
return res
} catch (e) {
Notify.create({ type: 'negative', message: `Erreur remboursement: ${e.message}`, position: 'top' })
} finally {
refunding.value = false
}
}
return {
loading, sendingLink, chargingCard, togglingPpa, refunding,
fetchBalance, fetchMethods,
sendPaymentLink, chargeCard, togglePpa, openPortal, createCheckout,
refundPayment,
}
}