diff --git a/apps/ops/src/modules/dispatch/components/RightPanel.vue b/apps/ops/src/modules/dispatch/components/RightPanel.vue
index ff902c7..6969262 100644
--- a/apps/ops/src/modules/dispatch/components/RightPanel.vue
+++ b/apps/ops/src/modules/dispatch/components/RightPanel.vue
@@ -36,6 +36,28 @@ const onDeleteTag = inject('onDeleteTag')
Titre{{ panel.data?.job?.subject }}
+
+
+
Adresse{{ panel.data?.job?.address || '—' }}
Durée{{ fmtDur(panel.data?.job?.duration) }}
Priorité
diff --git a/apps/ops/src/pages/DispatchPage.vue b/apps/ops/src/pages/DispatchPage.vue
index 034a7c8..59d8feb 100644
--- a/apps/ops/src/pages/DispatchPage.vue
+++ b/apps/ops/src/pages/DispatchPage.vue
@@ -1672,6 +1672,15 @@ onUnmounted(() => {
+
+ 👤 Voir la fiche client ({{ ctxMenu.job.customer }})
+
+
+ 🏠 Lieu de service ({{ ctxMenu.job.serviceLocation }})
+
+
diff --git a/apps/ops/src/pages/dispatch-styles.scss b/apps/ops/src/pages/dispatch-styles.scss
index da8891e..f3f1bdb 100644
--- a/apps/ops/src/pages/dispatch-styles.scss
+++ b/apps/ops/src/pages/dispatch-styles.scss
@@ -629,6 +629,10 @@
.sb-rp-urgent-tag { background:rgba(239,68,68,0.15); color:#ef4444; font-size:0.7rem; font-weight:700; padding:0.25rem 0.5rem; border-radius:6px; display:inline-block; margin-bottom:0.5rem; }
.sb-rp-field { margin-bottom:0.45rem; color:var(--sb-text); }
.sb-rp-lbl { display:block; font-size:0.58rem; font-weight:700; text-transform:uppercase; letter-spacing:0.05em; color:#7b80a0; margin-bottom:0.1rem; }
+.sb-rp-link { color:#6366f1; text-decoration:none; font-size:0.78rem; font-weight:600; display:inline-flex; align-items:center; gap:4px; }
+.sb-rp-link:hover { text-decoration:underline; }
+.sb-rp-link-icon { font-size:0.65rem; opacity:0.7; }
+.sb-rp-link code { background:rgba(99,102,241,0.08); padding:1px 5px; border-radius:3px; font-size:0.7rem; }
.sb-rp-actions { padding:0.65rem 0.75rem; border-top:1px solid rgba(0,0,0,0.04); display:flex; flex-direction:column; gap:0.35rem; flex-shrink:0; }
.sb-rp-primary { background:#6366f1; border:none; border-radius:7px; color:var(--sb-text); font-size:0.72rem; font-weight:700; padding:0.4rem 0.75rem; cursor:pointer; }
.sb-rp-primary:hover { filter:brightness(1.12); }
diff --git a/apps/ops/src/stores/dispatch.js b/apps/ops/src/stores/dispatch.js
index 217da6c..d61b15e 100644
--- a/apps/ops/src/stores/dispatch.js
+++ b/apps/ops/src/stores/dispatch.js
@@ -30,6 +30,14 @@ export const useDispatchStore = defineStore('dispatch', () => {
subject: j.subject || 'Job sans titre',
address: j.address || 'Adresse inconnue',
coords: [j.longitude || 0, j.latitude || 0],
+ // Persisted ERPNext links — surfaced as clickable shortcuts in
+ // the RightPanel so the dispatcher can jump to the client's
+ // full record (or the Service Location in ERPNext) without
+ // leaving the dispatch board. The Mapbox marker still uses
+ // the cached coords above; for source-of-truth verification
+ // (geocode mismatch) the rep clicks through to /clients/:id.
+ customer: j.customer || null,
+ serviceLocation: j.service_location || null,
priority: j.priority || 'low',
duration: j.duration_h || 1,
status: j.status || 'open',