6997 lines
160 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!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/migration/feature-parity/">
<link rel="prev" href="../">
<link rel="next" href="../breaking-changes/">
<link rel="icon" href="../../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.7.1">
<title>Feature Parity - 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="Feature Parity - 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/migration/feature-parity.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/migration/feature-parity/" />
<meta property="twitter:card" content="summary_large_image" />
<meta property="twitter:title" content="Feature Parity - 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/migration/feature-parity.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="#feature-parity-v1-vs-v2" 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">
Feature Parity
</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--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle md-toggle--indeterminate" type="checkbox" id="__nav_2_7" >
<div class="md-nav__link md-nav__container">
<a href="../../features/" 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="false">
<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="../../features/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--pruned md-nav__item--nested">
<a href="../../features/map/" class="md-nav__link">
<span class="md-ellipsis">
Map
</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="../../features/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="../../features/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="../../features/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="../../features/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="../../features/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="../../features/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--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_2_13" checked>
<div class="md-nav__link md-nav__container">
<a href="../" 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="true">
<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 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">
Feature Parity
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Feature Parity
</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="#feature-comparison-matrix" class="md-nav__link">
<span class="md-ellipsis">
Feature Comparison Matrix
</span>
</a>
<nav class="md-nav" aria-label="Feature Comparison Matrix">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#core-features" class="md-nav__link">
<span class="md-ellipsis">
Core Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#map-features" class="md-nav__link">
<span class="md-ellipsis">
Map Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#canvassing-features" class="md-nav__link">
<span class="md-ellipsis">
Canvassing Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#content-management" class="md-nav__link">
<span class="md-ellipsis">
Content Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#media-management" class="md-nav__link">
<span class="md-ellipsis">
Media Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#email-newsletters" class="md-nav__link">
<span class="md-ellipsis">
Email &amp; Newsletters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#monitoring-devops" class="md-nav__link">
<span class="md-ellipsis">
Monitoring &amp; DevOps
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#platform-services" class="md-nav__link">
<span class="md-ellipsis">
Platform Services
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#detailed-feature-comparisons" class="md-nav__link">
<span class="md-ellipsis">
Detailed Feature Comparisons
</span>
</a>
<nav class="md-nav" aria-label="Detailed Feature Comparisons">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-email-advocacy-campaigns" class="md-nav__link">
<span class="md-ellipsis">
1. Email Advocacy Campaigns
</span>
</a>
<nav class="md-nav" aria-label="1. Email Advocacy Campaigns">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#2-representative-lookup" class="md-nav__link">
<span class="md-ellipsis">
2. Representative Lookup
</span>
</a>
<nav class="md-nav" aria-label="2. Representative Lookup">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation_1" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation_1" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#3-location-management-geocoding" class="md-nav__link">
<span class="md-ellipsis">
3. Location Management &amp; Geocoding
</span>
</a>
<nav class="md-nav" aria-label="3. Location Management &amp; Geocoding">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation_2" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation_2" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#4-volunteer-shifts" class="md-nav__link">
<span class="md-ellipsis">
4. Volunteer Shifts
</span>
</a>
<nav class="md-nav" aria-label="4. Volunteer Shifts">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation_3" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation_3" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#5-canvassing-system-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
5. Canvassing System (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="5. Canvassing System (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#6-landing-page-builder-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
6. Landing Page Builder (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="6. Landing Page Builder (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_1" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#7-email-templates-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
7. Email Templates (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="7. Email Templates (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_2" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#8-media-library-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
8. Media Library (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="8. Media Library (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_3" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#9-monitoring-stack-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
9. Monitoring Stack (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="9. Monitoring Stack (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_4" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#feature-status-summary" class="md-nav__link">
<span class="md-ellipsis">
Feature Status Summary
</span>
</a>
<nav class="md-nav" aria-label="Feature Status Summary">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-features-in-v2" class="md-nav__link">
<span class="md-ellipsis">
V1 Features in V2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v1-features-not-in-v2" class="md-nav__link">
<span class="md-ellipsis">
V1 Features NOT in V2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-only-features" class="md-nav__link">
<span class="md-ellipsis">
V2-Only Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#migration-priority" class="md-nav__link">
<span class="md-ellipsis">
Migration Priority
</span>
</a>
<nav class="md-nav" aria-label="Migration Priority">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-critical-must-migrate-first" class="md-nav__link">
<span class="md-ellipsis">
1. Critical (Must Migrate First)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-high-priority-migrate-early" class="md-nav__link">
<span class="md-ellipsis">
2. High Priority (Migrate Early)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-medium-priority-migrate-mid-phase" class="md-nav__link">
<span class="md-ellipsis">
3. Medium Priority (Migrate Mid-Phase)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-low-priority-migrate-later" class="md-nav__link">
<span class="md-ellipsis">
4. Low Priority (Migrate Later)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-optional-new-v2-features" class="md-nav__link">
<span class="md-ellipsis">
5. Optional (New V2 Features)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#workarounds-for-missing-features" class="md-nav__link">
<span class="md-ellipsis">
Workarounds for Missing Features
</span>
</a>
<nav class="md-nav" aria-label="Workarounds for Missing Features">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-run-v1-and-v2-in-parallel" class="md-nav__link">
<span class="md-ellipsis">
1. Run V1 and V2 in Parallel
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-manual-data-entry" class="md-nav__link">
<span class="md-ellipsis">
2. Manual Data Entry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-custom-migration-scripts" class="md-nav__link">
<span class="md-ellipsis">
3. Custom Migration Scripts
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#future-roadmap" class="md-nav__link">
<span class="md-ellipsis">
Future Roadmap
</span>
</a>
<nav class="md-nav" aria-label="Future Roadmap">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#planned-for-v2-phase-15" class="md-nav__link">
<span class="md-ellipsis">
Planned for V2 Phase 15+
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#community-feature-requests" class="md-nav__link">
<span class="md-ellipsis">
Community Feature Requests
</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>
</li>
<li class="md-nav__item">
<a href="#next-steps" class="md-nav__link">
<span class="md-ellipsis">
Next Steps
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../breaking-changes/" class="md-nav__link">
<span class="md-ellipsis">
Breaking Changes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../api-changes/" class="md-nav__link">
<span class="md-ellipsis">
API Changes
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../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="#feature-comparison-matrix" class="md-nav__link">
<span class="md-ellipsis">
Feature Comparison Matrix
</span>
</a>
<nav class="md-nav" aria-label="Feature Comparison Matrix">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#core-features" class="md-nav__link">
<span class="md-ellipsis">
Core Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#map-features" class="md-nav__link">
<span class="md-ellipsis">
Map Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#canvassing-features" class="md-nav__link">
<span class="md-ellipsis">
Canvassing Features
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#content-management" class="md-nav__link">
<span class="md-ellipsis">
Content Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#media-management" class="md-nav__link">
<span class="md-ellipsis">
Media Management
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#email-newsletters" class="md-nav__link">
<span class="md-ellipsis">
Email &amp; Newsletters
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#monitoring-devops" class="md-nav__link">
<span class="md-ellipsis">
Monitoring &amp; DevOps
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#platform-services" class="md-nav__link">
<span class="md-ellipsis">
Platform Services
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#detailed-feature-comparisons" class="md-nav__link">
<span class="md-ellipsis">
Detailed Feature Comparisons
</span>
</a>
<nav class="md-nav" aria-label="Detailed Feature Comparisons">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-email-advocacy-campaigns" class="md-nav__link">
<span class="md-ellipsis">
1. Email Advocacy Campaigns
</span>
</a>
<nav class="md-nav" aria-label="1. Email Advocacy Campaigns">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#2-representative-lookup" class="md-nav__link">
<span class="md-ellipsis">
2. Representative Lookup
</span>
</a>
<nav class="md-nav" aria-label="2. Representative Lookup">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation_1" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation_1" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#3-location-management-geocoding" class="md-nav__link">
<span class="md-ellipsis">
3. Location Management &amp; Geocoding
</span>
</a>
<nav class="md-nav" aria-label="3. Location Management &amp; Geocoding">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation_2" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation_2" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#4-volunteer-shifts" class="md-nav__link">
<span class="md-ellipsis">
4. Volunteer Shifts
</span>
</a>
<nav class="md-nav" aria-label="4. Volunteer Shifts">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-implementation_3" class="md-nav__link">
<span class="md-ellipsis">
V1 Implementation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-implementation_3" class="md-nav__link">
<span class="md-ellipsis">
V2 Implementation
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#5-canvassing-system-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
5. Canvassing System (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="5. Canvassing System (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#6-landing-page-builder-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
6. Landing Page Builder (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="6. Landing Page Builder (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_1" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#7-email-templates-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
7. Email Templates (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="7. Email Templates (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_2" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#8-media-library-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
8. Media Library (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="8. Media Library (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_3" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#9-monitoring-stack-new-in-v2" class="md-nav__link">
<span class="md-ellipsis">
9. Monitoring Stack (New in V2)
</span>
</a>
<nav class="md-nav" aria-label="9. Monitoring Stack (New in V2)">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v2-features_4" class="md-nav__link">
<span class="md-ellipsis">
V2 Features
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#feature-status-summary" class="md-nav__link">
<span class="md-ellipsis">
Feature Status Summary
</span>
</a>
<nav class="md-nav" aria-label="Feature Status Summary">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#v1-features-in-v2" class="md-nav__link">
<span class="md-ellipsis">
V1 Features in V2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v1-features-not-in-v2" class="md-nav__link">
<span class="md-ellipsis">
V1 Features NOT in V2
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#v2-only-features" class="md-nav__link">
<span class="md-ellipsis">
V2-Only Features
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#migration-priority" class="md-nav__link">
<span class="md-ellipsis">
Migration Priority
</span>
</a>
<nav class="md-nav" aria-label="Migration Priority">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-critical-must-migrate-first" class="md-nav__link">
<span class="md-ellipsis">
1. Critical (Must Migrate First)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-high-priority-migrate-early" class="md-nav__link">
<span class="md-ellipsis">
2. High Priority (Migrate Early)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-medium-priority-migrate-mid-phase" class="md-nav__link">
<span class="md-ellipsis">
3. Medium Priority (Migrate Mid-Phase)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-low-priority-migrate-later" class="md-nav__link">
<span class="md-ellipsis">
4. Low Priority (Migrate Later)
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#5-optional-new-v2-features" class="md-nav__link">
<span class="md-ellipsis">
5. Optional (New V2 Features)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#workarounds-for-missing-features" class="md-nav__link">
<span class="md-ellipsis">
Workarounds for Missing Features
</span>
</a>
<nav class="md-nav" aria-label="Workarounds for Missing Features">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-run-v1-and-v2-in-parallel" class="md-nav__link">
<span class="md-ellipsis">
1. Run V1 and V2 in Parallel
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-manual-data-entry" class="md-nav__link">
<span class="md-ellipsis">
2. Manual Data Entry
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-custom-migration-scripts" class="md-nav__link">
<span class="md-ellipsis">
3. Custom Migration Scripts
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#future-roadmap" class="md-nav__link">
<span class="md-ellipsis">
Future Roadmap
</span>
</a>
<nav class="md-nav" aria-label="Future Roadmap">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#planned-for-v2-phase-15" class="md-nav__link">
<span class="md-ellipsis">
Planned for V2 Phase 15+
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#community-feature-requests" class="md-nav__link">
<span class="md-ellipsis">
Community Feature Requests
</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>
</li>
<li class="md-nav__item">
<a href="#next-steps" class="md-nav__link">
<span class="md-ellipsis">
Next Steps
</span>
</a>
</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">
Migration
</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/migration/feature-parity.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/migration/feature-parity.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="feature-parity-v1-vs-v2">Feature Parity: V1 vs V2<a class="headerlink" href="#feature-parity-v1-vs-v2" title="Permanent link">&para;</a></h1>
<p>This document provides a comprehensive comparison of features between Changemaker Lite V1 and V2, including feature status, implementation differences, and migration priorities.</p>
<h2 id="overview">Overview<a class="headerlink" href="#overview" title="Permanent link">&para;</a></h2>
<p>V2 achieves <strong>100% feature parity</strong> with V1 core functionality and adds significant new capabilities. Some V1 features are implemented differently (better!) in V2.</p>
<div class="admonition success">
<p class="admonition-title">V2 Feature Status</p>
<ul>
<li><strong>✅ All V1 Core Features</strong>: Campaigns, locations, shifts, response wall</li>
<li><strong>✅ Enhanced Features</strong>: Multi-provider geocoding, canvassing with GPS, monitoring</li>
<li><strong>✅ New Features</strong>: Landing pages, email templates, media library, NAR import</li>
</ul>
</div>
<h2 id="feature-comparison-matrix">Feature Comparison Matrix<a class="headerlink" href="#feature-comparison-matrix" title="Permanent link">&para;</a></h2>
<h3 id="core-features">Core Features<a class="headerlink" href="#core-features" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Email Advocacy Campaigns</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds BullMQ queue, Listmonk sync</td>
</tr>
<tr>
<td><strong>Representative Lookup</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds caching, multi-level support</td>
</tr>
<tr>
<td><strong>Response Wall</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds moderation, upvoting, verification</td>
</tr>
<tr>
<td><strong>Location Management</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds structured address, geocoding quality</td>
</tr>
<tr>
<td><strong>Geocoding</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V1: Nominatim only → V2: 6 providers</td>
</tr>
<tr>
<td><strong>Volunteer Shifts</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds cut assignments, status tracking</td>
</tr>
<tr>
<td><strong>Public Shift Signup</strong></td>
<td></td>
<td></td>
<td>Same</td>
<td>V2 creates temp users automatically</td>
</tr>
<tr>
<td><strong>User Management</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds unified user model, RBAC</td>
</tr>
<tr>
<td><strong>Admin Authentication</strong></td>
<td></td>
<td></td>
<td>Changed</td>
<td>V1: Sessions → V2: JWT</td>
</tr>
</tbody>
</table>
<h3 id="map-features">Map Features<a class="headerlink" href="#map-features" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Location Map (Public)</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds color-coded markers, cut overlays</td>
</tr>
<tr>
<td><strong>Location Map (Admin)</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds click-to-add, move mode, geolocate</td>
</tr>
<tr>
<td><strong>Cuts (Territories)</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds drawing mode, point-in-polygon</td>
</tr>
<tr>
<td><strong>CSV Import/Export</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds flexible column mapping</td>
</tr>
<tr>
<td><strong>Bulk Geocoding</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds bulk geocode endpoint</td>
</tr>
<tr>
<td><strong>Reverse Geocoding</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds lat/lng → address lookup</td>
</tr>
<tr>
<td><strong>Walk Sheets</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds printable walk sheets with QR codes</td>
</tr>
<tr>
<td><strong>Cut Export</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds printable location reports</td>
</tr>
<tr>
<td><strong>NAR Import</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds Canadian electoral data import</td>
</tr>
<tr>
<td><strong>Data Quality Dashboard</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds geocoding quality metrics</td>
</tr>
</tbody>
</table>
<h3 id="canvassing-features">Canvassing Features<a class="headerlink" href="#canvassing-features" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Canvassing System</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds full canvassing workflow</td>
</tr>
<tr>
<td><strong>GPS Tracking</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds volunteer GPS trail recording</td>
</tr>
<tr>
<td><strong>Walking Routes</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds optimized route algorithm</td>
</tr>
<tr>
<td><strong>Visit Recording</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds outcome tracking, notes</td>
</tr>
<tr>
<td><strong>Canvass Dashboard</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds admin analytics, leaderboards</td>
</tr>
<tr>
<td><strong>Volunteer Portal</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds dedicated volunteer interface</td>
</tr>
<tr>
<td><strong>Activity History</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds visit history, stats</td>
</tr>
</tbody>
</table>
<h3 id="content-management">Content Management<a class="headerlink" href="#content-management" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Landing Page Builder</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds GrapesJS editor</td>
</tr>
<tr>
<td><strong>Block Library</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds reusable content blocks</td>
</tr>
<tr>
<td><strong>MkDocs Export</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds static site generation</td>
</tr>
<tr>
<td><strong>Email Templates</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds template system with versioning</td>
</tr>
<tr>
<td><strong>Template Variables</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds dynamic content substitution</td>
</tr>
</tbody>
</table>
<h3 id="media-management">Media Management<a class="headerlink" href="#media-management" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Video Library</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds video CRUD, categories</td>
</tr>
<tr>
<td><strong>Video Upload</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds upload with metadata extraction</td>
</tr>
<tr>
<td><strong>Public Gallery</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds public video gallery</td>
</tr>
<tr>
<td><strong>Reactions</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds 6 emoji reactions</td>
</tr>
<tr>
<td><strong>Video Sharing</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds lock/unlock system</td>
</tr>
</tbody>
</table>
<h3 id="email-newsletters">Email &amp; Newsletters<a class="headerlink" href="#email-newsletters" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>SMTP Email Sending</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds BullMQ queue, test mode</td>
</tr>
<tr>
<td><strong>Email Queue</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V1: Bull → V2: BullMQ with monitoring</td>
</tr>
<tr>
<td><strong>Email Tracking</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds sent/failed stats per campaign</td>
</tr>
<tr>
<td><strong>Listmonk Integration</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds newsletter sync</td>
</tr>
<tr>
<td><strong>Subscriber Management</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds campaign participant → list sync</td>
</tr>
</tbody>
</table>
<h3 id="monitoring-devops">Monitoring &amp; DevOps<a class="headerlink" href="#monitoring-devops" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>Prometheus Metrics</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds 12 custom <code>cm_*</code> metrics</td>
</tr>
<tr>
<td><strong>Grafana Dashboards</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds 3 pre-configured dashboards</td>
</tr>
<tr>
<td><strong>Alertmanager</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds alert rules, Gotify integration</td>
</tr>
<tr>
<td><strong>Health Checks</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds Docker healthchecks (7 services)</td>
</tr>
<tr>
<td><strong>Backup Script</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds PostgreSQL + Listmonk + uploads</td>
</tr>
<tr>
<td><strong>Observability Dashboard</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds admin observability page</td>
</tr>
</tbody>
</table>
<h3 id="platform-services">Platform Services<a class="headerlink" href="#platform-services" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V1</th>
<th>V2</th>
<th>Status</th>
<th>Notes</th>
</tr>
</thead>
<tbody>
<tr>
<td><strong>NocoDB</strong></td>
<td>✅ (data layer)</td>
<td>✅ (read-only)</td>
<td>Changed</td>
<td>V2 uses Prisma, NocoDB for browsing</td>
</tr>
<tr>
<td><strong>Redis</strong></td>
<td></td>
<td></td>
<td>Enhanced</td>
<td>V2 adds authentication required</td>
</tr>
<tr>
<td><strong>PostgreSQL</strong></td>
<td>✅ (NocoDB)</td>
<td>✅ (direct)</td>
<td>Enhanced</td>
<td>V2 uses PostgreSQL 16 directly</td>
</tr>
<tr>
<td><strong>MkDocs</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds documentation site</td>
</tr>
<tr>
<td><strong>Code Server</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds web-based IDE</td>
</tr>
<tr>
<td><strong>n8n</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds workflow automation</td>
</tr>
<tr>
<td><strong>Gitea</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds Git repository hosting</td>
</tr>
<tr>
<td><strong>Homepage</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds service dashboard</td>
</tr>
<tr>
<td><strong>Pangolin Tunnel</strong></td>
<td></td>
<td></td>
<td>New</td>
<td>V2 adds self-hosted tunnel alternative</td>
</tr>
<tr>
<td><strong>Cloudflare Tunnel</strong></td>
<td></td>
<td></td>
<td>Removed</td>
<td>Replaced by Pangolin</td>
</tr>
</tbody>
</table>
<h2 id="detailed-feature-comparisons">Detailed Feature Comparisons<a class="headerlink" href="#detailed-feature-comparisons" title="Permanent link">&para;</a></h2>
<h3 id="1-email-advocacy-campaigns">1. Email Advocacy Campaigns<a class="headerlink" href="#1-email-advocacy-campaigns" title="Permanent link">&para;</a></h3>
<h4 id="v1-implementation">V1 Implementation<a class="headerlink" href="#v1-implementation" title="Permanent link">&para;</a></h4>
<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>Features:
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>- Create campaign (title, description, slug)
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>- Target representatives via postal code lookup
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>- Send emails to representatives (SMTP)
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>- Track sent emails
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>- Basic campaign listing
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>Technology:
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a>- NocoDB tables (campaigns, campaign_emails)
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>- Bull job queue for async sending
</span><span id="__span-0-11"><a id="__codelineno-0-11" name="__codelineno-0-11" href="#__codelineno-0-11"></a>- Nodemailer SMTP
</span><span id="__span-0-12"><a id="__codelineno-0-12" name="__codelineno-0-12" href="#__codelineno-0-12"></a>- Represent API integration
</span></code></pre></div>
<h4 id="v2-implementation">V2 Implementation<a class="headerlink" href="#v2-implementation" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>Features:
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>- All V1 features plus:
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a> - Highlighted campaigns (featured on homepage)
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a> - Response wall toggle per campaign
</span><span id="__span-1-5"><a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a> - Custom email subject/body templates
</span><span id="__span-1-6"><a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a> - Target filtering (level, position, name, email, postal code)
</span><span id="__span-1-7"><a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a> - Email stats dashboard (queued, sent, failed, mailto clicks)
</span><span id="__span-1-8"><a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a> - BullMQ queue admin (pause, resume, retry failed)
</span><span id="__span-1-9"><a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a> - Listmonk newsletter sync (campaign participants → list)
</span><span id="__span-1-10"><a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a> - Public campaign gallery
</span><span id="__span-1-11"><a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a> - Public campaign detail page
</span><span id="__span-1-12"><a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a>
</span><span id="__span-1-13"><a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a>Technology:
</span><span id="__span-1-14"><a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a>- Prisma models (Campaign, CampaignEmail, Representative, etc.)
</span><span id="__span-1-15"><a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a>- BullMQ job queue with monitoring
</span><span id="__span-1-16"><a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a>- Nodemailer SMTP + MailHog test mode
</span><span id="__span-1-17"><a id="__codelineno-1-17" name="__codelineno-1-17" href="#__codelineno-1-17"></a>- Represent API client with in-memory rate limiter (55/min)
</span><span id="__span-1-18"><a id="__codelineno-1-18" name="__codelineno-1-18" href="#__codelineno-1-18"></a>- Redis cache for representatives (60min TTL)
</span></code></pre></div>
<p><strong>Migration Impact</strong>: V1 campaigns migrate directly. New fields default to sensible values.</p>
<h3 id="2-representative-lookup">2. Representative Lookup<a class="headerlink" href="#2-representative-lookup" title="Permanent link">&para;</a></h3>
<h4 id="v1-implementation_1">V1 Implementation<a class="headerlink" href="#v1-implementation_1" title="Permanent link">&para;</a></h4>
<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>Features:
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a>- Lookup by postal code (Represent API)
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a>- Display representative name, email, district, party
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a>- No caching (every lookup hits API)
</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>Limitations:
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a>- Rate limit issues (API throttling)
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a>- Slow response times
</span><span id="__span-2-9"><a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a>- No offline capability
</span></code></pre></div>
<h4 id="v2-implementation_1">V2 Implementation<a class="headerlink" href="#v2-implementation_1" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>Features:
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>- All V1 features plus:
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a> - Redis cache (60min TTL)
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a> - Fire-and-forget cache writes (non-blocking)
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a> - Multi-level support (federal, provincial, municipal)
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a> - Representative admin (view cache, stats, delete)
</span><span id="__span-3-7"><a id="__codelineno-3-7" name="__codelineno-3-7" href="#__codelineno-3-7"></a> - Cache stats (total, by level, by party)
</span><span id="__span-3-8"><a id="__codelineno-3-8" name="__codelineno-3-8" href="#__codelineno-3-8"></a> - Health check endpoint
</span><span id="__span-3-9"><a id="__codelineno-3-9" name="__codelineno-3-9" href="#__codelineno-3-9"></a>
</span><span id="__span-3-10"><a id="__codelineno-3-10" name="__codelineno-3-10" href="#__codelineno-3-10"></a>Performance:
</span><span id="__span-3-11"><a id="__codelineno-3-11" name="__codelineno-3-11" href="#__codelineno-3-11"></a>- First lookup: ~500ms (API call + cache write)
</span><span id="__span-3-12"><a id="__codelineno-3-12" name="__codelineno-3-12" href="#__codelineno-3-12"></a>- Cached lookup: ~20ms (Redis)
</span><span id="__span-3-13"><a id="__codelineno-3-13" name="__codelineno-3-13" href="#__codelineno-3-13"></a>- Rate limiter: 55 requests/min (Represent API limit)
</span></code></pre></div>
<p><strong>Migration Impact</strong>: Representative cache can be migrated or rebuilt from API.</p>
<h3 id="3-location-management-geocoding">3. Location Management &amp; Geocoding<a class="headerlink" href="#3-location-management-geocoding" title="Permanent link">&para;</a></h3>
<h4 id="v1-implementation_2">V1 Implementation<a class="headerlink" href="#v1-implementation_2" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a>Features:
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a>- Create location (single address field)
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a>- Geocode via Nominatim (single provider)
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a>- Support level (string field)
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a>- Public map display (circle markers)
</span><span id="__span-4-6"><a id="__codelineno-4-6" name="__codelineno-4-6" href="#__codelineno-4-6"></a>
</span><span id="__span-4-7"><a id="__codelineno-4-7" name="__codelineno-4-7" href="#__codelineno-4-7"></a>Limitations:
</span><span id="__span-4-8"><a id="__codelineno-4-8" name="__codelineno-4-8" href="#__codelineno-4-8"></a>- No structured address (city, province separate)
</span><span id="__span-4-9"><a id="__codelineno-4-9" name="__codelineno-4-9" href="#__codelineno-4-9"></a>- Single geocoding provider (Nominatim)
</span><span id="__span-4-10"><a id="__codelineno-4-10" name="__codelineno-4-10" href="#__codelineno-4-10"></a>- No geocoding quality tracking
</span><span id="__span-4-11"><a id="__codelineno-4-11" name="__codelineno-4-11" href="#__codelineno-4-11"></a>- No bulk operations
</span></code></pre></div>
<h4 id="v2-implementation_2">V2 Implementation<a class="headerlink" href="#v2-implementation_2" title="Permanent link">&para;</a></h4>
<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>Features:
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a>- All V1 features plus:
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a> - Structured address (street, city, province, postal code, country)
</span><span id="__span-5-4"><a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a> - Multi-provider geocoding (6 providers with fallback):
</span><span id="__span-5-5"><a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a> 1. Nominatim (default, free)
</span><span id="__span-5-6"><a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a> 2. ArcGIS (enterprise)
</span><span id="__span-5-7"><a id="__codelineno-5-7" name="__codelineno-5-7" href="#__codelineno-5-7"></a> 3. Photon (European focus)
</span><span id="__span-5-8"><a id="__codelineno-5-8" name="__codelineno-5-8" href="#__codelineno-5-8"></a> 4. Mapbox (if API key provided)
</span><span id="__span-5-9"><a id="__codelineno-5-9" name="__codelineno-5-9" href="#__codelineno-5-9"></a> 5. Google (if API key provided)
</span><span id="__span-5-10"><a id="__codelineno-5-10" name="__codelineno-5-10" href="#__codelineno-5-10"></a> 6. OpenCage (if API key provided)
</span><span id="__span-5-11"><a id="__codelineno-5-11" name="__codelineno-5-11" href="#__codelineno-5-11"></a> - Geocoding metadata (provider, quality, timestamp)
</span><span id="__span-5-12"><a id="__codelineno-5-12" name="__codelineno-5-12" href="#__codelineno-5-12"></a> - Bulk geocoding endpoint (100 at a time)
</span><span id="__span-5-13"><a id="__codelineno-5-13" name="__codelineno-5-13" href="#__codelineno-5-13"></a> - Reverse geocoding (lat/lng → address)
</span><span id="__span-5-14"><a id="__codelineno-5-14" name="__codelineno-5-14" href="#__codelineno-5-14"></a> - CSV import with flexible column mapping
</span><span id="__span-5-15"><a id="__codelineno-5-15" name="__codelineno-5-15" href="#__codelineno-5-15"></a> - CSV export with filters
</span><span id="__span-5-16"><a id="__codelineno-5-16" name="__codelineno-5-16" href="#__codelineno-5-16"></a> - Location history (edit trail)
</span><span id="__span-5-17"><a id="__codelineno-5-17" name="__codelineno-5-17" href="#__codelineno-5-17"></a> - Contact fields (name, phone, email)
</span><span id="__span-5-18"><a id="__codelineno-5-18" name="__codelineno-5-18" href="#__codelineno-5-18"></a> - NAR import (Canadian electoral data, 50k+ locations)
</span><span id="__span-5-19"><a id="__codelineno-5-19" name="__codelineno-5-19" href="#__codelineno-5-19"></a> - Data quality dashboard (geocoding success rate by provider)
</span><span id="__span-5-20"><a id="__codelineno-5-20" name="__codelineno-5-20" href="#__codelineno-5-20"></a> - Click-to-add location on map
</span><span id="__span-5-21"><a id="__codelineno-5-21" name="__codelineno-5-21" href="#__codelineno-5-21"></a> - Drag-to-move location on map
</span><span id="__span-5-22"><a id="__codelineno-5-22" name="__codelineno-5-22" href="#__codelineno-5-22"></a> - Geolocate button (browser location)
</span><span id="__span-5-23"><a id="__codelineno-5-23" name="__codelineno-5-23" href="#__codelineno-5-23"></a> - Fullscreen map mode
</span><span id="__span-5-24"><a id="__codelineno-5-24" name="__codelineno-5-24" href="#__codelineno-5-24"></a>
</span><span id="__span-5-25"><a id="__codelineno-5-25" name="__codelineno-5-25" href="#__codelineno-5-25"></a>Technology:
</span><span id="__span-5-26"><a id="__codelineno-5-26" name="__codelineno-5-26" href="#__codelineno-5-26"></a>- Prisma Location model (structured schema)
</span><span id="__span-5-27"><a id="__codelineno-5-27" name="__codelineno-5-27" href="#__codelineno-5-27"></a>- Multi-provider geocoding service with retry logic
</span><span id="__span-5-28"><a id="__codelineno-5-28" name="__codelineno-5-28" href="#__codelineno-5-28"></a>- PostgreSQL spatial extensions (future: PostGIS)
</span><span id="__span-5-29"><a id="__codelineno-5-29" name="__codelineno-5-29" href="#__codelineno-5-29"></a>- React Leaflet map components
</span></code></pre></div>
<p><strong>Migration Impact</strong>: V1 single address field parsed into structured fields. Geocoding metadata added.</p>
<h3 id="4-volunteer-shifts">4. Volunteer Shifts<a class="headerlink" href="#4-volunteer-shifts" title="Permanent link">&para;</a></h3>
<h4 id="v1-implementation_3">V1 Implementation<a class="headerlink" href="#v1-implementation_3" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>Features:
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a>- Create shift (name, start/end time, location, capacity)
</span><span id="__span-6-3"><a id="__codelineno-6-3" name="__codelineno-6-3" href="#__codelineno-6-3"></a>- Public signup form
</span><span id="__span-6-4"><a id="__codelineno-6-4" name="__codelineno-6-4" href="#__codelineno-6-4"></a>- Email confirmation
</span><span id="__span-6-5"><a id="__codelineno-6-5" name="__codelineno-6-5" href="#__codelineno-6-5"></a>- Admin view signups
</span><span id="__span-6-6"><a id="__codelineno-6-6" name="__codelineno-6-6" href="#__codelineno-6-6"></a>
</span><span id="__span-6-7"><a id="__codelineno-6-7" name="__codelineno-6-7" href="#__codelineno-6-7"></a>Limitations:
</span><span id="__span-6-8"><a id="__codelineno-6-8" name="__codelineno-6-8" href="#__codelineno-6-8"></a>- No cut assignment (shifts not linked to territories)
</span><span id="__span-6-9"><a id="__codelineno-6-9" name="__codelineno-6-9" href="#__codelineno-6-9"></a>- No signup status tracking
</span><span id="__span-6-10"><a id="__codelineno-6-10" name="__codelineno-6-10" href="#__codelineno-6-10"></a>- No volunteer portal
</span></code></pre></div>
<h4 id="v2-implementation_3">V2 Implementation<a class="headerlink" href="#v2-implementation_3" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>Features:
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>- All V1 features plus:
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a> - Cut assignment (link shift to territory)
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a> - Signup status (PENDING, CONFIRMED, CANCELLED, COMPLETED, NO_SHOW)
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a> - Shift requirements field
</span><span id="__span-7-6"><a id="__codelineno-7-6" name="__codelineno-7-6" href="#__codelineno-7-6"></a> - Temp user creation (public signup creates USER with 30-day expiry)
</span><span id="__span-7-7"><a id="__codelineno-7-7" name="__codelineno-7-7" href="#__codelineno-7-7"></a> - Signup cancellation (volunteer self-service)
</span><span id="__span-7-8"><a id="__codelineno-7-8" name="__codelineno-7-8" href="#__codelineno-7-8"></a> - Admin signup management (update status, notes)
</span><span id="__span-7-9"><a id="__codelineno-7-9" name="__codelineno-7-9" href="#__codelineno-7-9"></a> - Email all signups (broadcast to shift volunteers)
</span><span id="__span-7-10"><a id="__codelineno-7-10" name="__codelineno-7-10" href="#__codelineno-7-10"></a> - Shift stats (total shifts, upcoming, signups by status)
</span><span id="__span-7-11"><a id="__codelineno-7-11" name="__codelineno-7-11" href="#__codelineno-7-11"></a> - Volunteer portal (view assigned shifts)
</span><span id="__span-7-12"><a id="__codelineno-7-12" name="__codelineno-7-12" href="#__codelineno-7-12"></a>
</span><span id="__span-7-13"><a id="__codelineno-7-13" name="__codelineno-7-13" href="#__codelineno-7-13"></a>Technology:
</span><span id="__span-7-14"><a id="__codelineno-7-14" name="__codelineno-7-14" href="#__codelineno-7-14"></a>- Prisma models (Shift, ShiftSignup with status enum)
</span><span id="__span-7-15"><a id="__codelineno-7-15" name="__codelineno-7-15" href="#__codelineno-7-15"></a>- TEMP user creation (automatic expiry)
</span><span id="__span-7-16"><a id="__codelineno-7-16" name="__codelineno-7-16" href="#__codelineno-7-16"></a>- Email templates for confirmations
</span></code></pre></div>
<p><strong>Migration Impact</strong>: V1 shifts migrate. Signups extracted to separate table. Status defaults to CONFIRMED.</p>
<h3 id="5-canvassing-system-new-in-v2">5. Canvassing System (New in V2)<a class="headerlink" href="#5-canvassing-system-new-in-v2" title="Permanent link">&para;</a></h3>
<h4 id="v2-features">V2 Features<a class="headerlink" href="#v2-features" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>Complete canvassing workflow:
</span><span id="__span-8-2"><a id="__codelineno-8-2" name="__codelineno-8-2" href="#__codelineno-8-2"></a>- Start/end canvass session (track volunteer time)
</span><span id="__span-8-3"><a id="__codelineno-8-3" name="__codelineno-8-3" href="#__codelineno-8-3"></a>- GPS tracking (real-time trail recording, 30-day retention)
</span><span id="__span-8-4"><a id="__codelineno-8-4" name="__codelineno-8-4" href="#__codelineno-8-4"></a>- Walking route algorithm (nearest-neighbor with haversine distance)
</span><span id="__span-8-5"><a id="__codelineno-8-5" name="__codelineno-8-5" href="#__codelineno-8-5"></a>- Visit recording (outcome, support level, notes, rate-limited 30/min)
</span><span id="__span-8-6"><a id="__codelineno-8-6" name="__codelineno-8-6" href="#__codelineno-8-6"></a>- Visit outcomes:
</span><span id="__span-8-7"><a id="__codelineno-8-7" name="__codelineno-8-7" href="#__codelineno-8-7"></a> - CONTACT_MADE
</span><span id="__span-8-8"><a id="__codelineno-8-8" name="__codelineno-8-8" href="#__codelineno-8-8"></a> - NOT_HOME
</span><span id="__span-8-9"><a id="__codelineno-8-9" name="__codelineno-8-9" href="#__codelineno-8-9"></a> - REFUSED
</span><span id="__span-8-10"><a id="__codelineno-8-10" name="__codelineno-8-10" href="#__codelineno-8-10"></a> - MOVED
</span><span id="__span-8-11"><a id="__codelineno-8-11" name="__codelineno-8-11" href="#__codelineno-8-11"></a> - DECEASED
</span><span id="__span-8-12"><a id="__codelineno-8-12" name="__codelineno-8-12" href="#__codelineno-8-12"></a> - WRONG_ADDRESS
</span><span id="__span-8-13"><a id="__codelineno-8-13" name="__codelineno-8-13" href="#__codelineno-8-13"></a>- Admin dashboard:
</span><span id="__span-8-14"><a id="__codelineno-8-14" name="__codelineno-8-14" href="#__codelineno-8-14"></a> - Active sessions
</span><span id="__span-8-15"><a id="__codelineno-8-15" name="__codelineno-8-15" href="#__codelineno-8-15"></a> - Total visits (today, week)
</span><span id="__span-8-16"><a id="__codelineno-8-16" name="__codelineno-8-16" href="#__codelineno-8-16"></a> - Activity feed (recent visits)
</span><span id="__span-8-17"><a id="__codelineno-8-17" name="__codelineno-8-17" href="#__codelineno-8-17"></a> - Cut progress (locations visited vs total)
</span><span id="__span-8-18"><a id="__codelineno-8-18" name="__codelineno-8-18" href="#__codelineno-8-18"></a> - Leaderboard (top volunteers by visits, period filter)
</span><span id="__span-8-19"><a id="__codelineno-8-19" name="__codelineno-8-19" href="#__codelineno-8-19"></a>- Volunteer portal:
</span><span id="__span-8-20"><a id="__codelineno-8-20" name="__codelineno-8-20" href="#__codelineno-8-20"></a> - Full-screen canvass map
</span><span id="__span-8-21"><a id="__codelineno-8-21" name="__codelineno-8-21" href="#__codelineno-8-21"></a> - GPS position tracking
</span><span id="__span-8-22"><a id="__codelineno-8-22" name="__codelineno-8-22" href="#__codelineno-8-22"></a> - Walking route display
</span><span id="__span-8-23"><a id="__codelineno-8-23" name="__codelineno-8-23" href="#__codelineno-8-23"></a> - Bottom sheet visit recording
</span><span id="__span-8-24"><a id="__codelineno-8-24" name="__codelineno-8-24" href="#__codelineno-8-24"></a> - Activity history (my visits)
</span><span id="__span-8-25"><a id="__codelineno-8-25" name="__codelineno-8-25" href="#__codelineno-8-25"></a> - Route history (past sessions)
</span><span id="__span-8-26"><a id="__codelineno-8-26" name="__codelineno-8-26" href="#__codelineno-8-26"></a>
</span><span id="__span-8-27"><a id="__codelineno-8-27" name="__codelineno-8-27" href="#__codelineno-8-27"></a>Technology:
</span><span id="__span-8-28"><a id="__codelineno-8-28" name="__codelineno-8-28" href="#__codelineno-8-28"></a>- Prisma models (CanvassSession, CanvassVisit, TrackingSession, TrackPoint)
</span><span id="__span-8-29"><a id="__codelineno-8-29" name="__codelineno-8-29" href="#__codelineno-8-29"></a>- React Leaflet map with custom controls
</span><span id="__span-8-30"><a id="__codelineno-8-30" name="__codelineno-8-30" href="#__codelineno-8-30"></a>- Zustand canvass store (client state)
</span><span id="__span-8-31"><a id="__codelineno-8-31" name="__codelineno-8-31" href="#__codelineno-8-31"></a>- Abandoned session cleanup (hourly, ACTIVE &gt; 12h → ABANDONED)
</span><span id="__span-8-32"><a id="__codelineno-8-32" name="__codelineno-8-32" href="#__codelineno-8-32"></a>- Stale tracking cleanup (no data for 2h)
</span></code></pre></div>
<p><strong>Migration Impact</strong>: New feature, no V1 equivalent.</p>
<h3 id="6-landing-page-builder-new-in-v2">6. Landing Page Builder (New in V2)<a class="headerlink" href="#6-landing-page-builder-new-in-v2" title="Permanent link">&para;</a></h3>
<h4 id="v2-features_1">V2 Features<a class="headerlink" href="#v2-features_1" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>Visual page builder:
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>- GrapesJS WYSIWYG editor
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>- Drag-and-drop block placement
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a>- Custom block library (Hero, Features, CTA, etc.)
</span><span id="__span-9-5"><a id="__codelineno-9-5" name="__codelineno-9-5" href="#__codelineno-9-5"></a>- Live preview
</span><span id="__span-9-6"><a id="__codelineno-9-6" name="__codelineno-9-6" href="#__codelineno-9-6"></a>- Desktop-only editor (mobile warning)
</span><span id="__span-9-7"><a id="__codelineno-9-7" name="__codelineno-9-7" href="#__codelineno-9-7"></a>- Save hotkey (Ctrl+S)
</span><span id="__span-9-8"><a id="__codelineno-9-8" name="__codelineno-9-8" href="#__codelineno-9-8"></a>
</span><span id="__span-9-9"><a id="__codelineno-9-9" name="__codelineno-9-9" href="#__codelineno-9-9"></a>Page management:
</span><span id="__span-9-10"><a id="__codelineno-9-10" name="__codelineno-9-10" href="#__codelineno-9-10"></a>- CRUD operations (create, edit, delete, publish)
</span><span id="__span-9-11"><a id="__codelineno-9-11" name="__codelineno-9-11" href="#__codelineno-9-11"></a>- Slug-based routing (/p/:slug)
</span><span id="__span-9-12"><a id="__codelineno-9-12" name="__codelineno-9-12" href="#__codelineno-9-12"></a>- Public rendering
</span><span id="__span-9-13"><a id="__codelineno-9-13" name="__codelineno-9-13" href="#__codelineno-9-13"></a>- MkDocs export (Jinja2 Material theme overrides)
</span><span id="__span-9-14"><a id="__codelineno-9-14" name="__codelineno-9-14" href="#__codelineno-9-14"></a>- Export formats: themed (with header/footer) or standalone
</span><span id="__span-9-15"><a id="__codelineno-9-15" name="__codelineno-9-15" href="#__codelineno-9-15"></a>
</span><span id="__span-9-16"><a id="__codelineno-9-16" name="__codelineno-9-16" href="#__codelineno-9-16"></a>Technology:
</span><span id="__span-9-17"><a id="__codelineno-9-17" name="__codelineno-9-17" href="#__codelineno-9-17"></a>- GrapesJS 0.21+
</span><span id="__span-9-18"><a id="__codelineno-9-18" name="__codelineno-9-18" href="#__codelineno-9-18"></a>- Prisma models (LandingPage, PageBlock)
</span><span id="__span-9-19"><a id="__codelineno-9-19" name="__codelineno-9-19" href="#__codelineno-9-19"></a>- React admin UI
</span><span id="__span-9-20"><a id="__codelineno-9-20" name="__codelineno-9-20" href="#__codelineno-9-20"></a>- MkDocs integration (override templates)
</span></code></pre></div>
<p><strong>Migration Impact</strong>: New feature, no V1 equivalent.</p>
<h3 id="7-email-templates-new-in-v2">7. Email Templates (New in V2)<a class="headerlink" href="#7-email-templates-new-in-v2" title="Permanent link">&para;</a></h3>
<h4 id="v2-features_2">V2 Features<a class="headerlink" href="#v2-features_2" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a>Template management:
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>- Create templates (HTML + plain text)
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>- Template categories (campaign, shift, response, system)
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a>- Variable substitution ({{campaignTitle}}, {{userName}}, etc.)
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a>- Version control (publish creates new version)
</span><span id="__span-10-6"><a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a>- Live preview
</span><span id="__span-10-7"><a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a>- Test email sending
</span><span id="__span-10-8"><a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a>
</span><span id="__span-10-9"><a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a>Admin features:
</span><span id="__span-10-10"><a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a>- Template library
</span><span id="__span-10-11"><a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a>- Version history
</span><span id="__span-10-12"><a id="__codelineno-10-12" name="__codelineno-10-12" href="#__codelineno-10-12"></a>- Rollback to previous version
</span><span id="__span-10-13"><a id="__codelineno-10-13" name="__codelineno-10-13" href="#__codelineno-10-13"></a>- Duplicate template
</span><span id="__span-10-14"><a id="__codelineno-10-14" name="__codelineno-10-14" href="#__codelineno-10-14"></a>- Delete template (soft delete)
</span><span id="__span-10-15"><a id="__codelineno-10-15" name="__codelineno-10-15" href="#__codelineno-10-15"></a>
</span><span id="__span-10-16"><a id="__codelineno-10-16" name="__codelineno-10-16" href="#__codelineno-10-16"></a>Technology:
</span><span id="__span-10-17"><a id="__codelineno-10-17" name="__codelineno-10-17" href="#__codelineno-10-17"></a>- Prisma models (EmailTemplate, EmailTemplateVersion)
</span><span id="__span-10-18"><a id="__codelineno-10-18" name="__codelineno-10-18" href="#__codelineno-10-18"></a>- Handlebars-style variable syntax
</span><span id="__span-10-19"><a id="__codelineno-10-19" name="__codelineno-10-19" href="#__codelineno-10-19"></a>- HTML + plain text variants
</span></code></pre></div>
<p><strong>Migration Impact</strong>: New feature, no V1 equivalent.</p>
<h3 id="8-media-library-new-in-v2">8. Media Library (New in V2)<a class="headerlink" href="#8-media-library-new-in-v2" title="Permanent link">&para;</a></h3>
<h4 id="v2-features_3">V2 Features<a class="headerlink" href="#v2-features_3" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a>Video management:
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a>- Upload videos (MP4, MOV, AVI, MKV, WebM, M4V, FLV up to 10GB)
</span><span id="__span-11-3"><a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>- Automatic metadata extraction (FFprobe):
</span><span id="__span-11-4"><a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a> - Duration, dimensions, orientation
</span><span id="__span-11-5"><a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a> - Video quality (resolution-based)
</span><span id="__span-11-6"><a id="__codelineno-11-6" name="__codelineno-11-6" href="#__codelineno-11-6"></a> - Audio track detection
</span><span id="__span-11-7"><a id="__codelineno-11-7" name="__codelineno-11-7" href="#__codelineno-11-7"></a>- Bulk operations (delete, lock/unlock)
</span><span id="__span-11-8"><a id="__codelineno-11-8" name="__codelineno-11-8" href="#__codelineno-11-8"></a>- Categories (assign to shared gallery)
</span><span id="__span-11-9"><a id="__codelineno-11-9" name="__codelineno-11-9" href="#__codelineno-11-9"></a>- Lock/unlock system (public visibility control)
</span><span id="__span-11-10"><a id="__codelineno-11-10" name="__codelineno-11-10" href="#__codelineno-11-10"></a>
</span><span id="__span-11-11"><a id="__codelineno-11-11" name="__codelineno-11-11" href="#__codelineno-11-11"></a>Public gallery:
</span><span id="__span-11-12"><a id="__codelineno-11-12" name="__codelineno-11-12" href="#__codelineno-11-12"></a>- Category-based filtering
</span><span id="__span-11-13"><a id="__codelineno-11-13" name="__codelineno-11-13" href="#__codelineno-11-13"></a>- Video detail page
</span><span id="__span-11-14"><a id="__codelineno-11-14" name="__codelineno-11-14" href="#__codelineno-11-14"></a>- Reactions (6 emoji types: like, love, laugh, wow, sad, angry)
</span><span id="__span-11-15"><a id="__codelineno-11-15" name="__codelineno-11-15" href="#__codelineno-11-15"></a>- Comment system (future)
</span><span id="__span-11-16"><a id="__codelineno-11-16" name="__codelineno-11-16" href="#__codelineno-11-16"></a>
</span><span id="__span-11-17"><a id="__codelineno-11-17" name="__codelineno-11-17" href="#__codelineno-11-17"></a>Technology:
</span><span id="__span-11-18"><a id="__codelineno-11-18" name="__codelineno-11-18" href="#__codelineno-11-18"></a>- Fastify microservice (port 4100)
</span><span id="__span-11-19"><a id="__codelineno-11-19" name="__codelineno-11-19" href="#__codelineno-11-19"></a>- Drizzle ORM (separate from Prisma)
</span><span id="__span-11-20"><a id="__codelineno-11-20" name="__codelineno-11-20" href="#__codelineno-11-20"></a>- FFprobe metadata extraction (30s timeout)
</span><span id="__span-11-21"><a id="__codelineno-11-21" name="__codelineno-11-21" href="#__codelineno-11-21"></a>- Dual API architecture (media separate from main API)
</span></code></pre></div>
<p><strong>Migration Impact</strong>: New feature, no V1 equivalent.</p>
<h3 id="9-monitoring-stack-new-in-v2">9. Monitoring Stack (New in V2)<a class="headerlink" href="#9-monitoring-stack-new-in-v2" title="Permanent link">&para;</a></h3>
<h4 id="v2-features_4">V2 Features<a class="headerlink" href="#v2-features_4" title="Permanent link">&para;</a></h4>
<div class="language-text highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a>Metrics collection:
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a>- 12 custom cm_* metrics:
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a> - cm_api_uptime_seconds
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a> - cm_emails_sent_total
</span><span id="__span-12-5"><a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a> - cm_emails_failed_total
</span><span id="__span-12-6"><a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a> - cm_email_queue_size
</span><span id="__span-12-7"><a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a> - cm_email_send_duration_seconds
</span><span id="__span-12-8"><a id="__codelineno-12-8" name="__codelineno-12-8" href="#__codelineno-12-8"></a> - cm_login_attempts_total
</span><span id="__span-12-9"><a id="__codelineno-12-9" name="__codelineno-12-9" href="#__codelineno-12-9"></a> - cm_active_sessions
</span><span id="__span-12-10"><a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a> - cm_campaign_emails_total
</span><span id="__span-12-11"><a id="__codelineno-12-11" name="__codelineno-12-11" href="#__codelineno-12-11"></a> - cm_response_submissions_total
</span><span id="__span-12-12"><a id="__codelineno-12-12" name="__codelineno-12-12" href="#__codelineno-12-12"></a> - cm_canvass_visits_total
</span><span id="__span-12-13"><a id="__codelineno-12-13" name="__codelineno-12-13" href="#__codelineno-12-13"></a> - cm_active_canvass_sessions
</span><span id="__span-12-14"><a id="__codelineno-12-14" name="__codelineno-12-14" href="#__codelineno-12-14"></a> - cm_shift_signups_total
</span><span id="__span-12-15"><a id="__codelineno-12-15" name="__codelineno-12-15" href="#__codelineno-12-15"></a> - cm_external_service_up
</span><span id="__span-12-16"><a id="__codelineno-12-16" name="__codelineno-12-16" href="#__codelineno-12-16"></a>
</span><span id="__span-12-17"><a id="__codelineno-12-17" name="__codelineno-12-17" href="#__codelineno-12-17"></a>Dashboards:
</span><span id="__span-12-18"><a id="__codelineno-12-18" name="__codelineno-12-18" href="#__codelineno-12-18"></a>- System Health (CPU, memory, disk, network)
</span><span id="__span-12-19"><a id="__codelineno-12-19" name="__codelineno-12-19" href="#__codelineno-12-19"></a>- Application Overview (API requests, errors, response times)
</span><span id="__span-12-20"><a id="__codelineno-12-20" name="__codelineno-12-20" href="#__codelineno-12-20"></a>- API Performance (endpoint latency, throughput)
</span><span id="__span-12-21"><a id="__codelineno-12-21" name="__codelineno-12-21" href="#__codelineno-12-21"></a>
</span><span id="__span-12-22"><a id="__codelineno-12-22" name="__codelineno-12-22" href="#__codelineno-12-22"></a>Alerts:
</span><span id="__span-12-23"><a id="__codelineno-12-23" name="__codelineno-12-23" href="#__codelineno-12-23"></a>- High error rate (&gt; 5% for 5min)
</span><span id="__span-12-24"><a id="__codelineno-12-24" name="__codelineno-12-24" href="#__codelineno-12-24"></a>- API down
</span><span id="__span-12-25"><a id="__codelineno-12-25" name="__codelineno-12-25" href="#__codelineno-12-25"></a>- High email queue size (&gt; 1000)
</span><span id="__span-12-26"><a id="__codelineno-12-26" name="__codelineno-12-26" href="#__codelineno-12-26"></a>- External service down (NocoDB, Redis, PostgreSQL)
</span><span id="__span-12-27"><a id="__codelineno-12-27" name="__codelineno-12-27" href="#__codelineno-12-27"></a>
</span><span id="__span-12-28"><a id="__codelineno-12-28" name="__codelineno-12-28" href="#__codelineno-12-28"></a>Technology:
</span><span id="__span-12-29"><a id="__codelineno-12-29" name="__codelineno-12-29" href="#__codelineno-12-29"></a>- Prometheus (metrics collection, 15s scrape)
</span><span id="__span-12-30"><a id="__codelineno-12-30" name="__codelineno-12-30" href="#__codelineno-12-30"></a>- Grafana (visualization, 3 dashboards)
</span><span id="__span-12-31"><a id="__codelineno-12-31" name="__codelineno-12-31" href="#__codelineno-12-31"></a>- Alertmanager (alert routing)
</span><span id="__span-12-32"><a id="__codelineno-12-32" name="__codelineno-12-32" href="#__codelineno-12-32"></a>- Gotify (notification delivery, optional)
</span><span id="__span-12-33"><a id="__codelineno-12-33" name="__codelineno-12-33" href="#__codelineno-12-33"></a>- cAdvisor (container metrics)
</span><span id="__span-12-34"><a id="__codelineno-12-34" name="__codelineno-12-34" href="#__codelineno-12-34"></a>- Node Exporter (host metrics)
</span><span id="__span-12-35"><a id="__codelineno-12-35" name="__codelineno-12-35" href="#__codelineno-12-35"></a>- Redis Exporter (Redis metrics)
</span></code></pre></div>
<p><strong>Migration Impact</strong>: New feature, no V1 equivalent. Enable with <code>--profile monitoring</code>.</p>
<h2 id="feature-status-summary">Feature Status Summary<a class="headerlink" href="#feature-status-summary" title="Permanent link">&para;</a></h2>
<h3 id="v1-features-in-v2">V1 Features in V2<a class="headerlink" href="#v1-features-in-v2" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>V2 Status</th>
<th>Implementation</th>
</tr>
</thead>
<tbody>
<tr>
<td>Campaigns</td>
<td>✅ Complete</td>
<td>Enhanced with highlighting, response wall toggle</td>
</tr>
<tr>
<td>Representative Lookup</td>
<td>✅ Complete</td>
<td>Enhanced with caching, stats</td>
</tr>
<tr>
<td>Response Wall</td>
<td>✅ Complete</td>
<td>Enhanced with moderation, upvoting</td>
</tr>
<tr>
<td>Locations</td>
<td>✅ Complete</td>
<td>Enhanced with structured address, multi-provider geocoding</td>
</tr>
<tr>
<td>Shifts</td>
<td>✅ Complete</td>
<td>Enhanced with cut assignment, status tracking</td>
</tr>
<tr>
<td>Public Shift Signup</td>
<td>✅ Complete</td>
<td>Same functionality, improved UX</td>
</tr>
<tr>
<td>User Management</td>
<td>✅ Complete</td>
<td>Enhanced with unified model, RBAC</td>
</tr>
<tr>
<td>Email Sending</td>
<td>✅ Complete</td>
<td>Enhanced with BullMQ, monitoring</td>
</tr>
<tr>
<td>CSV Import/Export</td>
<td>✅ Complete</td>
<td>Enhanced with flexible mapping</td>
</tr>
</tbody>
</table>
<p><strong>Result</strong>: <strong>100% V1 feature parity achieved</strong></p>
<h3 id="v1-features-not-in-v2">V1 Features NOT in V2<a class="headerlink" href="#v1-features-not-in-v2" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Reason</th>
<th>Alternative</th>
</tr>
</thead>
<tbody>
<tr>
<td>NocoDB as primary data layer</td>
<td>Replaced by Prisma ORM</td>
<td>NocoDB available as read-only browser</td>
</tr>
<tr>
<td>Session-based authentication</td>
<td>Replaced by JWT</td>
<td>More scalable, stateless auth</td>
</tr>
<tr>
<td>Separate apps (influence, map)</td>
<td>Unified into single API</td>
<td>Better code reuse, consistency</td>
</tr>
</tbody>
</table>
<h3 id="v2-only-features">V2-Only Features<a class="headerlink" href="#v2-only-features" title="Permanent link">&para;</a></h3>
<table>
<thead>
<tr>
<th>Feature</th>
<th>Status</th>
<th>Phase</th>
</tr>
</thead>
<tbody>
<tr>
<td>Landing Page Builder</td>
<td>✅ Complete</td>
<td>Phase 12</td>
</tr>
<tr>
<td>Email Templates</td>
<td>✅ Complete</td>
<td>Phase 12</td>
</tr>
<tr>
<td>Media Library</td>
<td>✅ Complete</td>
<td>Phase 12</td>
</tr>
<tr>
<td>Canvassing System</td>
<td>✅ Complete</td>
<td>Phase 13</td>
</tr>
<tr>
<td>GPS Tracking</td>
<td>✅ Complete</td>
<td>Phase 13</td>
</tr>
<tr>
<td>Walk Sheets</td>
<td>✅ Complete</td>
<td>Phase 10</td>
</tr>
<tr>
<td>NAR Import</td>
<td>✅ Complete</td>
<td>Phase 14</td>
</tr>
<tr>
<td>Data Quality Dashboard</td>
<td>✅ Complete</td>
<td>Phase 14</td>
</tr>
<tr>
<td>Monitoring Stack</td>
<td>✅ Complete</td>
<td>Phase 14</td>
</tr>
<tr>
<td>Pangolin Tunnel</td>
<td>✅ Complete</td>
<td>Phase 14</td>
</tr>
<tr>
<td>Observability Dashboard</td>
<td>✅ Complete</td>
<td>Phase 14</td>
</tr>
</tbody>
</table>
<h2 id="migration-priority">Migration Priority<a class="headerlink" href="#migration-priority" title="Permanent link">&para;</a></h2>
<p>When migrating from V1 to V2, prioritize features in this order:</p>
<h3 id="1-critical-must-migrate-first">1. Critical (Must Migrate First)<a class="headerlink" href="#1-critical-must-migrate-first" title="Permanent link">&para;</a></h3>
<ul class="task-list">
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>User Authentication</strong> - Foundational for all access</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>User Management</strong> - Admin accounts</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Campaigns</strong> - Core advocacy feature</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Locations</strong> - Core mapping feature</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Representative Lookup</strong> - Core advocacy feature</li>
</ul>
<h3 id="2-high-priority-migrate-early">2. High Priority (Migrate Early)<a class="headerlink" href="#2-high-priority-migrate-early" title="Permanent link">&para;</a></h3>
<ul class="task-list">
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Response Wall</strong> - Public engagement</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Email Sending</strong> - Campaign functionality</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Shift Management</strong> - Volunteer coordination</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Public Shift Signup</strong> - Volunteer onboarding</li>
</ul>
<h3 id="3-medium-priority-migrate-mid-phase">3. Medium Priority (Migrate Mid-Phase)<a class="headerlink" href="#3-medium-priority-migrate-mid-phase" title="Permanent link">&para;</a></h3>
<ul class="task-list">
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Representative Cache</strong> - Performance optimization</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Postal Code Cache</strong> - Performance optimization</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Cuts (Territories)</strong> - Advanced mapping</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>CSV Import/Export</strong> - Bulk operations</li>
</ul>
<h3 id="4-low-priority-migrate-later">4. Low Priority (Migrate Later)<a class="headerlink" href="#4-low-priority-migrate-later" title="Permanent link">&para;</a></h3>
<ul class="task-list">
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Email Queue Monitoring</strong> - Admin analytics</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Campaign Email Tracking</strong> - Admin analytics</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Representative Admin</strong> - Cache management</li>
</ul>
<h3 id="5-optional-new-v2-features">5. Optional (New V2 Features)<a class="headerlink" href="#5-optional-new-v2-features" title="Permanent link">&para;</a></h3>
<ul class="task-list">
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Landing Pages</strong> - Public content</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Email Templates</strong> - Email customization</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Media Library</strong> - Video management</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Canvassing</strong> - Field operations</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Monitoring</strong> - System observability</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>NAR Import</strong> - Canadian data</li>
</ul>
<h2 id="workarounds-for-missing-features">Workarounds for Missing Features<a class="headerlink" href="#workarounds-for-missing-features" title="Permanent link">&para;</a></h2>
<p>If you need a V1 feature not yet migrated:</p>
<h3 id="1-run-v1-and-v2-in-parallel">1. Run V1 and V2 in Parallel<a class="headerlink" href="#1-run-v1-and-v2-in-parallel" title="Permanent link">&para;</a></h3>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-13-1"><a id="__codelineno-13-1" name="__codelineno-13-1" href="#__codelineno-13-1"></a><span class="c1"># Keep V1 running for specific features</span>
</span><span id="__span-13-2"><a id="__codelineno-13-2" name="__codelineno-13-2" href="#__codelineno-13-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>-f<span class="w"> </span>docker-compose.v1.yml<span class="w"> </span>up<span class="w"> </span>-d
</span><span id="__span-13-3"><a id="__codelineno-13-3" name="__codelineno-13-3" href="#__codelineno-13-3"></a>
</span><span id="__span-13-4"><a id="__codelineno-13-4" name="__codelineno-13-4" href="#__codelineno-13-4"></a><span class="c1"># Run V2 for new features</span>
</span><span id="__span-13-5"><a id="__codelineno-13-5" name="__codelineno-13-5" href="#__codelineno-13-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span><span id="__span-13-6"><a id="__codelineno-13-6" name="__codelineno-13-6" href="#__codelineno-13-6"></a>
</span><span id="__span-13-7"><a id="__codelineno-13-7" name="__codelineno-13-7" href="#__codelineno-13-7"></a><span class="c1"># Use reverse proxy to route by path:</span>
</span><span id="__span-13-8"><a id="__codelineno-13-8" name="__codelineno-13-8" href="#__codelineno-13-8"></a><span class="c1"># /v1/* → V1 apps</span>
</span><span id="__span-13-9"><a id="__codelineno-13-9" name="__codelineno-13-9" href="#__codelineno-13-9"></a><span class="c1"># /v2/* → V2 API</span>
</span></code></pre></div>
<h3 id="2-manual-data-entry">2. Manual Data Entry<a class="headerlink" href="#2-manual-data-entry" title="Permanent link">&para;</a></h3>
<p>For small datasets, manually re-enter data in V2 admin:</p>
<ul>
<li>Campaigns: Use Campaigns page (CRUD)</li>
<li>Locations: Use Locations page or CSV import</li>
<li>Shifts: Use Shifts page (CRUD)</li>
</ul>
<h3 id="3-custom-migration-scripts">3. Custom Migration Scripts<a class="headerlink" href="#3-custom-migration-scripts" title="Permanent link">&para;</a></h3>
<p>For unique V1 customizations, write custom transformation scripts:</p>
<div class="language-javascript 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="c1">// scripts/migrate-custom-fields.js</span>
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a><span class="kd">const</span><span class="w"> </span><span class="nx">customFieldMapping</span><span class="w"> </span><span class="o">=</span><span class="w"> </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="nx">v1Field</span><span class="o">:</span><span class="w"> </span><span class="s1">&#39;v2Field&#39;</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="c1">// Add your mappings</span>
</span><span id="__span-14-5"><a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a><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><span id="__span-14-7"><a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a><span class="c1">// Transform and import</span>
</span></code></pre></div>
<h2 id="future-roadmap">Future Roadmap<a class="headerlink" href="#future-roadmap" title="Permanent link">&para;</a></h2>
<h3 id="planned-for-v2-phase-15">Planned for V2 Phase 15+<a class="headerlink" href="#planned-for-v2-phase-15" title="Permanent link">&para;</a></h3>
<ul class="task-list">
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Multi-tenancy</strong> - Multiple organizations per instance</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Mobile apps</strong> - iOS/Android native apps</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Advanced analytics</strong> - Campaign performance, volunteer metrics</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>AI integration</strong> - Campaign suggestions, email drafting</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Social media integration</strong> - Share campaigns, auto-post</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>SMS campaigns</strong> - Text message advocacy</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Phone banking</strong> - Call tracking, scripts</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Donation tracking</strong> - Fundraising integration</li>
<li class="task-list-item"><label class="task-list-control"><input type="checkbox" disabled/><span class="task-list-indicator"></span></label> <strong>Event management</strong> - Rally, town hall scheduling</li>
</ul>
<h3 id="community-feature-requests">Community Feature Requests<a class="headerlink" href="#community-feature-requests" title="Permanent link">&para;</a></h3>
<p>Vote on features at: https://github.com/changemaker-lite/v2/discussions</p>
<h2 id="related-documentation">Related Documentation<a class="headerlink" href="#related-documentation" title="Permanent link">&para;</a></h2>
<ul>
<li><a href="../">Migration Overview</a> - Migration planning</li>
<li><a href="../breaking-changes/">Breaking Changes</a> - V1→V2 differences</li>
<li><a href="../data-migration/">Data Migration</a> - Migration procedures</li>
<li><a href="../../features/">V2 Features</a> - Complete feature documentation</li>
</ul>
<h2 id="next-steps">Next Steps<a class="headerlink" href="#next-steps" title="Permanent link">&para;</a></h2>
<ol>
<li><strong>Review feature matrix</strong> - Identify features you use</li>
<li><strong>Prioritize migration</strong> - Critical features first</li>
<li><strong>Test on staging</strong> - Verify feature parity</li>
<li><strong>Provide feedback</strong> - Report missing features</li>
<li><strong>Plan new feature adoption</strong> - Landing pages, canvassing, etc.</li>
</ol>
<div class="admonition success">
<p class="admonition-title">Feature Parity Achieved</p>
<p>V2 provides 100% V1 feature parity plus significant new capabilities. No functionality will be lost in migration.</p>
</div>
</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="../" class="md-footer__link md-footer__link--prev" aria-label="Previous: Migration Guide: V1 to V2 Overview">
<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">
Migration Guide: V1 to V2 Overview
</div>
</div>
</a>
<a href="../breaking-changes/" class="md-footer__link md-footer__link--next" aria-label="Next: Breaking Changes">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Breaking Changes
</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 &copy; 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>