7906 lines
437 KiB
HTML
7906 lines
437 KiB
HTML
|
||
<!doctype html>
|
||
<html lang="en" class="no-js">
|
||
<head>
|
||
|
||
<meta charset="utf-8">
|
||
<meta name="viewport" content="width=device-width,initial-scale=1">
|
||
|
||
<meta name="description" content="Build Power. Not Rent It. Own your digital infrastructure.">
|
||
|
||
|
||
<meta name="author" content="Bunker Operations">
|
||
|
||
|
||
<link rel="canonical" href="https://bnkserve.org/v2/features/map/data-quality/">
|
||
|
||
|
||
<link rel="prev" href="../nar-import/">
|
||
|
||
|
||
<link rel="next" href="../../landing-pages/">
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="icon" href="../../../../assets/favicon.png">
|
||
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
|
||
|
||
|
||
|
||
<title>Data Quality - Changemaker Lite</title>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../../../assets/stylesheets/main.484c7ddc.min.css">
|
||
|
||
|
||
<link rel="stylesheet" href="../../../../assets/stylesheets/palette.ab4e12ef.min.css">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||
<link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Inter:300,300i,400,400i,700,700i%7CJetBrains+Mono:400,400i,700,700i&display=fallback">
|
||
<style>:root{--md-text-font:"Inter";--md-code-font:"JetBrains Mono"}</style>
|
||
|
||
|
||
|
||
<link rel="stylesheet" href="../../../../stylesheets/extra.css">
|
||
|
||
<link rel="stylesheet" href="../../../../stylesheets/home.css">
|
||
|
||
<link rel="stylesheet" href="../../../../assets/css/video-player.css">
|
||
|
||
<script>__md_scope=new URL("../../../..",location),__md_hash=e=>[...e].reduce(((e,_)=>(e<<5)-e+_.charCodeAt(0)),0),__md_get=(e,_=localStorage,t=__md_scope)=>JSON.parse(_.getItem(t.pathname+"."+e)),__md_set=(e,_,t=localStorage,a=__md_scope)=>{try{t.setItem(a.pathname+"."+e,JSON.stringify(_))}catch(e){}}</script>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<meta property="og:type" content="website" />
|
||
<meta property="og:title" content="Data Quality - Changemaker Lite" />
|
||
<meta property="og:description" content="Build Power. Not Rent It. Own your digital infrastructure." />
|
||
<meta property="og:image" content="https://bnkserve.org/assets/images/social/v2/features/map/data-quality.png" />
|
||
<meta property="og:image:type" content="image/png" />
|
||
<meta property="og:image:width" content="1200" />
|
||
<meta property="og:image:height" content="630" />
|
||
<meta property="og:url" content="https://bnkserve.org/v2/features/map/data-quality/" />
|
||
<meta property="twitter:card" content="summary_large_image" />
|
||
<meta property="twitter:title" content="Data Quality - Changemaker Lite" />
|
||
<meta property="twitter:description" content="Build Power. Not Rent It. Own your digital infrastructure." />
|
||
<meta property="twitter:image" content="https://bnkserve.org/assets/images/social/v2/features/map/data-quality.png" />
|
||
</head>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<body dir="ltr" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber">
|
||
|
||
|
||
<input class="md-toggle" data-md-toggle="drawer" type="checkbox" id="__drawer" autocomplete="off">
|
||
<input class="md-toggle" data-md-toggle="search" type="checkbox" id="__search" autocomplete="off">
|
||
<label class="md-overlay" for="__drawer"></label>
|
||
<div data-md-component="skip">
|
||
|
||
|
||
<a href="#data-quality-dashboard" class="md-skip">
|
||
Skip to content
|
||
</a>
|
||
|
||
</div>
|
||
<div data-md-component="announce">
|
||
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<header class="md-header md-header--shadow md-header--lifted" data-md-component="header">
|
||
<nav class="md-header__inner md-grid" aria-label="Header">
|
||
<a href="../../../.." title="Changemaker Lite" class="md-header__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
|
||
|
||
<img src="../../../../assets/logo.png" alt="logo">
|
||
|
||
</a>
|
||
<label class="md-header__button md-icon" for="__drawer">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M3 6h18v2H3zm0 5h18v2H3zm0 5h18v2H3z"/></svg>
|
||
</label>
|
||
<div class="md-header__title" data-md-component="header-title">
|
||
<div class="md-header__ellipsis">
|
||
<div class="md-header__topic">
|
||
<span class="md-ellipsis">
|
||
Changemaker Lite
|
||
</span>
|
||
</div>
|
||
<div class="md-header__topic" data-md-component="header-topic">
|
||
<span class="md-ellipsis">
|
||
|
||
Data Quality
|
||
|
||
</span>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
<form class="md-header__option" data-md-component="palette">
|
||
|
||
|
||
|
||
|
||
<input class="md-option" data-md-color-media="" data-md-color-scheme="slate" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to light mode" type="radio" name="__palette" id="__palette_0">
|
||
|
||
<label class="md-header__button md-icon" title="Switch to light mode" for="__palette_1" hidden>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="m17.75 4.09-2.53 1.94.91 3.06-2.63-1.81-2.63 1.81.91-3.06-2.53-1.94L12.44 4l1.06-3 1.06 3zm3.5 6.91-1.64 1.25.59 1.98-1.7-1.17-1.7 1.17.59-1.98L15.75 11l2.06-.05L18.5 9l.69 1.95zm-2.28 4.95c.83-.08 1.72 1.1 1.19 1.85-.32.45-.66.87-1.08 1.27C15.17 23 8.84 23 4.94 19.07c-3.91-3.9-3.91-10.24 0-14.14.4-.4.82-.76 1.27-1.08.75-.53 1.93.36 1.85 1.19-.27 2.86.69 5.83 2.89 8.02a9.96 9.96 0 0 0 8.02 2.89m-1.64 2.02a12.08 12.08 0 0 1-7.8-3.47c-2.17-2.19-3.33-5-3.49-7.82-2.81 3.14-2.7 7.96.31 10.98 3.02 3.01 7.84 3.12 10.98.31"/></svg>
|
||
</label>
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-option" data-md-color-media="" data-md-color-scheme="default" data-md-color-primary="deep-purple" data-md-color-accent="amber" aria-label="Switch to dark mode" type="radio" name="__palette" id="__palette_1">
|
||
|
||
<label class="md-header__button md-icon" title="Switch to dark mode" for="__palette_0" hidden>
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 7a5 5 0 0 1 5 5 5 5 0 0 1-5 5 5 5 0 0 1-5-5 5 5 0 0 1 5-5m0 2a3 3 0 0 0-3 3 3 3 0 0 0 3 3 3 3 0 0 0 3-3 3 3 0 0 0-3-3m0-7 2.39 3.42C13.65 5.15 12.84 5 12 5s-1.65.15-2.39.42zM3.34 7l4.16-.35A7.2 7.2 0 0 0 5.94 8.5c-.44.74-.69 1.5-.83 2.29zm.02 10 1.76-3.77a7.131 7.131 0 0 0 2.38 4.14zM20.65 7l-1.77 3.79a7.02 7.02 0 0 0-2.38-4.15zm-.01 10-4.14.36c.59-.51 1.12-1.14 1.54-1.86.42-.73.69-1.5.83-2.29zM12 22l-2.41-3.44c.74.27 1.55.44 2.41.44.82 0 1.63-.17 2.37-.44z"/></svg>
|
||
</label>
|
||
|
||
|
||
</form>
|
||
|
||
|
||
|
||
<script>var palette=__md_get("__palette");if(palette&&palette.color){if("(prefers-color-scheme)"===palette.color.media){var media=matchMedia("(prefers-color-scheme: light)"),input=document.querySelector(media.matches?"[data-md-color-media='(prefers-color-scheme: light)']":"[data-md-color-media='(prefers-color-scheme: dark)']");palette.color.media=input.getAttribute("data-md-color-media"),palette.color.scheme=input.getAttribute("data-md-color-scheme"),palette.color.primary=input.getAttribute("data-md-color-primary"),palette.color.accent=input.getAttribute("data-md-color-accent")}for(var[key,value]of Object.entries(palette.color))document.body.setAttribute("data-md-color-"+key,value)}</script>
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-header__button md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
||
</label>
|
||
<div class="md-search" data-md-component="search" role="dialog">
|
||
<label class="md-search__overlay" for="__search"></label>
|
||
<div class="md-search__inner" role="search">
|
||
<form class="md-search__form" name="search">
|
||
<input type="text" class="md-search__input" name="query" aria-label="Search" placeholder="Search" autocapitalize="off" autocorrect="off" autocomplete="off" spellcheck="false" data-md-component="search-query" required>
|
||
<label class="md-search__icon md-icon" for="__search">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M9.5 3A6.5 6.5 0 0 1 16 9.5c0 1.61-.59 3.09-1.56 4.23l.27.27h.79l5 5-1.5 1.5-5-5v-.79l-.27-.27A6.52 6.52 0 0 1 9.5 16 6.5 6.5 0 0 1 3 9.5 6.5 6.5 0 0 1 9.5 3m0 2C7 5 5 7 5 9.5S7 14 9.5 14 14 12 14 9.5 12 5 9.5 5"/></svg>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
||
</label>
|
||
<nav class="md-search__options" aria-label="Search">
|
||
|
||
<a href="javascript:void(0)" class="md-search__icon md-icon" title="Share" aria-label="Share" data-clipboard data-clipboard-text="" data-md-component="search-share" tabindex="-1">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18 16.08c-.76 0-1.44.3-1.96.77L8.91 12.7c.05-.23.09-.46.09-.7s-.04-.47-.09-.7l7.05-4.11c.54.5 1.25.81 2.04.81a3 3 0 0 0 3-3 3 3 0 0 0-3-3 3 3 0 0 0-3 3c0 .24.04.47.09.7L8.04 9.81C7.5 9.31 6.79 9 6 9a3 3 0 0 0-3 3 3 3 0 0 0 3 3c.79 0 1.5-.31 2.04-.81l7.12 4.15c-.05.21-.08.43-.08.66 0 1.61 1.31 2.91 2.92 2.91s2.92-1.3 2.92-2.91A2.92 2.92 0 0 0 18 16.08"/></svg>
|
||
</a>
|
||
|
||
<button type="reset" class="md-search__icon md-icon" title="Clear" aria-label="Clear" tabindex="-1">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z"/></svg>
|
||
</button>
|
||
</nav>
|
||
|
||
<div class="md-search__suggest" data-md-component="search-suggest"></div>
|
||
|
||
</form>
|
||
<div class="md-search__output">
|
||
<div class="md-search__scrollwrap" tabindex="0" data-md-scrollfix>
|
||
<div class="md-search-result" data-md-component="search-result">
|
||
<div class="md-search-result__meta">
|
||
Initializing search
|
||
</div>
|
||
<ol class="md-search-result__list" role="presentation"></ol>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-header__source">
|
||
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
changemaker.lite
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
</nav>
|
||
|
||
|
||
|
||
<nav class="md-tabs" aria-label="Tabs" data-md-component="tabs">
|
||
<div class="md-grid">
|
||
<ul class="md-tabs__list">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../../.." class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
|
||
Home
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item md-tabs__item--active">
|
||
<a href="../../../" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
|
||
V2 Documentation
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../../../phil/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
|
||
Philosophy
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../../../v1/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
|
||
V1 Documentation (Legacy)
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-tabs__item">
|
||
<a href="../../../../blog/" class="md-tabs__link">
|
||
|
||
|
||
|
||
|
||
|
||
Blog
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</div>
|
||
</nav>
|
||
|
||
|
||
</header>
|
||
|
||
<div class="md-container" data-md-component="container">
|
||
|
||
|
||
|
||
|
||
<main class="md-main" data-md-component="main">
|
||
<div class="md-main__inner md-grid">
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--primary" data-md-component="sidebar" data-md-type="navigation" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--primary md-nav--lifted" aria-label="Navigation" data-md-level="0">
|
||
<label class="md-nav__title" for="__drawer">
|
||
<a href="../../../.." title="Changemaker Lite" class="md-nav__button md-logo" aria-label="Changemaker Lite" data-md-component="logo">
|
||
|
||
<img src="../../../../assets/logo.png" alt="logo">
|
||
|
||
</a>
|
||
Changemaker Lite
|
||
</label>
|
||
|
||
<div class="md-nav__source">
|
||
<a href="https://gitea.bnkops.com/admin/changemaker.lite" title="Go to repository" class="md-source" data-md-component="source">
|
||
<div class="md-source__icon md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M439.6 236.1 244 40.5c-5.4-5.5-12.8-8.5-20.4-8.5s-15 3-20.4 8.4L162.5 81l51.5 51.5c27.1-9.1 52.7 16.8 43.4 43.7l49.7 49.7c34.2-11.8 61.2 31 35.5 56.7-26.5 26.5-70.2-2.9-56-37.3L240.3 199v121.9c25.3 12.5 22.3 41.8 9.1 55-6.4 6.4-15.2 10.1-24.3 10.1s-17.8-3.6-24.3-10.1c-17.6-17.6-11.1-46.9 11.2-56v-123c-20.8-8.5-24.6-30.7-18.6-45L142.6 101 8.5 235.1C3 240.6 0 247.9 0 255.5s3 15 8.5 20.4l195.6 195.7c5.4 5.4 12.7 8.4 20.4 8.4s15-3 20.4-8.4l194.7-194.7c5.4-5.4 8.4-12.8 8.4-20.4s-3-15-8.4-20.4"/></svg>
|
||
</div>
|
||
<div class="md-source__repository">
|
||
changemaker.lite
|
||
</div>
|
||
</a>
|
||
</div>
|
||
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../.." class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Home
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2" checked>
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
V2 Documentation
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2" id="__nav_2_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_2_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_2">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
V2 Documentation
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_2" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../getting-started/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Getting Started
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_2" id="__nav_2_2_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_2_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_2">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Getting Started
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../getting-started/quick-start/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Quick Start
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_3" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../architecture/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Architecture
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_3" id="__nav_2_3_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_3_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_3">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Architecture
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../architecture/dual-api/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Dual API System
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../architecture/authentication/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Authentication & Security
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_4" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../backend/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Backend
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_4" id="__nav_2_4_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_4_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_4">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Backend
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../backend/modules/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Modules
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../backend/services/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Services
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../backend/middleware/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Middleware
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../backend/utilities/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Utilities
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_5" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../frontend/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Frontend
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_5" id="__nav_2_5_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_5_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_5">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Frontend
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../frontend/components/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Components
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../frontend/layouts/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Layouts
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../frontend/pages/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Pages
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_6" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../database/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Database
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_6" id="__nav_2_6_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_6_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_6">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Database
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../database/schema/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Schema Overview
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../database/migrations/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Migrations
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../database/seeding/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Seeding
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../database/indexes/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Indexes
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../database/models/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Models
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_7" checked>
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Features
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_7" id="__nav_2_7_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_7_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_2_7">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Features
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../influence/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Influence
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active md-nav__item--nested">
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_7_3" checked>
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Map
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_7_3" id="__nav_2_7_3_label" tabindex="0">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="3" aria-labelledby="__nav_2_7_3_label" aria-expanded="true">
|
||
<label class="md-nav__title" for="__nav_2_7_3">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Map
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../locations/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Locations
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../geocoding/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Geocoding
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../cuts/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Cuts
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../shifts/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Shifts
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../canvassing/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Canvassing
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../tracking/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Tracking
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../walk-sheets/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Walk Sheets
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../nar-import/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
NAR Import
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--active">
|
||
|
||
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__link md-nav__link--active" for="__toc">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Data Quality
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
<a href="./" class="md-nav__link md-nav__link--active">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Data Quality
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="On this page">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
On this page
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#overview" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Overview
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#architecture" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Architecture
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#database-models" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Database Models
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Database Models">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#location-model" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Location Model
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#address-model" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Address Model
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#api-endpoints" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
API Endpoints
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="API Endpoints">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#get-apilocationsgeocode-stats" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
GET /api/locations/geocode-stats
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#get-apilocationsgeocodeconfidencelt50" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
GET /api/locations?geocodeConfidence=lt:50
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#get-apilocationsduplicates" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
GET /api/locations/duplicates
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#post-apilocationsidregeocode" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
POST /api/locations/:id/regeocode
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#post-apilocationsbulk-geocode" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
POST /api/locations/bulk-geocode
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#configuration" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Configuration
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Configuration">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#environment-variables" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Environment Variables
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quality-thresholds" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quality Thresholds
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#prometheus-metrics" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Prometheus Metrics
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quality-metrics" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quality Metrics
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Quality Metrics">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#geocoding-confidence" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Geocoding Confidence
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#provider-success-rates" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Provider Success Rates
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#duplicate-detection" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Duplicate Detection
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#address-validation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Address Validation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#admin-workflow" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Admin Workflow
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Admin Workflow">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#navigate-to-data-quality-dashboard" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Navigate to Data Quality Dashboard
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#identify-and-review-low-confidence-locations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Identify and Review Low-Confidence Locations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#bulk-re-geocoding" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Bulk Re-geocoding
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#handle-duplicates" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Handle Duplicates
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quality-improvement-strategies" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quality Improvement Strategies
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Quality Improvement Strategies">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#multi-provider-geocoding" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Multi-Provider Geocoding
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#address-normalization" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Address Normalization
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#geocoding-cache" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Geocoding Cache
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#manual-verification" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Manual Verification
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#regular-audits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Regular Audits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#code-examples" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Code Examples
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Code Examples">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#dataqualitydashboardpagetsx" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
DataQualityDashboardPage.tsx
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#geocode-statistics-service" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Geocode Statistics Service
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#troubleshooting" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Troubleshooting
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Troubleshooting">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#problem-many-low-confidence-locations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Problem: Many low-confidence locations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#problem-duplicate-locations-detected" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Problem: Duplicate locations detected
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#problem-geocoding-stats-slow-to-load" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Problem: Geocoding stats slow to load
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#performance-considerations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Performance Considerations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Performance Considerations">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#database-query-optimization" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Database Query Optimization
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#api-rate-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
API Rate Limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#caching-strategy" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Caching Strategy
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#related-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Related Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Related Documentation">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#backend-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Backend Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#frontend-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Frontend Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#database-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Database Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#monitoring-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Monitoring Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#external-resources" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
External Resources
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../landing-pages/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Landing Pages
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../email-templates/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Email Templates
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../media/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Media
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../newsletter/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Newsletter
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../observability/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Observability
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../tunnel/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Tunnel
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_8" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../deployment/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Deployment
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_8" id="__nav_2_8_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_8_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_8">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Deployment
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/docker-compose/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Docker Compose
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/environment-variables/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Environment Variables
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/nginx/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Nginx Configuration
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/ssl-tls/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
SSL/TLS
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/tunneling/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Tunneling
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/monitoring-stack/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Monitoring Stack
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/healthchecks/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Health Checks
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/scaling/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Scaling
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../deployment/backup-restore/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Backup & Restore
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_9" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../development/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Development
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_9" id="__nav_2_9_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_9_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_9">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Development
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/local-setup/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Local Setup
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/docker-workflow/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Docker Workflow
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/git-workflow/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Git Workflow
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/npm-commands/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
NPM Commands
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/migrations/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Migrations
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/typescript/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
TypeScript
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/testing/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Testing
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/debugging/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Debugging
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../development/code-style/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Code Style
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_10" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../api-reference/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
API Reference
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_10_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_10">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
API Reference
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_11" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../user-guides/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
User Guides
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_11" id="__nav_2_11_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_11_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_11">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
User Guides
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../user-guides/admin-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Admin Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../user-guides/campaign-manager-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Campaign Manager Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../user-guides/map-organizer-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Map Organizer Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../user-guides/content-editor-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Content Editor Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../user-guides/volunteer-guide/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Volunteer Guide
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_12" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../troubleshooting/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Troubleshooting
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_12" id="__nav_2_12_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_12_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_12">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Troubleshooting
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/faq/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
FAQ
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/common-errors/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Common Errors
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/auth-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Auth Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/database-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Database Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/docker-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Docker Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/email-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Email Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/geocoding-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Geocoding Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/monitoring-issues/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Monitoring Issues
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../troubleshooting/performance-optimization/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Performance Optimization
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_13" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../migration/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Migration
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_13" id="__nav_2_13_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_13_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_13">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Migration
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../migration/feature-parity/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Feature Parity
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../migration/breaking-changes/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Breaking Changes
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../migration/api-changes/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
API Changes
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../migration/data-migration/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Data Migration
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--section md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_14" >
|
||
|
||
|
||
<div class="md-nav__link md-nav__container">
|
||
<a href="../../../contributing/" class="md-nav__link ">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Contributing
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
|
||
|
||
<label class="md-nav__link " for="__nav_2_14" id="__nav_2_14_label" tabindex="">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
</label>
|
||
|
||
</div>
|
||
|
||
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_2_14_label" aria-expanded="false">
|
||
<label class="md-nav__title" for="__nav_2_14">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
|
||
Contributing
|
||
|
||
|
||
</label>
|
||
<ul class="md-nav__list" data-md-scrollfix>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../contributing/development-setup/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Development Setup
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../contributing/code-of-conduct/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Code of Conduct
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../contributing/pull-requests/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Pull Requests
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item">
|
||
<a href="../../../contributing/roadmap/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Roadmap
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../../phil/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Philosophy
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../../v1/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
V1 Documentation (Legacy)
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-nav__item md-nav__item--pruned md-nav__item--nested">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="../../../../blog/" class="md-nav__link">
|
||
|
||
|
||
|
||
<span class="md-ellipsis">
|
||
|
||
|
||
Blog
|
||
|
||
|
||
|
||
</span>
|
||
|
||
|
||
|
||
|
||
<span class="md-nav__icon md-icon"></span>
|
||
|
||
</a>
|
||
|
||
|
||
|
||
</li>
|
||
|
||
|
||
|
||
</ul>
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-sidebar md-sidebar--secondary" data-md-component="sidebar" data-md-type="toc" >
|
||
<div class="md-sidebar__scrollwrap">
|
||
<div class="md-sidebar__inner">
|
||
|
||
|
||
|
||
|
||
<nav class="md-nav md-nav--secondary" aria-label="On this page">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<label class="md-nav__title" for="__toc">
|
||
<span class="md-nav__icon md-icon"></span>
|
||
On this page
|
||
</label>
|
||
<ul class="md-nav__list" data-md-component="toc" data-md-scrollfix>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#overview" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Overview
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#architecture" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Architecture
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#database-models" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Database Models
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Database Models">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#location-model" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Location Model
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#address-model" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Address Model
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#api-endpoints" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
API Endpoints
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="API Endpoints">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#get-apilocationsgeocode-stats" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
GET /api/locations/geocode-stats
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#get-apilocationsgeocodeconfidencelt50" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
GET /api/locations?geocodeConfidence=lt:50
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#get-apilocationsduplicates" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
GET /api/locations/duplicates
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#post-apilocationsidregeocode" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
POST /api/locations/:id/regeocode
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#post-apilocationsbulk-geocode" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
POST /api/locations/bulk-geocode
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#configuration" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Configuration
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Configuration">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#environment-variables" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Environment Variables
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quality-thresholds" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quality Thresholds
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#prometheus-metrics" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Prometheus Metrics
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quality-metrics" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quality Metrics
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Quality Metrics">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#geocoding-confidence" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Geocoding Confidence
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#provider-success-rates" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Provider Success Rates
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#duplicate-detection" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Duplicate Detection
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#address-validation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Address Validation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#admin-workflow" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Admin Workflow
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Admin Workflow">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#navigate-to-data-quality-dashboard" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Navigate to Data Quality Dashboard
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#identify-and-review-low-confidence-locations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Identify and Review Low-Confidence Locations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#bulk-re-geocoding" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Bulk Re-geocoding
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#handle-duplicates" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Handle Duplicates
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#quality-improvement-strategies" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Quality Improvement Strategies
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Quality Improvement Strategies">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#multi-provider-geocoding" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Multi-Provider Geocoding
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#address-normalization" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Address Normalization
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#geocoding-cache" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Geocoding Cache
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#manual-verification" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Manual Verification
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#regular-audits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Regular Audits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#code-examples" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Code Examples
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Code Examples">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#dataqualitydashboardpagetsx" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
DataQualityDashboardPage.tsx
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#geocode-statistics-service" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Geocode Statistics Service
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#troubleshooting" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Troubleshooting
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Troubleshooting">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#problem-many-low-confidence-locations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Problem: Many low-confidence locations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#problem-duplicate-locations-detected" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Problem: Duplicate locations detected
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#problem-geocoding-stats-slow-to-load" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Problem: Geocoding stats slow to load
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#performance-considerations" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Performance Considerations
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Performance Considerations">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#database-query-optimization" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Database Query Optimization
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#api-rate-limits" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
API Rate Limits
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#caching-strategy" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Caching Strategy
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#related-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Related Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
<nav class="md-nav" aria-label="Related Documentation">
|
||
<ul class="md-nav__list">
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#backend-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Backend Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#frontend-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Frontend Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#database-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Database Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#monitoring-documentation" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
Monitoring Documentation
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
<li class="md-nav__item">
|
||
<a href="#external-resources" class="md-nav__link">
|
||
<span class="md-ellipsis">
|
||
|
||
External Resources
|
||
|
||
</span>
|
||
</a>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
</nav>
|
||
|
||
</li>
|
||
|
||
</ul>
|
||
|
||
</nav>
|
||
</div>
|
||
</div>
|
||
</div>
|
||
|
||
|
||
|
||
<div class="md-content" data-md-component="content">
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<nav class="md-path" aria-label="Navigation" >
|
||
<ol class="md-path__list">
|
||
|
||
|
||
|
||
|
||
<li class="md-path__item">
|
||
<a href="../../../.." class="md-path__link">
|
||
|
||
<span class="md-ellipsis">
|
||
Home
|
||
</span>
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-path__item">
|
||
<a href="../../../" class="md-path__link">
|
||
|
||
<span class="md-ellipsis">
|
||
V2 Documentation
|
||
</span>
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-path__item">
|
||
<a href="../../" class="md-path__link">
|
||
|
||
<span class="md-ellipsis">
|
||
Features
|
||
</span>
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
<li class="md-path__item">
|
||
<a href="../" class="md-path__link">
|
||
|
||
<span class="md-ellipsis">
|
||
Map
|
||
</span>
|
||
|
||
</a>
|
||
</li>
|
||
|
||
|
||
|
||
|
||
</ol>
|
||
</nav>
|
||
|
||
|
||
<article class="md-content__inner md-typeset">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/v2/features/map/data-quality.md" title="Edit this page" class="md-content__button md-icon" rel="edit">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M10 20H6V4h7v5h5v3.1l2-2V8l-6-6H6c-1.1 0-2 .9-2 2v16c0 1.1.9 2 2 2h4zm10.2-7c.1 0 .3.1.4.2l1.3 1.3c.2.2.2.6 0 .8l-1 1-2.1-2.1 1-1c.1-.1.2-.2.4-.2m0 3.9L14.1 23H12v-2.1l6.1-6.1z"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/v2/features/map/data-quality.md" title="View source of this page" class="md-content__button md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M17 18c.56 0 1 .44 1 1s-.44 1-1 1-1-.44-1-1 .44-1 1-1m0-3c-2.73 0-5.06 1.66-6 4 .94 2.34 3.27 4 6 4s5.06-1.66 6-4c-.94-2.34-3.27-4-6-4m0 6.5a2.5 2.5 0 0 1-2.5-2.5 2.5 2.5 0 0 1 2.5-2.5 2.5 2.5 0 0 1 2.5 2.5 2.5 2.5 0 0 1-2.5 2.5M9.27 20H6V4h7v5h5v4.07c.7.08 1.36.25 2 .49V8l-6-6H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h4.5a8.2 8.2 0 0 1-1.23-2"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
<h1 id="data-quality-dashboard">Data Quality Dashboard<a class="headerlink" href="#data-quality-dashboard" title="Permanent link">¶</a></h1>
|
||
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">¶</a></h2>
|
||
<p>The Data Quality Dashboard provides comprehensive monitoring and management of geocoding accuracy and location data integrity. This feature enables campaign administrators to identify and resolve data quality issues, track geocoding provider performance, and ensure reliable map data for canvassing operations.</p>
|
||
<p><strong>Key Features:</strong></p>
|
||
<ul>
|
||
<li>Real-time geocoding quality metrics</li>
|
||
<li>Provider success rate tracking</li>
|
||
<li>Low-confidence location detection</li>
|
||
<li>Duplicate location identification</li>
|
||
<li>Bulk re-geocoding operations</li>
|
||
<li>Address validation reporting</li>
|
||
<li>Interactive quality charts</li>
|
||
<li>Export quality reports</li>
|
||
</ul>
|
||
<p><strong>Use Cases:</strong></p>
|
||
<ul>
|
||
<li>Monthly data quality audits</li>
|
||
<li>NAR import validation</li>
|
||
<li>Geocoding provider evaluation</li>
|
||
<li>Pre-canvass data verification</li>
|
||
<li>Address database cleanup</li>
|
||
<li>Campaign planning accuracy checks</li>
|
||
</ul>
|
||
<p><strong>Architecture Highlights:</strong></p>
|
||
<ul>
|
||
<li>Aggregate statistics via database queries</li>
|
||
<li>Confidence threshold filtering (0-100 scale)</li>
|
||
<li>Provider performance comparison</li>
|
||
<li>Duplicate detection via coordinate matching</li>
|
||
<li>Manual review workflows</li>
|
||
<li>Prometheus metrics integration</li>
|
||
</ul>
|
||
<h2 id="architecture">Architecture<a class="headerlink" href="#architecture" title="Permanent link">¶</a></h2>
|
||
<pre class="mermaid"><code>flowchart TB
|
||
subgraph Admin Interface
|
||
Admin[Admin User]
|
||
Dashboard[DataQualityDashboardPage]
|
||
LocationsPage[LocationsPage]
|
||
end
|
||
|
||
subgraph API Layer
|
||
StatsAPI["/api/locations/geocode-stats"]
|
||
LocationsAPI["/api/locations"]
|
||
DuplicatesAPI["/api/locations/duplicates"]
|
||
RegeocodeAPI["/api/locations/:id/regeocode"]
|
||
BulkGeocodeAPI["/api/locations/bulk-geocode"]
|
||
end
|
||
|
||
subgraph Database
|
||
LocationsDB[(Locations)]
|
||
Indexes[(Indexes)]
|
||
end
|
||
|
||
subgraph Geocoding Service
|
||
GeocodingService[GeocodingService]
|
||
Providers[6 Providers]
|
||
Cache[Redis Cache]
|
||
end
|
||
|
||
subgraph Monitoring
|
||
Prometheus[Prometheus]
|
||
Metrics[cm_locations_low_confidence_count]
|
||
end
|
||
|
||
Admin --> Dashboard
|
||
Admin --> LocationsPage
|
||
|
||
Dashboard --> StatsAPI
|
||
Dashboard --> LocationsAPI
|
||
Dashboard --> DuplicatesAPI
|
||
LocationsPage --> RegeocodeAPI
|
||
LocationsPage --> BulkGeocodeAPI
|
||
|
||
StatsAPI --> LocationsDB
|
||
LocationsAPI --> LocationsDB
|
||
DuplicatesAPI --> LocationsDB
|
||
RegeocodeAPI --> GeocodingService
|
||
BulkGeocodeAPI --> GeocodingService
|
||
|
||
LocationsDB --> Indexes
|
||
GeocodingService --> Providers
|
||
GeocodingService --> Cache
|
||
|
||
StatsAPI --> Prometheus
|
||
Prometheus --> Metrics</code></pre>
|
||
<p><strong>Data Flow:</strong></p>
|
||
<ol>
|
||
<li><strong>Statistics Aggregation:</strong></li>
|
||
<li>Query all locations with geocoding metadata</li>
|
||
<li>Calculate aggregate metrics (total, geocoded %, avg confidence)</li>
|
||
<li>Group by provider for success rate comparison</li>
|
||
<li>Identify low-confidence locations (< 50)</li>
|
||
<li>
|
||
<p>Detect duplicates via coordinate matching</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Quality Review:</strong></p>
|
||
</li>
|
||
<li>Admin views dashboard statistics</li>
|
||
<li>Filters low-confidence locations</li>
|
||
<li>Reviews individual location details</li>
|
||
<li>
|
||
<p>Identifies patterns (provider failures, address format issues)</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Remediation:</strong></p>
|
||
</li>
|
||
<li>Manual address correction</li>
|
||
<li>Single location re-geocoding</li>
|
||
<li>Bulk re-geocoding with different provider</li>
|
||
<li>
|
||
<p>Duplicate merging or marking</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Monitoring:</strong></p>
|
||
</li>
|
||
<li>Prometheus metrics track quality trends</li>
|
||
<li>Alert rules trigger for quality degradation</li>
|
||
<li>Grafana dashboards visualize provider performance</li>
|
||
</ol>
|
||
<h2 id="database-models">Database Models<a class="headerlink" href="#database-models" title="Permanent link">¶</a></h2>
|
||
<h3 id="location-model">Location Model<a class="headerlink" href="#location-model" title="Permanent link">¶</a></h3>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a>model Location {
|
||
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a> id Int @id @default(autoincrement())
|
||
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a> address String
|
||
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a> latitude Float?
|
||
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a> longitude Float?
|
||
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a> postalCode String?
|
||
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a> province String?
|
||
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>
|
||
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a> // Geocoding metadata
|
||
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a> geocodeConfidence Int? // 0-100 quality score
|
||
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a> geocodeProvider String? // Provider used for geocoding
|
||
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a> geocodedAt DateTime? // Timestamp of last geocode
|
||
</span><span id="__span-0-13"><a id="__codelineno-0-13" name="__codelineno-0-13" href="#__codelineno-0-13"></a>
|
||
</span><span id="__span-0-14"><a id="__codelineno-0-14" name="__codelineno-0-14" href="#__codelineno-0-14"></a> // NAR import fields
|
||
</span><span id="__span-0-15"><a id="__codelineno-0-15" name="__codelineno-0-15" href="#__codelineno-0-15"></a> locGuid String? @unique
|
||
</span><span id="__span-0-16"><a id="__codelineno-0-16" name="__codelineno-0-16" href="#__codelineno-0-16"></a> federalDistrict String?
|
||
</span><span id="__span-0-17"><a id="__codelineno-0-17" name="__codelineno-0-17" href="#__codelineno-0-17"></a> buildingUse Int? // 1 = Residential
|
||
</span><span id="__span-0-18"><a id="__codelineno-0-18" name="__codelineno-0-18" href="#__codelineno-0-18"></a>
|
||
</span><span id="__span-0-19"><a id="__codelineno-0-19" name="__codelineno-0-19" href="#__codelineno-0-19"></a> addresses Address[]
|
||
</span><span id="__span-0-20"><a id="__codelineno-0-20" name="__codelineno-0-20" href="#__codelineno-0-20"></a>
|
||
</span><span id="__span-0-21"><a id="__codelineno-0-21" name="__codelineno-0-21" href="#__codelineno-0-21"></a> createdAt DateTime @default(now())
|
||
</span><span id="__span-0-22"><a id="__codelineno-0-22" name="__codelineno-0-22" href="#__codelineno-0-22"></a> updatedAt DateTime @updatedAt
|
||
</span><span id="__span-0-23"><a id="__codelineno-0-23" name="__codelineno-0-23" href="#__codelineno-0-23"></a>
|
||
</span><span id="__span-0-24"><a id="__codelineno-0-24" name="__codelineno-0-24" href="#__codelineno-0-24"></a> @@index([geocodeConfidence])
|
||
</span><span id="__span-0-25"><a id="__codelineno-0-25" name="__codelineno-0-25" href="#__codelineno-0-25"></a> @@index([geocodeProvider])
|
||
</span><span id="__span-0-26"><a id="__codelineno-0-26" name="__codelineno-0-26" href="#__codelineno-0-26"></a> @@index([latitude, longitude])
|
||
</span><span id="__span-0-27"><a id="__codelineno-0-27" name="__codelineno-0-27" href="#__codelineno-0-27"></a> @@index([latitude, longitude], where: latitude IS NOT NULL AND longitude IS NOT NULL)
|
||
</span><span id="__span-0-28"><a id="__codelineno-0-28" name="__codelineno-0-28" href="#__codelineno-0-28"></a>}
|
||
</span></code></pre></div>
|
||
<p><strong>Geocode Confidence Scale:</strong>
|
||
- 0-20: Very Low (manual review required)
|
||
- 21-40: Low (likely incorrect, re-geocode recommended)
|
||
- 41-60: Medium (acceptable but consider verification)
|
||
- 61-80: Good (likely accurate)
|
||
- 81-100: Excellent (high confidence)</p>
|
||
<p><strong>Geocode Provider Enum:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a><span class="kd">enum</span><span class="w"> </span><span class="nx">GeocodeProvider</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a><span class="w"> </span><span class="nx">GOOGLE</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'GOOGLE'</span><span class="p">,</span>
|
||
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a><span class="w"> </span><span class="nx">MAPBOX</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'MAPBOX'</span><span class="p">,</span>
|
||
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a><span class="w"> </span><span class="nx">NOMINATIM</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'NOMINATIM'</span><span class="p">,</span>
|
||
</span><span id="__span-1-5"><a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a><span class="w"> </span><span class="nx">PHOTON</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'PHOTON'</span><span class="p">,</span>
|
||
</span><span id="__span-1-6"><a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a><span class="w"> </span><span class="nx">LOCATIONIQ</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'LOCATIONIQ'</span><span class="p">,</span>
|
||
</span><span id="__span-1-7"><a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a><span class="w"> </span><span class="nx">ARCGIS</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'ARCGIS'</span><span class="p">,</span>
|
||
</span><span id="__span-1-8"><a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a><span class="w"> </span><span class="nx">UNKNOWN</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s1">'UNKNOWN'</span>
|
||
</span><span id="__span-1-9"><a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<h3 id="address-model">Address Model<a class="headerlink" href="#address-model" title="Permanent link">¶</a></h3>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>model Address {
|
||
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a> id Int @id @default(autoincrement())
|
||
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a> locationId Int
|
||
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a> location Location @relation(fields: [locationId], references: [id], onDelete: Cascade)
|
||
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a>
|
||
</span><span id="__span-2-6"><a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a> unitNumber String?
|
||
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a> firstName String?
|
||
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a> lastName String?
|
||
</span><span id="__span-2-9"><a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a> supportLevel Int?
|
||
</span><span id="__span-2-10"><a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a> notes String?
|
||
</span><span id="__span-2-11"><a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a>
|
||
</span><span id="__span-2-12"><a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a> // Address validation
|
||
</span><span id="__span-2-13"><a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a> isValidated Boolean @default(false)
|
||
</span><span id="__span-2-14"><a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a> validatedAt DateTime?
|
||
</span><span id="__span-2-15"><a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a>
|
||
</span><span id="__span-2-16"><a id="__codelineno-2-16" name="__codelineno-2-16" href="#__codelineno-2-16"></a> createdAt DateTime @default(now())
|
||
</span><span id="__span-2-17"><a id="__codelineno-2-17" name="__codelineno-2-17" href="#__codelineno-2-17"></a> updatedAt DateTime @updatedAt
|
||
</span><span id="__span-2-18"><a id="__codelineno-2-18" name="__codelineno-2-18" href="#__codelineno-2-18"></a>
|
||
</span><span id="__span-2-19"><a id="__codelineno-2-19" name="__codelineno-2-19" href="#__codelineno-2-19"></a> @@index([locationId])
|
||
</span><span id="__span-2-20"><a id="__codelineno-2-20" name="__codelineno-2-20" href="#__codelineno-2-20"></a>}
|
||
</span></code></pre></div>
|
||
<h2 id="api-endpoints">API Endpoints<a class="headerlink" href="#api-endpoints" title="Permanent link">¶</a></h2>
|
||
<h3 id="get-apilocationsgeocode-stats">GET /api/locations/geocode-stats<a class="headerlink" href="#get-apilocationsgeocode-stats" title="Permanent link">¶</a></h3>
|
||
<p>Fetch aggregate geocoding quality statistics.</p>
|
||
<p><strong>Authentication:</strong> Required (SUPER_ADMIN, MAP_ADMIN)</p>
|
||
<p><strong>Response:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a><span class="p">{</span>
|
||
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="w"> </span><span class="nt">"total"</span><span class="p">:</span><span class="w"> </span><span class="mi">1500</span><span class="p">,</span>
|
||
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="w"> </span><span class="nt">"geocoded"</span><span class="p">:</span><span class="w"> </span><span class="mi">1450</span><span class="p">,</span>
|
||
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="w"> </span><span class="nt">"geocodedPercent"</span><span class="p">:</span><span class="w"> </span><span class="mf">96.67</span><span class="p">,</span>
|
||
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a><span class="w"> </span><span class="nt">"avgConfidence"</span><span class="p">:</span><span class="w"> </span><span class="mf">78.5</span><span class="p">,</span>
|
||
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="w"> </span><span class="nt">"providerBreakdown"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-3-7"><a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a><span class="w"> </span><span class="nt">"GOOGLE"</span><span class="p">:</span><span class="w"> </span><span class="mi">800</span><span class="p">,</span>
|
||
</span><span id="__span-3-8"><a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a><span class="w"> </span><span class="nt">"MAPBOX"</span><span class="p">:</span><span class="w"> </span><span class="mi">350</span><span class="p">,</span>
|
||
</span><span id="__span-3-9"><a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a><span class="w"> </span><span class="nt">"NOMINATIM"</span><span class="p">:</span><span class="w"> </span><span class="mi">200</span><span class="p">,</span>
|
||
</span><span id="__span-3-10"><a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a><span class="w"> </span><span class="nt">"PHOTON"</span><span class="p">:</span><span class="w"> </span><span class="mi">100</span><span class="p">,</span>
|
||
</span><span id="__span-3-11"><a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a><span class="w"> </span><span class="nt">"ARCGIS"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||
</span><span id="__span-3-12"><a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a><span class="w"> </span><span class="nt">"LOCATIONIQ"</span><span class="p">:</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span>
|
||
</span><span id="__span-3-13"><a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a><span class="w"> </span><span class="nt">"UNKNOWN"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span>
|
||
</span><span id="__span-3-14"><a id="__codelineno-3-14" name="__codelineno-3-14" href="#__codelineno-3-14"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-3-15"><a id="__codelineno-3-15" name="__codelineno-3-15" href="#__codelineno-3-15"></a><span class="w"> </span><span class="nt">"confidenceDistribution"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-3-16"><a id="__codelineno-3-16" name="__codelineno-3-16" href="#__codelineno-3-16"></a><span class="w"> </span><span class="nt">"0-20"</span><span class="p">:</span><span class="w"> </span><span class="mi">15</span><span class="p">,</span>
|
||
</span><span id="__span-3-17"><a id="__codelineno-3-17" name="__codelineno-3-17" href="#__codelineno-3-17"></a><span class="w"> </span><span class="nt">"21-40"</span><span class="p">:</span><span class="w"> </span><span class="mi">35</span><span class="p">,</span>
|
||
</span><span id="__span-3-18"><a id="__codelineno-3-18" name="__codelineno-3-18" href="#__codelineno-3-18"></a><span class="w"> </span><span class="nt">"41-60"</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
|
||
</span><span id="__span-3-19"><a id="__codelineno-3-19" name="__codelineno-3-19" href="#__codelineno-3-19"></a><span class="w"> </span><span class="nt">"61-80"</span><span class="p">:</span><span class="w"> </span><span class="mi">450</span><span class="p">,</span>
|
||
</span><span id="__span-3-20"><a id="__codelineno-3-20" name="__codelineno-3-20" href="#__codelineno-3-20"></a><span class="w"> </span><span class="nt">"81-100"</span><span class="p">:</span><span class="w"> </span><span class="mi">800</span>
|
||
</span><span id="__span-3-21"><a id="__codelineno-3-21" name="__codelineno-3-21" href="#__codelineno-3-21"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-3-22"><a id="__codelineno-3-22" name="__codelineno-3-22" href="#__codelineno-3-22"></a><span class="w"> </span><span class="nt">"lowConfidenceCount"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span><span class="p">,</span>
|
||
</span><span id="__span-3-23"><a id="__codelineno-3-23" name="__codelineno-3-23" href="#__codelineno-3-23"></a><span class="w"> </span><span class="nt">"missingCoordinates"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span><span class="p">,</span>
|
||
</span><span id="__span-3-24"><a id="__codelineno-3-24" name="__codelineno-3-24" href="#__codelineno-3-24"></a><span class="w"> </span><span class="nt">"duplicatesCount"</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span>
|
||
</span><span id="__span-3-25"><a id="__codelineno-3-25" name="__codelineno-3-25" href="#__codelineno-3-25"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<p><strong>Implementation:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="c1">// locations.service.ts</span>
|
||
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="k">async</span><span class="w"> </span><span class="nx">getGeocodeStats</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">locations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
|
||
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="w"> </span><span class="nx">select</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-4-6"><a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-4-7"><a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a><span class="w"> </span><span class="nx">geocodeConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-4-8"><a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a><span class="w"> </span><span class="nx">geocodeProvider</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span>
|
||
</span><span id="__span-4-9"><a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-4-10"><a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-4-11"><a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a>
|
||
</span><span id="__span-4-12"><a id="__codelineno-4-12" name="__codelineno-4-12" href="#__codelineno-4-12"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-4-13"><a id="__codelineno-4-13" name="__codelineno-4-13" href="#__codelineno-4-13"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">geocoded</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">latitude</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">longitude</span><span class="p">).</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-4-14"><a id="__codelineno-4-14" name="__codelineno-4-14" href="#__codelineno-4-14"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">avgConfidence</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">sum</span><span class="p">,</span><span class="w"> </span><span class="nx">l</span><span class="p">)</span><span class="w"> </span><span class="p">=></span>
|
||
</span><span id="__span-4-15"><a id="__codelineno-4-15" name="__codelineno-4-15" href="#__codelineno-4-15"></a><span class="w"> </span><span class="nx">sum</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">),</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">total</span><span class="p">;</span>
|
||
</span><span id="__span-4-16"><a id="__codelineno-4-16" name="__codelineno-4-16" href="#__codelineno-4-16"></a>
|
||
</span><span id="__span-4-17"><a id="__codelineno-4-17" name="__codelineno-4-17" href="#__codelineno-4-17"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">providerBreakdown</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">acc</span><span class="p">,</span><span class="w"> </span><span class="nx">l</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-4-18"><a id="__codelineno-4-18" name="__codelineno-4-18" href="#__codelineno-4-18"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">provider</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeProvider</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">'UNKNOWN'</span><span class="p">;</span>
|
||
</span><span id="__span-4-19"><a id="__codelineno-4-19" name="__codelineno-4-19" href="#__codelineno-4-19"></a><span class="w"> </span><span class="nx">acc</span><span class="p">[</span><span class="nx">provider</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">acc</span><span class="p">[</span><span class="nx">provider</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
|
||
</span><span id="__span-4-20"><a id="__codelineno-4-20" name="__codelineno-4-20" href="#__codelineno-4-20"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">acc</span><span class="p">;</span>
|
||
</span><span id="__span-4-21"><a id="__codelineno-4-21" name="__codelineno-4-21" href="#__codelineno-4-21"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">{}</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="nx">Record</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">number</span><span class="o">></span><span class="p">);</span>
|
||
</span><span id="__span-4-22"><a id="__codelineno-4-22" name="__codelineno-4-22" href="#__codelineno-4-22"></a>
|
||
</span><span id="__span-4-23"><a id="__codelineno-4-23" name="__codelineno-4-23" href="#__codelineno-4-23"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-4-24"><a id="__codelineno-4-24" name="__codelineno-4-24" href="#__codelineno-4-24"></a><span class="w"> </span><span class="s1">'0-20'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-4-25"><a id="__codelineno-4-25" name="__codelineno-4-25" href="#__codelineno-4-25"></a><span class="w"> </span><span class="s1">'21-40'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-4-26"><a id="__codelineno-4-26" name="__codelineno-4-26" href="#__codelineno-4-26"></a><span class="w"> </span><span class="s1">'41-60'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-4-27"><a id="__codelineno-4-27" name="__codelineno-4-27" href="#__codelineno-4-27"></a><span class="w"> </span><span class="s1">'61-80'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-4-28"><a id="__codelineno-4-28" name="__codelineno-4-28" href="#__codelineno-4-28"></a><span class="w"> </span><span class="s1">'81-100'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span>
|
||
</span><span id="__span-4-29"><a id="__codelineno-4-29" name="__codelineno-4-29" href="#__codelineno-4-29"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-4-30"><a id="__codelineno-4-30" name="__codelineno-4-30" href="#__codelineno-4-30"></a>
|
||
</span><span id="__span-4-31"><a id="__codelineno-4-31" name="__codelineno-4-31" href="#__codelineno-4-31"></a><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-4-32"><a id="__codelineno-4-32" name="__codelineno-4-32" href="#__codelineno-4-32"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">conf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
|
||
</span><span id="__span-4-33"><a id="__codelineno-4-33" name="__codelineno-4-33" href="#__codelineno-4-33"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">20</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'0-20'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-4-34"><a id="__codelineno-4-34" name="__codelineno-4-34" href="#__codelineno-4-34"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">40</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'21-40'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-4-35"><a id="__codelineno-4-35" name="__codelineno-4-35" href="#__codelineno-4-35"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">60</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'41-60'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-4-36"><a id="__codelineno-4-36" name="__codelineno-4-36" href="#__codelineno-4-36"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">80</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'61-80'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-4-37"><a id="__codelineno-4-37" name="__codelineno-4-37" href="#__codelineno-4-37"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'81-100'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-4-38"><a id="__codelineno-4-38" name="__codelineno-4-38" href="#__codelineno-4-38"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-4-39"><a id="__codelineno-4-39" name="__codelineno-4-39" href="#__codelineno-4-39"></a>
|
||
</span><span id="__span-4-40"><a id="__codelineno-4-40" name="__codelineno-4-40" href="#__codelineno-4-40"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">lowConfidenceCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span>
|
||
</span><span id="__span-4-41"><a id="__codelineno-4-41" name="__codelineno-4-41" href="#__codelineno-4-41"></a><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mf">50</span><span class="p">).</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-4-42"><a id="__codelineno-4-42" name="__codelineno-4-42" href="#__codelineno-4-42"></a>
|
||
</span><span id="__span-4-43"><a id="__codelineno-4-43" name="__codelineno-4-43" href="#__codelineno-4-43"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-4-44"><a id="__codelineno-4-44" name="__codelineno-4-44" href="#__codelineno-4-44"></a><span class="w"> </span><span class="nx">total</span><span class="p">,</span>
|
||
</span><span id="__span-4-45"><a id="__codelineno-4-45" name="__codelineno-4-45" href="#__codelineno-4-45"></a><span class="w"> </span><span class="nx">geocoded</span><span class="p">,</span>
|
||
</span><span id="__span-4-46"><a id="__codelineno-4-46" name="__codelineno-4-46" href="#__codelineno-4-46"></a><span class="w"> </span><span class="nx">geocodedPercent</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">geocoded</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">total</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">100</span><span class="p">,</span>
|
||
</span><span id="__span-4-47"><a id="__codelineno-4-47" name="__codelineno-4-47" href="#__codelineno-4-47"></a><span class="w"> </span><span class="nx">avgConfidence</span><span class="p">,</span>
|
||
</span><span id="__span-4-48"><a id="__codelineno-4-48" name="__codelineno-4-48" href="#__codelineno-4-48"></a><span class="w"> </span><span class="nx">providerBreakdown</span><span class="p">,</span>
|
||
</span><span id="__span-4-49"><a id="__codelineno-4-49" name="__codelineno-4-49" href="#__codelineno-4-49"></a><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">,</span>
|
||
</span><span id="__span-4-50"><a id="__codelineno-4-50" name="__codelineno-4-50" href="#__codelineno-4-50"></a><span class="w"> </span><span class="nx">lowConfidenceCount</span><span class="p">,</span>
|
||
</span><span id="__span-4-51"><a id="__codelineno-4-51" name="__codelineno-4-51" href="#__codelineno-4-51"></a><span class="w"> </span><span class="nx">missingCoordinates</span><span class="o">:</span><span class="w"> </span><span class="kt">total</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">geocoded</span><span class="p">,</span>
|
||
</span><span id="__span-4-52"><a id="__codelineno-4-52" name="__codelineno-4-52" href="#__codelineno-4-52"></a><span class="w"> </span><span class="nx">duplicatesCount</span><span class="o">:</span><span class="w"> </span><span class="kt">await</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">countDuplicates</span><span class="p">()</span>
|
||
</span><span id="__span-4-53"><a id="__codelineno-4-53" name="__codelineno-4-53" href="#__codelineno-4-53"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-4-54"><a id="__codelineno-4-54" name="__codelineno-4-54" href="#__codelineno-4-54"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<h3 id="get-apilocationsgeocodeconfidencelt50">GET /api/locations?geocodeConfidence=lt:50<a class="headerlink" href="#get-apilocationsgeocodeconfidencelt50" title="Permanent link">¶</a></h3>
|
||
<p>Fetch locations filtered by geocode confidence.</p>
|
||
<p><strong>Authentication:</strong> Required</p>
|
||
<p><strong>Query Parameters:</strong>
|
||
- <code>geocodeConfidence</code> (filter): <code>lt:X</code>, <code>gt:X</code>, <code>eq:X</code>, <code>null</code>
|
||
- <code>geocodeProvider</code> (filter): Provider name (GOOGLE, MAPBOX, etc.)
|
||
- <code>page</code> (optional): Page number (default: 1)
|
||
- <code>limit</code> (optional): Results per page (default: 50)
|
||
- <code>sortBy</code> (optional): Field to sort by (default: "geocodeConfidence")
|
||
- <code>order</code> (optional): "asc" or "desc" (default: "asc")</p>
|
||
<p><strong>Examples:</strong></p>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>GET /api/locations?geocodeConfidence=lt:50
|
||
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a>GET /api/locations?geocodeConfidence=null
|
||
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a>GET /api/locations?geocodeProvider=NOMINATIM&geocodeConfidence=lt:70
|
||
</span><span id="__span-5-4"><a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a>GET /api/locations?geocodeConfidence=gt:80&sortBy=address
|
||
</span></code></pre></div>
|
||
<p><strong>Response:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a><span class="p">{</span>
|
||
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="w"> </span><span class="nt">"data"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1001</span><span class="p">,</span>
|
||
</span><span id="__span-6-5"><a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a><span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123 Main St"</span><span class="p">,</span>
|
||
</span><span id="__span-6-6"><a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a><span class="w"> </span><span class="nt">"latitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">43.6532</span><span class="p">,</span>
|
||
</span><span id="__span-6-7"><a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a><span class="w"> </span><span class="nt">"longitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">-79.3832</span><span class="p">,</span>
|
||
</span><span id="__span-6-8"><a id="__codelineno-6-8" name="__codelineno-6-8" href="#__codelineno-6-8"></a><span class="w"> </span><span class="nt">"postalCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"M5H 2N2"</span><span class="p">,</span>
|
||
</span><span id="__span-6-9"><a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a><span class="w"> </span><span class="nt">"geocodeConfidence"</span><span class="p">:</span><span class="w"> </span><span class="mi">45</span><span class="p">,</span>
|
||
</span><span id="__span-6-10"><a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a><span class="w"> </span><span class="nt">"geocodeProvider"</span><span class="p">:</span><span class="w"> </span><span class="s2">"NOMINATIM"</span><span class="p">,</span>
|
||
</span><span id="__span-6-11"><a id="__codelineno-6-11" name="__codelineno-6-11" href="#__codelineno-6-11"></a><span class="w"> </span><span class="nt">"geocodedAt"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-02-10T10:00:00Z"</span><span class="p">,</span>
|
||
</span><span id="__span-6-12"><a id="__codelineno-6-12" name="__codelineno-6-12" href="#__codelineno-6-12"></a><span class="w"> </span><span class="nt">"addresses"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="err">...</span><span class="p">]</span>
|
||
</span><span id="__span-6-13"><a id="__codelineno-6-13" name="__codelineno-6-13" href="#__codelineno-6-13"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-6-14"><a id="__codelineno-6-14" name="__codelineno-6-14" href="#__codelineno-6-14"></a><span class="w"> </span><span class="p">],</span>
|
||
</span><span id="__span-6-15"><a id="__codelineno-6-15" name="__codelineno-6-15" href="#__codelineno-6-15"></a><span class="w"> </span><span class="nt">"pagination"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-6-16"><a id="__codelineno-6-16" name="__codelineno-6-16" href="#__codelineno-6-16"></a><span class="w"> </span><span class="nt">"page"</span><span class="p">:</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span>
|
||
</span><span id="__span-6-17"><a id="__codelineno-6-17" name="__codelineno-6-17" href="#__codelineno-6-17"></a><span class="w"> </span><span class="nt">"limit"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span><span class="p">,</span>
|
||
</span><span id="__span-6-18"><a id="__codelineno-6-18" name="__codelineno-6-18" href="#__codelineno-6-18"></a><span class="w"> </span><span class="nt">"total"</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
|
||
</span><span id="__span-6-19"><a id="__codelineno-6-19" name="__codelineno-6-19" href="#__codelineno-6-19"></a><span class="w"> </span><span class="nt">"pages"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span>
|
||
</span><span id="__span-6-20"><a id="__codelineno-6-20" name="__codelineno-6-20" href="#__codelineno-6-20"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-6-21"><a id="__codelineno-6-21" name="__codelineno-6-21" href="#__codelineno-6-21"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<h3 id="get-apilocationsduplicates">GET /api/locations/duplicates<a class="headerlink" href="#get-apilocationsduplicates" title="Permanent link">¶</a></h3>
|
||
<p>Identify locations with identical coordinates.</p>
|
||
<p><strong>Authentication:</strong> Required (SUPER_ADMIN, MAP_ADMIN)</p>
|
||
<p><strong>Query Parameters:</strong>
|
||
- <code>threshold</code> (optional): Distance threshold in meters (default: 1, matches exact duplicates)</p>
|
||
<p><strong>Response:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a><span class="p">{</span>
|
||
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a><span class="w"> </span><span class="nt">"duplicates"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a><span class="w"> </span><span class="nt">"coordinates"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a><span class="w"> </span><span class="nt">"latitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">43.6532</span><span class="p">,</span>
|
||
</span><span id="__span-7-6"><a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a><span class="w"> </span><span class="nt">"longitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">-79.3832</span>
|
||
</span><span id="__span-7-7"><a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-7-8"><a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a><span class="w"> </span><span class="nt">"count"</span><span class="p">:</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span>
|
||
</span><span id="__span-7-9"><a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a><span class="w"> </span><span class="nt">"locations"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-7-10"><a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-7-11"><a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1001</span><span class="p">,</span>
|
||
</span><span id="__span-7-12"><a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a><span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123 Main St"</span><span class="p">,</span>
|
||
</span><span id="__span-7-13"><a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a><span class="w"> </span><span class="nt">"postalCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"M5H 2N2"</span>
|
||
</span><span id="__span-7-14"><a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-7-15"><a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-7-16"><a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1002</span><span class="p">,</span>
|
||
</span><span id="__span-7-17"><a id="__codelineno-7-17" name="__codelineno-7-17" href="#__codelineno-7-17"></a><span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123 Main Street"</span><span class="p">,</span>
|
||
</span><span id="__span-7-18"><a id="__codelineno-7-18" name="__codelineno-7-18" href="#__codelineno-7-18"></a><span class="w"> </span><span class="nt">"postalCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"M5H 2N2"</span>
|
||
</span><span id="__span-7-19"><a id="__codelineno-7-19" name="__codelineno-7-19" href="#__codelineno-7-19"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-7-20"><a id="__codelineno-7-20" name="__codelineno-7-20" href="#__codelineno-7-20"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-7-21"><a id="__codelineno-7-21" name="__codelineno-7-21" href="#__codelineno-7-21"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1003</span><span class="p">,</span>
|
||
</span><span id="__span-7-22"><a id="__codelineno-7-22" name="__codelineno-7-22" href="#__codelineno-7-22"></a><span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123 Main St, Unit 1"</span><span class="p">,</span>
|
||
</span><span id="__span-7-23"><a id="__codelineno-7-23" name="__codelineno-7-23" href="#__codelineno-7-23"></a><span class="w"> </span><span class="nt">"postalCode"</span><span class="p">:</span><span class="w"> </span><span class="s2">"M5H 2N2"</span>
|
||
</span><span id="__span-7-24"><a id="__codelineno-7-24" name="__codelineno-7-24" href="#__codelineno-7-24"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-7-25"><a id="__codelineno-7-25" name="__codelineno-7-25" href="#__codelineno-7-25"></a><span class="w"> </span><span class="p">]</span>
|
||
</span><span id="__span-7-26"><a id="__codelineno-7-26" name="__codelineno-7-26" href="#__codelineno-7-26"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-7-27"><a id="__codelineno-7-27" name="__codelineno-7-27" href="#__codelineno-7-27"></a><span class="w"> </span><span class="p">],</span>
|
||
</span><span id="__span-7-28"><a id="__codelineno-7-28" name="__codelineno-7-28" href="#__codelineno-7-28"></a><span class="w"> </span><span class="nt">"total"</span><span class="p">:</span><span class="w"> </span><span class="mi">12</span>
|
||
</span><span id="__span-7-29"><a id="__codelineno-7-29" name="__codelineno-7-29" href="#__codelineno-7-29"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<p><strong>Implementation:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a><span class="c1">// locations.service.ts</span>
|
||
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a><span class="k">async</span><span class="w"> </span><span class="nx">findDuplicates</span><span class="p">(</span><span class="nx">thresholdMeters</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-3"><a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">locations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
|
||
</span><span id="__span-8-4"><a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-5"><a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a><span class="w"> </span><span class="nx">AND</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-8-6"><a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">not</span><span class="o">:</span><span class="w"> </span><span class="kt">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-8-7"><a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">not</span><span class="o">:</span><span class="w"> </span><span class="kt">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-8-8"><a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a><span class="w"> </span><span class="p">]</span>
|
||
</span><span id="__span-8-9"><a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-8-10"><a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a><span class="w"> </span><span class="nx">select</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-11"><a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-8-12"><a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a><span class="w"> </span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-8-13"><a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-8-14"><a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-8-15"><a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a><span class="w"> </span><span class="nx">postalCode</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span>
|
||
</span><span id="__span-8-16"><a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-8-17"><a id="__codelineno-8-17" name="__codelineno-8-17" href="#__codelineno-8-17"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-8-18"><a id="__codelineno-8-18" name="__codelineno-8-18" href="#__codelineno-8-18"></a>
|
||
</span><span id="__span-8-19"><a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">coordMap</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Map</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="ow">typeof</span><span class="w"> </span><span class="nx">locations</span><span class="o">></span><span class="p">();</span>
|
||
</span><span id="__span-8-20"><a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a>
|
||
</span><span id="__span-8-21"><a id="__codelineno-8-21" name="__codelineno-8-21" href="#__codelineno-8-21"></a><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">loc</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-22"><a id="__codelineno-8-22" name="__codelineno-8-22" href="#__codelineno-8-22"></a><span class="w"> </span><span class="c1">// Round to 6 decimal places (~0.1m precision)</span>
|
||
</span><span id="__span-8-23"><a id="__codelineno-8-23" name="__codelineno-8-23" href="#__codelineno-8-23"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">loc</span><span class="p">.</span><span class="nx">latitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="si">}</span><span class="sb">,</span><span class="si">${</span><span class="nx">loc</span><span class="p">.</span><span class="nx">longitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
|
||
</span><span id="__span-8-24"><a id="__codelineno-8-24" name="__codelineno-8-24" href="#__codelineno-8-24"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">has</span><span class="p">(</span><span class="nx">key</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-25"><a id="__codelineno-8-25" name="__codelineno-8-25" href="#__codelineno-8-25"></a><span class="w"> </span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span><span class="w"> </span><span class="p">[]);</span>
|
||
</span><span id="__span-8-26"><a id="__codelineno-8-26" name="__codelineno-8-26" href="#__codelineno-8-26"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-8-27"><a id="__codelineno-8-27" name="__codelineno-8-27" href="#__codelineno-8-27"></a><span class="w"> </span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span><span class="o">!</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">loc</span><span class="p">);</span>
|
||
</span><span id="__span-8-28"><a id="__codelineno-8-28" name="__codelineno-8-28" href="#__codelineno-8-28"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-8-29"><a id="__codelineno-8-29" name="__codelineno-8-29" href="#__codelineno-8-29"></a>
|
||
</span><span id="__span-8-30"><a id="__codelineno-8-30" name="__codelineno-8-30" href="#__codelineno-8-30"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">duplicates</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Array</span><span class="p">.</span><span class="kr">from</span><span class="p">(</span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">entries</span><span class="p">())</span>
|
||
</span><span id="__span-8-31"><a id="__codelineno-8-31" name="__codelineno-8-31" href="#__codelineno-8-31"></a><span class="w"> </span><span class="p">.</span><span class="nx">filter</span><span class="p">(([</span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">locs</span><span class="p">])</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">locs</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">1</span><span class="p">)</span>
|
||
</span><span id="__span-8-32"><a id="__codelineno-8-32" name="__codelineno-8-32" href="#__codelineno-8-32"></a><span class="w"> </span><span class="p">.</span><span class="nx">map</span><span class="p">(([</span><span class="nx">coords</span><span class="p">,</span><span class="w"> </span><span class="nx">locs</span><span class="p">])</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-33"><a id="__codelineno-8-33" name="__codelineno-8-33" href="#__codelineno-8-33"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">lat</span><span class="p">,</span><span class="w"> </span><span class="nx">lng</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">coords</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">','</span><span class="p">).</span><span class="nx">map</span><span class="p">(</span><span class="nb">Number</span><span class="p">);</span>
|
||
</span><span id="__span-8-34"><a id="__codelineno-8-34" name="__codelineno-8-34" href="#__codelineno-8-34"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-35"><a id="__codelineno-8-35" name="__codelineno-8-35" href="#__codelineno-8-35"></a><span class="w"> </span><span class="nx">coordinates</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">lat</span><span class="p">,</span><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">lng</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-8-36"><a id="__codelineno-8-36" name="__codelineno-8-36" href="#__codelineno-8-36"></a><span class="w"> </span><span class="nx">count</span><span class="o">:</span><span class="w"> </span><span class="kt">locs.length</span><span class="p">,</span>
|
||
</span><span id="__span-8-37"><a id="__codelineno-8-37" name="__codelineno-8-37" href="#__codelineno-8-37"></a><span class="w"> </span><span class="nx">locations</span><span class="o">:</span><span class="w"> </span><span class="kt">locs</span>
|
||
</span><span id="__span-8-38"><a id="__codelineno-8-38" name="__codelineno-8-38" href="#__codelineno-8-38"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-8-39"><a id="__codelineno-8-39" name="__codelineno-8-39" href="#__codelineno-8-39"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-8-40"><a id="__codelineno-8-40" name="__codelineno-8-40" href="#__codelineno-8-40"></a>
|
||
</span><span id="__span-8-41"><a id="__codelineno-8-41" name="__codelineno-8-41" href="#__codelineno-8-41"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-8-42"><a id="__codelineno-8-42" name="__codelineno-8-42" href="#__codelineno-8-42"></a><span class="w"> </span><span class="nx">duplicates</span><span class="p">,</span>
|
||
</span><span id="__span-8-43"><a id="__codelineno-8-43" name="__codelineno-8-43" href="#__codelineno-8-43"></a><span class="w"> </span><span class="nx">total</span><span class="o">:</span><span class="w"> </span><span class="kt">duplicates.reduce</span><span class="p">((</span><span class="nx">sum</span><span class="p">,</span><span class="w"> </span><span class="nx">dup</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">sum</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">dup</span><span class="p">.</span><span class="nx">count</span><span class="p">,</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span>
|
||
</span><span id="__span-8-44"><a id="__codelineno-8-44" name="__codelineno-8-44" href="#__codelineno-8-44"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-8-45"><a id="__codelineno-8-45" name="__codelineno-8-45" href="#__codelineno-8-45"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<h3 id="post-apilocationsidregeocode">POST /api/locations/:id/regeocode<a class="headerlink" href="#post-apilocationsidregeocode" title="Permanent link">¶</a></h3>
|
||
<p>Re-geocode a single location with specified provider.</p>
|
||
<p><strong>Authentication:</strong> Required (SUPER_ADMIN, MAP_ADMIN)</p>
|
||
<p><strong>Request Body:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a><span class="p">{</span>
|
||
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a><span class="w"> </span><span class="nt">"provider"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GOOGLE"</span><span class="p">,</span>
|
||
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a><span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123 Main St, Toronto ON M5H 2N2"</span>
|
||
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<p><strong>Parameters:</strong>
|
||
- <code>provider</code> (optional): Specific provider to use (default: fallback chain)
|
||
- <code>address</code> (optional): Override address string (default: use existing)</p>
|
||
<p><strong>Response:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="p">{</span>
|
||
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a><span class="w"> </span><span class="nt">"id"</span><span class="p">:</span><span class="w"> </span><span class="mi">1001</span><span class="p">,</span>
|
||
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a><span class="w"> </span><span class="nt">"address"</span><span class="p">:</span><span class="w"> </span><span class="s2">"123 Main St"</span><span class="p">,</span>
|
||
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="w"> </span><span class="nt">"latitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">43.6532</span><span class="p">,</span>
|
||
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a><span class="w"> </span><span class="nt">"longitude"</span><span class="p">:</span><span class="w"> </span><span class="mf">-79.3832</span><span class="p">,</span>
|
||
</span><span id="__span-10-6"><a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a><span class="w"> </span><span class="nt">"geocodeConfidence"</span><span class="p">:</span><span class="w"> </span><span class="mi">95</span><span class="p">,</span>
|
||
</span><span id="__span-10-7"><a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="w"> </span><span class="nt">"geocodeProvider"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GOOGLE"</span><span class="p">,</span>
|
||
</span><span id="__span-10-8"><a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a><span class="w"> </span><span class="nt">"geocodedAt"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-02-13T10:30:00Z"</span>
|
||
</span><span id="__span-10-9"><a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<h3 id="post-apilocationsbulk-geocode">POST /api/locations/bulk-geocode<a class="headerlink" href="#post-apilocationsbulk-geocode" title="Permanent link">¶</a></h3>
|
||
<p>Bulk re-geocode multiple locations.</p>
|
||
<p><strong>Authentication:</strong> Required (SUPER_ADMIN, MAP_ADMIN)</p>
|
||
<p><strong>Request Body:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="p">{</span>
|
||
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a><span class="w"> </span><span class="nt">"locationIds"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="mi">1001</span><span class="p">,</span><span class="w"> </span><span class="mi">1002</span><span class="p">,</span><span class="w"> </span><span class="mi">1003</span><span class="p">],</span>
|
||
</span><span id="__span-11-3"><a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a><span class="w"> </span><span class="nt">"provider"</span><span class="p">:</span><span class="w"> </span><span class="s2">"GOOGLE"</span><span class="p">,</span>
|
||
</span><span id="__span-11-4"><a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="w"> </span><span class="nt">"confidenceThreshold"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span>
|
||
</span><span id="__span-11-5"><a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<p><strong>Parameters:</strong>
|
||
- <code>locationIds</code> (optional): Specific location IDs (default: all with confidence < threshold)
|
||
- <code>provider</code> (optional): Specific provider to use (default: fallback chain)
|
||
- <code>confidenceThreshold</code> (optional): Only re-geocode locations below this confidence (default: 50)</p>
|
||
<p><strong>Response:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="p">{</span>
|
||
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="w"> </span><span class="nt">"jobId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bulk-geocode-20250213-103000"</span><span class="p">,</span>
|
||
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"queued"</span><span class="p">,</span>
|
||
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="w"> </span><span class="nt">"total"</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
|
||
</span><span id="__span-12-5"><a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a><span class="w"> </span><span class="nt">"message"</span><span class="p">:</span><span class="w"> </span><span class="s2">"Bulk geocoding job started"</span>
|
||
</span><span id="__span-12-6"><a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<p><strong>Job Progress Endpoint:</strong>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a>GET /api/locations/bulk-geocode/:jobId
|
||
</span></code></pre></div></p>
|
||
<p><strong>Job Status Response:</strong>
|
||
<div class="language-json highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a><span class="p">{</span>
|
||
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="w"> </span><span class="nt">"jobId"</span><span class="p">:</span><span class="w"> </span><span class="s2">"bulk-geocode-20250213-103000"</span><span class="p">,</span>
|
||
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a><span class="w"> </span><span class="nt">"status"</span><span class="p">:</span><span class="w"> </span><span class="s2">"processing"</span><span class="p">,</span>
|
||
</span><span id="__span-14-4"><a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a><span class="w"> </span><span class="nt">"progress"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-14-5"><a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a><span class="w"> </span><span class="nt">"total"</span><span class="p">:</span><span class="w"> </span><span class="mi">150</span><span class="p">,</span>
|
||
</span><span id="__span-14-6"><a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a><span class="w"> </span><span class="nt">"processed"</span><span class="p">:</span><span class="w"> </span><span class="mi">75</span><span class="p">,</span>
|
||
</span><span id="__span-14-7"><a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="w"> </span><span class="nt">"successful"</span><span class="p">:</span><span class="w"> </span><span class="mi">70</span><span class="p">,</span>
|
||
</span><span id="__span-14-8"><a id="__codelineno-14-8" name="__codelineno-14-8" href="#__codelineno-14-8"></a><span class="w"> </span><span class="nt">"failed"</span><span class="p">:</span><span class="w"> </span><span class="mi">5</span><span class="p">,</span>
|
||
</span><span id="__span-14-9"><a id="__codelineno-14-9" name="__codelineno-14-9" href="#__codelineno-14-9"></a><span class="w"> </span><span class="nt">"percent"</span><span class="p">:</span><span class="w"> </span><span class="mi">50</span>
|
||
</span><span id="__span-14-10"><a id="__codelineno-14-10" name="__codelineno-14-10" href="#__codelineno-14-10"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-14-11"><a id="__codelineno-14-11" name="__codelineno-14-11" href="#__codelineno-14-11"></a><span class="w"> </span><span class="nt">"startedAt"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-02-13T10:30:00Z"</span><span class="p">,</span>
|
||
</span><span id="__span-14-12"><a id="__codelineno-14-12" name="__codelineno-14-12" href="#__codelineno-14-12"></a><span class="w"> </span><span class="nt">"estimatedCompletion"</span><span class="p">:</span><span class="w"> </span><span class="s2">"2025-02-13T10:35:00Z"</span>
|
||
</span><span id="__span-14-13"><a id="__codelineno-14-13" name="__codelineno-14-13" href="#__codelineno-14-13"></a><span class="p">}</span>
|
||
</span></code></pre></div></p>
|
||
<h2 id="configuration">Configuration<a class="headerlink" href="#configuration" title="Permanent link">¶</a></h2>
|
||
<h3 id="environment-variables">Environment Variables<a class="headerlink" href="#environment-variables" title="Permanent link">¶</a></h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Variable</th>
|
||
<th>Type</th>
|
||
<th>Default</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>GEOCODE_CONFIDENCE_THRESHOLD</td>
|
||
<td>number</td>
|
||
<td>50</td>
|
||
<td>Minimum confidence for acceptable geocoding</td>
|
||
</tr>
|
||
<tr>
|
||
<td>GEOCODE_PRIMARY_PROVIDER</td>
|
||
<td>string</td>
|
||
<td>GOOGLE</td>
|
||
<td>Primary geocoding provider</td>
|
||
</tr>
|
||
<tr>
|
||
<td>GEOCODE_FALLBACK_PROVIDERS</td>
|
||
<td>string</td>
|
||
<td>MAPBOX,NOMINATIM</td>
|
||
<td>Comma-separated fallback providers</td>
|
||
</tr>
|
||
<tr>
|
||
<td>GEOCODE_CACHE_TTL</td>
|
||
<td>number</td>
|
||
<td>2592000</td>
|
||
<td>Cache TTL in seconds (30 days)</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="quality-thresholds">Quality Thresholds<a class="headerlink" href="#quality-thresholds" title="Permanent link">¶</a></h3>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Metric</th>
|
||
<th>Warning</th>
|
||
<th>Critical</th>
|
||
<th>Description</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>Geocoded %</td>
|
||
<td>< 95%</td>
|
||
<td>< 90%</td>
|
||
<td>Percentage of locations with coordinates</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Avg Confidence</td>
|
||
<td>< 70</td>
|
||
<td>< 60</td>
|
||
<td>Average geocode confidence score</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Low Confidence Count</td>
|
||
<td>> 50</td>
|
||
<td>> 100</td>
|
||
<td>Locations with confidence < 50</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Duplicates</td>
|
||
<td>> 20</td>
|
||
<td>> 50</td>
|
||
<td>Locations with identical coordinates</td>
|
||
</tr>
|
||
<tr>
|
||
<td>Missing Coordinates</td>
|
||
<td>> 5%</td>
|
||
<td>> 10%</td>
|
||
<td>Locations without lat/lng</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<h3 id="prometheus-metrics">Prometheus Metrics<a class="headerlink" href="#prometheus-metrics" title="Permanent link">¶</a></h3>
|
||
<p><strong>Custom Metrics:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="c1">// api/src/utils/metrics.ts</span>
|
||
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>
|
||
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a><span class="k">export</span><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">geocodingQualityGauge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Gauge</span><span class="p">({</span>
|
||
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s1">'cm_geocoding_avg_confidence'</span><span class="p">,</span>
|
||
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a><span class="w"> </span><span class="nx">help</span><span class="o">:</span><span class="w"> </span><span class="s1">'Average geocoding confidence score (0-100)'</span><span class="p">,</span>
|
||
</span><span id="__span-15-6"><a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">collect</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-15-7"><a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">stats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">locationsService</span><span class="p">.</span><span class="nx">getGeocodeStats</span><span class="p">();</span>
|
||
</span><span id="__span-15-8"><a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">avgConfidence</span><span class="p">);</span>
|
||
</span><span id="__span-15-9"><a id="__codelineno-15-9" name="__codelineno-15-9" href="#__codelineno-15-9"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-15-10"><a id="__codelineno-15-10" name="__codelineno-15-10" href="#__codelineno-15-10"></a><span class="p">});</span>
|
||
</span><span id="__span-15-11"><a id="__codelineno-15-11" name="__codelineno-15-11" href="#__codelineno-15-11"></a>
|
||
</span><span id="__span-15-12"><a id="__codelineno-15-12" name="__codelineno-15-12" href="#__codelineno-15-12"></a><span class="k">export</span><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">lowConfidenceLocationsGauge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Gauge</span><span class="p">({</span>
|
||
</span><span id="__span-15-13"><a id="__codelineno-15-13" name="__codelineno-15-13" href="#__codelineno-15-13"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s1">'cm_locations_low_confidence_count'</span><span class="p">,</span>
|
||
</span><span id="__span-15-14"><a id="__codelineno-15-14" name="__codelineno-15-14" href="#__codelineno-15-14"></a><span class="w"> </span><span class="nx">help</span><span class="o">:</span><span class="w"> </span><span class="s1">'Number of locations with geocode confidence < 50'</span><span class="p">,</span>
|
||
</span><span id="__span-15-15"><a id="__codelineno-15-15" name="__codelineno-15-15" href="#__codelineno-15-15"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">collect</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-15-16"><a id="__codelineno-15-16" name="__codelineno-15-16" href="#__codelineno-15-16"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">stats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">locationsService</span><span class="p">.</span><span class="nx">getGeocodeStats</span><span class="p">();</span>
|
||
</span><span id="__span-15-17"><a id="__codelineno-15-17" name="__codelineno-15-17" href="#__codelineno-15-17"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">lowConfidenceCount</span><span class="p">);</span>
|
||
</span><span id="__span-15-18"><a id="__codelineno-15-18" name="__codelineno-15-18" href="#__codelineno-15-18"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-15-19"><a id="__codelineno-15-19" name="__codelineno-15-19" href="#__codelineno-15-19"></a><span class="p">});</span>
|
||
</span><span id="__span-15-20"><a id="__codelineno-15-20" name="__codelineno-15-20" href="#__codelineno-15-20"></a>
|
||
</span><span id="__span-15-21"><a id="__codelineno-15-21" name="__codelineno-15-21" href="#__codelineno-15-21"></a><span class="k">export</span><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">geocodedPercentGauge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Gauge</span><span class="p">({</span>
|
||
</span><span id="__span-15-22"><a id="__codelineno-15-22" name="__codelineno-15-22" href="#__codelineno-15-22"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s1">'cm_locations_geocoded_percent'</span><span class="p">,</span>
|
||
</span><span id="__span-15-23"><a id="__codelineno-15-23" name="__codelineno-15-23" href="#__codelineno-15-23"></a><span class="w"> </span><span class="nx">help</span><span class="o">:</span><span class="w"> </span><span class="s1">'Percentage of locations with coordinates'</span><span class="p">,</span>
|
||
</span><span id="__span-15-24"><a id="__codelineno-15-24" name="__codelineno-15-24" href="#__codelineno-15-24"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">collect</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-15-25"><a id="__codelineno-15-25" name="__codelineno-15-25" href="#__codelineno-15-25"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">stats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">locationsService</span><span class="p">.</span><span class="nx">getGeocodeStats</span><span class="p">();</span>
|
||
</span><span id="__span-15-26"><a id="__codelineno-15-26" name="__codelineno-15-26" href="#__codelineno-15-26"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">geocodedPercent</span><span class="p">);</span>
|
||
</span><span id="__span-15-27"><a id="__codelineno-15-27" name="__codelineno-15-27" href="#__codelineno-15-27"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-15-28"><a id="__codelineno-15-28" name="__codelineno-15-28" href="#__codelineno-15-28"></a><span class="p">});</span>
|
||
</span><span id="__span-15-29"><a id="__codelineno-15-29" name="__codelineno-15-29" href="#__codelineno-15-29"></a>
|
||
</span><span id="__span-15-30"><a id="__codelineno-15-30" name="__codelineno-15-30" href="#__codelineno-15-30"></a><span class="k">export</span><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">duplicateLocationsGauge</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nx">Gauge</span><span class="p">({</span>
|
||
</span><span id="__span-15-31"><a id="__codelineno-15-31" name="__codelineno-15-31" href="#__codelineno-15-31"></a><span class="w"> </span><span class="nx">name</span><span class="o">:</span><span class="w"> </span><span class="s1">'cm_locations_duplicates_count'</span><span class="p">,</span>
|
||
</span><span id="__span-15-32"><a id="__codelineno-15-32" name="__codelineno-15-32" href="#__codelineno-15-32"></a><span class="w"> </span><span class="nx">help</span><span class="o">:</span><span class="w"> </span><span class="s1">'Number of duplicate location entries'</span><span class="p">,</span>
|
||
</span><span id="__span-15-33"><a id="__codelineno-15-33" name="__codelineno-15-33" href="#__codelineno-15-33"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">collect</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-15-34"><a id="__codelineno-15-34" name="__codelineno-15-34" href="#__codelineno-15-34"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">duplicates</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">locationsService</span><span class="p">.</span><span class="nx">findDuplicates</span><span class="p">();</span>
|
||
</span><span id="__span-15-35"><a id="__codelineno-15-35" name="__codelineno-15-35" href="#__codelineno-15-35"></a><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">duplicates</span><span class="p">.</span><span class="nx">total</span><span class="p">);</span>
|
||
</span><span id="__span-15-36"><a id="__codelineno-15-36" name="__codelineno-15-36" href="#__codelineno-15-36"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-15-37"><a id="__codelineno-15-37" name="__codelineno-15-37" href="#__codelineno-15-37"></a><span class="p">});</span>
|
||
</span></code></pre></div>
|
||
<p><strong>Alert Rules:</strong></p>
|
||
<div class="language-yaml highlight"><pre><span></span><code><span id="__span-16-1"><a id="__codelineno-16-1" name="__codelineno-16-1" href="#__codelineno-16-1"></a><span class="c1"># configs/prometheus/alerts.yml</span>
|
||
</span><span id="__span-16-2"><a id="__codelineno-16-2" name="__codelineno-16-2" href="#__codelineno-16-2"></a>
|
||
</span><span id="__span-16-3"><a id="__codelineno-16-3" name="__codelineno-16-3" href="#__codelineno-16-3"></a><span class="nt">groups</span><span class="p">:</span>
|
||
</span><span id="__span-16-4"><a id="__codelineno-16-4" name="__codelineno-16-4" href="#__codelineno-16-4"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">name</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">data_quality</span>
|
||
</span><span id="__span-16-5"><a id="__codelineno-16-5" name="__codelineno-16-5" href="#__codelineno-16-5"></a><span class="w"> </span><span class="nt">interval</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">5m</span>
|
||
</span><span id="__span-16-6"><a id="__codelineno-16-6" name="__codelineno-16-6" href="#__codelineno-16-6"></a><span class="w"> </span><span class="nt">rules</span><span class="p">:</span>
|
||
</span><span id="__span-16-7"><a id="__codelineno-16-7" name="__codelineno-16-7" href="#__codelineno-16-7"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">LowGeocodingConfidence</span>
|
||
</span><span id="__span-16-8"><a id="__codelineno-16-8" name="__codelineno-16-8" href="#__codelineno-16-8"></a><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cm_geocoding_avg_confidence < 60</span>
|
||
</span><span id="__span-16-9"><a id="__codelineno-16-9" name="__codelineno-16-9" href="#__codelineno-16-9"></a><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">10m</span>
|
||
</span><span id="__span-16-10"><a id="__codelineno-16-10" name="__codelineno-16-10" href="#__codelineno-16-10"></a><span class="w"> </span><span class="nt">labels</span><span class="p">:</span>
|
||
</span><span id="__span-16-11"><a id="__codelineno-16-11" name="__codelineno-16-11" href="#__codelineno-16-11"></a><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">warning</span>
|
||
</span><span id="__span-16-12"><a id="__codelineno-16-12" name="__codelineno-16-12" href="#__codelineno-16-12"></a><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span>
|
||
</span><span id="__span-16-13"><a id="__codelineno-16-13" name="__codelineno-16-13" href="#__codelineno-16-13"></a><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Low average geocoding confidence</span>
|
||
</span><span id="__span-16-14"><a id="__codelineno-16-14" name="__codelineno-16-14" href="#__codelineno-16-14"></a><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s">"Average</span><span class="nv"> </span><span class="s">geocoding</span><span class="nv"> </span><span class="s">confidence</span><span class="nv"> </span><span class="s">is</span><span class="nv"> </span><span class="s">{{</span><span class="nv"> </span><span class="s">$value</span><span class="nv"> </span><span class="s">}},</span><span class="nv"> </span><span class="s">below</span><span class="nv"> </span><span class="s">threshold</span><span class="nv"> </span><span class="s">of</span><span class="nv"> </span><span class="s">60"</span>
|
||
</span><span id="__span-16-15"><a id="__codelineno-16-15" name="__codelineno-16-15" href="#__codelineno-16-15"></a>
|
||
</span><span id="__span-16-16"><a id="__codelineno-16-16" name="__codelineno-16-16" href="#__codelineno-16-16"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">HighLowConfidenceLocations</span>
|
||
</span><span id="__span-16-17"><a id="__codelineno-16-17" name="__codelineno-16-17" href="#__codelineno-16-17"></a><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cm_locations_low_confidence_count > 100</span>
|
||
</span><span id="__span-16-18"><a id="__codelineno-16-18" name="__codelineno-16-18" href="#__codelineno-16-18"></a><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">5m</span>
|
||
</span><span id="__span-16-19"><a id="__codelineno-16-19" name="__codelineno-16-19" href="#__codelineno-16-19"></a><span class="w"> </span><span class="nt">labels</span><span class="p">:</span>
|
||
</span><span id="__span-16-20"><a id="__codelineno-16-20" name="__codelineno-16-20" href="#__codelineno-16-20"></a><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">critical</span>
|
||
</span><span id="__span-16-21"><a id="__codelineno-16-21" name="__codelineno-16-21" href="#__codelineno-16-21"></a><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span>
|
||
</span><span id="__span-16-22"><a id="__codelineno-16-22" name="__codelineno-16-22" href="#__codelineno-16-22"></a><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">High number of low-confidence locations</span>
|
||
</span><span id="__span-16-23"><a id="__codelineno-16-23" name="__codelineno-16-23" href="#__codelineno-16-23"></a><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s">"{{</span><span class="nv"> </span><span class="s">$value</span><span class="nv"> </span><span class="s">}}</span><span class="nv"> </span><span class="s">locations</span><span class="nv"> </span><span class="s">have</span><span class="nv"> </span><span class="s">geocoding</span><span class="nv"> </span><span class="s">confidence</span><span class="nv"> </span><span class="s"><</span><span class="nv"> </span><span class="s">50"</span>
|
||
</span><span id="__span-16-24"><a id="__codelineno-16-24" name="__codelineno-16-24" href="#__codelineno-16-24"></a>
|
||
</span><span id="__span-16-25"><a id="__codelineno-16-25" name="__codelineno-16-25" href="#__codelineno-16-25"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">LowGeocodedPercent</span>
|
||
</span><span id="__span-16-26"><a id="__codelineno-16-26" name="__codelineno-16-26" href="#__codelineno-16-26"></a><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cm_locations_geocoded_percent < 90</span>
|
||
</span><span id="__span-16-27"><a id="__codelineno-16-27" name="__codelineno-16-27" href="#__codelineno-16-27"></a><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">10m</span>
|
||
</span><span id="__span-16-28"><a id="__codelineno-16-28" name="__codelineno-16-28" href="#__codelineno-16-28"></a><span class="w"> </span><span class="nt">labels</span><span class="p">:</span>
|
||
</span><span id="__span-16-29"><a id="__codelineno-16-29" name="__codelineno-16-29" href="#__codelineno-16-29"></a><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">warning</span>
|
||
</span><span id="__span-16-30"><a id="__codelineno-16-30" name="__codelineno-16-30" href="#__codelineno-16-30"></a><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span>
|
||
</span><span id="__span-16-31"><a id="__codelineno-16-31" name="__codelineno-16-31" href="#__codelineno-16-31"></a><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">Low percentage of geocoded locations</span>
|
||
</span><span id="__span-16-32"><a id="__codelineno-16-32" name="__codelineno-16-32" href="#__codelineno-16-32"></a><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s">"Only</span><span class="nv"> </span><span class="s">{{</span><span class="nv"> </span><span class="s">$value</span><span class="nv"> </span><span class="s">}}%</span><span class="nv"> </span><span class="s">of</span><span class="nv"> </span><span class="s">locations</span><span class="nv"> </span><span class="s">have</span><span class="nv"> </span><span class="s">coordinates"</span>
|
||
</span><span id="__span-16-33"><a id="__codelineno-16-33" name="__codelineno-16-33" href="#__codelineno-16-33"></a>
|
||
</span><span id="__span-16-34"><a id="__codelineno-16-34" name="__codelineno-16-34" href="#__codelineno-16-34"></a><span class="w"> </span><span class="p p-Indicator">-</span><span class="w"> </span><span class="nt">alert</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">HighDuplicateLocations</span>
|
||
</span><span id="__span-16-35"><a id="__codelineno-16-35" name="__codelineno-16-35" href="#__codelineno-16-35"></a><span class="w"> </span><span class="nt">expr</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">cm_locations_duplicates_count > 50</span>
|
||
</span><span id="__span-16-36"><a id="__codelineno-16-36" name="__codelineno-16-36" href="#__codelineno-16-36"></a><span class="w"> </span><span class="nt">for</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">15m</span>
|
||
</span><span id="__span-16-37"><a id="__codelineno-16-37" name="__codelineno-16-37" href="#__codelineno-16-37"></a><span class="w"> </span><span class="nt">labels</span><span class="p">:</span>
|
||
</span><span id="__span-16-38"><a id="__codelineno-16-38" name="__codelineno-16-38" href="#__codelineno-16-38"></a><span class="w"> </span><span class="nt">severity</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">warning</span>
|
||
</span><span id="__span-16-39"><a id="__codelineno-16-39" name="__codelineno-16-39" href="#__codelineno-16-39"></a><span class="w"> </span><span class="nt">annotations</span><span class="p">:</span>
|
||
</span><span id="__span-16-40"><a id="__codelineno-16-40" name="__codelineno-16-40" href="#__codelineno-16-40"></a><span class="w"> </span><span class="nt">summary</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">High number of duplicate locations</span>
|
||
</span><span id="__span-16-41"><a id="__codelineno-16-41" name="__codelineno-16-41" href="#__codelineno-16-41"></a><span class="w"> </span><span class="nt">description</span><span class="p">:</span><span class="w"> </span><span class="s">"{{</span><span class="nv"> </span><span class="s">$value</span><span class="nv"> </span><span class="s">}}</span><span class="nv"> </span><span class="s">duplicate</span><span class="nv"> </span><span class="s">location</span><span class="nv"> </span><span class="s">entries</span><span class="nv"> </span><span class="s">detected"</span>
|
||
</span></code></pre></div>
|
||
<h2 id="quality-metrics">Quality Metrics<a class="headerlink" href="#quality-metrics" title="Permanent link">¶</a></h2>
|
||
<h3 id="geocoding-confidence">Geocoding Confidence<a class="headerlink" href="#geocoding-confidence" title="Permanent link">¶</a></h3>
|
||
<p><strong>Calculation:</strong></p>
|
||
<p>Geocoding confidence is calculated based on multiple factors:</p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-17-1"><a id="__codelineno-17-1" name="__codelineno-17-1" href="#__codelineno-17-1"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">GeocodeResult</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-17-2"><a id="__codelineno-17-2" name="__codelineno-17-2" href="#__codelineno-17-2"></a><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-17-3"><a id="__codelineno-17-3" name="__codelineno-17-3" href="#__codelineno-17-3"></a><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-17-4"><a id="__codelineno-17-4" name="__codelineno-17-4" href="#__codelineno-17-4"></a><span class="w"> </span><span class="nx">matchType</span><span class="o">:</span><span class="w"> </span><span class="s1">'exact'</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="s1">'interpolated'</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="s1">'approximate'</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="s1">'fallback'</span><span class="p">;</span>
|
||
</span><span id="__span-17-5"><a id="__codelineno-17-5" name="__codelineno-17-5" href="#__codelineno-17-5"></a><span class="w"> </span><span class="nx">addressComponents</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-17-6"><a id="__codelineno-17-6" name="__codelineno-17-6" href="#__codelineno-17-6"></a><span class="w"> </span><span class="nx">streetNumber?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
|
||
</span><span id="__span-17-7"><a id="__codelineno-17-7" name="__codelineno-17-7" href="#__codelineno-17-7"></a><span class="w"> </span><span class="nx">street?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
|
||
</span><span id="__span-17-8"><a id="__codelineno-17-8" name="__codelineno-17-8" href="#__codelineno-17-8"></a><span class="w"> </span><span class="nx">city?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
|
||
</span><span id="__span-17-9"><a id="__codelineno-17-9" name="__codelineno-17-9" href="#__codelineno-17-9"></a><span class="w"> </span><span class="nx">postalCode?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
|
||
</span><span id="__span-17-10"><a id="__codelineno-17-10" name="__codelineno-17-10" href="#__codelineno-17-10"></a><span class="w"> </span><span class="nx">province?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
|
||
</span><span id="__span-17-11"><a id="__codelineno-17-11" name="__codelineno-17-11" href="#__codelineno-17-11"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-17-12"><a id="__codelineno-17-12" name="__codelineno-17-12" href="#__codelineno-17-12"></a><span class="w"> </span><span class="nx">providerConfidence?</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span><span class="w"> </span><span class="c1">// Provider-specific score</span>
|
||
</span><span id="__span-17-13"><a id="__codelineno-17-13" name="__codelineno-17-13" href="#__codelineno-17-13"></a><span class="p">}</span>
|
||
</span><span id="__span-17-14"><a id="__codelineno-17-14" name="__codelineno-17-14" href="#__codelineno-17-14"></a>
|
||
</span><span id="__span-17-15"><a id="__codelineno-17-15" name="__codelineno-17-15" href="#__codelineno-17-15"></a><span class="kd">function</span><span class="w"> </span><span class="nx">calculateConfidence</span><span class="p">(</span><span class="nx">result</span><span class="o">:</span><span class="w"> </span><span class="kt">GeocodeResult</span><span class="p">,</span><span class="w"> </span><span class="nx">inputAddress</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-17-16"><a id="__codelineno-17-16" name="__codelineno-17-16" href="#__codelineno-17-16"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
|
||
</span><span id="__span-17-17"><a id="__codelineno-17-17" name="__codelineno-17-17" href="#__codelineno-17-17"></a>
|
||
</span><span id="__span-17-18"><a id="__codelineno-17-18" name="__codelineno-17-18" href="#__codelineno-17-18"></a><span class="w"> </span><span class="c1">// Match type (0-40 points)</span>
|
||
</span><span id="__span-17-19"><a id="__codelineno-17-19" name="__codelineno-17-19" href="#__codelineno-17-19"></a><span class="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">matchType</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-17-20"><a id="__codelineno-17-20" name="__codelineno-17-20" href="#__codelineno-17-20"></a><span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="s1">'exact'</span><span class="o">:</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">40</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
|
||
</span><span id="__span-17-21"><a id="__codelineno-17-21" name="__codelineno-17-21" href="#__codelineno-17-21"></a><span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="s1">'interpolated'</span><span class="o">:</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">30</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
|
||
</span><span id="__span-17-22"><a id="__codelineno-17-22" name="__codelineno-17-22" href="#__codelineno-17-22"></a><span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="s1">'approximate'</span><span class="o">:</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">20</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
|
||
</span><span id="__span-17-23"><a id="__codelineno-17-23" name="__codelineno-17-23" href="#__codelineno-17-23"></a><span class="w"> </span><span class="k">case</span><span class="w"> </span><span class="s1">'fallback'</span><span class="o">:</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">10</span><span class="p">;</span><span class="w"> </span><span class="k">break</span><span class="p">;</span>
|
||
</span><span id="__span-17-24"><a id="__codelineno-17-24" name="__codelineno-17-24" href="#__codelineno-17-24"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-17-25"><a id="__codelineno-17-25" name="__codelineno-17-25" href="#__codelineno-17-25"></a>
|
||
</span><span id="__span-17-26"><a id="__codelineno-17-26" name="__codelineno-17-26" href="#__codelineno-17-26"></a><span class="w"> </span><span class="c1">// Address component completeness (0-30 points)</span>
|
||
</span><span id="__span-17-27"><a id="__codelineno-17-27" name="__codelineno-17-27" href="#__codelineno-17-27"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">components</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">addressComponents</span><span class="p">;</span>
|
||
</span><span id="__span-17-28"><a id="__codelineno-17-28" name="__codelineno-17-28" href="#__codelineno-17-28"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">components</span><span class="p">.</span><span class="nx">streetNumber</span><span class="p">)</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">10</span><span class="p">;</span>
|
||
</span><span id="__span-17-29"><a id="__codelineno-17-29" name="__codelineno-17-29" href="#__codelineno-17-29"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">components</span><span class="p">.</span><span class="nx">street</span><span class="p">)</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">10</span><span class="p">;</span>
|
||
</span><span id="__span-17-30"><a id="__codelineno-17-30" name="__codelineno-17-30" href="#__codelineno-17-30"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">components</span><span class="p">.</span><span class="nx">postalCode</span><span class="p">)</span><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mf">10</span><span class="p">;</span>
|
||
</span><span id="__span-17-31"><a id="__codelineno-17-31" name="__codelineno-17-31" href="#__codelineno-17-31"></a>
|
||
</span><span id="__span-17-32"><a id="__codelineno-17-32" name="__codelineno-17-32" href="#__codelineno-17-32"></a><span class="w"> </span><span class="c1">// Provider-specific confidence (0-30 points)</span>
|
||
</span><span id="__span-17-33"><a id="__codelineno-17-33" name="__codelineno-17-33" href="#__codelineno-17-33"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">providerConfidence</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-17-34"><a id="__codelineno-17-34" name="__codelineno-17-34" href="#__codelineno-17-34"></a><span class="w"> </span><span class="nx">confidence</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="p">(</span><span class="nx">result</span><span class="p">.</span><span class="nx">providerConfidence</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="mf">100</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">30</span><span class="p">;</span>
|
||
</span><span id="__span-17-35"><a id="__codelineno-17-35" name="__codelineno-17-35" href="#__codelineno-17-35"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-17-36"><a id="__codelineno-17-36" name="__codelineno-17-36" href="#__codelineno-17-36"></a>
|
||
</span><span id="__span-17-37"><a id="__codelineno-17-37" name="__codelineno-17-37" href="#__codelineno-17-37"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">min</span><span class="p">(</span><span class="nb">Math</span><span class="p">.</span><span class="nx">round</span><span class="p">(</span><span class="nx">confidence</span><span class="p">),</span><span class="w"> </span><span class="mf">100</span><span class="p">);</span>
|
||
</span><span id="__span-17-38"><a id="__codelineno-17-38" name="__codelineno-17-38" href="#__codelineno-17-38"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<p><strong>Confidence Levels:</strong></p>
|
||
<ul>
|
||
<li><strong>81-100 (Excellent):</strong> Exact match with full address components</li>
|
||
<li><strong>61-80 (Good):</strong> Interpolated match with most components</li>
|
||
<li><strong>41-60 (Medium):</strong> Approximate match, missing some components</li>
|
||
<li><strong>21-40 (Low):</strong> Fallback geocoding, significant uncertainty</li>
|
||
<li><strong>0-20 (Very Low):</strong> Minimal match, likely incorrect</li>
|
||
</ul>
|
||
<h3 id="provider-success-rates">Provider Success Rates<a class="headerlink" href="#provider-success-rates" title="Permanent link">¶</a></h3>
|
||
<p><strong>Metrics Tracked:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-18-1"><a id="__codelineno-18-1" name="__codelineno-18-1" href="#__codelineno-18-1"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">ProviderMetrics</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-18-2"><a id="__codelineno-18-2" name="__codelineno-18-2" href="#__codelineno-18-2"></a><span class="w"> </span><span class="nx">provider</span><span class="o">:</span><span class="w"> </span><span class="kt">GeocodeProvider</span><span class="p">;</span>
|
||
</span><span id="__span-18-3"><a id="__codelineno-18-3" name="__codelineno-18-3" href="#__codelineno-18-3"></a><span class="w"> </span><span class="nx">totalAttempts</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-18-4"><a id="__codelineno-18-4" name="__codelineno-18-4" href="#__codelineno-18-4"></a><span class="w"> </span><span class="nx">successfulGeocodes</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-18-5"><a id="__codelineno-18-5" name="__codelineno-18-5" href="#__codelineno-18-5"></a><span class="w"> </span><span class="nx">successRate</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0-100%</span>
|
||
</span><span id="__span-18-6"><a id="__codelineno-18-6" name="__codelineno-18-6" href="#__codelineno-18-6"></a><span class="w"> </span><span class="nx">avgConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span><span class="w"> </span><span class="c1">// 0-100</span>
|
||
</span><span id="__span-18-7"><a id="__codelineno-18-7" name="__codelineno-18-7" href="#__codelineno-18-7"></a><span class="w"> </span><span class="nx">avgResponseTime</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span><span class="w"> </span><span class="c1">// milliseconds</span>
|
||
</span><span id="__span-18-8"><a id="__codelineno-18-8" name="__codelineno-18-8" href="#__codelineno-18-8"></a><span class="w"> </span><span class="nx">errorCount</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-18-9"><a id="__codelineno-18-9" name="__codelineno-18-9" href="#__codelineno-18-9"></a><span class="w"> </span><span class="nx">lastError?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">;</span>
|
||
</span><span id="__span-18-10"><a id="__codelineno-18-10" name="__codelineno-18-10" href="#__codelineno-18-10"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<p><strong>Success Rate Calculation:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-19-1"><a id="__codelineno-19-1" name="__codelineno-19-1" href="#__codelineno-19-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">calculateProviderMetrics</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">()</span><span class="o">:</span><span class="w"> </span><span class="nb">Promise</span><span class="o"><</span><span class="nx">ProviderMetrics</span><span class="p">[]</span><span class="o">></span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-19-2"><a id="__codelineno-19-2" name="__codelineno-19-2" href="#__codelineno-19-2"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">locations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
|
||
</span><span id="__span-19-3"><a id="__codelineno-19-3" name="__codelineno-19-3" href="#__codelineno-19-3"></a><span class="w"> </span><span class="nx">select</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-19-4"><a id="__codelineno-19-4" name="__codelineno-19-4" href="#__codelineno-19-4"></a><span class="w"> </span><span class="nx">geocodeProvider</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-19-5"><a id="__codelineno-19-5" name="__codelineno-19-5" href="#__codelineno-19-5"></a><span class="w"> </span><span class="nx">geocodeConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-19-6"><a id="__codelineno-19-6" name="__codelineno-19-6" href="#__codelineno-19-6"></a><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-19-7"><a id="__codelineno-19-7" name="__codelineno-19-7" href="#__codelineno-19-7"></a><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span>
|
||
</span><span id="__span-19-8"><a id="__codelineno-19-8" name="__codelineno-19-8" href="#__codelineno-19-8"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-19-9"><a id="__codelineno-19-9" name="__codelineno-19-9" href="#__codelineno-19-9"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-19-10"><a id="__codelineno-19-10" name="__codelineno-19-10" href="#__codelineno-19-10"></a>
|
||
</span><span id="__span-19-11"><a id="__codelineno-19-11" name="__codelineno-19-11" href="#__codelineno-19-11"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">providerGroups</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">groupBy</span><span class="p">(</span><span class="nx">locations</span><span class="p">,</span><span class="w"> </span><span class="s1">'geocodeProvider'</span><span class="p">);</span>
|
||
</span><span id="__span-19-12"><a id="__codelineno-19-12" name="__codelineno-19-12" href="#__codelineno-19-12"></a>
|
||
</span><span id="__span-19-13"><a id="__codelineno-19-13" name="__codelineno-19-13" href="#__codelineno-19-13"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Object</span><span class="p">.</span><span class="nx">entries</span><span class="p">(</span><span class="nx">providerGroups</span><span class="p">).</span><span class="nx">map</span><span class="p">(([</span><span class="nx">provider</span><span class="p">,</span><span class="w"> </span><span class="nx">locs</span><span class="p">])</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-19-14"><a id="__codelineno-19-14" name="__codelineno-19-14" href="#__codelineno-19-14"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locs</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-19-15"><a id="__codelineno-19-15" name="__codelineno-19-15" href="#__codelineno-19-15"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">successful</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locs</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">latitude</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">longitude</span><span class="p">).</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-19-16"><a id="__codelineno-19-16" name="__codelineno-19-16" href="#__codelineno-19-16"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">avgConf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locs</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">sum</span><span class="p">,</span><span class="w"> </span><span class="nx">l</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">sum</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">),</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">total</span><span class="p">;</span>
|
||
</span><span id="__span-19-17"><a id="__codelineno-19-17" name="__codelineno-19-17" href="#__codelineno-19-17"></a>
|
||
</span><span id="__span-19-18"><a id="__codelineno-19-18" name="__codelineno-19-18" href="#__codelineno-19-18"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-19-19"><a id="__codelineno-19-19" name="__codelineno-19-19" href="#__codelineno-19-19"></a><span class="w"> </span><span class="nx">provider</span><span class="o">:</span><span class="w"> </span><span class="kt">provider</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="nx">GeocodeProvider</span><span class="p">,</span>
|
||
</span><span id="__span-19-20"><a id="__codelineno-19-20" name="__codelineno-19-20" href="#__codelineno-19-20"></a><span class="w"> </span><span class="nx">totalAttempts</span><span class="o">:</span><span class="w"> </span><span class="kt">total</span><span class="p">,</span>
|
||
</span><span id="__span-19-21"><a id="__codelineno-19-21" name="__codelineno-19-21" href="#__codelineno-19-21"></a><span class="w"> </span><span class="nx">successfulGeocodes</span><span class="o">:</span><span class="w"> </span><span class="kt">successful</span><span class="p">,</span>
|
||
</span><span id="__span-19-22"><a id="__codelineno-19-22" name="__codelineno-19-22" href="#__codelineno-19-22"></a><span class="w"> </span><span class="nx">successRate</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">successful</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">total</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mf">100</span><span class="p">,</span>
|
||
</span><span id="__span-19-23"><a id="__codelineno-19-23" name="__codelineno-19-23" href="#__codelineno-19-23"></a><span class="w"> </span><span class="nx">avgConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">avgConf</span><span class="p">,</span>
|
||
</span><span id="__span-19-24"><a id="__codelineno-19-24" name="__codelineno-19-24" href="#__codelineno-19-24"></a><span class="w"> </span><span class="nx">avgResponseTime</span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span><span class="w"> </span><span class="c1">// Would need separate tracking</span>
|
||
</span><span id="__span-19-25"><a id="__codelineno-19-25" name="__codelineno-19-25" href="#__codelineno-19-25"></a><span class="w"> </span><span class="nx">errorCount</span><span class="o">:</span><span class="w"> </span><span class="kt">total</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">successful</span>
|
||
</span><span id="__span-19-26"><a id="__codelineno-19-26" name="__codelineno-19-26" href="#__codelineno-19-26"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-19-27"><a id="__codelineno-19-27" name="__codelineno-19-27" href="#__codelineno-19-27"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-19-28"><a id="__codelineno-19-28" name="__codelineno-19-28" href="#__codelineno-19-28"></a><span class="p">};</span>
|
||
</span></code></pre></div>
|
||
<h3 id="duplicate-detection">Duplicate Detection<a class="headerlink" href="#duplicate-detection" title="Permanent link">¶</a></h3>
|
||
<p><strong>Detection Methods:</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Exact Coordinate Match:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-20-1"><a id="__codelineno-20-1" name="__codelineno-20-1" href="#__codelineno-20-1"></a><span class="c1">// Round to 6 decimal places (~0.1m precision)</span>
|
||
</span><span id="__span-20-2"><a id="__codelineno-20-2" name="__codelineno-20-2" href="#__codelineno-20-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">isDuplicateExact</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">loc1</span><span class="o">:</span><span class="w"> </span><span class="kt">Location</span><span class="p">,</span><span class="w"> </span><span class="nx">loc2</span><span class="o">:</span><span class="w"> </span><span class="kt">Location</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">boolean</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-20-3"><a id="__codelineno-20-3" name="__codelineno-20-3" href="#__codelineno-20-3"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">loc1</span><span class="p">.</span><span class="nx">latitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">loc2</span><span class="p">.</span><span class="nx">latitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="w"> </span><span class="o">&&</span>
|
||
</span><span id="__span-20-4"><a id="__codelineno-20-4" name="__codelineno-20-4" href="#__codelineno-20-4"></a><span class="w"> </span><span class="nx">loc1</span><span class="p">.</span><span class="nx">longitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">loc2</span><span class="p">.</span><span class="nx">longitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">);</span>
|
||
</span><span id="__span-20-5"><a id="__codelineno-20-5" name="__codelineno-20-5" href="#__codelineno-20-5"></a><span class="p">};</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Proximity Threshold:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-21-1"><a id="__codelineno-21-1" name="__codelineno-21-1" href="#__codelineno-21-1"></a><span class="c1">// Haversine distance check</span>
|
||
</span><span id="__span-21-2"><a id="__codelineno-21-2" name="__codelineno-21-2" href="#__codelineno-21-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">isDuplicateProximity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">loc1</span><span class="o">:</span><span class="w"> </span><span class="kt">Location</span><span class="p">,</span><span class="w"> </span><span class="nx">loc2</span><span class="o">:</span><span class="w"> </span><span class="kt">Location</span><span class="p">,</span><span class="w"> </span><span class="nx">thresholdM</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">boolean</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-21-3"><a id="__codelineno-21-3" name="__codelineno-21-3" href="#__codelineno-21-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">distance</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">haversineDistance</span><span class="p">(</span>
|
||
</span><span id="__span-21-4"><a id="__codelineno-21-4" name="__codelineno-21-4" href="#__codelineno-21-4"></a><span class="w"> </span><span class="p">[</span><span class="nx">loc1</span><span class="p">.</span><span class="nx">latitude</span><span class="o">!</span><span class="p">,</span><span class="w"> </span><span class="nx">loc1</span><span class="p">.</span><span class="nx">longitude</span><span class="o">!</span><span class="p">],</span>
|
||
</span><span id="__span-21-5"><a id="__codelineno-21-5" name="__codelineno-21-5" href="#__codelineno-21-5"></a><span class="w"> </span><span class="p">[</span><span class="nx">loc2</span><span class="p">.</span><span class="nx">latitude</span><span class="o">!</span><span class="p">,</span><span class="w"> </span><span class="nx">loc2</span><span class="p">.</span><span class="nx">longitude</span><span class="o">!</span><span class="p">]</span>
|
||
</span><span id="__span-21-6"><a id="__codelineno-21-6" name="__codelineno-21-6" href="#__codelineno-21-6"></a><span class="w"> </span><span class="p">);</span>
|
||
</span><span id="__span-21-7"><a id="__codelineno-21-7" name="__codelineno-21-7" href="#__codelineno-21-7"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">distance</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="nx">thresholdM</span><span class="p">;</span>
|
||
</span><span id="__span-21-8"><a id="__codelineno-21-8" name="__codelineno-21-8" href="#__codelineno-21-8"></a><span class="p">};</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Address Similarity:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-22-1"><a id="__codelineno-22-1" name="__codelineno-22-1" href="#__codelineno-22-1"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">distance</span><span class="w"> </span><span class="kr">as</span><span class="w"> </span><span class="nx">levenshteinDistance</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'fastest-levenshtein'</span><span class="p">;</span>
|
||
</span><span id="__span-22-2"><a id="__codelineno-22-2" name="__codelineno-22-2" href="#__codelineno-22-2"></a>
|
||
</span><span id="__span-22-3"><a id="__codelineno-22-3" name="__codelineno-22-3" href="#__codelineno-22-3"></a><span class="kd">const</span><span class="w"> </span><span class="nx">isDuplicateAddress</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">addr1</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="nx">addr2</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">boolean</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-22-4"><a id="__codelineno-22-4" name="__codelineno-22-4" href="#__codelineno-22-4"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">normalized1</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">normalizeAddress</span><span class="p">(</span><span class="nx">addr1</span><span class="p">);</span>
|
||
</span><span id="__span-22-5"><a id="__codelineno-22-5" name="__codelineno-22-5" href="#__codelineno-22-5"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">normalized2</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">normalizeAddress</span><span class="p">(</span><span class="nx">addr2</span><span class="p">);</span>
|
||
</span><span id="__span-22-6"><a id="__codelineno-22-6" name="__codelineno-22-6" href="#__codelineno-22-6"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">dist</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">levenshteinDistance</span><span class="p">(</span><span class="nx">normalized1</span><span class="p">,</span><span class="w"> </span><span class="nx">normalized2</span><span class="p">);</span>
|
||
</span><span id="__span-22-7"><a id="__codelineno-22-7" name="__codelineno-22-7" href="#__codelineno-22-7"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">similarity</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mf">1</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="p">(</span><span class="nx">dist</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nb">Math</span><span class="p">.</span><span class="nx">max</span><span class="p">(</span><span class="nx">normalized1</span><span class="p">.</span><span class="nx">length</span><span class="p">,</span><span class="w"> </span><span class="nx">normalized2</span><span class="p">.</span><span class="nx">length</span><span class="p">));</span>
|
||
</span><span id="__span-22-8"><a id="__codelineno-22-8" name="__codelineno-22-8" href="#__codelineno-22-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">similarity</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">0.9</span><span class="p">;</span><span class="w"> </span><span class="c1">// 90% similar</span>
|
||
</span><span id="__span-22-9"><a id="__codelineno-22-9" name="__codelineno-22-9" href="#__codelineno-22-9"></a><span class="p">};</span>
|
||
</span><span id="__span-22-10"><a id="__codelineno-22-10" name="__codelineno-22-10" href="#__codelineno-22-10"></a>
|
||
</span><span id="__span-22-11"><a id="__codelineno-22-11" name="__codelineno-22-11" href="#__codelineno-22-11"></a><span class="kd">const</span><span class="w"> </span><span class="nx">normalizeAddress</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-22-12"><a id="__codelineno-22-12" name="__codelineno-22-12" href="#__codelineno-22-12"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">address</span>
|
||
</span><span id="__span-22-13"><a id="__codelineno-22-13" name="__codelineno-22-13" href="#__codelineno-22-13"></a><span class="w"> </span><span class="p">.</span><span class="nx">toLowerCase</span><span class="p">()</span>
|
||
</span><span id="__span-22-14"><a id="__codelineno-22-14" name="__codelineno-22-14" href="#__codelineno-22-14"></a><span class="w"> </span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\bstreet\b/g</span><span class="p">,</span><span class="w"> </span><span class="s1">'st'</span><span class="p">)</span>
|
||
</span><span id="__span-22-15"><a id="__codelineno-22-15" name="__codelineno-22-15" href="#__codelineno-22-15"></a><span class="w"> </span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\bavenue\b/g</span><span class="p">,</span><span class="w"> </span><span class="s1">'ave'</span><span class="p">)</span>
|
||
</span><span id="__span-22-16"><a id="__codelineno-22-16" name="__codelineno-22-16" href="#__codelineno-22-16"></a><span class="w"> </span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\broad\b/g</span><span class="p">,</span><span class="w"> </span><span class="s1">'rd'</span><span class="p">)</span>
|
||
</span><span id="__span-22-17"><a id="__codelineno-22-17" name="__codelineno-22-17" href="#__codelineno-22-17"></a><span class="w"> </span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\bdrive\b/g</span><span class="p">,</span><span class="w"> </span><span class="s1">'dr'</span><span class="p">)</span>
|
||
</span><span id="__span-22-18"><a id="__codelineno-22-18" name="__codelineno-22-18" href="#__codelineno-22-18"></a><span class="w"> </span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/[^a-z0-9]/g</span><span class="p">,</span><span class="w"> </span><span class="s1">''</span><span class="p">);</span>
|
||
</span><span id="__span-22-19"><a id="__codelineno-22-19" name="__codelineno-22-19" href="#__codelineno-22-19"></a><span class="p">};</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
</ol>
|
||
<h3 id="address-validation">Address Validation<a class="headerlink" href="#address-validation" title="Permanent link">¶</a></h3>
|
||
<p><strong>Validation Checks:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-23-1"><a id="__codelineno-23-1" name="__codelineno-23-1" href="#__codelineno-23-1"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">AddressValidationResult</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-2"><a id="__codelineno-23-2" name="__codelineno-23-2" href="#__codelineno-23-2"></a><span class="w"> </span><span class="nx">isValid</span><span class="o">:</span><span class="w"> </span><span class="kt">boolean</span><span class="p">;</span>
|
||
</span><span id="__span-23-3"><a id="__codelineno-23-3" name="__codelineno-23-3" href="#__codelineno-23-3"></a><span class="w"> </span><span class="nx">issues</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">[];</span>
|
||
</span><span id="__span-23-4"><a id="__codelineno-23-4" name="__codelineno-23-4" href="#__codelineno-23-4"></a><span class="w"> </span><span class="nx">suggestions?</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">[];</span>
|
||
</span><span id="__span-23-5"><a id="__codelineno-23-5" name="__codelineno-23-5" href="#__codelineno-23-5"></a><span class="p">}</span>
|
||
</span><span id="__span-23-6"><a id="__codelineno-23-6" name="__codelineno-23-6" href="#__codelineno-23-6"></a>
|
||
</span><span id="__span-23-7"><a id="__codelineno-23-7" name="__codelineno-23-7" href="#__codelineno-23-7"></a><span class="kd">const</span><span class="w"> </span><span class="nx">validateAddress</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nx">AddressValidationResult</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-8"><a id="__codelineno-23-8" name="__codelineno-23-8" href="#__codelineno-23-8"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">issues</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[];</span>
|
||
</span><span id="__span-23-9"><a id="__codelineno-23-9" name="__codelineno-23-9" href="#__codelineno-23-9"></a>
|
||
</span><span id="__span-23-10"><a id="__codelineno-23-10" name="__codelineno-23-10" href="#__codelineno-23-10"></a><span class="w"> </span><span class="c1">// Check minimum length</span>
|
||
</span><span id="__span-23-11"><a id="__codelineno-23-11" name="__codelineno-23-11" href="#__codelineno-23-11"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">address</span><span class="p">.</span><span class="nx">length</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mf">5</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-12"><a id="__codelineno-23-12" name="__codelineno-23-12" href="#__codelineno-23-12"></a><span class="w"> </span><span class="nx">issues</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">'Address too short'</span><span class="p">);</span>
|
||
</span><span id="__span-23-13"><a id="__codelineno-23-13" name="__codelineno-23-13" href="#__codelineno-23-13"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-23-14"><a id="__codelineno-23-14" name="__codelineno-23-14" href="#__codelineno-23-14"></a>
|
||
</span><span id="__span-23-15"><a id="__codelineno-23-15" name="__codelineno-23-15" href="#__codelineno-23-15"></a><span class="w"> </span><span class="c1">// Check for street number</span>
|
||
</span><span id="__span-23-16"><a id="__codelineno-23-16" name="__codelineno-23-16" href="#__codelineno-23-16"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="sr">/^\d+/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">address</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-17"><a id="__codelineno-23-17" name="__codelineno-23-17" href="#__codelineno-23-17"></a><span class="w"> </span><span class="nx">issues</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">'Missing street number'</span><span class="p">);</span>
|
||
</span><span id="__span-23-18"><a id="__codelineno-23-18" name="__codelineno-23-18" href="#__codelineno-23-18"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-23-19"><a id="__codelineno-23-19" name="__codelineno-23-19" href="#__codelineno-23-19"></a>
|
||
</span><span id="__span-23-20"><a id="__codelineno-23-20" name="__codelineno-23-20" href="#__codelineno-23-20"></a><span class="w"> </span><span class="c1">// Check for street name</span>
|
||
</span><span id="__span-23-21"><a id="__codelineno-23-21" name="__codelineno-23-21" href="#__codelineno-23-21"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="sr">/\d+\s+([A-Za-z]+\s*)+/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">address</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-22"><a id="__codelineno-23-22" name="__codelineno-23-22" href="#__codelineno-23-22"></a><span class="w"> </span><span class="nx">issues</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">'Missing street name'</span><span class="p">);</span>
|
||
</span><span id="__span-23-23"><a id="__codelineno-23-23" name="__codelineno-23-23" href="#__codelineno-23-23"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-23-24"><a id="__codelineno-23-24" name="__codelineno-23-24" href="#__codelineno-23-24"></a>
|
||
</span><span id="__span-23-25"><a id="__codelineno-23-25" name="__codelineno-23-25" href="#__codelineno-23-25"></a><span class="w"> </span><span class="c1">// Check for postal code (Canadian format)</span>
|
||
</span><span id="__span-23-26"><a id="__codelineno-23-26" name="__codelineno-23-26" href="#__codelineno-23-26"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="sr">/[A-Z]\d[A-Z]\s?\d[A-Z]\d/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">address</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-27"><a id="__codelineno-23-27" name="__codelineno-23-27" href="#__codelineno-23-27"></a><span class="w"> </span><span class="nx">issues</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">'Missing or invalid postal code'</span><span class="p">);</span>
|
||
</span><span id="__span-23-28"><a id="__codelineno-23-28" name="__codelineno-23-28" href="#__codelineno-23-28"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-23-29"><a id="__codelineno-23-29" name="__codelineno-23-29" href="#__codelineno-23-29"></a>
|
||
</span><span id="__span-23-30"><a id="__codelineno-23-30" name="__codelineno-23-30" href="#__codelineno-23-30"></a><span class="w"> </span><span class="c1">// Check for unusual characters</span>
|
||
</span><span id="__span-23-31"><a id="__codelineno-23-31" name="__codelineno-23-31" href="#__codelineno-23-31"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="sr">/[^A-Za-z0-9\s,.-]/</span><span class="p">.</span><span class="nx">test</span><span class="p">(</span><span class="nx">address</span><span class="p">))</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-32"><a id="__codelineno-23-32" name="__codelineno-23-32" href="#__codelineno-23-32"></a><span class="w"> </span><span class="nx">issues</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="s1">'Contains unusual characters'</span><span class="p">);</span>
|
||
</span><span id="__span-23-33"><a id="__codelineno-23-33" name="__codelineno-23-33" href="#__codelineno-23-33"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-23-34"><a id="__codelineno-23-34" name="__codelineno-23-34" href="#__codelineno-23-34"></a>
|
||
</span><span id="__span-23-35"><a id="__codelineno-23-35" name="__codelineno-23-35" href="#__codelineno-23-35"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-23-36"><a id="__codelineno-23-36" name="__codelineno-23-36" href="#__codelineno-23-36"></a><span class="w"> </span><span class="nx">isValid</span><span class="o">:</span><span class="w"> </span><span class="kt">issues.length</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-23-37"><a id="__codelineno-23-37" name="__codelineno-23-37" href="#__codelineno-23-37"></a><span class="w"> </span><span class="nx">issues</span>
|
||
</span><span id="__span-23-38"><a id="__codelineno-23-38" name="__codelineno-23-38" href="#__codelineno-23-38"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-23-39"><a id="__codelineno-23-39" name="__codelineno-23-39" href="#__codelineno-23-39"></a><span class="p">};</span>
|
||
</span></code></pre></div>
|
||
<h2 id="admin-workflow">Admin Workflow<a class="headerlink" href="#admin-workflow" title="Permanent link">¶</a></h2>
|
||
<h3 id="navigate-to-data-quality-dashboard">Navigate to Data Quality Dashboard<a class="headerlink" href="#navigate-to-data-quality-dashboard" title="Permanent link">¶</a></h3>
|
||
<p><strong>Step 1: Access Dashboard</strong></p>
|
||
<ol>
|
||
<li>Log in as SUPER_ADMIN or MAP_ADMIN</li>
|
||
<li>Click <strong>Map</strong> in sidebar</li>
|
||
<li>Click <strong>Data Quality</strong> submenu</li>
|
||
<li>Dashboard loads with statistics</li>
|
||
</ol>
|
||
<p><strong>Step 2: Review Overall Statistics</strong></p>
|
||
<p>Dashboard displays 4 main statistic cards:</p>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-24-1"><a id="__codelineno-24-1" name="__codelineno-24-1" href="#__codelineno-24-1"></a>┌──────────────────┬──────────────────┬──────────────────┬──────────────────┐
|
||
</span><span id="__span-24-2"><a id="__codelineno-24-2" name="__codelineno-24-2" href="#__codelineno-24-2"></a>│ Total Locations │ Geocoded │ Avg Confidence │ Low Confidence │
|
||
</span><span id="__span-24-3"><a id="__codelineno-24-3" name="__codelineno-24-3" href="#__codelineno-24-3"></a>│ 1,500 │ 1,450 (96.7%) │ 78.5 │ 50 │
|
||
</span><span id="__span-24-4"><a id="__codelineno-24-4" name="__codelineno-24-4" href="#__codelineno-24-4"></a>└──────────────────┴──────────────────┴──────────────────┴──────────────────┘
|
||
</span></code></pre></div>
|
||
<p><strong>Step 3: Analyze Provider Performance</strong></p>
|
||
<p>Provider breakdown table shows:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Provider</th>
|
||
<th>Count</th>
|
||
<th>Success Rate</th>
|
||
<th>Avg Confidence</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>GOOGLE</td>
|
||
<td>800</td>
|
||
<td>99.2%</td>
|
||
<td>85.3</td>
|
||
</tr>
|
||
<tr>
|
||
<td>MAPBOX</td>
|
||
<td>350</td>
|
||
<td>97.1%</td>
|
||
<td>82.1</td>
|
||
</tr>
|
||
<tr>
|
||
<td>NOMINATIM</td>
|
||
<td>200</td>
|
||
<td>94.5%</td>
|
||
<td>75.8</td>
|
||
</tr>
|
||
<tr>
|
||
<td>PHOTON</td>
|
||
<td>100</td>
|
||
<td>91.0%</td>
|
||
<td>68.2</td>
|
||
</tr>
|
||
<tr>
|
||
<td>UNKNOWN</td>
|
||
<td>50</td>
|
||
<td>N/A</td>
|
||
<td>0</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><strong>Step 4: Review Confidence Distribution</strong></p>
|
||
<p>Bar chart displays confidence distribution:</p>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-25-1"><a id="__codelineno-25-1" name="__codelineno-25-1" href="#__codelineno-25-1"></a>Confidence Distribution
|
||
</span><span id="__span-25-2"><a id="__codelineno-25-2" name="__codelineno-25-2" href="#__codelineno-25-2"></a>100 | ┌──────┐
|
||
</span><span id="__span-25-3"><a id="__codelineno-25-3" name="__codelineno-25-3" href="#__codelineno-25-3"></a> 80 | │ │
|
||
</span><span id="__span-25-4"><a id="__codelineno-25-4" name="__codelineno-25-4" href="#__codelineno-25-4"></a> 60 | ┌──────┤ │
|
||
</span><span id="__span-25-5"><a id="__codelineno-25-5" name="__codelineno-25-5" href="#__codelineno-25-5"></a> 40 | ┌──────┤ │ │
|
||
</span><span id="__span-25-6"><a id="__codelineno-25-6" name="__codelineno-25-6" href="#__codelineno-25-6"></a> 20 | │ │ │ │
|
||
</span><span id="__span-25-7"><a id="__codelineno-25-7" name="__codelineno-25-7" href="#__codelineno-25-7"></a> 0 └──┴──────┴──────┴──────┴──────┘
|
||
</span><span id="__span-25-8"><a id="__codelineno-25-8" name="__codelineno-25-8" href="#__codelineno-25-8"></a> 0-20 21-40 41-60 61-80 81-100
|
||
</span><span id="__span-25-9"><a id="__codelineno-25-9" name="__codelineno-25-9" href="#__codelineno-25-9"></a> 15 35 150 450 800
|
||
</span></code></pre></div>
|
||
<h3 id="identify-and-review-low-confidence-locations">Identify and Review Low-Confidence Locations<a class="headerlink" href="#identify-and-review-low-confidence-locations" title="Permanent link">¶</a></h3>
|
||
<p><strong>Step 1: Filter Low-Confidence Locations</strong></p>
|
||
<ol>
|
||
<li>Click <strong>Low Confidence</strong> tab on dashboard</li>
|
||
<li>Table loads with locations where confidence < 50</li>
|
||
<li>Sort by confidence (ascending) to prioritize worst</li>
|
||
</ol>
|
||
<p><strong>Step 2: Review Location Details</strong></p>
|
||
<p>Click row to open detail drawer:</p>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-26-1"><a id="__codelineno-26-1" name="__codelineno-26-1" href="#__codelineno-26-1"></a>┌─────────────────────────────────────────┐
|
||
</span><span id="__span-26-2"><a id="__codelineno-26-2" name="__codelineno-26-2" href="#__codelineno-26-2"></a>│ Location Details │
|
||
</span><span id="__span-26-3"><a id="__codelineno-26-3" name="__codelineno-26-3" href="#__codelineno-26-3"></a>├─────────────────────────────────────────┤
|
||
</span><span id="__span-26-4"><a id="__codelineno-26-4" name="__codelineno-26-4" href="#__codelineno-26-4"></a>│ Address: 123 Main St │
|
||
</span><span id="__span-26-5"><a id="__codelineno-26-5" name="__codelineno-26-5" href="#__codelineno-26-5"></a>│ Postal Code: M5H 2N2 │
|
||
</span><span id="__span-26-6"><a id="__codelineno-26-6" name="__codelineno-26-6" href="#__codelineno-26-6"></a>│ Coordinates: 43.6532, -79.3832 │
|
||
</span><span id="__span-26-7"><a id="__codelineno-26-7" name="__codelineno-26-7" href="#__codelineno-26-7"></a>│ │
|
||
</span><span id="__span-26-8"><a id="__codelineno-26-8" name="__codelineno-26-8" href="#__codelineno-26-8"></a>│ Geocoding Info: │
|
||
</span><span id="__span-26-9"><a id="__codelineno-26-9" name="__codelineno-26-9" href="#__codelineno-26-9"></a>│ Confidence: 45 (Low) │
|
||
</span><span id="__span-26-10"><a id="__codelineno-26-10" name="__codelineno-26-10" href="#__codelineno-26-10"></a>│ Provider: NOMINATIM │
|
||
</span><span id="__span-26-11"><a id="__codelineno-26-11" name="__codelineno-26-11" href="#__codelineno-26-11"></a>│ Geocoded: Feb 10, 2025 10:00 AM │
|
||
</span><span id="__span-26-12"><a id="__codelineno-26-12" name="__codelineno-26-12" href="#__codelineno-26-12"></a>│ │
|
||
</span><span id="__span-26-13"><a id="__codelineno-26-13" name="__codelineno-26-13" href="#__codelineno-26-13"></a>│ Issues: │
|
||
</span><span id="__span-26-14"><a id="__codelineno-26-14" name="__codelineno-26-14" href="#__codelineno-26-14"></a>│ • Missing street number in response │
|
||
</span><span id="__span-26-15"><a id="__codelineno-26-15" name="__codelineno-26-15" href="#__codelineno-26-15"></a>│ • Approximate match only │
|
||
</span><span id="__span-26-16"><a id="__codelineno-26-16" name="__codelineno-26-16" href="#__codelineno-26-16"></a>│ │
|
||
</span><span id="__span-26-17"><a id="__codelineno-26-17" name="__codelineno-26-17" href="#__codelineno-26-17"></a>│ [Re-geocode] [Edit Address] [View Map] │
|
||
</span><span id="__span-26-18"><a id="__codelineno-26-18" name="__codelineno-26-18" href="#__codelineno-26-18"></a>└─────────────────────────────────────────┘
|
||
</span></code></pre></div>
|
||
<p><strong>Step 3: Take Action</strong></p>
|
||
<p>Options for remediation:</p>
|
||
<ol>
|
||
<li><strong>Re-geocode with different provider:</strong></li>
|
||
<li>Click <strong>Re-geocode</strong> button</li>
|
||
<li>Select provider (GOOGLE recommended for low confidence)</li>
|
||
<li>Click <strong>Geocode Now</strong></li>
|
||
<li>
|
||
<p>New confidence displayed</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Edit address:</strong></p>
|
||
</li>
|
||
<li>Click <strong>Edit Address</strong></li>
|
||
<li>Correct typos or formatting issues</li>
|
||
<li>Save changes</li>
|
||
<li>
|
||
<p>Auto-triggers re-geocoding</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>View on map:</strong></p>
|
||
</li>
|
||
<li>Click <strong>View Map</strong></li>
|
||
<li>Verify location accuracy visually</li>
|
||
<li>Drag marker to correct position if needed</li>
|
||
</ol>
|
||
<h3 id="bulk-re-geocoding">Bulk Re-geocoding<a class="headerlink" href="#bulk-re-geocoding" title="Permanent link">¶</a></h3>
|
||
<p><strong>Step 1: Select Locations</strong></p>
|
||
<ol>
|
||
<li>In Low Confidence tab, use table checkboxes to select locations</li>
|
||
<li>Or click <strong>Select All</strong> to select all visible</li>
|
||
<li>Selected count displays: "50 selected"</li>
|
||
</ol>
|
||
<p><strong>Step 2: Choose Provider</strong></p>
|
||
<ol>
|
||
<li>Click <strong>Bulk Re-geocode</strong> button</li>
|
||
<li>Modal opens with provider selection:
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-27-1"><a id="__codelineno-27-1" name="__codelineno-27-1" href="#__codelineno-27-1"></a>┌─────────────────────────────────────┐
|
||
</span><span id="__span-27-2"><a id="__codelineno-27-2" name="__codelineno-27-2" href="#__codelineno-27-2"></a>│ Bulk Re-geocode │
|
||
</span><span id="__span-27-3"><a id="__codelineno-27-3" name="__codelineno-27-3" href="#__codelineno-27-3"></a>├─────────────────────────────────────┤
|
||
</span><span id="__span-27-4"><a id="__codelineno-27-4" name="__codelineno-27-4" href="#__codelineno-27-4"></a>│ Re-geocode 50 locations │
|
||
</span><span id="__span-27-5"><a id="__codelineno-27-5" name="__codelineno-27-5" href="#__codelineno-27-5"></a>│ │
|
||
</span><span id="__span-27-6"><a id="__codelineno-27-6" name="__codelineno-27-6" href="#__codelineno-27-6"></a>│ Provider: [GOOGLE ▼] │
|
||
</span><span id="__span-27-7"><a id="__codelineno-27-7" name="__codelineno-27-7" href="#__codelineno-27-7"></a>│ │
|
||
</span><span id="__span-27-8"><a id="__codelineno-27-8" name="__codelineno-27-8" href="#__codelineno-27-8"></a>│ Options: │
|
||
</span><span id="__span-27-9"><a id="__codelineno-27-9" name="__codelineno-27-9" href="#__codelineno-27-9"></a>│ ☑ Only if confidence < 50 │
|
||
</span><span id="__span-27-10"><a id="__codelineno-27-10" name="__codelineno-27-10" href="#__codelineno-27-10"></a>│ ☑ Cache results │
|
||
</span><span id="__span-27-11"><a id="__codelineno-27-11" name="__codelineno-27-11" href="#__codelineno-27-11"></a>│ ☐ Overwrite existing coordinates │
|
||
</span><span id="__span-27-12"><a id="__codelineno-27-12" name="__codelineno-27-12" href="#__codelineno-27-12"></a>│ │
|
||
</span><span id="__span-27-13"><a id="__codelineno-27-13" name="__codelineno-27-13" href="#__codelineno-27-13"></a>│ Estimated time: ~2 minutes │
|
||
</span><span id="__span-27-14"><a id="__codelineno-27-14" name="__codelineno-27-14" href="#__codelineno-27-14"></a>│ │
|
||
</span><span id="__span-27-15"><a id="__codelineno-27-15" name="__codelineno-27-15" href="#__codelineno-27-15"></a>│ [Cancel] [Start Re-geocoding] │
|
||
</span><span id="__span-27-16"><a id="__codelineno-27-16" name="__codelineno-27-16" href="#__codelineno-27-16"></a>└─────────────────────────────────────┘
|
||
</span></code></pre></div></li>
|
||
</ol>
|
||
<p><strong>Step 3: Monitor Progress</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p>Job starts, progress bar appears:
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-28-1"><a id="__codelineno-28-1" name="__codelineno-28-1" href="#__codelineno-28-1"></a>Re-geocoding in progress... 25/50 (50%)
|
||
</span><span id="__span-28-2"><a id="__codelineno-28-2" name="__codelineno-28-2" href="#__codelineno-28-2"></a>[████████████░░░░░░░░░░░░] 50%
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p>Real-time updates:</p>
|
||
</li>
|
||
<li>Total processed</li>
|
||
<li>Successful geocodes</li>
|
||
<li>Failed geocodes</li>
|
||
<li>Average new confidence</li>
|
||
</ol>
|
||
<p><strong>Step 4: Review Results</strong></p>
|
||
<p>Job completion summary:</p>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-29-1"><a id="__codelineno-29-1" name="__codelineno-29-1" href="#__codelineno-29-1"></a>┌─────────────────────────────────────┐
|
||
</span><span id="__span-29-2"><a id="__codelineno-29-2" name="__codelineno-29-2" href="#__codelineno-29-2"></a>│ Bulk Re-geocode Complete │
|
||
</span><span id="__span-29-3"><a id="__codelineno-29-3" name="__codelineno-29-3" href="#__codelineno-29-3"></a>├─────────────────────────────────────┤
|
||
</span><span id="__span-29-4"><a id="__codelineno-29-4" name="__codelineno-29-4" href="#__codelineno-29-4"></a>│ Processed: 50 │
|
||
</span><span id="__span-29-5"><a id="__codelineno-29-5" name="__codelineno-29-5" href="#__codelineno-29-5"></a>│ Successful: 47 (94%) │
|
||
</span><span id="__span-29-6"><a id="__codelineno-29-6" name="__codelineno-29-6" href="#__codelineno-29-6"></a>│ Failed: 3 (6%) │
|
||
</span><span id="__span-29-7"><a id="__codelineno-29-7" name="__codelineno-29-7" href="#__codelineno-29-7"></a>│ │
|
||
</span><span id="__span-29-8"><a id="__codelineno-29-8" name="__codelineno-29-8" href="#__codelineno-29-8"></a>│ Quality Improvement: │
|
||
</span><span id="__span-29-9"><a id="__codelineno-29-9" name="__codelineno-29-9" href="#__codelineno-29-9"></a>│ Avg Confidence Before: 42.5 │
|
||
</span><span id="__span-29-10"><a id="__codelineno-29-10" name="__codelineno-29-10" href="#__codelineno-29-10"></a>│ Avg Confidence After: 81.3 │
|
||
</span><span id="__span-29-11"><a id="__codelineno-29-11" name="__codelineno-29-11" href="#__codelineno-29-11"></a>│ Improvement: +38.8 │
|
||
</span><span id="__span-29-12"><a id="__codelineno-29-12" name="__codelineno-29-12" href="#__codelineno-29-12"></a>│ │
|
||
</span><span id="__span-29-13"><a id="__codelineno-29-13" name="__codelineno-29-13" href="#__codelineno-29-13"></a>│ [View Failed] [Close] │
|
||
</span><span id="__span-29-14"><a id="__codelineno-29-14" name="__codelineno-29-14" href="#__codelineno-29-14"></a>└─────────────────────────────────────┘
|
||
</span></code></pre></div>
|
||
<h3 id="handle-duplicates">Handle Duplicates<a class="headerlink" href="#handle-duplicates" title="Permanent link">¶</a></h3>
|
||
<p><strong>Step 1: View Duplicates Tab</strong></p>
|
||
<ol>
|
||
<li>Click <strong>Duplicates</strong> tab on dashboard</li>
|
||
<li>Table groups locations by coordinates</li>
|
||
</ol>
|
||
<p><strong>Step 2: Review Duplicate Groups</strong></p>
|
||
<p>Table displays:</p>
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>Coordinates</th>
|
||
<th>Count</th>
|
||
<th>Addresses</th>
|
||
<th>Action</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
<tr>
|
||
<td>43.6532, -79.3832</td>
|
||
<td>3</td>
|
||
<td>123 Main St, 123 Main Street, 123 Main St Unit 1</td>
|
||
<td>[Review]</td>
|
||
</tr>
|
||
<tr>
|
||
<td>43.6540, -79.3825</td>
|
||
<td>2</td>
|
||
<td>456 Bay St, 456 Bay Street</td>
|
||
<td>[Review]</td>
|
||
</tr>
|
||
</tbody>
|
||
</table>
|
||
<p><strong>Step 3: Resolve Duplicates</strong></p>
|
||
<p>Click <strong>Review</strong> to open resolution modal:</p>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-30-1"><a id="__codelineno-30-1" name="__codelineno-30-1" href="#__codelineno-30-1"></a>┌─────────────────────────────────────┐
|
||
</span><span id="__span-30-2"><a id="__codelineno-30-2" name="__codelineno-30-2" href="#__codelineno-30-2"></a>│ Resolve Duplicates │
|
||
</span><span id="__span-30-3"><a id="__codelineno-30-3" name="__codelineno-30-3" href="#__codelineno-30-3"></a>├─────────────────────────────────────┤
|
||
</span><span id="__span-30-4"><a id="__codelineno-30-4" name="__codelineno-30-4" href="#__codelineno-30-4"></a>│ 3 locations at 43.6532, -79.3832 │
|
||
</span><span id="__span-30-5"><a id="__codelineno-30-5" name="__codelineno-30-5" href="#__codelineno-30-5"></a>│ │
|
||
</span><span id="__span-30-6"><a id="__codelineno-30-6" name="__codelineno-30-6" href="#__codelineno-30-6"></a>│ ○ Merge into single location │
|
||
</span><span id="__span-30-7"><a id="__codelineno-30-7" name="__codelineno-30-7" href="#__codelineno-30-7"></a>│ Primary: 123 Main St │
|
||
</span><span id="__span-30-8"><a id="__codelineno-30-8" name="__codelineno-30-8" href="#__codelineno-30-8"></a>│ Merge units from duplicates │
|
||
</span><span id="__span-30-9"><a id="__codelineno-30-9" name="__codelineno-30-9" href="#__codelineno-30-9"></a>│ │
|
||
</span><span id="__span-30-10"><a id="__codelineno-30-10" name="__codelineno-30-10" href="#__codelineno-30-10"></a>│ ○ Keep as separate multi-unit │
|
||
</span><span id="__span-30-11"><a id="__codelineno-30-11" name="__codelineno-30-11" href="#__codelineno-30-11"></a>│ Mark as validated multi-unit │
|
||
</span><span id="__span-30-12"><a id="__codelineno-30-12" name="__codelineno-30-12" href="#__codelineno-30-12"></a>│ │
|
||
</span><span id="__span-30-13"><a id="__codelineno-30-13" name="__codelineno-30-13" href="#__codelineno-30-13"></a>│ ○ Re-geocode individually │
|
||
</span><span id="__span-30-14"><a id="__codelineno-30-14" name="__codelineno-30-14" href="#__codelineno-30-14"></a>│ Try to get unique coordinates │
|
||
</span><span id="__span-30-15"><a id="__codelineno-30-15" name="__codelineno-30-15" href="#__codelineno-30-15"></a>│ │
|
||
</span><span id="__span-30-16"><a id="__codelineno-30-16" name="__codelineno-30-16" href="#__codelineno-30-16"></a>│ [Cancel] [Resolve] │
|
||
</span><span id="__span-30-17"><a id="__codelineno-30-17" name="__codelineno-30-17" href="#__codelineno-30-17"></a>└─────────────────────────────────────┘
|
||
</span></code></pre></div>
|
||
<p><strong>Resolution Options:</strong></p>
|
||
<ol>
|
||
<li><strong>Merge:</strong> Combine into single Location with multiple Address records</li>
|
||
<li><strong>Multi-unit:</strong> Mark as legitimate multi-unit building</li>
|
||
<li><strong>Re-geocode:</strong> Attempt to get unique coordinates for each</li>
|
||
</ol>
|
||
<h2 id="quality-improvement-strategies">Quality Improvement Strategies<a class="headerlink" href="#quality-improvement-strategies" title="Permanent link">¶</a></h2>
|
||
<h3 id="multi-provider-geocoding">Multi-Provider Geocoding<a class="headerlink" href="#multi-provider-geocoding" title="Permanent link">¶</a></h3>
|
||
<p><strong>Fallback Chain:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-31-1"><a id="__codelineno-31-1" name="__codelineno-31-1" href="#__codelineno-31-1"></a><span class="c1">// geocoding.service.ts</span>
|
||
</span><span id="__span-31-2"><a id="__codelineno-31-2" name="__codelineno-31-2" href="#__codelineno-31-2"></a>
|
||
</span><span id="__span-31-3"><a id="__codelineno-31-3" name="__codelineno-31-3" href="#__codelineno-31-3"></a><span class="kd">const</span><span class="w"> </span><span class="nx">PROVIDER_CHAIN</span><span class="o">:</span><span class="w"> </span><span class="kt">GeocodeProvider</span><span class="p">[]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-31-4"><a id="__codelineno-31-4" name="__codelineno-31-4" href="#__codelineno-31-4"></a><span class="w"> </span><span class="s1">'GOOGLE'</span><span class="p">,</span><span class="w"> </span><span class="c1">// Primary: Best accuracy, paid</span>
|
||
</span><span id="__span-31-5"><a id="__codelineno-31-5" name="__codelineno-31-5" href="#__codelineno-31-5"></a><span class="w"> </span><span class="s1">'MAPBOX'</span><span class="p">,</span><span class="w"> </span><span class="c1">// Fallback 1: Good accuracy, paid</span>
|
||
</span><span id="__span-31-6"><a id="__codelineno-31-6" name="__codelineno-31-6" href="#__codelineno-31-6"></a><span class="w"> </span><span class="s1">'NOMINATIM'</span><span class="p">,</span><span class="w"> </span><span class="c1">// Fallback 2: Free, decent accuracy</span>
|
||
</span><span id="__span-31-7"><a id="__codelineno-31-7" name="__codelineno-31-7" href="#__codelineno-31-7"></a><span class="w"> </span><span class="s1">'PHOTON'</span><span class="p">,</span><span class="w"> </span><span class="c1">// Fallback 3: Free, lower accuracy</span>
|
||
</span><span id="__span-31-8"><a id="__codelineno-31-8" name="__codelineno-31-8" href="#__codelineno-31-8"></a><span class="w"> </span><span class="s1">'ARCGIS'</span><span class="w"> </span><span class="c1">// Fallback 4: Free, basic accuracy</span>
|
||
</span><span id="__span-31-9"><a id="__codelineno-31-9" name="__codelineno-31-9" href="#__codelineno-31-9"></a><span class="p">];</span>
|
||
</span><span id="__span-31-10"><a id="__codelineno-31-10" name="__codelineno-31-10" href="#__codelineno-31-10"></a>
|
||
</span><span id="__span-31-11"><a id="__codelineno-31-11" name="__codelineno-31-11" href="#__codelineno-31-11"></a><span class="k">async</span><span class="w"> </span><span class="nx">geocode</span><span class="p">(</span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nb">Promise</span><span class="o"><</span><span class="nx">GeocodeResult</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-31-12"><a id="__codelineno-31-12" name="__codelineno-31-12" href="#__codelineno-31-12"></a><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="kd">const</span><span class="w"> </span><span class="nx">provider</span><span class="w"> </span><span class="k">of</span><span class="w"> </span><span class="nx">PROVIDER_CHAIN</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-31-13"><a id="__codelineno-31-13" name="__codelineno-31-13" href="#__codelineno-31-13"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-31-14"><a id="__codelineno-31-14" name="__codelineno-31-14" href="#__codelineno-31-14"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">geocodeWithProvider</span><span class="p">(</span><span class="nx">address</span><span class="p">,</span><span class="w"> </span><span class="nx">provider</span><span class="p">);</span>
|
||
</span><span id="__span-31-15"><a id="__codelineno-31-15" name="__codelineno-31-15" href="#__codelineno-31-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">result</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">result</span><span class="p">.</span><span class="nx">confidence</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="mf">50</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-31-16"><a id="__codelineno-31-16" name="__codelineno-31-16" href="#__codelineno-31-16"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">result</span><span class="p">;</span><span class="w"> </span><span class="c1">// Success, confidence acceptable</span>
|
||
</span><span id="__span-31-17"><a id="__codelineno-31-17" name="__codelineno-31-17" href="#__codelineno-31-17"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-31-18"><a id="__codelineno-31-18" name="__codelineno-31-18" href="#__codelineno-31-18"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-31-19"><a id="__codelineno-31-19" name="__codelineno-31-19" href="#__codelineno-31-19"></a><span class="w"> </span><span class="nx">logger</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="sb">`Geocoding failed with </span><span class="si">${</span><span class="nx">provider</span><span class="si">}</span><span class="sb">:`</span><span class="p">,</span><span class="w"> </span><span class="nx">error</span><span class="p">);</span>
|
||
</span><span id="__span-31-20"><a id="__codelineno-31-20" name="__codelineno-31-20" href="#__codelineno-31-20"></a><span class="w"> </span><span class="c1">// Try next provider</span>
|
||
</span><span id="__span-31-21"><a id="__codelineno-31-21" name="__codelineno-31-21" href="#__codelineno-31-21"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-31-22"><a id="__codelineno-31-22" name="__codelineno-31-22" href="#__codelineno-31-22"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-31-23"><a id="__codelineno-31-23" name="__codelineno-31-23" href="#__codelineno-31-23"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w"> </span><span class="c1">// All providers failed</span>
|
||
</span><span id="__span-31-24"><a id="__codelineno-31-24" name="__codelineno-31-24" href="#__codelineno-31-24"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<p><strong>Benefits:</strong>
|
||
- Increases success rate (90% → 96%+)
|
||
- Reduces dependency on single provider
|
||
- Cost optimization (use free providers as fallback)
|
||
- Provider outage resilience</p>
|
||
<h3 id="address-normalization">Address Normalization<a class="headerlink" href="#address-normalization" title="Permanent link">¶</a></h3>
|
||
<p><strong>Pre-Geocoding Normalization:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-32-1"><a id="__codelineno-32-1" name="__codelineno-32-1" href="#__codelineno-32-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">normalizeAddressForGeocoding</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-32-2"><a id="__codelineno-32-2" name="__codelineno-32-2" href="#__codelineno-32-2"></a><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nx">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">address</span><span class="p">;</span>
|
||
</span><span id="__span-32-3"><a id="__codelineno-32-3" name="__codelineno-32-3" href="#__codelineno-32-3"></a>
|
||
</span><span id="__span-32-4"><a id="__codelineno-32-4" name="__codelineno-32-4" href="#__codelineno-32-4"></a><span class="w"> </span><span class="c1">// Remove extra whitespace</span>
|
||
</span><span id="__span-32-5"><a id="__codelineno-32-5" name="__codelineno-32-5" href="#__codelineno-32-5"></a><span class="w"> </span><span class="nx">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">normalized</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\s+/g</span><span class="p">,</span><span class="w"> </span><span class="s1">' '</span><span class="p">).</span><span class="nx">trim</span><span class="p">();</span>
|
||
</span><span id="__span-32-6"><a id="__codelineno-32-6" name="__codelineno-32-6" href="#__codelineno-32-6"></a>
|
||
</span><span id="__span-32-7"><a id="__codelineno-32-7" name="__codelineno-32-7" href="#__codelineno-32-7"></a><span class="w"> </span><span class="c1">// Standardize abbreviations</span>
|
||
</span><span id="__span-32-8"><a id="__codelineno-32-8" name="__codelineno-32-8" href="#__codelineno-32-8"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">replacements</span><span class="o">:</span><span class="w"> </span><span class="kt">Record</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">string</span><span class="o">></span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-32-9"><a id="__codelineno-32-9" name="__codelineno-32-9" href="#__codelineno-32-9"></a><span class="w"> </span><span class="s1">'Street'</span><span class="o">:</span><span class="w"> </span><span class="s1">'St'</span><span class="p">,</span>
|
||
</span><span id="__span-32-10"><a id="__codelineno-32-10" name="__codelineno-32-10" href="#__codelineno-32-10"></a><span class="w"> </span><span class="s1">'Avenue'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Ave'</span><span class="p">,</span>
|
||
</span><span id="__span-32-11"><a id="__codelineno-32-11" name="__codelineno-32-11" href="#__codelineno-32-11"></a><span class="w"> </span><span class="s1">'Road'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Rd'</span><span class="p">,</span>
|
||
</span><span id="__span-32-12"><a id="__codelineno-32-12" name="__codelineno-32-12" href="#__codelineno-32-12"></a><span class="w"> </span><span class="s1">'Drive'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Dr'</span><span class="p">,</span>
|
||
</span><span id="__span-32-13"><a id="__codelineno-32-13" name="__codelineno-32-13" href="#__codelineno-32-13"></a><span class="w"> </span><span class="s1">'Boulevard'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Blvd'</span><span class="p">,</span>
|
||
</span><span id="__span-32-14"><a id="__codelineno-32-14" name="__codelineno-32-14" href="#__codelineno-32-14"></a><span class="w"> </span><span class="s1">'Apartment'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Apt'</span><span class="p">,</span>
|
||
</span><span id="__span-32-15"><a id="__codelineno-32-15" name="__codelineno-32-15" href="#__codelineno-32-15"></a><span class="w"> </span><span class="s1">'Unit'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Unit'</span><span class="p">,</span>
|
||
</span><span id="__span-32-16"><a id="__codelineno-32-16" name="__codelineno-32-16" href="#__codelineno-32-16"></a><span class="w"> </span><span class="s1">'Suite'</span><span class="o">:</span><span class="w"> </span><span class="s1">'Ste'</span>
|
||
</span><span id="__span-32-17"><a id="__codelineno-32-17" name="__codelineno-32-17" href="#__codelineno-32-17"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-32-18"><a id="__codelineno-32-18" name="__codelineno-32-18" href="#__codelineno-32-18"></a>
|
||
</span><span id="__span-32-19"><a id="__codelineno-32-19" name="__codelineno-32-19" href="#__codelineno-32-19"></a><span class="w"> </span><span class="nb">Object</span><span class="p">.</span><span class="nx">entries</span><span class="p">(</span><span class="nx">replacements</span><span class="p">).</span><span class="nx">forEach</span><span class="p">(([</span><span class="kr">long</span><span class="p">,</span><span class="w"> </span><span class="kr">short</span><span class="p">])</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-32-20"><a id="__codelineno-32-20" name="__codelineno-32-20" href="#__codelineno-32-20"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">regex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">RegExp</span><span class="p">(</span><span class="sb">`\\b</span><span class="si">${</span><span class="kr">long</span><span class="si">}</span><span class="sb">\\b`</span><span class="p">,</span><span class="w"> </span><span class="s1">'gi'</span><span class="p">);</span>
|
||
</span><span id="__span-32-21"><a id="__codelineno-32-21" name="__codelineno-32-21" href="#__codelineno-32-21"></a><span class="w"> </span><span class="nx">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">normalized</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="nx">regex</span><span class="p">,</span><span class="w"> </span><span class="kr">short</span><span class="p">);</span>
|
||
</span><span id="__span-32-22"><a id="__codelineno-32-22" name="__codelineno-32-22" href="#__codelineno-32-22"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-32-23"><a id="__codelineno-32-23" name="__codelineno-32-23" href="#__codelineno-32-23"></a>
|
||
</span><span id="__span-32-24"><a id="__codelineno-32-24" name="__codelineno-32-24" href="#__codelineno-32-24"></a><span class="w"> </span><span class="c1">// Ensure postal code spacing (Canadian format)</span>
|
||
</span><span id="__span-32-25"><a id="__codelineno-32-25" name="__codelineno-32-25" href="#__codelineno-32-25"></a><span class="w"> </span><span class="nx">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">normalized</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/([A-Z]\d[A-Z])(\d[A-Z]\d)/</span><span class="p">,</span><span class="w"> </span><span class="s1">'$1 $2'</span><span class="p">);</span>
|
||
</span><span id="__span-32-26"><a id="__codelineno-32-26" name="__codelineno-32-26" href="#__codelineno-32-26"></a>
|
||
</span><span id="__span-32-27"><a id="__codelineno-32-27" name="__codelineno-32-27" href="#__codelineno-32-27"></a><span class="w"> </span><span class="c1">// Remove periods from abbreviations</span>
|
||
</span><span id="__span-32-28"><a id="__codelineno-32-28" name="__codelineno-32-28" href="#__codelineno-32-28"></a><span class="w"> </span><span class="nx">normalized</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">normalized</span><span class="p">.</span><span class="nx">replace</span><span class="p">(</span><span class="sr">/\./g</span><span class="p">,</span><span class="w"> </span><span class="s1">''</span><span class="p">);</span>
|
||
</span><span id="__span-32-29"><a id="__codelineno-32-29" name="__codelineno-32-29" href="#__codelineno-32-29"></a>
|
||
</span><span id="__span-32-30"><a id="__codelineno-32-30" name="__codelineno-32-30" href="#__codelineno-32-30"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">normalized</span><span class="p">;</span>
|
||
</span><span id="__span-32-31"><a id="__codelineno-32-31" name="__codelineno-32-31" href="#__codelineno-32-31"></a><span class="p">};</span>
|
||
</span></code></pre></div>
|
||
<p><strong>Improvements:</strong>
|
||
- Reduces geocoding errors by 10-15%
|
||
- Increases confidence scores
|
||
- Better cache hit rate</p>
|
||
<h3 id="geocoding-cache">Geocoding Cache<a class="headerlink" href="#geocoding-cache" title="Permanent link">¶</a></h3>
|
||
<p><strong>Redis Cache Implementation:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-33-1"><a id="__codelineno-33-1" name="__codelineno-33-1" href="#__codelineno-33-1"></a><span class="c1">// geocoding.service.ts</span>
|
||
</span><span id="__span-33-2"><a id="__codelineno-33-2" name="__codelineno-33-2" href="#__codelineno-33-2"></a>
|
||
</span><span id="__span-33-3"><a id="__codelineno-33-3" name="__codelineno-33-3" href="#__codelineno-33-3"></a><span class="k">private</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">geocodeWithCache</span><span class="p">(</span><span class="nx">address</span><span class="o">:</span><span class="w"> </span><span class="kt">string</span><span class="p">)</span><span class="o">:</span><span class="w"> </span><span class="nb">Promise</span><span class="o"><</span><span class="nx">GeocodeResult</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-33-4"><a id="__codelineno-33-4" name="__codelineno-33-4" href="#__codelineno-33-4"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">cacheKey</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sb">`geocode:</span><span class="si">${</span><span class="nx">normalizeAddress</span><span class="p">(</span><span class="nx">address</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
|
||
</span><span id="__span-33-5"><a id="__codelineno-33-5" name="__codelineno-33-5" href="#__codelineno-33-5"></a>
|
||
</span><span id="__span-33-6"><a id="__codelineno-33-6" name="__codelineno-33-6" href="#__codelineno-33-6"></a><span class="w"> </span><span class="c1">// Check cache</span>
|
||
</span><span id="__span-33-7"><a id="__codelineno-33-7" name="__codelineno-33-7" href="#__codelineno-33-7"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">cached</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">);</span>
|
||
</span><span id="__span-33-8"><a id="__codelineno-33-8" name="__codelineno-33-8" href="#__codelineno-33-8"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">cached</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-33-9"><a id="__codelineno-33-9" name="__codelineno-33-9" href="#__codelineno-33-9"></a><span class="w"> </span><span class="nx">logger</span><span class="p">.</span><span class="nx">debug</span><span class="p">(</span><span class="s1">'Geocoding cache hit:'</span><span class="p">,</span><span class="w"> </span><span class="nx">address</span><span class="p">);</span>
|
||
</span><span id="__span-33-10"><a id="__codelineno-33-10" name="__codelineno-33-10" href="#__codelineno-33-10"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">cached</span><span class="p">);</span>
|
||
</span><span id="__span-33-11"><a id="__codelineno-33-11" name="__codelineno-33-11" href="#__codelineno-33-11"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-33-12"><a id="__codelineno-33-12" name="__codelineno-33-12" href="#__codelineno-33-12"></a>
|
||
</span><span id="__span-33-13"><a id="__codelineno-33-13" name="__codelineno-33-13" href="#__codelineno-33-13"></a><span class="w"> </span><span class="c1">// Cache miss, geocode</span>
|
||
</span><span id="__span-33-14"><a id="__codelineno-33-14" name="__codelineno-33-14" href="#__codelineno-33-14"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">geocode</span><span class="p">(</span><span class="nx">address</span><span class="p">);</span>
|
||
</span><span id="__span-33-15"><a id="__codelineno-33-15" name="__codelineno-33-15" href="#__codelineno-33-15"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">result</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-33-16"><a id="__codelineno-33-16" name="__codelineno-33-16" href="#__codelineno-33-16"></a><span class="w"> </span><span class="c1">// Cache for 30 days</span>
|
||
</span><span id="__span-33-17"><a id="__codelineno-33-17" name="__codelineno-33-17" href="#__codelineno-33-17"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">setex</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">,</span><span class="w"> </span><span class="mf">2592000</span><span class="p">,</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">result</span><span class="p">));</span>
|
||
</span><span id="__span-33-18"><a id="__codelineno-33-18" name="__codelineno-33-18" href="#__codelineno-33-18"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-33-19"><a id="__codelineno-33-19" name="__codelineno-33-19" href="#__codelineno-33-19"></a>
|
||
</span><span id="__span-33-20"><a id="__codelineno-33-20" name="__codelineno-33-20" href="#__codelineno-33-20"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">result</span><span class="p">;</span>
|
||
</span><span id="__span-33-21"><a id="__codelineno-33-21" name="__codelineno-33-21" href="#__codelineno-33-21"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<p><strong>Benefits:</strong>
|
||
- Reduces API costs (90% cache hit rate)
|
||
- Faster response times (Redis: <5ms vs API: 200-500ms)
|
||
- Consistent results for same address
|
||
- Provider API rate limit avoidance</p>
|
||
<h3 id="manual-verification">Manual Verification<a class="headerlink" href="#manual-verification" title="Permanent link">¶</a></h3>
|
||
<p><strong>Critical Location Verification:</strong></p>
|
||
<p>Manually verify high-priority locations:</p>
|
||
<ol>
|
||
<li><strong>Campaign offices:</strong> Ensure exact coordinates</li>
|
||
<li><strong>Shift start points:</strong> Verify accessibility</li>
|
||
<li><strong>Event venues:</strong> Confirm entrance location</li>
|
||
<li><strong>Polling stations:</strong> Critical for voter info</li>
|
||
</ol>
|
||
<p><strong>Verification Process:</strong></p>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-34-1"><a id="__codelineno-34-1" name="__codelineno-34-1" href="#__codelineno-34-1"></a><span class="c1">// Mark location as manually verified</span>
|
||
</span><span id="__span-34-2"><a id="__codelineno-34-2" name="__codelineno-34-2" href="#__codelineno-34-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">update</span><span class="p">({</span>
|
||
</span><span id="__span-34-3"><a id="__codelineno-34-3" name="__codelineno-34-3" href="#__codelineno-34-3"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">locationId</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-34-4"><a id="__codelineno-34-4" name="__codelineno-34-4" href="#__codelineno-34-4"></a><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-34-5"><a id="__codelineno-34-5" name="__codelineno-34-5" href="#__codelineno-34-5"></a><span class="w"> </span><span class="nx">geocodeConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">100</span><span class="p">,</span>
|
||
</span><span id="__span-34-6"><a id="__codelineno-34-6" name="__codelineno-34-6" href="#__codelineno-34-6"></a><span class="w"> </span><span class="nx">geocodeProvider</span><span class="o">:</span><span class="w"> </span><span class="s1">'MANUAL'</span><span class="p">,</span>
|
||
</span><span id="__span-34-7"><a id="__codelineno-34-7" name="__codelineno-34-7" href="#__codelineno-34-7"></a><span class="w"> </span><span class="nx">geocodedAt</span><span class="o">:</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">()</span>
|
||
</span><span id="__span-34-8"><a id="__codelineno-34-8" name="__codelineno-34-8" href="#__codelineno-34-8"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-34-9"><a id="__codelineno-34-9" name="__codelineno-34-9" href="#__codelineno-34-9"></a><span class="p">});</span>
|
||
</span></code></pre></div>
|
||
<h3 id="regular-audits">Regular Audits<a class="headerlink" href="#regular-audits" title="Permanent link">¶</a></h3>
|
||
<p><strong>Monthly Quality Audit Checklist:</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Run quality report:</strong>
|
||
<div class="language-bash highlight"><pre><span></span><code><span id="__span-35-1"><a id="__codelineno-35-1" name="__codelineno-35-1" href="#__codelineno-35-1"></a>curl<span class="w"> </span>http://localhost:4000/api/locations/geocode-stats
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Check metrics against thresholds:</strong></p>
|
||
</li>
|
||
<li>Geocoded % > 95%</li>
|
||
<li>Avg confidence > 70</li>
|
||
<li>Low confidence count < 50</li>
|
||
<li>
|
||
<p>Duplicates < 20</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Review low-confidence locations:</strong></p>
|
||
</li>
|
||
<li>Filter locations with confidence < 50</li>
|
||
<li>Review top 20 by address</li>
|
||
<li>
|
||
<p>Identify patterns (specific streets, providers)</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Bulk re-geocode low confidence:</strong></p>
|
||
</li>
|
||
<li>Use GOOGLE provider for accuracy</li>
|
||
<li>
|
||
<p>Monitor improvement in avg confidence</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Resolve duplicates:</strong></p>
|
||
</li>
|
||
<li>Review all duplicate groups</li>
|
||
<li>Merge or mark as multi-unit</li>
|
||
<li>
|
||
<p>Update addresses as needed</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Export quality report:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-36-1"><a id="__codelineno-36-1" name="__codelineno-36-1" href="#__codelineno-36-1"></a><span class="kd">const</span><span class="w"> </span><span class="nx">report</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">generateQualityReport</span><span class="p">();</span>
|
||
</span><span id="__span-36-2"><a id="__codelineno-36-2" name="__codelineno-36-2" href="#__codelineno-36-2"></a><span class="nx">fs</span><span class="p">.</span><span class="nx">writeFileSync</span><span class="p">(</span><span class="sb">`quality-report-</span><span class="si">${</span><span class="nx">date</span><span class="si">}</span><span class="sb">.json`</span><span class="p">,</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">report</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="mf">2</span><span class="p">));</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="code-examples">Code Examples<a class="headerlink" href="#code-examples" title="Permanent link">¶</a></h2>
|
||
<h3 id="dataqualitydashboardpagetsx">DataQualityDashboardPage.tsx<a class="headerlink" href="#dataqualitydashboardpagetsx" title="Permanent link">¶</a></h3>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-37-1"><a id="__codelineno-37-1" name="__codelineno-37-1" href="#__codelineno-37-1"></a><span class="k">import</span><span class="w"> </span><span class="nx">React</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">useEffect</span><span class="p">,</span><span class="w"> </span><span class="nx">useState</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'react'</span><span class="p">;</span>
|
||
</span><span id="__span-37-2"><a id="__codelineno-37-2" name="__codelineno-37-2" href="#__codelineno-37-2"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">Card</span><span class="p">,</span><span class="w"> </span><span class="nx">Row</span><span class="p">,</span><span class="w"> </span><span class="nx">Col</span><span class="p">,</span><span class="w"> </span><span class="nx">Statistic</span><span class="p">,</span><span class="w"> </span><span class="nx">Table</span><span class="p">,</span><span class="w"> </span><span class="nx">Tabs</span><span class="p">,</span><span class="w"> </span><span class="nx">Button</span><span class="p">,</span><span class="w"> </span><span class="nx">message</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'antd'</span><span class="p">;</span>
|
||
</span><span id="__span-37-3"><a id="__codelineno-37-3" name="__codelineno-37-3" href="#__codelineno-37-3"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">WarningOutlined</span><span class="p">,</span><span class="w"> </span><span class="nx">CheckCircleOutlined</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'@ant-design/icons'</span><span class="p">;</span>
|
||
</span><span id="__span-37-4"><a id="__codelineno-37-4" name="__codelineno-37-4" href="#__codelineno-37-4"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">api</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'@/lib/api'</span><span class="p">;</span>
|
||
</span><span id="__span-37-5"><a id="__codelineno-37-5" name="__codelineno-37-5" href="#__codelineno-37-5"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">Bar</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'react-chartjs-2'</span><span class="p">;</span>
|
||
</span><span id="__span-37-6"><a id="__codelineno-37-6" name="__codelineno-37-6" href="#__codelineno-37-6"></a>
|
||
</span><span id="__span-37-7"><a id="__codelineno-37-7" name="__codelineno-37-7" href="#__codelineno-37-7"></a><span class="kd">interface</span><span class="w"> </span><span class="nx">GeocodeStats</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-8"><a id="__codelineno-37-8" name="__codelineno-37-8" href="#__codelineno-37-8"></a><span class="w"> </span><span class="nx">total</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-9"><a id="__codelineno-37-9" name="__codelineno-37-9" href="#__codelineno-37-9"></a><span class="w"> </span><span class="nx">geocoded</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-10"><a id="__codelineno-37-10" name="__codelineno-37-10" href="#__codelineno-37-10"></a><span class="w"> </span><span class="nx">geocodedPercent</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-11"><a id="__codelineno-37-11" name="__codelineno-37-11" href="#__codelineno-37-11"></a><span class="w"> </span><span class="nx">avgConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-12"><a id="__codelineno-37-12" name="__codelineno-37-12" href="#__codelineno-37-12"></a><span class="w"> </span><span class="nx">providerBreakdown</span><span class="o">:</span><span class="w"> </span><span class="kt">Record</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">number</span><span class="o">></span><span class="p">;</span>
|
||
</span><span id="__span-37-13"><a id="__codelineno-37-13" name="__codelineno-37-13" href="#__codelineno-37-13"></a><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="o">:</span><span class="w"> </span><span class="kt">Record</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">number</span><span class="o">></span><span class="p">;</span>
|
||
</span><span id="__span-37-14"><a id="__codelineno-37-14" name="__codelineno-37-14" href="#__codelineno-37-14"></a><span class="w"> </span><span class="nx">lowConfidenceCount</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-15"><a id="__codelineno-37-15" name="__codelineno-37-15" href="#__codelineno-37-15"></a><span class="w"> </span><span class="nx">missingCoordinates</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-16"><a id="__codelineno-37-16" name="__codelineno-37-16" href="#__codelineno-37-16"></a><span class="w"> </span><span class="nx">duplicatesCount</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">;</span>
|
||
</span><span id="__span-37-17"><a id="__codelineno-37-17" name="__codelineno-37-17" href="#__codelineno-37-17"></a><span class="p">}</span>
|
||
</span><span id="__span-37-18"><a id="__codelineno-37-18" name="__codelineno-37-18" href="#__codelineno-37-18"></a>
|
||
</span><span id="__span-37-19"><a id="__codelineno-37-19" name="__codelineno-37-19" href="#__codelineno-37-19"></a><span class="kd">const</span><span class="w"> </span><span class="nx">DataQualityDashboardPage</span><span class="o">:</span><span class="w"> </span><span class="kt">React.FC</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-20"><a id="__codelineno-37-20" name="__codelineno-37-20" href="#__codelineno-37-20"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">stats</span><span class="p">,</span><span class="w"> </span><span class="nx">setStats</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="o"><</span><span class="nx">GeocodeStats</span><span class="w"> </span><span class="o">|</span><span class="w"> </span><span class="kc">null</span><span class="o">></span><span class="p">(</span><span class="kc">null</span><span class="p">);</span>
|
||
</span><span id="__span-37-21"><a id="__codelineno-37-21" name="__codelineno-37-21" href="#__codelineno-37-21"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">lowConfLocations</span><span class="p">,</span><span class="w"> </span><span class="nx">setLowConfLocations</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="o"><</span><span class="nx">any</span><span class="p">[]</span><span class="o">></span><span class="p">([]);</span>
|
||
</span><span id="__span-37-22"><a id="__codelineno-37-22" name="__codelineno-37-22" href="#__codelineno-37-22"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">duplicates</span><span class="p">,</span><span class="w"> </span><span class="nx">setDuplicates</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="o"><</span><span class="nx">any</span><span class="p">[]</span><span class="o">></span><span class="p">([]);</span>
|
||
</span><span id="__span-37-23"><a id="__codelineno-37-23" name="__codelineno-37-23" href="#__codelineno-37-23"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">[</span><span class="nx">loading</span><span class="p">,</span><span class="w"> </span><span class="nx">setLoading</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">useState</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
|
||
</span><span id="__span-37-24"><a id="__codelineno-37-24" name="__codelineno-37-24" href="#__codelineno-37-24"></a>
|
||
</span><span id="__span-37-25"><a id="__codelineno-37-25" name="__codelineno-37-25" href="#__codelineno-37-25"></a><span class="w"> </span><span class="nx">useEffect</span><span class="p">(()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-26"><a id="__codelineno-37-26" name="__codelineno-37-26" href="#__codelineno-37-26"></a><span class="w"> </span><span class="nx">fetchStats</span><span class="p">();</span>
|
||
</span><span id="__span-37-27"><a id="__codelineno-37-27" name="__codelineno-37-27" href="#__codelineno-37-27"></a><span class="w"> </span><span class="nx">fetchLowConfidenceLocations</span><span class="p">();</span>
|
||
</span><span id="__span-37-28"><a id="__codelineno-37-28" name="__codelineno-37-28" href="#__codelineno-37-28"></a><span class="w"> </span><span class="nx">fetchDuplicates</span><span class="p">();</span>
|
||
</span><span id="__span-37-29"><a id="__codelineno-37-29" name="__codelineno-37-29" href="#__codelineno-37-29"></a><span class="w"> </span><span class="p">},</span><span class="w"> </span><span class="p">[]);</span>
|
||
</span><span id="__span-37-30"><a id="__codelineno-37-30" name="__codelineno-37-30" href="#__codelineno-37-30"></a>
|
||
</span><span id="__span-37-31"><a id="__codelineno-37-31" name="__codelineno-37-31" href="#__codelineno-37-31"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">fetchStats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-32"><a id="__codelineno-37-32" name="__codelineno-37-32" href="#__codelineno-37-32"></a><span class="w"> </span><span class="nx">setLoading</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
|
||
</span><span id="__span-37-33"><a id="__codelineno-37-33" name="__codelineno-37-33" href="#__codelineno-37-33"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-34"><a id="__codelineno-37-34" name="__codelineno-37-34" href="#__codelineno-37-34"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">api</span><span class="p">.</span><span class="nx">get</span><span class="o"><</span><span class="nx">GeocodeStats</span><span class="o">></span><span class="p">(</span><span class="s1">'/locations/geocode-stats'</span><span class="p">);</span>
|
||
</span><span id="__span-37-35"><a id="__codelineno-37-35" name="__codelineno-37-35" href="#__codelineno-37-35"></a><span class="w"> </span><span class="nx">setStats</span><span class="p">(</span><span class="nx">data</span><span class="p">);</span>
|
||
</span><span id="__span-37-36"><a id="__codelineno-37-36" name="__codelineno-37-36" href="#__codelineno-37-36"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-37"><a id="__codelineno-37-37" name="__codelineno-37-37" href="#__codelineno-37-37"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Failed to load statistics'</span><span class="p">);</span>
|
||
</span><span id="__span-37-38"><a id="__codelineno-37-38" name="__codelineno-37-38" href="#__codelineno-37-38"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">finally</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-39"><a id="__codelineno-37-39" name="__codelineno-37-39" href="#__codelineno-37-39"></a><span class="w"> </span><span class="nx">setLoading</span><span class="p">(</span><span class="kc">false</span><span class="p">);</span>
|
||
</span><span id="__span-37-40"><a id="__codelineno-37-40" name="__codelineno-37-40" href="#__codelineno-37-40"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-41"><a id="__codelineno-37-41" name="__codelineno-37-41" href="#__codelineno-37-41"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-37-42"><a id="__codelineno-37-42" name="__codelineno-37-42" href="#__codelineno-37-42"></a>
|
||
</span><span id="__span-37-43"><a id="__codelineno-37-43" name="__codelineno-37-43" href="#__codelineno-37-43"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">fetchLowConfidenceLocations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-44"><a id="__codelineno-37-44" name="__codelineno-37-44" href="#__codelineno-37-44"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-45"><a id="__codelineno-37-45" name="__codelineno-37-45" href="#__codelineno-37-45"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">api</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'/locations?geocodeConfidence=lt:50&limit=100'</span><span class="p">);</span>
|
||
</span><span id="__span-37-46"><a id="__codelineno-37-46" name="__codelineno-37-46" href="#__codelineno-37-46"></a><span class="w"> </span><span class="nx">setLowConfLocations</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">data</span><span class="p">);</span>
|
||
</span><span id="__span-37-47"><a id="__codelineno-37-47" name="__codelineno-37-47" href="#__codelineno-37-47"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-48"><a id="__codelineno-37-48" name="__codelineno-37-48" href="#__codelineno-37-48"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Failed to load low-confidence locations'</span><span class="p">);</span>
|
||
</span><span id="__span-37-49"><a id="__codelineno-37-49" name="__codelineno-37-49" href="#__codelineno-37-49"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-50"><a id="__codelineno-37-50" name="__codelineno-37-50" href="#__codelineno-37-50"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-37-51"><a id="__codelineno-37-51" name="__codelineno-37-51" href="#__codelineno-37-51"></a>
|
||
</span><span id="__span-37-52"><a id="__codelineno-37-52" name="__codelineno-37-52" href="#__codelineno-37-52"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">fetchDuplicates</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-53"><a id="__codelineno-37-53" name="__codelineno-37-53" href="#__codelineno-37-53"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-54"><a id="__codelineno-37-54" name="__codelineno-37-54" href="#__codelineno-37-54"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">data</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">api</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'/locations/duplicates'</span><span class="p">);</span>
|
||
</span><span id="__span-37-55"><a id="__codelineno-37-55" name="__codelineno-37-55" href="#__codelineno-37-55"></a><span class="w"> </span><span class="nx">setDuplicates</span><span class="p">(</span><span class="nx">data</span><span class="p">.</span><span class="nx">duplicates</span><span class="p">);</span>
|
||
</span><span id="__span-37-56"><a id="__codelineno-37-56" name="__codelineno-37-56" href="#__codelineno-37-56"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-57"><a id="__codelineno-37-57" name="__codelineno-37-57" href="#__codelineno-37-57"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Failed to load duplicates'</span><span class="p">);</span>
|
||
</span><span id="__span-37-58"><a id="__codelineno-37-58" name="__codelineno-37-58" href="#__codelineno-37-58"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-59"><a id="__codelineno-37-59" name="__codelineno-37-59" href="#__codelineno-37-59"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-37-60"><a id="__codelineno-37-60" name="__codelineno-37-60" href="#__codelineno-37-60"></a>
|
||
</span><span id="__span-37-61"><a id="__codelineno-37-61" name="__codelineno-37-61" href="#__codelineno-37-61"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">handleRegeocodeLocation</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">(</span><span class="nx">locationId</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-62"><a id="__codelineno-37-62" name="__codelineno-37-62" href="#__codelineno-37-62"></a><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-63"><a id="__codelineno-37-63" name="__codelineno-37-63" href="#__codelineno-37-63"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">api</span><span class="p">.</span><span class="nx">post</span><span class="p">(</span><span class="sb">`/locations/</span><span class="si">${</span><span class="nx">locationId</span><span class="si">}</span><span class="sb">/regeocode`</span><span class="p">,</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">provider</span><span class="o">:</span><span class="w"> </span><span class="s1">'GOOGLE'</span><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-37-64"><a id="__codelineno-37-64" name="__codelineno-37-64" href="#__codelineno-37-64"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">success</span><span class="p">(</span><span class="s1">'Location re-geocoded successfully'</span><span class="p">);</span>
|
||
</span><span id="__span-37-65"><a id="__codelineno-37-65" name="__codelineno-37-65" href="#__codelineno-37-65"></a><span class="w"> </span><span class="nx">fetchStats</span><span class="p">();</span>
|
||
</span><span id="__span-37-66"><a id="__codelineno-37-66" name="__codelineno-37-66" href="#__codelineno-37-66"></a><span class="w"> </span><span class="nx">fetchLowConfidenceLocations</span><span class="p">();</span>
|
||
</span><span id="__span-37-67"><a id="__codelineno-37-67" name="__codelineno-37-67" href="#__codelineno-37-67"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">(</span><span class="nx">error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-68"><a id="__codelineno-37-68" name="__codelineno-37-68" href="#__codelineno-37-68"></a><span class="w"> </span><span class="nx">message</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="s1">'Failed to re-geocode location'</span><span class="p">);</span>
|
||
</span><span id="__span-37-69"><a id="__codelineno-37-69" name="__codelineno-37-69" href="#__codelineno-37-69"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-70"><a id="__codelineno-37-70" name="__codelineno-37-70" href="#__codelineno-37-70"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-37-71"><a id="__codelineno-37-71" name="__codelineno-37-71" href="#__codelineno-37-71"></a>
|
||
</span><span id="__span-37-72"><a id="__codelineno-37-72" name="__codelineno-37-72" href="#__codelineno-37-72"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">confidenceChartData</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">stats</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-73"><a id="__codelineno-37-73" name="__codelineno-37-73" href="#__codelineno-37-73"></a><span class="w"> </span><span class="nx">labels</span><span class="o">:</span><span class="w"> </span><span class="kt">Object.keys</span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">confidenceDistribution</span><span class="p">),</span>
|
||
</span><span id="__span-37-74"><a id="__codelineno-37-74" name="__codelineno-37-74" href="#__codelineno-37-74"></a><span class="w"> </span><span class="nx">datasets</span><span class="o">:</span><span class="w"> </span><span class="p">[{</span>
|
||
</span><span id="__span-37-75"><a id="__codelineno-37-75" name="__codelineno-37-75" href="#__codelineno-37-75"></a><span class="w"> </span><span class="nx">label</span><span class="o">:</span><span class="w"> </span><span class="s1">'Locations'</span><span class="p">,</span>
|
||
</span><span id="__span-37-76"><a id="__codelineno-37-76" name="__codelineno-37-76" href="#__codelineno-37-76"></a><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="kt">Object.values</span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">confidenceDistribution</span><span class="p">),</span>
|
||
</span><span id="__span-37-77"><a id="__codelineno-37-77" name="__codelineno-37-77" href="#__codelineno-37-77"></a><span class="w"> </span><span class="nx">backgroundColor</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-37-78"><a id="__codelineno-37-78" name="__codelineno-37-78" href="#__codelineno-37-78"></a><span class="w"> </span><span class="s1">'#e74c3c'</span><span class="p">,</span><span class="w"> </span><span class="c1">// 0-20: Red</span>
|
||
</span><span id="__span-37-79"><a id="__codelineno-37-79" name="__codelineno-37-79" href="#__codelineno-37-79"></a><span class="w"> </span><span class="s1">'#f39c12'</span><span class="p">,</span><span class="w"> </span><span class="c1">// 21-40: Orange</span>
|
||
</span><span id="__span-37-80"><a id="__codelineno-37-80" name="__codelineno-37-80" href="#__codelineno-37-80"></a><span class="w"> </span><span class="s1">'#f1c40f'</span><span class="p">,</span><span class="w"> </span><span class="c1">// 41-60: Yellow</span>
|
||
</span><span id="__span-37-81"><a id="__codelineno-37-81" name="__codelineno-37-81" href="#__codelineno-37-81"></a><span class="w"> </span><span class="s1">'#3498db'</span><span class="p">,</span><span class="w"> </span><span class="c1">// 61-80: Blue</span>
|
||
</span><span id="__span-37-82"><a id="__codelineno-37-82" name="__codelineno-37-82" href="#__codelineno-37-82"></a><span class="w"> </span><span class="s1">'#27ae60'</span><span class="w"> </span><span class="c1">// 81-100: Green</span>
|
||
</span><span id="__span-37-83"><a id="__codelineno-37-83" name="__codelineno-37-83" href="#__codelineno-37-83"></a><span class="w"> </span><span class="p">]</span>
|
||
</span><span id="__span-37-84"><a id="__codelineno-37-84" name="__codelineno-37-84" href="#__codelineno-37-84"></a><span class="w"> </span><span class="p">}]</span>
|
||
</span><span id="__span-37-85"><a id="__codelineno-37-85" name="__codelineno-37-85" href="#__codelineno-37-85"></a><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span>
|
||
</span><span id="__span-37-86"><a id="__codelineno-37-86" name="__codelineno-37-86" href="#__codelineno-37-86"></a>
|
||
</span><span id="__span-37-87"><a id="__codelineno-37-87" name="__codelineno-37-87" href="#__codelineno-37-87"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">lowConfColumns</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-37-88"><a id="__codelineno-37-88" name="__codelineno-37-88" href="#__codelineno-37-88"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Address'</span><span class="p">,</span><span class="w"> </span><span class="nx">dataIndex</span><span class="o">:</span><span class="w"> </span><span class="s1">'address'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'address'</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-89"><a id="__codelineno-37-89" name="__codelineno-37-89" href="#__codelineno-37-89"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Confidence'</span><span class="p">,</span><span class="w"> </span><span class="nx">dataIndex</span><span class="o">:</span><span class="w"> </span><span class="s1">'geocodeConfidence'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'confidence'</span><span class="p">,</span><span class="w"> </span><span class="nx">render</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">val</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">(</span>
|
||
</span><span id="__span-37-90"><a id="__codelineno-37-90" name="__codelineno-37-90" href="#__codelineno-37-90"></a><span class="w"> </span><span class="o"><</span><span class="nx">span</span><span class="w"> </span><span class="nx">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="kt">val</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mf">30</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">'#e74c3c'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">'#f39c12'</span><span class="w"> </span><span class="p">}}</span><span class="o">></span><span class="p">{</span><span class="nx">val</span><span class="p">}</span><span class="o"><</span><span class="err">/span></span>
|
||
</span><span id="__span-37-91"><a id="__codelineno-37-91" name="__codelineno-37-91" href="#__codelineno-37-91"></a><span class="w"> </span><span class="p">)},</span>
|
||
</span><span id="__span-37-92"><a id="__codelineno-37-92" name="__codelineno-37-92" href="#__codelineno-37-92"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Provider'</span><span class="p">,</span><span class="w"> </span><span class="nx">dataIndex</span><span class="o">:</span><span class="w"> </span><span class="s1">'geocodeProvider'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'provider'</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-93"><a id="__codelineno-37-93" name="__codelineno-37-93" href="#__codelineno-37-93"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Action'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'action'</span><span class="p">,</span><span class="w"> </span><span class="nx">render</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">_</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">,</span><span class="w"> </span><span class="nx">record</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">(</span>
|
||
</span><span id="__span-37-94"><a id="__codelineno-37-94" name="__codelineno-37-94" href="#__codelineno-37-94"></a><span class="w"> </span><span class="o"><</span><span class="nx">Button</span><span class="w"> </span><span class="nx">size</span><span class="o">=</span><span class="s2">"small"</span><span class="w"> </span><span class="nx">onClick</span><span class="o">=</span><span class="p">{()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">handleRegeocodeLocation</span><span class="p">(</span><span class="nx">record</span><span class="p">.</span><span class="nx">id</span><span class="p">)}</span><span class="o">></span>
|
||
</span><span id="__span-37-95"><a id="__codelineno-37-95" name="__codelineno-37-95" href="#__codelineno-37-95"></a><span class="w"> </span><span class="nx">Re</span><span class="o">-</span><span class="nx">geocode</span>
|
||
</span><span id="__span-37-96"><a id="__codelineno-37-96" name="__codelineno-37-96" href="#__codelineno-37-96"></a><span class="w"> </span><span class="o"><</span><span class="err">/Button></span>
|
||
</span><span id="__span-37-97"><a id="__codelineno-37-97" name="__codelineno-37-97" href="#__codelineno-37-97"></a><span class="w"> </span><span class="p">)}</span>
|
||
</span><span id="__span-37-98"><a id="__codelineno-37-98" name="__codelineno-37-98" href="#__codelineno-37-98"></a><span class="w"> </span><span class="p">];</span>
|
||
</span><span id="__span-37-99"><a id="__codelineno-37-99" name="__codelineno-37-99" href="#__codelineno-37-99"></a>
|
||
</span><span id="__span-37-100"><a id="__codelineno-37-100" name="__codelineno-37-100" href="#__codelineno-37-100"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">(</span>
|
||
</span><span id="__span-37-101"><a id="__codelineno-37-101" name="__codelineno-37-101" href="#__codelineno-37-101"></a><span class="w"> </span><span class="o"><</span><span class="nx">div</span><span class="o">></span>
|
||
</span><span id="__span-37-102"><a id="__codelineno-37-102" name="__codelineno-37-102" href="#__codelineno-37-102"></a><span class="w"> </span><span class="o"><</span><span class="nx">h1</span><span class="o">></span><span class="nx">Data</span><span class="w"> </span><span class="nx">Quality</span><span class="w"> </span><span class="nx">Dashboard</span><span class="o"><</span><span class="err">/h1></span>
|
||
</span><span id="__span-37-103"><a id="__codelineno-37-103" name="__codelineno-37-103" href="#__codelineno-37-103"></a>
|
||
</span><span id="__span-37-104"><a id="__codelineno-37-104" name="__codelineno-37-104" href="#__codelineno-37-104"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Statistics Cards */</span><span class="p">}</span>
|
||
</span><span id="__span-37-105"><a id="__codelineno-37-105" name="__codelineno-37-105" href="#__codelineno-37-105"></a><span class="w"> </span><span class="o"><</span><span class="nx">Row</span><span class="w"> </span><span class="nx">gutter</span><span class="o">=</span><span class="p">{</span><span class="mf">16</span><span class="p">}</span><span class="w"> </span><span class="nx">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">24</span><span class="w"> </span><span class="p">}}</span><span class="o">></span>
|
||
</span><span id="__span-37-106"><a id="__codelineno-37-106" name="__codelineno-37-106" href="#__codelineno-37-106"></a><span class="w"> </span><span class="o"><</span><span class="nx">Col</span><span class="w"> </span><span class="nx">span</span><span class="o">=</span><span class="p">{</span><span class="mf">6</span><span class="p">}</span><span class="o">></span>
|
||
</span><span id="__span-37-107"><a id="__codelineno-37-107" name="__codelineno-37-107" href="#__codelineno-37-107"></a><span class="w"> </span><span class="o"><</span><span class="nx">Card</span><span class="o">></span>
|
||
</span><span id="__span-37-108"><a id="__codelineno-37-108" name="__codelineno-37-108" href="#__codelineno-37-108"></a><span class="w"> </span><span class="o"><</span><span class="nx">Statistic</span>
|
||
</span><span id="__span-37-109"><a id="__codelineno-37-109" name="__codelineno-37-109" href="#__codelineno-37-109"></a><span class="w"> </span><span class="nx">title</span><span class="o">=</span><span class="s2">"Total Locations"</span>
|
||
</span><span id="__span-37-110"><a id="__codelineno-37-110" name="__codelineno-37-110" href="#__codelineno-37-110"></a><span class="w"> </span><span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">total</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">}</span>
|
||
</span><span id="__span-37-111"><a id="__codelineno-37-111" name="__codelineno-37-111" href="#__codelineno-37-111"></a><span class="w"> </span><span class="nx">prefix</span><span class="o">=</span><span class="p">{</span><span class="o"><</span><span class="nx">CheckCircleOutlined</span><span class="w"> </span><span class="o">/></span><span class="p">}</span>
|
||
</span><span id="__span-37-112"><a id="__codelineno-37-112" name="__codelineno-37-112" href="#__codelineno-37-112"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-113"><a id="__codelineno-37-113" name="__codelineno-37-113" href="#__codelineno-37-113"></a><span class="w"> </span><span class="o"><</span><span class="err">/Card></span>
|
||
</span><span id="__span-37-114"><a id="__codelineno-37-114" name="__codelineno-37-114" href="#__codelineno-37-114"></a><span class="w"> </span><span class="o"><</span><span class="err">/Col></span>
|
||
</span><span id="__span-37-115"><a id="__codelineno-37-115" name="__codelineno-37-115" href="#__codelineno-37-115"></a><span class="w"> </span><span class="o"><</span><span class="nx">Col</span><span class="w"> </span><span class="nx">span</span><span class="o">=</span><span class="p">{</span><span class="mf">6</span><span class="p">}</span><span class="o">></span>
|
||
</span><span id="__span-37-116"><a id="__codelineno-37-116" name="__codelineno-37-116" href="#__codelineno-37-116"></a><span class="w"> </span><span class="o"><</span><span class="nx">Card</span><span class="o">></span>
|
||
</span><span id="__span-37-117"><a id="__codelineno-37-117" name="__codelineno-37-117" href="#__codelineno-37-117"></a><span class="w"> </span><span class="o"><</span><span class="nx">Statistic</span>
|
||
</span><span id="__span-37-118"><a id="__codelineno-37-118" name="__codelineno-37-118" href="#__codelineno-37-118"></a><span class="w"> </span><span class="nx">title</span><span class="o">=</span><span class="s2">"Geocoded"</span>
|
||
</span><span id="__span-37-119"><a id="__codelineno-37-119" name="__codelineno-37-119" href="#__codelineno-37-119"></a><span class="w"> </span><span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">geocoded</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">}</span>
|
||
</span><span id="__span-37-120"><a id="__codelineno-37-120" name="__codelineno-37-120" href="#__codelineno-37-120"></a><span class="w"> </span><span class="nx">suffix</span><span class="o">=</span><span class="p">{</span><span class="sb">`(</span><span class="si">${</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">geocodedPercent</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="si">}</span><span class="sb">%)`</span><span class="p">}</span>
|
||
</span><span id="__span-37-121"><a id="__codelineno-37-121" name="__codelineno-37-121" href="#__codelineno-37-121"></a><span class="w"> </span><span class="nx">valueStyle</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">geocodedPercent</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">95</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">'#27ae60'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">'#f39c12'</span><span class="w"> </span><span class="p">}}</span>
|
||
</span><span id="__span-37-122"><a id="__codelineno-37-122" name="__codelineno-37-122" href="#__codelineno-37-122"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-123"><a id="__codelineno-37-123" name="__codelineno-37-123" href="#__codelineno-37-123"></a><span class="w"> </span><span class="o"><</span><span class="err">/Card></span>
|
||
</span><span id="__span-37-124"><a id="__codelineno-37-124" name="__codelineno-37-124" href="#__codelineno-37-124"></a><span class="w"> </span><span class="o"><</span><span class="err">/Col></span>
|
||
</span><span id="__span-37-125"><a id="__codelineno-37-125" name="__codelineno-37-125" href="#__codelineno-37-125"></a><span class="w"> </span><span class="o"><</span><span class="nx">Col</span><span class="w"> </span><span class="nx">span</span><span class="o">=</span><span class="p">{</span><span class="mf">6</span><span class="p">}</span><span class="o">></span>
|
||
</span><span id="__span-37-126"><a id="__codelineno-37-126" name="__codelineno-37-126" href="#__codelineno-37-126"></a><span class="w"> </span><span class="o"><</span><span class="nx">Card</span><span class="o">></span>
|
||
</span><span id="__span-37-127"><a id="__codelineno-37-127" name="__codelineno-37-127" href="#__codelineno-37-127"></a><span class="w"> </span><span class="o"><</span><span class="nx">Statistic</span>
|
||
</span><span id="__span-37-128"><a id="__codelineno-37-128" name="__codelineno-37-128" href="#__codelineno-37-128"></a><span class="w"> </span><span class="nx">title</span><span class="o">=</span><span class="s2">"Avg Confidence"</span>
|
||
</span><span id="__span-37-129"><a id="__codelineno-37-129" name="__codelineno-37-129" href="#__codelineno-37-129"></a><span class="w"> </span><span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">avgConfidence</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">1</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">}</span>
|
||
</span><span id="__span-37-130"><a id="__codelineno-37-130" name="__codelineno-37-130" href="#__codelineno-37-130"></a><span class="w"> </span><span class="nx">valueStyle</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">avgConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">70</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">'#27ae60'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">'#f39c12'</span><span class="w"> </span><span class="p">}}</span>
|
||
</span><span id="__span-37-131"><a id="__codelineno-37-131" name="__codelineno-37-131" href="#__codelineno-37-131"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-132"><a id="__codelineno-37-132" name="__codelineno-37-132" href="#__codelineno-37-132"></a><span class="w"> </span><span class="o"><</span><span class="err">/Card></span>
|
||
</span><span id="__span-37-133"><a id="__codelineno-37-133" name="__codelineno-37-133" href="#__codelineno-37-133"></a><span class="w"> </span><span class="o"><</span><span class="err">/Col></span>
|
||
</span><span id="__span-37-134"><a id="__codelineno-37-134" name="__codelineno-37-134" href="#__codelineno-37-134"></a><span class="w"> </span><span class="o"><</span><span class="nx">Col</span><span class="w"> </span><span class="nx">span</span><span class="o">=</span><span class="p">{</span><span class="mf">6</span><span class="p">}</span><span class="o">></span>
|
||
</span><span id="__span-37-135"><a id="__codelineno-37-135" name="__codelineno-37-135" href="#__codelineno-37-135"></a><span class="w"> </span><span class="o"><</span><span class="nx">Card</span><span class="o">></span>
|
||
</span><span id="__span-37-136"><a id="__codelineno-37-136" name="__codelineno-37-136" href="#__codelineno-37-136"></a><span class="w"> </span><span class="o"><</span><span class="nx">Statistic</span>
|
||
</span><span id="__span-37-137"><a id="__codelineno-37-137" name="__codelineno-37-137" href="#__codelineno-37-137"></a><span class="w"> </span><span class="nx">title</span><span class="o">=</span><span class="s2">"Low Confidence"</span>
|
||
</span><span id="__span-37-138"><a id="__codelineno-37-138" name="__codelineno-37-138" href="#__codelineno-37-138"></a><span class="w"> </span><span class="nx">value</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">lowConfidenceCount</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">}</span>
|
||
</span><span id="__span-37-139"><a id="__codelineno-37-139" name="__codelineno-37-139" href="#__codelineno-37-139"></a><span class="w"> </span><span class="nx">prefix</span><span class="o">=</span><span class="p">{</span><span class="o"><</span><span class="nx">WarningOutlined</span><span class="w"> </span><span class="o">/></span><span class="p">}</span>
|
||
</span><span id="__span-37-140"><a id="__codelineno-37-140" name="__codelineno-37-140" href="#__codelineno-37-140"></a><span class="w"> </span><span class="nx">valueStyle</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">color</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">stats</span><span class="o">?</span><span class="p">.</span><span class="nx">lowConfidenceCount</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">50</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="s1">'#e74c3c'</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="s1">'#f39c12'</span><span class="w"> </span><span class="p">}}</span>
|
||
</span><span id="__span-37-141"><a id="__codelineno-37-141" name="__codelineno-37-141" href="#__codelineno-37-141"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-142"><a id="__codelineno-37-142" name="__codelineno-37-142" href="#__codelineno-37-142"></a><span class="w"> </span><span class="o"><</span><span class="err">/Card></span>
|
||
</span><span id="__span-37-143"><a id="__codelineno-37-143" name="__codelineno-37-143" href="#__codelineno-37-143"></a><span class="w"> </span><span class="o"><</span><span class="err">/Col></span>
|
||
</span><span id="__span-37-144"><a id="__codelineno-37-144" name="__codelineno-37-144" href="#__codelineno-37-144"></a><span class="w"> </span><span class="o"><</span><span class="err">/Row></span>
|
||
</span><span id="__span-37-145"><a id="__codelineno-37-145" name="__codelineno-37-145" href="#__codelineno-37-145"></a>
|
||
</span><span id="__span-37-146"><a id="__codelineno-37-146" name="__codelineno-37-146" href="#__codelineno-37-146"></a><span class="w"> </span><span class="p">{</span><span class="cm">/* Charts and Tables */</span><span class="p">}</span>
|
||
</span><span id="__span-37-147"><a id="__codelineno-37-147" name="__codelineno-37-147" href="#__codelineno-37-147"></a><span class="w"> </span><span class="o"><</span><span class="nx">Tabs</span>
|
||
</span><span id="__span-37-148"><a id="__codelineno-37-148" name="__codelineno-37-148" href="#__codelineno-37-148"></a><span class="w"> </span><span class="nx">items</span><span class="o">=</span><span class="p">{[</span>
|
||
</span><span id="__span-37-149"><a id="__codelineno-37-149" name="__codelineno-37-149" href="#__codelineno-37-149"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-150"><a id="__codelineno-37-150" name="__codelineno-37-150" href="#__codelineno-37-150"></a><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'overview'</span><span class="p">,</span>
|
||
</span><span id="__span-37-151"><a id="__codelineno-37-151" name="__codelineno-37-151" href="#__codelineno-37-151"></a><span class="w"> </span><span class="nx">label</span><span class="o">:</span><span class="w"> </span><span class="s1">'Overview'</span><span class="p">,</span>
|
||
</span><span id="__span-37-152"><a id="__codelineno-37-152" name="__codelineno-37-152" href="#__codelineno-37-152"></a><span class="w"> </span><span class="nx">children</span><span class="o">:</span><span class="w"> </span><span class="p">(</span>
|
||
</span><span id="__span-37-153"><a id="__codelineno-37-153" name="__codelineno-37-153" href="#__codelineno-37-153"></a><span class="w"> </span><span class="o"><</span><span class="nx">div</span><span class="o">></span>
|
||
</span><span id="__span-37-154"><a id="__codelineno-37-154" name="__codelineno-37-154" href="#__codelineno-37-154"></a><span class="w"> </span><span class="o"><</span><span class="nx">Card</span><span class="w"> </span><span class="nx">title</span><span class="o">=</span><span class="s2">"Confidence Distribution"</span><span class="w"> </span><span class="nx">style</span><span class="o">=</span><span class="p">{{</span><span class="w"> </span><span class="nx">marginBottom</span><span class="o">:</span><span class="w"> </span><span class="kt">24</span><span class="w"> </span><span class="p">}}</span><span class="o">></span>
|
||
</span><span id="__span-37-155"><a id="__codelineno-37-155" name="__codelineno-37-155" href="#__codelineno-37-155"></a><span class="w"> </span><span class="p">{</span><span class="nx">confidenceChartData</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="o"><</span><span class="nx">Bar</span><span class="w"> </span><span class="nx">data</span><span class="o">=</span><span class="p">{</span><span class="nx">confidenceChartData</span><span class="p">}</span><span class="w"> </span><span class="o">/></span><span class="p">}</span>
|
||
</span><span id="__span-37-156"><a id="__codelineno-37-156" name="__codelineno-37-156" href="#__codelineno-37-156"></a><span class="w"> </span><span class="o"><</span><span class="err">/Card></span>
|
||
</span><span id="__span-37-157"><a id="__codelineno-37-157" name="__codelineno-37-157" href="#__codelineno-37-157"></a><span class="w"> </span><span class="o"><</span><span class="nx">Card</span><span class="w"> </span><span class="nx">title</span><span class="o">=</span><span class="s2">"Provider Performance"</span><span class="o">></span>
|
||
</span><span id="__span-37-158"><a id="__codelineno-37-158" name="__codelineno-37-158" href="#__codelineno-37-158"></a><span class="w"> </span><span class="o"><</span><span class="nx">Table</span>
|
||
</span><span id="__span-37-159"><a id="__codelineno-37-159" name="__codelineno-37-159" href="#__codelineno-37-159"></a><span class="w"> </span><span class="nx">dataSource</span><span class="o">=</span><span class="p">{</span><span class="nx">stats</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nb">Object</span><span class="p">.</span><span class="nx">entries</span><span class="p">(</span><span class="nx">stats</span><span class="p">.</span><span class="nx">providerBreakdown</span><span class="p">).</span><span class="nx">map</span><span class="p">(([</span><span class="nx">provider</span><span class="p">,</span><span class="w"> </span><span class="nx">count</span><span class="p">])</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">({</span>
|
||
</span><span id="__span-37-160"><a id="__codelineno-37-160" name="__codelineno-37-160" href="#__codelineno-37-160"></a><span class="w"> </span><span class="nx">provider</span><span class="p">,</span>
|
||
</span><span id="__span-37-161"><a id="__codelineno-37-161" name="__codelineno-37-161" href="#__codelineno-37-161"></a><span class="w"> </span><span class="nx">count</span>
|
||
</span><span id="__span-37-162"><a id="__codelineno-37-162" name="__codelineno-37-162" href="#__codelineno-37-162"></a><span class="w"> </span><span class="p">}))</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="p">[]}</span>
|
||
</span><span id="__span-37-163"><a id="__codelineno-37-163" name="__codelineno-37-163" href="#__codelineno-37-163"></a><span class="w"> </span><span class="nx">columns</span><span class="o">=</span><span class="p">{[</span>
|
||
</span><span id="__span-37-164"><a id="__codelineno-37-164" name="__codelineno-37-164" href="#__codelineno-37-164"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Provider'</span><span class="p">,</span><span class="w"> </span><span class="nx">dataIndex</span><span class="o">:</span><span class="w"> </span><span class="s1">'provider'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'provider'</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-165"><a id="__codelineno-37-165" name="__codelineno-37-165" href="#__codelineno-37-165"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Count'</span><span class="p">,</span><span class="w"> </span><span class="nx">dataIndex</span><span class="o">:</span><span class="w"> </span><span class="s1">'count'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'count'</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-166"><a id="__codelineno-37-166" name="__codelineno-37-166" href="#__codelineno-37-166"></a><span class="w"> </span><span class="p">]}</span>
|
||
</span><span id="__span-37-167"><a id="__codelineno-37-167" name="__codelineno-37-167" href="#__codelineno-37-167"></a><span class="w"> </span><span class="nx">pagination</span><span class="o">=</span><span class="p">{</span><span class="kc">false</span><span class="p">}</span>
|
||
</span><span id="__span-37-168"><a id="__codelineno-37-168" name="__codelineno-37-168" href="#__codelineno-37-168"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-169"><a id="__codelineno-37-169" name="__codelineno-37-169" href="#__codelineno-37-169"></a><span class="w"> </span><span class="o"><</span><span class="err">/Card></span>
|
||
</span><span id="__span-37-170"><a id="__codelineno-37-170" name="__codelineno-37-170" href="#__codelineno-37-170"></a><span class="w"> </span><span class="o"><</span><span class="err">/div></span>
|
||
</span><span id="__span-37-171"><a id="__codelineno-37-171" name="__codelineno-37-171" href="#__codelineno-37-171"></a><span class="w"> </span><span class="p">)</span>
|
||
</span><span id="__span-37-172"><a id="__codelineno-37-172" name="__codelineno-37-172" href="#__codelineno-37-172"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-173"><a id="__codelineno-37-173" name="__codelineno-37-173" href="#__codelineno-37-173"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-174"><a id="__codelineno-37-174" name="__codelineno-37-174" href="#__codelineno-37-174"></a><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'low-confidence'</span><span class="p">,</span>
|
||
</span><span id="__span-37-175"><a id="__codelineno-37-175" name="__codelineno-37-175" href="#__codelineno-37-175"></a><span class="w"> </span><span class="nx">label</span><span class="o">:</span><span class="w"> </span><span class="sb">`Low Confidence (</span><span class="si">${</span><span class="nx">lowConfLocations</span><span class="p">.</span><span class="nx">length</span><span class="si">}</span><span class="sb">)`</span><span class="p">,</span>
|
||
</span><span id="__span-37-176"><a id="__codelineno-37-176" name="__codelineno-37-176" href="#__codelineno-37-176"></a><span class="w"> </span><span class="nx">children</span><span class="o">:</span><span class="w"> </span><span class="p">(</span>
|
||
</span><span id="__span-37-177"><a id="__codelineno-37-177" name="__codelineno-37-177" href="#__codelineno-37-177"></a><span class="w"> </span><span class="o"><</span><span class="nx">Table</span>
|
||
</span><span id="__span-37-178"><a id="__codelineno-37-178" name="__codelineno-37-178" href="#__codelineno-37-178"></a><span class="w"> </span><span class="nx">dataSource</span><span class="o">=</span><span class="p">{</span><span class="nx">lowConfLocations</span><span class="p">}</span>
|
||
</span><span id="__span-37-179"><a id="__codelineno-37-179" name="__codelineno-37-179" href="#__codelineno-37-179"></a><span class="w"> </span><span class="nx">columns</span><span class="o">=</span><span class="p">{</span><span class="nx">lowConfColumns</span><span class="p">}</span>
|
||
</span><span id="__span-37-180"><a id="__codelineno-37-180" name="__codelineno-37-180" href="#__codelineno-37-180"></a><span class="w"> </span><span class="nx">rowKey</span><span class="o">=</span><span class="s2">"id"</span>
|
||
</span><span id="__span-37-181"><a id="__codelineno-37-181" name="__codelineno-37-181" href="#__codelineno-37-181"></a><span class="w"> </span><span class="nx">loading</span><span class="o">=</span><span class="p">{</span><span class="nx">loading</span><span class="p">}</span>
|
||
</span><span id="__span-37-182"><a id="__codelineno-37-182" name="__codelineno-37-182" href="#__codelineno-37-182"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-183"><a id="__codelineno-37-183" name="__codelineno-37-183" href="#__codelineno-37-183"></a><span class="w"> </span><span class="p">)</span>
|
||
</span><span id="__span-37-184"><a id="__codelineno-37-184" name="__codelineno-37-184" href="#__codelineno-37-184"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-185"><a id="__codelineno-37-185" name="__codelineno-37-185" href="#__codelineno-37-185"></a><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-37-186"><a id="__codelineno-37-186" name="__codelineno-37-186" href="#__codelineno-37-186"></a><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'duplicates'</span><span class="p">,</span>
|
||
</span><span id="__span-37-187"><a id="__codelineno-37-187" name="__codelineno-37-187" href="#__codelineno-37-187"></a><span class="w"> </span><span class="nx">label</span><span class="o">:</span><span class="w"> </span><span class="sb">`Duplicates (</span><span class="si">${</span><span class="nx">duplicates</span><span class="p">.</span><span class="nx">length</span><span class="si">}</span><span class="sb">)`</span><span class="p">,</span>
|
||
</span><span id="__span-37-188"><a id="__codelineno-37-188" name="__codelineno-37-188" href="#__codelineno-37-188"></a><span class="w"> </span><span class="nx">children</span><span class="o">:</span><span class="w"> </span><span class="p">(</span>
|
||
</span><span id="__span-37-189"><a id="__codelineno-37-189" name="__codelineno-37-189" href="#__codelineno-37-189"></a><span class="w"> </span><span class="o"><</span><span class="nx">Table</span>
|
||
</span><span id="__span-37-190"><a id="__codelineno-37-190" name="__codelineno-37-190" href="#__codelineno-37-190"></a><span class="w"> </span><span class="nx">dataSource</span><span class="o">=</span><span class="p">{</span><span class="nx">duplicates</span><span class="p">}</span>
|
||
</span><span id="__span-37-191"><a id="__codelineno-37-191" name="__codelineno-37-191" href="#__codelineno-37-191"></a><span class="w"> </span><span class="nx">columns</span><span class="o">=</span><span class="p">{[</span>
|
||
</span><span id="__span-37-192"><a id="__codelineno-37-192" name="__codelineno-37-192" href="#__codelineno-37-192"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Coordinates'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'coords'</span><span class="p">,</span><span class="w"> </span><span class="nx">render</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">record</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">=></span>
|
||
</span><span id="__span-37-193"><a id="__codelineno-37-193" name="__codelineno-37-193" href="#__codelineno-37-193"></a><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">record</span><span class="p">.</span><span class="nx">coordinates</span><span class="p">.</span><span class="nx">latitude</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="si">}</span><span class="sb">, </span><span class="si">${</span><span class="nx">record</span><span class="p">.</span><span class="nx">coordinates</span><span class="p">.</span><span class="nx">longitude</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span>
|
||
</span><span id="__span-37-194"><a id="__codelineno-37-194" name="__codelineno-37-194" href="#__codelineno-37-194"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-195"><a id="__codelineno-37-195" name="__codelineno-37-195" href="#__codelineno-37-195"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Count'</span><span class="p">,</span><span class="w"> </span><span class="nx">dataIndex</span><span class="o">:</span><span class="w"> </span><span class="s1">'count'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'count'</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-37-196"><a id="__codelineno-37-196" name="__codelineno-37-196" href="#__codelineno-37-196"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">title</span><span class="o">:</span><span class="w"> </span><span class="s1">'Addresses'</span><span class="p">,</span><span class="w"> </span><span class="nx">key</span><span class="o">:</span><span class="w"> </span><span class="s1">'addresses'</span><span class="p">,</span><span class="w"> </span><span class="nx">render</span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="nx">_</span><span class="p">,</span><span class="w"> </span><span class="nx">record</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">=></span>
|
||
</span><span id="__span-37-197"><a id="__codelineno-37-197" name="__codelineno-37-197" href="#__codelineno-37-197"></a><span class="w"> </span><span class="nx">record</span><span class="p">.</span><span class="nx">locations</span><span class="p">.</span><span class="nx">map</span><span class="p">((</span><span class="nx">l</span><span class="o">:</span><span class="w"> </span><span class="kt">any</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">address</span><span class="p">).</span><span class="nx">join</span><span class="p">(</span><span class="s1">', '</span><span class="p">)</span>
|
||
</span><span id="__span-37-198"><a id="__codelineno-37-198" name="__codelineno-37-198" href="#__codelineno-37-198"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-199"><a id="__codelineno-37-199" name="__codelineno-37-199" href="#__codelineno-37-199"></a><span class="w"> </span><span class="p">]}</span>
|
||
</span><span id="__span-37-200"><a id="__codelineno-37-200" name="__codelineno-37-200" href="#__codelineno-37-200"></a><span class="w"> </span><span class="nx">rowKey</span><span class="o">=</span><span class="p">{(</span><span class="nx">record</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">record</span><span class="p">.</span><span class="nx">coordinates</span><span class="p">.</span><span class="nx">latitude</span><span class="si">}</span><span class="sb">-</span><span class="si">${</span><span class="nx">record</span><span class="p">.</span><span class="nx">coordinates</span><span class="p">.</span><span class="nx">longitude</span><span class="si">}</span><span class="sb">`</span><span class="p">}</span>
|
||
</span><span id="__span-37-201"><a id="__codelineno-37-201" name="__codelineno-37-201" href="#__codelineno-37-201"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-202"><a id="__codelineno-37-202" name="__codelineno-37-202" href="#__codelineno-37-202"></a><span class="w"> </span><span class="p">)</span>
|
||
</span><span id="__span-37-203"><a id="__codelineno-37-203" name="__codelineno-37-203" href="#__codelineno-37-203"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-37-204"><a id="__codelineno-37-204" name="__codelineno-37-204" href="#__codelineno-37-204"></a><span class="w"> </span><span class="p">]}</span>
|
||
</span><span id="__span-37-205"><a id="__codelineno-37-205" name="__codelineno-37-205" href="#__codelineno-37-205"></a><span class="w"> </span><span class="o">/></span>
|
||
</span><span id="__span-37-206"><a id="__codelineno-37-206" name="__codelineno-37-206" href="#__codelineno-37-206"></a><span class="w"> </span><span class="o"><</span><span class="err">/div></span>
|
||
</span><span id="__span-37-207"><a id="__codelineno-37-207" name="__codelineno-37-207" href="#__codelineno-37-207"></a><span class="w"> </span><span class="p">);</span>
|
||
</span><span id="__span-37-208"><a id="__codelineno-37-208" name="__codelineno-37-208" href="#__codelineno-37-208"></a><span class="p">};</span>
|
||
</span><span id="__span-37-209"><a id="__codelineno-37-209" name="__codelineno-37-209" href="#__codelineno-37-209"></a>
|
||
</span><span id="__span-37-210"><a id="__codelineno-37-210" name="__codelineno-37-210" href="#__codelineno-37-210"></a><span class="k">export</span><span class="w"> </span><span class="k">default</span><span class="w"> </span><span class="nx">DataQualityDashboardPage</span><span class="p">;</span>
|
||
</span></code></pre></div>
|
||
<h3 id="geocode-statistics-service">Geocode Statistics Service<a class="headerlink" href="#geocode-statistics-service" title="Permanent link">¶</a></h3>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-38-1"><a id="__codelineno-38-1" name="__codelineno-38-1" href="#__codelineno-38-1"></a><span class="c1">// locations.service.ts</span>
|
||
</span><span id="__span-38-2"><a id="__codelineno-38-2" name="__codelineno-38-2" href="#__codelineno-38-2"></a>
|
||
</span><span id="__span-38-3"><a id="__codelineno-38-3" name="__codelineno-38-3" href="#__codelineno-38-3"></a><span class="k">import</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">prisma</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'@/config/database'</span><span class="p">;</span>
|
||
</span><span id="__span-38-4"><a id="__codelineno-38-4" name="__codelineno-38-4" href="#__codelineno-38-4"></a><span class="k">import</span><span class="w"> </span><span class="kr">type</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">GeocodeProvider</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="kr">from</span><span class="w"> </span><span class="s1">'@prisma/client'</span><span class="p">;</span>
|
||
</span><span id="__span-38-5"><a id="__codelineno-38-5" name="__codelineno-38-5" href="#__codelineno-38-5"></a>
|
||
</span><span id="__span-38-6"><a id="__codelineno-38-6" name="__codelineno-38-6" href="#__codelineno-38-6"></a><span class="k">export</span><span class="w"> </span><span class="kd">class</span><span class="w"> </span><span class="nx">LocationsService</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-7"><a id="__codelineno-38-7" name="__codelineno-38-7" href="#__codelineno-38-7"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">getGeocodeStats</span><span class="p">()</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-8"><a id="__codelineno-38-8" name="__codelineno-38-8" href="#__codelineno-38-8"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">locations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
|
||
</span><span id="__span-38-9"><a id="__codelineno-38-9" name="__codelineno-38-9" href="#__codelineno-38-9"></a><span class="w"> </span><span class="nx">select</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-10"><a id="__codelineno-38-10" name="__codelineno-38-10" href="#__codelineno-38-10"></a><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-38-11"><a id="__codelineno-38-11" name="__codelineno-38-11" href="#__codelineno-38-11"></a><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-38-12"><a id="__codelineno-38-12" name="__codelineno-38-12" href="#__codelineno-38-12"></a><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-38-13"><a id="__codelineno-38-13" name="__codelineno-38-13" href="#__codelineno-38-13"></a><span class="w"> </span><span class="nx">geocodeConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span>
|
||
</span><span id="__span-38-14"><a id="__codelineno-38-14" name="__codelineno-38-14" href="#__codelineno-38-14"></a><span class="w"> </span><span class="nx">geocodeProvider</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span>
|
||
</span><span id="__span-38-15"><a id="__codelineno-38-15" name="__codelineno-38-15" href="#__codelineno-38-15"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-16"><a id="__codelineno-38-16" name="__codelineno-38-16" href="#__codelineno-38-16"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-17"><a id="__codelineno-38-17" name="__codelineno-38-17" href="#__codelineno-38-17"></a>
|
||
</span><span id="__span-38-18"><a id="__codelineno-38-18" name="__codelineno-38-18" href="#__codelineno-38-18"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">total</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-38-19"><a id="__codelineno-38-19" name="__codelineno-38-19" href="#__codelineno-38-19"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">geocoded</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">latitude</span><span class="w"> </span><span class="o">&&</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">longitude</span><span class="p">).</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-38-20"><a id="__codelineno-38-20" name="__codelineno-38-20" href="#__codelineno-38-20"></a>
|
||
</span><span id="__span-38-21"><a id="__codelineno-38-21" name="__codelineno-38-21" href="#__codelineno-38-21"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">sumConfidence</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">sum</span><span class="p">,</span><span class="w"> </span><span class="nx">l</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">sum</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">),</span><span class="w"> </span><span class="mf">0</span><span class="p">);</span>
|
||
</span><span id="__span-38-22"><a id="__codelineno-38-22" name="__codelineno-38-22" href="#__codelineno-38-22"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">avgConfidence</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">total</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="nx">sumConfidence</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">total</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">;</span>
|
||
</span><span id="__span-38-23"><a id="__codelineno-38-23" name="__codelineno-38-23" href="#__codelineno-38-23"></a>
|
||
</span><span id="__span-38-24"><a id="__codelineno-38-24" name="__codelineno-38-24" href="#__codelineno-38-24"></a><span class="w"> </span><span class="c1">// Provider breakdown</span>
|
||
</span><span id="__span-38-25"><a id="__codelineno-38-25" name="__codelineno-38-25" href="#__codelineno-38-25"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">providerBreakdown</span><span class="o">:</span><span class="w"> </span><span class="kt">Record</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">number</span><span class="o">></span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{};</span>
|
||
</span><span id="__span-38-26"><a id="__codelineno-38-26" name="__codelineno-38-26" href="#__codelineno-38-26"></a><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-27"><a id="__codelineno-38-27" name="__codelineno-38-27" href="#__codelineno-38-27"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">provider</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeProvider</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="s1">'UNKNOWN'</span><span class="p">;</span>
|
||
</span><span id="__span-38-28"><a id="__codelineno-38-28" name="__codelineno-38-28" href="#__codelineno-38-28"></a><span class="w"> </span><span class="nx">providerBreakdown</span><span class="p">[</span><span class="nx">provider</span><span class="p">]</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">providerBreakdown</span><span class="p">[</span><span class="nx">provider</span><span class="p">]</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">;</span>
|
||
</span><span id="__span-38-29"><a id="__codelineno-38-29" name="__codelineno-38-29" href="#__codelineno-38-29"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-30"><a id="__codelineno-38-30" name="__codelineno-38-30" href="#__codelineno-38-30"></a>
|
||
</span><span id="__span-38-31"><a id="__codelineno-38-31" name="__codelineno-38-31" href="#__codelineno-38-31"></a><span class="w"> </span><span class="c1">// Confidence distribution</span>
|
||
</span><span id="__span-38-32"><a id="__codelineno-38-32" name="__codelineno-38-32" href="#__codelineno-38-32"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-33"><a id="__codelineno-38-33" name="__codelineno-38-33" href="#__codelineno-38-33"></a><span class="w"> </span><span class="s1">'0-20'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-38-34"><a id="__codelineno-38-34" name="__codelineno-38-34" href="#__codelineno-38-34"></a><span class="w"> </span><span class="s1">'21-40'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-38-35"><a id="__codelineno-38-35" name="__codelineno-38-35" href="#__codelineno-38-35"></a><span class="w"> </span><span class="s1">'41-60'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-38-36"><a id="__codelineno-38-36" name="__codelineno-38-36" href="#__codelineno-38-36"></a><span class="w"> </span><span class="s1">'61-80'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span><span class="p">,</span>
|
||
</span><span id="__span-38-37"><a id="__codelineno-38-37" name="__codelineno-38-37" href="#__codelineno-38-37"></a><span class="w"> </span><span class="s1">'81-100'</span><span class="o">:</span><span class="w"> </span><span class="mf">0</span>
|
||
</span><span id="__span-38-38"><a id="__codelineno-38-38" name="__codelineno-38-38" href="#__codelineno-38-38"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-38-39"><a id="__codelineno-38-39" name="__codelineno-38-39" href="#__codelineno-38-39"></a>
|
||
</span><span id="__span-38-40"><a id="__codelineno-38-40" name="__codelineno-38-40" href="#__codelineno-38-40"></a><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-41"><a id="__codelineno-38-41" name="__codelineno-38-41" href="#__codelineno-38-41"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">conf</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">;</span>
|
||
</span><span id="__span-38-42"><a id="__codelineno-38-42" name="__codelineno-38-42" href="#__codelineno-38-42"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">20</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'0-20'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-38-43"><a id="__codelineno-38-43" name="__codelineno-38-43" href="#__codelineno-38-43"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">40</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'21-40'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-38-44"><a id="__codelineno-38-44" name="__codelineno-38-44" href="#__codelineno-38-44"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">60</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'41-60'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-38-45"><a id="__codelineno-38-45" name="__codelineno-38-45" href="#__codelineno-38-45"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">conf</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="mf">80</span><span class="p">)</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'61-80'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-38-46"><a id="__codelineno-38-46" name="__codelineno-38-46" href="#__codelineno-38-46"></a><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">[</span><span class="s1">'81-100'</span><span class="p">]</span><span class="o">++</span><span class="p">;</span>
|
||
</span><span id="__span-38-47"><a id="__codelineno-38-47" name="__codelineno-38-47" href="#__codelineno-38-47"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-48"><a id="__codelineno-38-48" name="__codelineno-38-48" href="#__codelineno-38-48"></a>
|
||
</span><span id="__span-38-49"><a id="__codelineno-38-49" name="__codelineno-38-49" href="#__codelineno-38-49"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">lowConfidenceCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">filter</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">(</span><span class="nx">l</span><span class="p">.</span><span class="nx">geocodeConfidence</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mf">50</span><span class="p">).</span><span class="nx">length</span><span class="p">;</span>
|
||
</span><span id="__span-38-50"><a id="__codelineno-38-50" name="__codelineno-38-50" href="#__codelineno-38-50"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">duplicatesCount</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="k">this</span><span class="p">.</span><span class="nx">countDuplicates</span><span class="p">();</span>
|
||
</span><span id="__span-38-51"><a id="__codelineno-38-51" name="__codelineno-38-51" href="#__codelineno-38-51"></a>
|
||
</span><span id="__span-38-52"><a id="__codelineno-38-52" name="__codelineno-38-52" href="#__codelineno-38-52"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-53"><a id="__codelineno-38-53" name="__codelineno-38-53" href="#__codelineno-38-53"></a><span class="w"> </span><span class="nx">total</span><span class="p">,</span>
|
||
</span><span id="__span-38-54"><a id="__codelineno-38-54" name="__codelineno-38-54" href="#__codelineno-38-54"></a><span class="w"> </span><span class="nx">geocoded</span><span class="p">,</span>
|
||
</span><span id="__span-38-55"><a id="__codelineno-38-55" name="__codelineno-38-55" href="#__codelineno-38-55"></a><span class="w"> </span><span class="nx">geocodedPercent</span><span class="o">:</span><span class="w"> </span><span class="kt">total</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">0</span><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="p">(</span><span class="nx">geocoded</span><span class="w"> </span><span class="o">/</span><span class="w"> </span><span class="nx">total</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="nx">100</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="kt">0</span><span class="p">,</span>
|
||
</span><span id="__span-38-56"><a id="__codelineno-38-56" name="__codelineno-38-56" href="#__codelineno-38-56"></a><span class="w"> </span><span class="nx">avgConfidence</span><span class="p">,</span>
|
||
</span><span id="__span-38-57"><a id="__codelineno-38-57" name="__codelineno-38-57" href="#__codelineno-38-57"></a><span class="w"> </span><span class="nx">providerBreakdown</span><span class="p">,</span>
|
||
</span><span id="__span-38-58"><a id="__codelineno-38-58" name="__codelineno-38-58" href="#__codelineno-38-58"></a><span class="w"> </span><span class="nx">confidenceDistribution</span><span class="p">,</span>
|
||
</span><span id="__span-38-59"><a id="__codelineno-38-59" name="__codelineno-38-59" href="#__codelineno-38-59"></a><span class="w"> </span><span class="nx">lowConfidenceCount</span><span class="p">,</span>
|
||
</span><span id="__span-38-60"><a id="__codelineno-38-60" name="__codelineno-38-60" href="#__codelineno-38-60"></a><span class="w"> </span><span class="nx">missingCoordinates</span><span class="o">:</span><span class="w"> </span><span class="kt">total</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="nx">geocoded</span><span class="p">,</span>
|
||
</span><span id="__span-38-61"><a id="__codelineno-38-61" name="__codelineno-38-61" href="#__codelineno-38-61"></a><span class="w"> </span><span class="nx">duplicatesCount</span>
|
||
</span><span id="__span-38-62"><a id="__codelineno-38-62" name="__codelineno-38-62" href="#__codelineno-38-62"></a><span class="w"> </span><span class="p">};</span>
|
||
</span><span id="__span-38-63"><a id="__codelineno-38-63" name="__codelineno-38-63" href="#__codelineno-38-63"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-64"><a id="__codelineno-38-64" name="__codelineno-38-64" href="#__codelineno-38-64"></a>
|
||
</span><span id="__span-38-65"><a id="__codelineno-38-65" name="__codelineno-38-65" href="#__codelineno-38-65"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">countDuplicates</span><span class="p">()</span><span class="o">:</span><span class="w"> </span><span class="nb">Promise</span><span class="o"><</span><span class="kt">number</span><span class="o">></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-66"><a id="__codelineno-38-66" name="__codelineno-38-66" href="#__codelineno-38-66"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">locations</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">findMany</span><span class="p">({</span>
|
||
</span><span id="__span-38-67"><a id="__codelineno-38-67" name="__codelineno-38-67" href="#__codelineno-38-67"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-68"><a id="__codelineno-38-68" name="__codelineno-38-68" href="#__codelineno-38-68"></a><span class="w"> </span><span class="nx">AND</span><span class="o">:</span><span class="w"> </span><span class="p">[</span>
|
||
</span><span id="__span-38-69"><a id="__codelineno-38-69" name="__codelineno-38-69" href="#__codelineno-38-69"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">not</span><span class="o">:</span><span class="w"> </span><span class="kt">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-38-70"><a id="__codelineno-38-70" name="__codelineno-38-70" href="#__codelineno-38-70"></a><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">not</span><span class="o">:</span><span class="w"> </span><span class="kt">null</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-71"><a id="__codelineno-38-71" name="__codelineno-38-71" href="#__codelineno-38-71"></a><span class="w"> </span><span class="p">]</span>
|
||
</span><span id="__span-38-72"><a id="__codelineno-38-72" name="__codelineno-38-72" href="#__codelineno-38-72"></a><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-38-73"><a id="__codelineno-38-73" name="__codelineno-38-73" href="#__codelineno-38-73"></a><span class="w"> </span><span class="nx">select</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="p">,</span><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">true</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-74"><a id="__codelineno-38-74" name="__codelineno-38-74" href="#__codelineno-38-74"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-75"><a id="__codelineno-38-75" name="__codelineno-38-75" href="#__codelineno-38-75"></a>
|
||
</span><span id="__span-38-76"><a id="__codelineno-38-76" name="__codelineno-38-76" href="#__codelineno-38-76"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">coordMap</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="nb">Map</span><span class="o"><</span><span class="kt">string</span><span class="p">,</span><span class="w"> </span><span class="kt">number</span><span class="o">></span><span class="p">();</span>
|
||
</span><span id="__span-38-77"><a id="__codelineno-38-77" name="__codelineno-38-77" href="#__codelineno-38-77"></a><span class="w"> </span><span class="nx">locations</span><span class="p">.</span><span class="nx">forEach</span><span class="p">(</span><span class="nx">l</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-78"><a id="__codelineno-38-78" name="__codelineno-38-78" href="#__codelineno-38-78"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">key</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">l</span><span class="p">.</span><span class="nx">latitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="si">}</span><span class="sb">,</span><span class="si">${</span><span class="nx">l</span><span class="p">.</span><span class="nx">longitude</span><span class="o">!</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">6</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
|
||
</span><span id="__span-38-79"><a id="__codelineno-38-79" name="__codelineno-38-79" href="#__codelineno-38-79"></a><span class="w"> </span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">set</span><span class="p">(</span><span class="nx">key</span><span class="p">,</span><span class="w"> </span><span class="p">(</span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="mf">0</span><span class="p">)</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mf">1</span><span class="p">);</span>
|
||
</span><span id="__span-38-80"><a id="__codelineno-38-80" name="__codelineno-38-80" href="#__codelineno-38-80"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-81"><a id="__codelineno-38-81" name="__codelineno-38-81" href="#__codelineno-38-81"></a>
|
||
</span><span id="__span-38-82"><a id="__codelineno-38-82" name="__codelineno-38-82" href="#__codelineno-38-82"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Array</span><span class="p">.</span><span class="kr">from</span><span class="p">(</span><span class="nx">coordMap</span><span class="p">.</span><span class="nx">values</span><span class="p">()).</span><span class="nx">filter</span><span class="p">(</span><span class="nx">count</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">count</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mf">1</span><span class="p">).</span><span class="nx">reduce</span><span class="p">((</span><span class="nx">sum</span><span class="p">,</span><span class="w"> </span><span class="nx">count</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="nx">sum</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nx">count</span><span class="p">,</span><span class="w"> </span><span class="mf">0</span><span class="p">);</span>
|
||
</span><span id="__span-38-83"><a id="__codelineno-38-83" name="__codelineno-38-83" href="#__codelineno-38-83"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-84"><a id="__codelineno-38-84" name="__codelineno-38-84" href="#__codelineno-38-84"></a>
|
||
</span><span id="__span-38-85"><a id="__codelineno-38-85" name="__codelineno-38-85" href="#__codelineno-38-85"></a><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="nx">regeocode</span><span class="p">(</span><span class="nx">locationId</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">,</span><span class="w"> </span><span class="nx">provider?</span><span class="o">:</span><span class="w"> </span><span class="kt">GeocodeProvider</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-86"><a id="__codelineno-38-86" name="__codelineno-38-86" href="#__codelineno-38-86"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">location</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">findUnique</span><span class="p">({</span>
|
||
</span><span id="__span-38-87"><a id="__codelineno-38-87" name="__codelineno-38-87" href="#__codelineno-38-87"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">locationId</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-88"><a id="__codelineno-38-88" name="__codelineno-38-88" href="#__codelineno-38-88"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-89"><a id="__codelineno-38-89" name="__codelineno-38-89" href="#__codelineno-38-89"></a>
|
||
</span><span id="__span-38-90"><a id="__codelineno-38-90" name="__codelineno-38-90" href="#__codelineno-38-90"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">location</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-91"><a id="__codelineno-38-91" name="__codelineno-38-91" href="#__codelineno-38-91"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">'Location not found'</span><span class="p">);</span>
|
||
</span><span id="__span-38-92"><a id="__codelineno-38-92" name="__codelineno-38-92" href="#__codelineno-38-92"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-93"><a id="__codelineno-38-93" name="__codelineno-38-93" href="#__codelineno-38-93"></a>
|
||
</span><span id="__span-38-94"><a id="__codelineno-38-94" name="__codelineno-38-94" href="#__codelineno-38-94"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">geocodingService</span><span class="p">.</span><span class="nx">geocode</span><span class="p">(</span><span class="nx">location</span><span class="p">.</span><span class="nx">address</span><span class="p">,</span><span class="w"> </span><span class="nx">provider</span><span class="p">);</span>
|
||
</span><span id="__span-38-95"><a id="__codelineno-38-95" name="__codelineno-38-95" href="#__codelineno-38-95"></a>
|
||
</span><span id="__span-38-96"><a id="__codelineno-38-96" name="__codelineno-38-96" href="#__codelineno-38-96"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="o">!</span><span class="nx">result</span><span class="p">)</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-97"><a id="__codelineno-38-97" name="__codelineno-38-97" href="#__codelineno-38-97"></a><span class="w"> </span><span class="k">throw</span><span class="w"> </span><span class="ow">new</span><span class="w"> </span><span class="ne">Error</span><span class="p">(</span><span class="s1">'Geocoding failed'</span><span class="p">);</span>
|
||
</span><span id="__span-38-98"><a id="__codelineno-38-98" name="__codelineno-38-98" href="#__codelineno-38-98"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-99"><a id="__codelineno-38-99" name="__codelineno-38-99" href="#__codelineno-38-99"></a>
|
||
</span><span id="__span-38-100"><a id="__codelineno-38-100" name="__codelineno-38-100" href="#__codelineno-38-100"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">update</span><span class="p">({</span>
|
||
</span><span id="__span-38-101"><a id="__codelineno-38-101" name="__codelineno-38-101" href="#__codelineno-38-101"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="kt">locationId</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-38-102"><a id="__codelineno-38-102" name="__codelineno-38-102" href="#__codelineno-38-102"></a><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-38-103"><a id="__codelineno-38-103" name="__codelineno-38-103" href="#__codelineno-38-103"></a><span class="w"> </span><span class="nx">latitude</span><span class="o">:</span><span class="w"> </span><span class="kt">result.latitude</span><span class="p">,</span>
|
||
</span><span id="__span-38-104"><a id="__codelineno-38-104" name="__codelineno-38-104" href="#__codelineno-38-104"></a><span class="w"> </span><span class="nx">longitude</span><span class="o">:</span><span class="w"> </span><span class="kt">result.longitude</span><span class="p">,</span>
|
||
</span><span id="__span-38-105"><a id="__codelineno-38-105" name="__codelineno-38-105" href="#__codelineno-38-105"></a><span class="w"> </span><span class="nx">geocodeConfidence</span><span class="o">:</span><span class="w"> </span><span class="kt">result.confidence</span><span class="p">,</span>
|
||
</span><span id="__span-38-106"><a id="__codelineno-38-106" name="__codelineno-38-106" href="#__codelineno-38-106"></a><span class="w"> </span><span class="nx">geocodeProvider</span><span class="o">:</span><span class="w"> </span><span class="kt">result.provider</span><span class="p">,</span>
|
||
</span><span id="__span-38-107"><a id="__codelineno-38-107" name="__codelineno-38-107" href="#__codelineno-38-107"></a><span class="w"> </span><span class="nx">geocodedAt</span><span class="o">:</span><span class="w"> </span><span class="kt">new</span><span class="w"> </span><span class="nb">Date</span><span class="p">()</span>
|
||
</span><span id="__span-38-108"><a id="__codelineno-38-108" name="__codelineno-38-108" href="#__codelineno-38-108"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-109"><a id="__codelineno-38-109" name="__codelineno-38-109" href="#__codelineno-38-109"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-38-110"><a id="__codelineno-38-110" name="__codelineno-38-110" href="#__codelineno-38-110"></a><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-38-111"><a id="__codelineno-38-111" name="__codelineno-38-111" href="#__codelineno-38-111"></a><span class="p">}</span>
|
||
</span></code></pre></div>
|
||
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">¶</a></h2>
|
||
<h3 id="problem-many-low-confidence-locations">Problem: Many low-confidence locations<a class="headerlink" href="#problem-many-low-confidence-locations" title="Permanent link">¶</a></h3>
|
||
<p><strong>Symptoms:</strong>
|
||
- > 100 locations with confidence < 50
|
||
- Avg confidence < 60
|
||
- Prometheus alert firing</p>
|
||
<p><strong>Solutions:</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Check provider API keys:</strong>
|
||
<div class="language-bash highlight"><pre><span></span><code><span id="__span-39-1"><a id="__codelineno-39-1" name="__codelineno-39-1" href="#__codelineno-39-1"></a><span class="c1"># Test Google Geocoding API</span>
|
||
</span><span id="__span-39-2"><a id="__codelineno-39-2" name="__codelineno-39-2" href="#__codelineno-39-2"></a>curl<span class="w"> </span><span class="s2">"https://maps.googleapis.com/maps/api/geocode/json?address=123+Main+St+Toronto&key=YOUR_KEY"</span>
|
||
</span><span id="__span-39-3"><a id="__codelineno-39-3" name="__codelineno-39-3" href="#__codelineno-39-3"></a>
|
||
</span><span id="__span-39-4"><a id="__codelineno-39-4" name="__codelineno-39-4" href="#__codelineno-39-4"></a><span class="c1"># Verify key in .env</span>
|
||
</span><span id="__span-39-5"><a id="__codelineno-39-5" name="__codelineno-39-5" href="#__codelineno-39-5"></a><span class="nb">echo</span><span class="w"> </span><span class="nv">$GEOCODE_GOOGLE_API_KEY</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Try different primary provider:</strong>
|
||
<div class="language-text highlight"><pre><span></span><code><span id="__span-40-1"><a id="__codelineno-40-1" name="__codelineno-40-1" href="#__codelineno-40-1"></a># In .env, change primary provider
|
||
</span><span id="__span-40-2"><a id="__codelineno-40-2" name="__codelineno-40-2" href="#__codelineno-40-2"></a>GEOCODE_PRIMARY_PROVIDER=GOOGLE # Most accurate
|
||
</span><span id="__span-40-3"><a id="__codelineno-40-3" name="__codelineno-40-3" href="#__codelineno-40-3"></a># Or try:
|
||
</span><span id="__span-40-4"><a id="__codelineno-40-4" name="__codelineno-40-4" href="#__codelineno-40-4"></a>GEOCODE_PRIMARY_PROVIDER=MAPBOX # Good alternative
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Verify address format:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-41-1"><a id="__codelineno-41-1" name="__codelineno-41-1" href="#__codelineno-41-1"></a><span class="c1">// Bad: Missing city/postal</span>
|
||
</span><span id="__span-41-2"><a id="__codelineno-41-2" name="__codelineno-41-2" href="#__codelineno-41-2"></a><span class="s2">"123 Main St"</span>
|
||
</span><span id="__span-41-3"><a id="__codelineno-41-3" name="__codelineno-41-3" href="#__codelineno-41-3"></a>
|
||
</span><span id="__span-41-4"><a id="__codelineno-41-4" name="__codelineno-41-4" href="#__codelineno-41-4"></a><span class="c1">// Good: Full address</span>
|
||
</span><span id="__span-41-5"><a id="__codelineno-41-5" name="__codelineno-41-5" href="#__codelineno-41-5"></a><span class="s2">"123 Main St, Toronto ON M5H 2N2"</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Use postal code for better accuracy:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-42-1"><a id="__codelineno-42-1" name="__codelineno-42-1" href="#__codelineno-42-1"></a><span class="c1">// Append postal code if available</span>
|
||
</span><span id="__span-42-2"><a id="__codelineno-42-2" name="__codelineno-42-2" href="#__codelineno-42-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">fullAddress</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nx">location</span><span class="p">.</span><span class="nx">postalCode</span>
|
||
</span><span id="__span-42-3"><a id="__codelineno-42-3" name="__codelineno-42-3" href="#__codelineno-42-3"></a><span class="w"> </span><span class="o">?</span><span class="w"> </span><span class="sb">`</span><span class="si">${</span><span class="nx">location</span><span class="p">.</span><span class="nx">address</span><span class="si">}</span><span class="sb">, </span><span class="si">${</span><span class="nx">location</span><span class="p">.</span><span class="nx">postalCode</span><span class="si">}</span><span class="sb">`</span>
|
||
</span><span id="__span-42-4"><a id="__codelineno-42-4" name="__codelineno-42-4" href="#__codelineno-42-4"></a><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="nx">location</span><span class="p">.</span><span class="nx">address</span><span class="p">;</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Bulk re-geocode with Google:</strong>
|
||
<div class="language-bash highlight"><pre><span></span><code><span id="__span-43-1"><a id="__codelineno-43-1" name="__codelineno-43-1" href="#__codelineno-43-1"></a><span class="c1"># Via API</span>
|
||
</span><span id="__span-43-2"><a id="__codelineno-43-2" name="__codelineno-43-2" href="#__codelineno-43-2"></a>curl<span class="w"> </span>-X<span class="w"> </span>POST<span class="w"> </span>http://localhost:4000/api/locations/bulk-geocode<span class="w"> </span><span class="se">\</span>
|
||
</span><span id="__span-43-3"><a id="__codelineno-43-3" name="__codelineno-43-3" href="#__codelineno-43-3"></a><span class="w"> </span>-H<span class="w"> </span><span class="s2">"Authorization: Bearer </span><span class="nv">$TOKEN</span><span class="s2">"</span><span class="w"> </span><span class="se">\</span>
|
||
</span><span id="__span-43-4"><a id="__codelineno-43-4" name="__codelineno-43-4" href="#__codelineno-43-4"></a><span class="w"> </span>-d<span class="w"> </span><span class="s1">'{"provider":"GOOGLE","confidenceThreshold":50}'</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
</ol>
|
||
<h3 id="problem-duplicate-locations-detected">Problem: Duplicate locations detected<a class="headerlink" href="#problem-duplicate-locations-detected" title="Permanent link">¶</a></h3>
|
||
<p><strong>Symptoms:</strong>
|
||
- Multiple locations at same coordinates
|
||
- Duplicates tab shows many groups
|
||
- Inflated location counts in cuts</p>
|
||
<p><strong>Solutions:</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Check if legitimately multi-unit:</strong>
|
||
<div class="language-sql highlight"><pre><span></span><code><span id="__span-44-1"><a id="__codelineno-44-1" name="__codelineno-44-1" href="#__codelineno-44-1"></a><span class="c1">-- Find buildings with multiple addresses</span>
|
||
</span><span id="__span-44-2"><a id="__codelineno-44-2" name="__codelineno-44-2" href="#__codelineno-44-2"></a><span class="k">SELECT</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">id</span><span class="p">,</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">address</span><span class="p">,</span><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">id</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">unit_count</span>
|
||
</span><span id="__span-44-3"><a id="__codelineno-44-3" name="__codelineno-44-3" href="#__codelineno-44-3"></a><span class="k">FROM</span><span class="w"> </span><span class="ss">"Location"</span><span class="w"> </span><span class="n">l</span>
|
||
</span><span id="__span-44-4"><a id="__codelineno-44-4" name="__codelineno-44-4" href="#__codelineno-44-4"></a><span class="k">JOIN</span><span class="w"> </span><span class="ss">"Address"</span><span class="w"> </span><span class="n">a</span><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="n">a</span><span class="p">.</span><span class="ss">"locationId"</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">id</span>
|
||
</span><span id="__span-44-5"><a id="__codelineno-44-5" name="__codelineno-44-5" href="#__codelineno-44-5"></a><span class="k">GROUP</span><span class="w"> </span><span class="k">BY</span><span class="w"> </span><span class="n">l</span><span class="p">.</span><span class="n">id</span>
|
||
</span><span id="__span-44-6"><a id="__codelineno-44-6" name="__codelineno-44-6" href="#__codelineno-44-6"></a><span class="k">HAVING</span><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="n">a</span><span class="p">.</span><span class="n">id</span><span class="p">)</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="mi">1</span><span class="p">;</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Verify geocoding precision:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-45-1"><a id="__codelineno-45-1" name="__codelineno-45-1" href="#__codelineno-45-1"></a><span class="c1">// Check if rounding issue</span>
|
||
</span><span id="__span-45-2"><a id="__codelineno-45-2" name="__codelineno-45-2" href="#__codelineno-45-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">isDuplicateRounding</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="nx">loc1</span><span class="p">,</span><span class="w"> </span><span class="nx">loc2</span><span class="p">)</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-45-3"><a id="__codelineno-45-3" name="__codelineno-45-3" href="#__codelineno-45-3"></a><span class="w"> </span><span class="c1">// Use 4 decimal places (~11m precision) instead of 6 (~0.1m)</span>
|
||
</span><span id="__span-45-4"><a id="__codelineno-45-4" name="__codelineno-45-4" href="#__codelineno-45-4"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">loc1</span><span class="p">.</span><span class="nx">latitude</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">4</span><span class="p">)</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">loc2</span><span class="p">.</span><span class="nx">latitude</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">4</span><span class="p">)</span><span class="w"> </span><span class="o">&&</span>
|
||
</span><span id="__span-45-5"><a id="__codelineno-45-5" name="__codelineno-45-5" href="#__codelineno-45-5"></a><span class="w"> </span><span class="nx">loc1</span><span class="p">.</span><span class="nx">longitude</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">4</span><span class="p">)</span><span class="w"> </span><span class="o">===</span><span class="w"> </span><span class="nx">loc2</span><span class="p">.</span><span class="nx">longitude</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mf">4</span><span class="p">);</span>
|
||
</span><span id="__span-45-6"><a id="__codelineno-45-6" name="__codelineno-45-6" href="#__codelineno-45-6"></a><span class="p">};</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Review NAR import process:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-46-1"><a id="__codelineno-46-1" name="__codelineno-46-1" href="#__codelineno-46-1"></a><span class="c1">// Ensure LOC_GUID unique constraint</span>
|
||
</span><span id="__span-46-2"><a id="__codelineno-46-2" name="__codelineno-46-2" href="#__codelineno-46-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">location</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">upsert</span><span class="p">({</span>
|
||
</span><span id="__span-46-3"><a id="__codelineno-46-3" name="__codelineno-46-3" href="#__codelineno-46-3"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">locGuid</span><span class="o">:</span><span class="w"> </span><span class="kt">narRecord.LOC_GUID</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-46-4"><a id="__codelineno-46-4" name="__codelineno-46-4" href="#__codelineno-46-4"></a><span class="w"> </span><span class="nx">update</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* update fields */</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-46-5"><a id="__codelineno-46-5" name="__codelineno-46-5" href="#__codelineno-46-5"></a><span class="w"> </span><span class="nx">create</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="cm">/* create fields */</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-46-6"><a id="__codelineno-46-6" name="__codelineno-46-6" href="#__codelineno-46-6"></a><span class="p">});</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Merge duplicates:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-47-1"><a id="__codelineno-47-1" name="__codelineno-47-1" href="#__codelineno-47-1"></a><span class="c1">// Merge function</span>
|
||
</span><span id="__span-47-2"><a id="__codelineno-47-2" name="__codelineno-47-2" href="#__codelineno-47-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">mergeDuplicates</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">(</span><span class="nx">primaryId</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">,</span><span class="w"> </span><span class="nx">duplicateIds</span><span class="o">:</span><span class="w"> </span><span class="kt">number</span><span class="p">[])</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-47-3"><a id="__codelineno-47-3" name="__codelineno-47-3" href="#__codelineno-47-3"></a><span class="w"> </span><span class="c1">// Move addresses to primary location</span>
|
||
</span><span id="__span-47-4"><a id="__codelineno-47-4" name="__codelineno-47-4" href="#__codelineno-47-4"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">address</span><span class="p">.</span><span class="nx">updateMany</span><span class="p">({</span>
|
||
</span><span id="__span-47-5"><a id="__codelineno-47-5" name="__codelineno-47-5" href="#__codelineno-47-5"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">locationId</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">in</span><span class="o">:</span><span class="w"> </span><span class="kt">duplicateIds</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">},</span>
|
||
</span><span id="__span-47-6"><a id="__codelineno-47-6" name="__codelineno-47-6" href="#__codelineno-47-6"></a><span class="w"> </span><span class="nx">data</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">locationId</span><span class="o">:</span><span class="w"> </span><span class="kt">primaryId</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-47-7"><a id="__codelineno-47-7" name="__codelineno-47-7" href="#__codelineno-47-7"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-47-8"><a id="__codelineno-47-8" name="__codelineno-47-8" href="#__codelineno-47-8"></a>
|
||
</span><span id="__span-47-9"><a id="__codelineno-47-9" name="__codelineno-47-9" href="#__codelineno-47-9"></a><span class="w"> </span><span class="c1">// Delete duplicates</span>
|
||
</span><span id="__span-47-10"><a id="__codelineno-47-10" name="__codelineno-47-10" href="#__codelineno-47-10"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">location</span><span class="p">.</span><span class="nx">deleteMany</span><span class="p">({</span>
|
||
</span><span id="__span-47-11"><a id="__codelineno-47-11" name="__codelineno-47-11" href="#__codelineno-47-11"></a><span class="w"> </span><span class="nx">where</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">id</span><span class="o">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nx">in</span><span class="o">:</span><span class="w"> </span><span class="kt">duplicateIds</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span>
|
||
</span><span id="__span-47-12"><a id="__codelineno-47-12" name="__codelineno-47-12" href="#__codelineno-47-12"></a><span class="w"> </span><span class="p">});</span>
|
||
</span><span id="__span-47-13"><a id="__codelineno-47-13" name="__codelineno-47-13" href="#__codelineno-47-13"></a><span class="p">};</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
</ol>
|
||
<h3 id="problem-geocoding-stats-slow-to-load">Problem: Geocoding stats slow to load<a class="headerlink" href="#problem-geocoding-stats-slow-to-load" title="Permanent link">¶</a></h3>
|
||
<p><strong>Symptoms:</strong>
|
||
- GET /api/locations/geocode-stats takes > 5 seconds
|
||
- Dashboard timeout errors
|
||
- High database CPU</p>
|
||
<p><strong>Solutions:</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Add database indexes:</strong>
|
||
<div class="language-sql highlight"><pre><span></span><code><span id="__span-48-1"><a id="__codelineno-48-1" name="__codelineno-48-1" href="#__codelineno-48-1"></a><span class="k">CREATE</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">CONCURRENTLY</span><span class="w"> </span><span class="n">idx_locations_geocode_confidence</span>
|
||
</span><span id="__span-48-2"><a id="__codelineno-48-2" name="__codelineno-48-2" href="#__codelineno-48-2"></a><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="ss">"Location"</span><span class="p">(</span><span class="n">geocodeConfidence</span><span class="p">);</span>
|
||
</span><span id="__span-48-3"><a id="__codelineno-48-3" name="__codelineno-48-3" href="#__codelineno-48-3"></a>
|
||
</span><span id="__span-48-4"><a id="__codelineno-48-4" name="__codelineno-48-4" href="#__codelineno-48-4"></a><span class="k">CREATE</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">CONCURRENTLY</span><span class="w"> </span><span class="n">idx_locations_geocode_provider</span>
|
||
</span><span id="__span-48-5"><a id="__codelineno-48-5" name="__codelineno-48-5" href="#__codelineno-48-5"></a><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="ss">"Location"</span><span class="p">(</span><span class="n">geocodeProvider</span><span class="p">);</span>
|
||
</span><span id="__span-48-6"><a id="__codelineno-48-6" name="__codelineno-48-6" href="#__codelineno-48-6"></a>
|
||
</span><span id="__span-48-7"><a id="__codelineno-48-7" name="__codelineno-48-7" href="#__codelineno-48-7"></a><span class="k">CREATE</span><span class="w"> </span><span class="k">INDEX</span><span class="w"> </span><span class="n">CONCURRENTLY</span><span class="w"> </span><span class="n">idx_locations_coords</span>
|
||
</span><span id="__span-48-8"><a id="__codelineno-48-8" name="__codelineno-48-8" href="#__codelineno-48-8"></a><span class="w"> </span><span class="k">ON</span><span class="w"> </span><span class="ss">"Location"</span><span class="p">(</span><span class="n">latitude</span><span class="p">,</span><span class="w"> </span><span class="n">longitude</span><span class="p">)</span>
|
||
</span><span id="__span-48-9"><a id="__codelineno-48-9" name="__codelineno-48-9" href="#__codelineno-48-9"></a><span class="w"> </span><span class="k">WHERE</span><span class="w"> </span><span class="n">latitude</span><span class="w"> </span><span class="k">IS</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="w"> </span><span class="k">AND</span><span class="w"> </span><span class="n">longitude</span><span class="w"> </span><span class="k">IS</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">;</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Cache stats in Redis:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-49-1"><a id="__codelineno-49-1" name="__codelineno-49-1" href="#__codelineno-49-1"></a><span class="c1">// Cache for 5 minutes</span>
|
||
</span><span id="__span-49-2"><a id="__codelineno-49-2" name="__codelineno-49-2" href="#__codelineno-49-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">getCachedStats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="p">=></span><span class="w"> </span><span class="p">{</span>
|
||
</span><span id="__span-49-3"><a id="__codelineno-49-3" name="__codelineno-49-3" href="#__codelineno-49-3"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">cached</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">get</span><span class="p">(</span><span class="s1">'geocode:stats'</span><span class="p">);</span>
|
||
</span><span id="__span-49-4"><a id="__codelineno-49-4" name="__codelineno-49-4" href="#__codelineno-49-4"></a><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nx">cached</span><span class="p">)</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">parse</span><span class="p">(</span><span class="nx">cached</span><span class="p">);</span>
|
||
</span><span id="__span-49-5"><a id="__codelineno-49-5" name="__codelineno-49-5" href="#__codelineno-49-5"></a>
|
||
</span><span id="__span-49-6"><a id="__codelineno-49-6" name="__codelineno-49-6" href="#__codelineno-49-6"></a><span class="w"> </span><span class="kd">const</span><span class="w"> </span><span class="nx">stats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">locationsService</span><span class="p">.</span><span class="nx">getGeocodeStats</span><span class="p">();</span>
|
||
</span><span id="__span-49-7"><a id="__codelineno-49-7" name="__codelineno-49-7" href="#__codelineno-49-7"></a><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">setex</span><span class="p">(</span><span class="s1">'geocode:stats'</span><span class="p">,</span><span class="w"> </span><span class="mf">300</span><span class="p">,</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">stats</span><span class="p">));</span>
|
||
</span><span id="__span-49-8"><a id="__codelineno-49-8" name="__codelineno-49-8" href="#__codelineno-49-8"></a><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nx">stats</span><span class="p">;</span>
|
||
</span><span id="__span-49-9"><a id="__codelineno-49-9" name="__codelineno-49-9" href="#__codelineno-49-9"></a><span class="p">};</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Use aggregation pipeline:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-50-1"><a id="__codelineno-50-1" name="__codelineno-50-1" href="#__codelineno-50-1"></a><span class="c1">// Raw SQL for better performance</span>
|
||
</span><span id="__span-50-2"><a id="__codelineno-50-2" name="__codelineno-50-2" href="#__codelineno-50-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">stats</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">await</span><span class="w"> </span><span class="nx">prisma</span><span class="p">.</span><span class="nx">$queryRaw</span><span class="sb">`</span>
|
||
</span><span id="__span-50-3"><a id="__codelineno-50-3" name="__codelineno-50-3" href="#__codelineno-50-3"></a><span class="sb"> SELECT</span>
|
||
</span><span id="__span-50-4"><a id="__codelineno-50-4" name="__codelineno-50-4" href="#__codelineno-50-4"></a><span class="sb"> COUNT(*) as total,</span>
|
||
</span><span id="__span-50-5"><a id="__codelineno-50-5" name="__codelineno-50-5" href="#__codelineno-50-5"></a><span class="sb"> COUNT(latitude) as geocoded,</span>
|
||
</span><span id="__span-50-6"><a id="__codelineno-50-6" name="__codelineno-50-6" href="#__codelineno-50-6"></a><span class="sb"> AVG(COALESCE("geocodeConfidence", 0)) as avg_confidence,</span>
|
||
</span><span id="__span-50-7"><a id="__codelineno-50-7" name="__codelineno-50-7" href="#__codelineno-50-7"></a><span class="sb"> "geocodeProvider",</span>
|
||
</span><span id="__span-50-8"><a id="__codelineno-50-8" name="__codelineno-50-8" href="#__codelineno-50-8"></a><span class="sb"> COUNT(*) FILTER (WHERE "geocodeConfidence" < 50) as low_confidence</span>
|
||
</span><span id="__span-50-9"><a id="__codelineno-50-9" name="__codelineno-50-9" href="#__codelineno-50-9"></a><span class="sb"> FROM "Location"</span>
|
||
</span><span id="__span-50-10"><a id="__codelineno-50-10" name="__codelineno-50-10" href="#__codelineno-50-10"></a><span class="sb"> GROUP BY "geocodeProvider"</span>
|
||
</span><span id="__span-50-11"><a id="__codelineno-50-11" name="__codelineno-50-11" href="#__codelineno-50-11"></a><span class="sb">`</span><span class="p">;</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Materialize stats view:</strong>
|
||
<div class="language-sql highlight"><pre><span></span><code><span id="__span-51-1"><a id="__codelineno-51-1" name="__codelineno-51-1" href="#__codelineno-51-1"></a><span class="c1">-- Create materialized view</span>
|
||
</span><span id="__span-51-2"><a id="__codelineno-51-2" name="__codelineno-51-2" href="#__codelineno-51-2"></a><span class="k">CREATE</span><span class="w"> </span><span class="n">MATERIALIZED</span><span class="w"> </span><span class="k">VIEW</span><span class="w"> </span><span class="n">geocode_stats_mv</span><span class="w"> </span><span class="k">AS</span>
|
||
</span><span id="__span-51-3"><a id="__codelineno-51-3" name="__codelineno-51-3" href="#__codelineno-51-3"></a><span class="k">SELECT</span>
|
||
</span><span id="__span-51-4"><a id="__codelineno-51-4" name="__codelineno-51-4" href="#__codelineno-51-4"></a><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">total</span><span class="p">,</span>
|
||
</span><span id="__span-51-5"><a id="__codelineno-51-5" name="__codelineno-51-5" href="#__codelineno-51-5"></a><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="n">latitude</span><span class="p">)</span><span class="w"> </span><span class="n">FILTER</span><span class="w"> </span><span class="p">(</span><span class="k">WHERE</span><span class="w"> </span><span class="n">latitude</span><span class="w"> </span><span class="k">IS</span><span class="w"> </span><span class="k">NOT</span><span class="w"> </span><span class="k">NULL</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">geocoded</span><span class="p">,</span>
|
||
</span><span id="__span-51-6"><a id="__codelineno-51-6" name="__codelineno-51-6" href="#__codelineno-51-6"></a><span class="w"> </span><span class="k">AVG</span><span class="p">(</span><span class="k">COALESCE</span><span class="p">(</span><span class="ss">"geocodeConfidence"</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">))</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">avg_confidence</span><span class="p">,</span>
|
||
</span><span id="__span-51-7"><a id="__codelineno-51-7" name="__codelineno-51-7" href="#__codelineno-51-7"></a><span class="w"> </span><span class="k">COUNT</span><span class="p">(</span><span class="o">*</span><span class="p">)</span><span class="w"> </span><span class="n">FILTER</span><span class="w"> </span><span class="p">(</span><span class="k">WHERE</span><span class="w"> </span><span class="ss">"geocodeConfidence"</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="mi">50</span><span class="p">)</span><span class="w"> </span><span class="k">as</span><span class="w"> </span><span class="n">low_confidence</span>
|
||
</span><span id="__span-51-8"><a id="__codelineno-51-8" name="__codelineno-51-8" href="#__codelineno-51-8"></a><span class="k">FROM</span><span class="w"> </span><span class="ss">"Location"</span><span class="p">;</span>
|
||
</span><span id="__span-51-9"><a id="__codelineno-51-9" name="__codelineno-51-9" href="#__codelineno-51-9"></a>
|
||
</span><span id="__span-51-10"><a id="__codelineno-51-10" name="__codelineno-51-10" href="#__codelineno-51-10"></a><span class="c1">-- Refresh hourly</span>
|
||
</span><span id="__span-51-11"><a id="__codelineno-51-11" name="__codelineno-51-11" href="#__codelineno-51-11"></a><span class="n">REFRESH</span><span class="w"> </span><span class="n">MATERIALIZED</span><span class="w"> </span><span class="k">VIEW</span><span class="w"> </span><span class="n">geocode_stats_mv</span><span class="p">;</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
</ol>
|
||
<h2 id="performance-considerations">Performance Considerations<a class="headerlink" href="#performance-considerations" title="Permanent link">¶</a></h2>
|
||
<h3 id="database-query-optimization">Database Query Optimization<a class="headerlink" href="#database-query-optimization" title="Permanent link">¶</a></h3>
|
||
<p><strong>Indexes:</strong>
|
||
- <code>geocodeConfidence</code> (filtering)
|
||
- <code>geocodeProvider</code> (grouping)
|
||
- <code>(latitude, longitude)</code> composite (duplicate detection)
|
||
- Partial index on non-null coordinates</p>
|
||
<p><strong>Query Performance:</strong>
|
||
- geocode-stats: ~500ms (1500 locations)
|
||
- Low confidence filter: ~100ms (with index)
|
||
- Duplicate detection: ~200ms (coordinate grouping)
|
||
- Bulk re-geocode: ~2-5 min (150 locations, depends on provider)</p>
|
||
<h3 id="api-rate-limits">API Rate Limits<a class="headerlink" href="#api-rate-limits" title="Permanent link">¶</a></h3>
|
||
<p><strong>Provider Limits:</strong>
|
||
- Google: 50 QPS, $5/1000 requests
|
||
- Mapbox: 100,000/month free, then $0.50/1000
|
||
- Nominatim: 1 QPS (public), no commercial use
|
||
- Photon: No official limit, self-hosted recommended
|
||
- ArcGIS: 100,000/month free</p>
|
||
<p><strong>Optimization:</strong>
|
||
- Use Redis cache (30-day TTL)
|
||
- Batch geocoding jobs (avoid rate limits)
|
||
- Fallback to free providers for non-critical
|
||
- Monitor usage via provider dashboards</p>
|
||
<h3 id="caching-strategy">Caching Strategy<a class="headerlink" href="#caching-strategy" title="Permanent link">¶</a></h3>
|
||
<p><strong>Cache Layers:</strong></p>
|
||
<ol>
|
||
<li>
|
||
<p><strong>Application Cache (Redis):</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-52-1"><a id="__codelineno-52-1" name="__codelineno-52-1" href="#__codelineno-52-1"></a><span class="c1">// 30-day TTL for geocode results</span>
|
||
</span><span id="__span-52-2"><a id="__codelineno-52-2" name="__codelineno-52-2" href="#__codelineno-52-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">cacheKey</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="sb">`geocode:</span><span class="si">${</span><span class="nx">normalizeAddress</span><span class="p">(</span><span class="nx">address</span><span class="p">)</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
|
||
</span><span id="__span-52-3"><a id="__codelineno-52-3" name="__codelineno-52-3" href="#__codelineno-52-3"></a><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">setex</span><span class="p">(</span><span class="nx">cacheKey</span><span class="p">,</span><span class="w"> </span><span class="mf">2592000</span><span class="p">,</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">result</span><span class="p">));</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Statistics Cache:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-53-1"><a id="__codelineno-53-1" name="__codelineno-53-1" href="#__codelineno-53-1"></a><span class="c1">// 5-minute TTL for stats</span>
|
||
</span><span id="__span-53-2"><a id="__codelineno-53-2" name="__codelineno-53-2" href="#__codelineno-53-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">setex</span><span class="p">(</span><span class="s1">'geocode:stats'</span><span class="p">,</span><span class="w"> </span><span class="mf">300</span><span class="p">,</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">stats</span><span class="p">));</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Provider Response Cache:</strong>
|
||
<div class="language-typescript highlight"><pre><span></span><code><span id="__span-54-1"><a id="__codelineno-54-1" name="__codelineno-54-1" href="#__codelineno-54-1"></a><span class="c1">// Cache raw provider responses separately</span>
|
||
</span><span id="__span-54-2"><a id="__codelineno-54-2" name="__codelineno-54-2" href="#__codelineno-54-2"></a><span class="k">await</span><span class="w"> </span><span class="nx">redis</span><span class="p">.</span><span class="nx">setex</span><span class="p">(</span><span class="sb">`provider:</span><span class="si">${</span><span class="nx">provider</span><span class="si">}</span><span class="sb">:</span><span class="si">${</span><span class="nx">address</span><span class="si">}</span><span class="sb">`</span><span class="p">,</span><span class="w"> </span><span class="mf">604800</span><span class="p">,</span><span class="w"> </span><span class="nb">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">(</span><span class="nx">rawResponse</span><span class="p">));</span>
|
||
</span></code></pre></div></p>
|
||
</li>
|
||
</ol>
|
||
<p><strong>Cache Hit Rates:</strong>
|
||
- Geocoding: 90%+ (repeated addresses)
|
||
- Statistics: 95%+ (frequent dashboard views)
|
||
- Provider responses: 85%+ (re-geocoding attempts)</p>
|
||
<h2 id="related-documentation">Related Documentation<a class="headerlink" href="#related-documentation" title="Permanent link">¶</a></h2>
|
||
<h3 id="backend-documentation">Backend Documentation<a class="headerlink" href="#backend-documentation" title="Permanent link">¶</a></h3>
|
||
<ul>
|
||
<li><strong>Locations Service:</strong> <code>api/src/modules/map/locations/locations.service.ts</code></li>
|
||
<li>Geocode stats aggregation</li>
|
||
<li>Duplicate detection</li>
|
||
<li>
|
||
<p>Re-geocoding operations</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Geocoding Service:</strong> <code>api/src/modules/map/geocoding/geocoding.service.ts</code></p>
|
||
</li>
|
||
<li>Multi-provider fallback</li>
|
||
<li>Confidence calculation</li>
|
||
<li>
|
||
<p>Cache integration</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Bulk Geocoding:</strong> <code>api/src/modules/map/locations/bulk-geocode.routes.ts</code></p>
|
||
</li>
|
||
<li>Job queue integration</li>
|
||
<li>Progress tracking</li>
|
||
<li>Error handling</li>
|
||
</ul>
|
||
<h3 id="frontend-documentation">Frontend Documentation<a class="headerlink" href="#frontend-documentation" title="Permanent link">¶</a></h3>
|
||
<ul>
|
||
<li><strong>Data Quality Dashboard:</strong> <code>admin/src/pages/DataQualityDashboardPage.tsx</code></li>
|
||
<li>Statistics display</li>
|
||
<li>Charts and tables</li>
|
||
<li>
|
||
<p>Bulk actions</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Locations Page:</strong> <code>admin/src/pages/LocationsPage.tsx</code></p>
|
||
</li>
|
||
<li>CSV import/export</li>
|
||
<li>Inline geocoding</li>
|
||
<li>Address editing</li>
|
||
</ul>
|
||
<h3 id="database-documentation">Database Documentation<a class="headerlink" href="#database-documentation" title="Permanent link">¶</a></h3>
|
||
<ul>
|
||
<li><strong>Location Model:</strong> <code>api/prisma/schema.prisma</code></li>
|
||
<li>Geocoding metadata fields</li>
|
||
<li>Indexes for performance</li>
|
||
<li>Relations to Address</li>
|
||
</ul>
|
||
<h3 id="monitoring-documentation">Monitoring Documentation<a class="headerlink" href="#monitoring-documentation" title="Permanent link">¶</a></h3>
|
||
<ul>
|
||
<li><strong>Prometheus Metrics:</strong> <code>api/src/utils/metrics.ts</code></li>
|
||
<li>Custom geocoding metrics</li>
|
||
<li>Quality gauges</li>
|
||
<li>
|
||
<p>Alert integration</p>
|
||
</li>
|
||
<li>
|
||
<p><strong>Grafana Dashboard:</strong> <code>configs/grafana/dashboards/data-quality.json</code></p>
|
||
</li>
|
||
<li>Quality trend charts</li>
|
||
<li>Provider comparison</li>
|
||
<li>Alert visualization</li>
|
||
</ul>
|
||
<h3 id="external-resources">External Resources<a class="headerlink" href="#external-resources" title="Permanent link">¶</a></h3>
|
||
<ul>
|
||
<li><strong>Google Geocoding API:</strong> https://developers.google.com/maps/documentation/geocoding</li>
|
||
<li><strong>Mapbox Geocoding API:</strong> https://docs.mapbox.com/api/search/geocoding</li>
|
||
<li><strong>Nominatim API:</strong> https://nominatim.org/release-docs/latest/api/Search</li>
|
||
<li><strong>Photon API:</strong> https://photon.komoot.io</li>
|
||
</ul>
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
|
||
</article>
|
||
</div>
|
||
|
||
|
||
<script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script>
|
||
</div>
|
||
|
||
<button type="button" class="md-top md-icon" data-md-component="top" hidden>
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg>
|
||
Back to top
|
||
</button>
|
||
|
||
</main>
|
||
|
||
<footer class="md-footer">
|
||
|
||
|
||
|
||
<nav class="md-footer__inner md-grid" aria-label="Footer" >
|
||
|
||
|
||
<a href="../nar-import/" class="md-footer__link md-footer__link--prev" aria-label="Previous: NAR Import">
|
||
<div class="md-footer__button md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M20 11v2H8l5.5 5.5-1.42 1.42L4.16 12l7.92-7.92L13.5 5.5 8 11z"/></svg>
|
||
</div>
|
||
<div class="md-footer__title">
|
||
<span class="md-footer__direction">
|
||
Previous
|
||
</span>
|
||
<div class="md-ellipsis">
|
||
NAR Import
|
||
</div>
|
||
</div>
|
||
</a>
|
||
|
||
|
||
|
||
<a href="../../landing-pages/" class="md-footer__link md-footer__link--next" aria-label="Next: Landing Pages (Page Builder)">
|
||
<div class="md-footer__title">
|
||
<span class="md-footer__direction">
|
||
Next
|
||
</span>
|
||
<div class="md-ellipsis">
|
||
Landing Pages (Page Builder)
|
||
</div>
|
||
</div>
|
||
<div class="md-footer__button md-icon">
|
||
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M4 11v2h12l-5.5 5.5 1.42 1.42L19.84 12l-7.92-7.92L10.5 5.5 16 11z"/></svg>
|
||
</div>
|
||
</a>
|
||
|
||
</nav>
|
||
|
||
|
||
<div class="md-footer-meta md-typeset">
|
||
<div class="md-footer-meta__inner md-grid">
|
||
<div class="md-copyright">
|
||
|
||
<div class="md-copyright__highlight">
|
||
Copyright © 2024 The Bunker Operations – <a href="#__consent">Change cookie settings</a>
|
||
|
||
</div>
|
||
|
||
|
||
</div>
|
||
|
||
|
||
<div class="md-social">
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://gitea.bnkops.com/admin" target="_blank" rel="noopener" title="Gitea Repository" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg>
|
||
</a>
|
||
|
||
|
||
|
||
|
||
|
||
<a href="https://listmonk.bnkops.com/subscription/form" target="_blank" rel="noopener" title="Newsletter" class="md-social__link">
|
||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 576 512"><!--! Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M536.4-26.3c9.8-3.5 20.6-1 28 6.3s9.8 18.2 6.3 28l-178 496.9c-5 13.9-18.1 23.1-32.8 23.1-14.2 0-27-8.6-32.3-21.7l-64.2-158c-4.5-11-2.5-23.6 5.2-32.6l94.5-112.4c5.1-6.1 4.7-15-.9-20.6s-14.6-6-20.6-.9l-112.4 94.3c-9.1 7.6-21.6 9.6-32.6 5.2L38.1 216.8c-13.1-5.3-21.7-18.1-21.7-32.3 0-14.7 9.2-27.8 23.1-32.8z"/></svg>
|
||
</a>
|
||
|
||
</div>
|
||
|
||
</div>
|
||
</div>
|
||
</footer>
|
||
|
||
</div>
|
||
<div class="md-dialog" data-md-component="dialog">
|
||
<div class="md-dialog__inner md-typeset"></div>
|
||
</div>
|
||
|
||
|
||
|
||
|
||
|
||
<script id="__config" type="application/json">{"annotate": null, "base": "../../../..", "features": ["announce.dismiss", "content.action.edit", "content.action.view", "content.code.annotate", "content.code.copy", "content.tooltips", "navigation.expand", "navigation.footer", "navigation.indexes", "navigation.path", "navigation.prune", "navigation.sections", "navigation.tabs", "navigation.tabs.sticky", "navigation.top", "navigation.tracking", "search.highlight", "search.share", "search.suggest", "toc.follow"], "search": "../../../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": null}</script>
|
||
|
||
|
||
<script src="../../../../assets/javascripts/bundle.79ae519e.min.js"></script>
|
||
|
||
<script src="../../../../javascripts/home.js"></script>
|
||
|
||
<script src="../../../../javascripts/github-widget.js"></script>
|
||
|
||
<script src="../../../../javascripts/gitea-widget.js"></script>
|
||
|
||
<script src="../../../../assets/js/env-config.js"></script>
|
||
|
||
<script src="../../../../assets/js/video-player.js"></script>
|
||
|
||
|
||
</body>
|
||
</html> |