2851 lines
82 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://cmlite.org/build/influence/">
<link rel="prev" href="../map/">
<link rel="next" href="../site/">
<link rel="icon" href="../../assets/favicon.png">
<meta name="generator" content="mkdocs-1.6.1, mkdocs-material-9.6.21">
<title>Build Influence - Changemaker Lite</title>
<link rel="stylesheet" href="../../assets/stylesheets/main.2a3383ac.min.css">
<link rel="stylesheet" href="../../assets/stylesheets/palette.06af60db.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">
<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="Build Influence - Changemaker Lite" >
<meta property="og:description" content="Build Power. Not Rent It. Own your digital infrastructure." >
<meta property="og:image" content="https://cmlite.org/assets/images/social/build/influence.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://cmlite.org/build/influence/" >
<meta name="twitter:card" content="summary_large_image" >
<meta name="twitter:title" content="Build Influence - Changemaker Lite" >
<meta name="twitter:description" content="Build Power. Not Rent It. Own your digital infrastructure." >
<meta name="twitter:image" content="https://cmlite.org/assets/images/social/build/influence.png" >
<!-- Custom meta tags or head content can go here -->
</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="#influence-build-guide" class="md-skip">
Skip to content
</a>
</div>
<div data-md-component="announce">
<aside class="md-banner">
<div class="md-banner__inner md-grid md-typeset">
<button class="md-banner__button md-icon" aria-label="Don't show this again">
<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>
<a href="https://homepage.cmlite.org" class="login-button">Login</a>
Changemaker Archive. <a href="https://docs.bnkops.com">Learn more</a>
</div>
<script>var el=document.querySelector("[data-md-component=announce]");if(el){var content=el.querySelector(".md-typeset");__md_hash(content.innerHTML)===__md_get("__announce")&&(el.hidden=!0)}</script>
</aside>
</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">
Build Influence
</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.0.1 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">
<a href="../../phil/" class="md-tabs__link">
Philosophy
</a>
</li>
<li class="md-tabs__item md-tabs__item--active">
<a href="../" class="md-tabs__link">
Getting Started
</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.0.1 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--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--active md-nav__item--section md-nav__item--nested">
<input class="md-nav__toggle md-toggle " type="checkbox" id="__nav_3" checked>
<div class="md-nav__link md-nav__container">
<a href="../" class="md-nav__link ">
<span class="md-ellipsis">
Getting Started
</span>
</a>
<label class="md-nav__link " for="__nav_3" id="__nav_3_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="1" aria-labelledby="__nav_3_label" aria-expanded="true">
<label class="md-nav__title" for="__nav_3">
<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="../server/" class="md-nav__link">
<span class="md-ellipsis">
Build Server
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../map/" class="md-nav__link">
<span class="md-ellipsis">
Build Map
</span>
</a>
</li>
<li class="md-nav__item md-nav__item--active">
<input class="md-nav__toggle md-toggle" type="checkbox" id="__toc">
<label class="md-nav__link md-nav__link--active" for="__toc">
<span class="md-ellipsis">
Build Influence
</span>
<span class="md-nav__icon md-icon"></span>
</label>
<a href="./" class="md-nav__link md-nav__link--active">
<span class="md-ellipsis">
Build Influence
</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="#prerequisites" class="md-nav__link">
<span class="md-ellipsis">
Prerequisites
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-build-process" class="md-nav__link">
<span class="md-ellipsis">
Quick Build Process
</span>
</a>
<nav class="md-nav" aria-label="Quick Build Process">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-get-nocodb-api-token" class="md-nav__link">
<span class="md-ellipsis">
1. Get NocoDB API Token
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-configure-environment" class="md-nav__link">
<span class="md-ellipsis">
2. Configure Environment
</span>
</a>
<nav class="md-nav" aria-label="2. Configure Environment">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#development-mode-configuration" class="md-nav__link">
<span class="md-ellipsis">
Development Mode Configuration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#3-auto-create-database-structure" class="md-nav__link">
<span class="md-ellipsis">
3. Auto-Create Database Structure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-build-and-deploy" class="md-nav__link">
<span class="md-ellipsis">
4. Build and Deploy
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#verify-installation" class="md-nav__link">
<span class="md-ellipsis">
Verify Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#initial-setup" class="md-nav__link">
<span class="md-ellipsis">
Initial Setup
</span>
</a>
<nav class="md-nav" aria-label="Initial Setup">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-create-admin-user" class="md-nav__link">
<span class="md-ellipsis">
1. Create Admin User
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-create-your-first-campaign" class="md-nav__link">
<span class="md-ellipsis">
2. Create Your First Campaign
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-test-representative-lookup" class="md-nav__link">
<span class="md-ellipsis">
3. Test Representative Lookup
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#development-workflow" class="md-nav__link">
<span class="md-ellipsis">
Development Workflow
</span>
</a>
<nav class="md-nav" aria-label="Development Workflow">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#email-testing-interface" class="md-nav__link">
<span class="md-ellipsis">
Email Testing Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mailhog-web-interface" class="md-nav__link">
<span class="md-ellipsis">
MailHog Web Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#switching-to-production" class="md-nav__link">
<span class="md-ellipsis">
Switching to Production
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#key-features" class="md-nav__link">
<span class="md-ellipsis">
Key Features
</span>
</a>
<nav class="md-nav" aria-label="Key Features">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#representative-lookup" class="md-nav__link">
<span class="md-ellipsis">
Representative Lookup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#campaign-system" class="md-nav__link">
<span class="md-ellipsis">
Campaign System
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#email-integration" class="md-nav__link">
<span class="md-ellipsis">
Email Integration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#api-endpoints" class="md-nav__link">
<span class="md-ellipsis">
API Endpoints
</span>
</a>
<nav class="md-nav" aria-label="API Endpoints">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#public-endpoints" class="md-nav__link">
<span class="md-ellipsis">
Public Endpoints
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-endpoints-authentication-required" class="md-nav__link">
<span class="md-ellipsis">
Admin Endpoints (Authentication Required)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#maintenance-commands" class="md-nav__link">
<span class="md-ellipsis">
Maintenance Commands
</span>
</a>
<nav class="md-nav" aria-label="Maintenance Commands">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#update-application" class="md-nav__link">
<span class="md-ellipsis">
Update Application
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#development-mode" class="md-nav__link">
<span class="md-ellipsis">
Development Mode
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#view-logs" class="md-nav__link">
<span class="md-ellipsis">
View Logs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#database-backup" class="md-nav__link">
<span class="md-ellipsis">
Database Backup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#health-check" class="md-nav__link">
<span class="md-ellipsis">
Health Check
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
<nav class="md-nav" aria-label="Troubleshooting">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#nocodb-connection-issues" class="md-nav__link">
<span class="md-ellipsis">
NocoDB Connection Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#email-not-sending" class="md-nav__link">
<span class="md-ellipsis">
Email Not Sending
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#no-representatives-found" class="md-nav__link">
<span class="md-ellipsis">
No Representatives Found
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#campaign-not-appearing" class="md-nav__link">
<span class="md-ellipsis">
Campaign Not Appearing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#production-deployment" class="md-nav__link">
<span class="md-ellipsis">
Production Deployment
</span>
</a>
<nav class="md-nav" aria-label="Production Deployment">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#environment-configuration" class="md-nav__link">
<span class="md-ellipsis">
Environment Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#docker-production" class="md-nav__link">
<span class="md-ellipsis">
Docker Production
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#monitoring" class="md-nav__link">
<span class="md-ellipsis">
Monitoring
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#security-considerations" class="md-nav__link">
<span class="md-ellipsis">
Security Considerations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#support" class="md-nav__link">
<span class="md-ellipsis">
Support
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="../site/" class="md-nav__link">
<span class="md-ellipsis">
Build Site
</span>
</a>
</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_3_6" >
<div class="md-nav__link md-nav__container">
<a href="../../services/" class="md-nav__link ">
<span class="md-ellipsis">
Services
</span>
</a>
<label class="md-nav__link " for="__nav_3_6" id="__nav_3_6_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_6_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_6">
<span class="md-nav__icon md-icon"></span>
Services
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../services/homepage/" class="md-nav__link">
<span class="md-ellipsis">
Homepage
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/code-server/" class="md-nav__link">
<span class="md-ellipsis">
Code Server
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/mkdocs/" class="md-nav__link">
<span class="md-ellipsis">
MKDocs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/static-server/" class="md-nav__link">
<span class="md-ellipsis">
Static Server
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/listmonk/" class="md-nav__link">
<span class="md-ellipsis">
Listmonk
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/postgresql/" class="md-nav__link">
<span class="md-ellipsis">
PostgreSQL
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/n8n/" class="md-nav__link">
<span class="md-ellipsis">
n8n
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/nocodb/" class="md-nav__link">
<span class="md-ellipsis">
NocoDB
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/gitea/" class="md-nav__link">
<span class="md-ellipsis">
Gitea
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/map/" class="md-nav__link">
<span class="md-ellipsis">
Map
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../services/mini-qr/" class="md-nav__link">
<span class="md-ellipsis">
Mini QR
</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_3_7" >
<div class="md-nav__link md-nav__container">
<a href="../../config/" class="md-nav__link ">
<span class="md-ellipsis">
Configuration
</span>
</a>
<label class="md-nav__link " for="__nav_3_7" id="__nav_3_7_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_7_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_7">
<span class="md-nav__icon md-icon"></span>
Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../config/cloudflare-config/" class="md-nav__link">
<span class="md-ellipsis">
Cloudflare
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../config/mkdocs/" class="md-nav__link">
<span class="md-ellipsis">
MKdocs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../config/coder/" class="md-nav__link">
<span class="md-ellipsis">
Code Server
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../config/map/" class="md-nav__link">
<span class="md-ellipsis">
Map
</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_3_8" >
<div class="md-nav__link md-nav__container">
<a href="../../manual/" class="md-nav__link ">
<span class="md-ellipsis">
Manuals
</span>
</a>
<label class="md-nav__link " for="__nav_3_8" id="__nav_3_8_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_8_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_8">
<span class="md-nav__icon md-icon"></span>
Manuals
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../manual/map/" class="md-nav__link">
<span class="md-ellipsis">
Map
</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_3_9" >
<div class="md-nav__link md-nav__container">
<a href="../../adv/" class="md-nav__link ">
<span class="md-ellipsis">
Advanced Configuration
</span>
</a>
<label class="md-nav__link " for="__nav_3_9" id="__nav_3_9_label" tabindex="">
<span class="md-nav__icon md-icon"></span>
</label>
</div>
<nav class="md-nav" data-md-level="2" aria-labelledby="__nav_3_9_label" aria-expanded="false">
<label class="md-nav__title" for="__nav_3_9">
<span class="md-nav__icon md-icon"></span>
Advanced Configuration
</label>
<ul class="md-nav__list" data-md-scrollfix>
<li class="md-nav__item">
<a href="../../adv/ansible/" class="md-nav__link">
<span class="md-ellipsis">
SSH + Tailscale + Ansible
</span>
</a>
</li>
<li class="md-nav__item">
<a href="../../adv/vscode-ssh/" class="md-nav__link">
<span class="md-ellipsis">
SSH + VScode
</span>
</a>
</li>
</ul>
</nav>
</li>
</ul>
</nav>
</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="#prerequisites" class="md-nav__link">
<span class="md-ellipsis">
Prerequisites
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#quick-build-process" class="md-nav__link">
<span class="md-ellipsis">
Quick Build Process
</span>
</a>
<nav class="md-nav" aria-label="Quick Build Process">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-get-nocodb-api-token" class="md-nav__link">
<span class="md-ellipsis">
1. Get NocoDB API Token
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-configure-environment" class="md-nav__link">
<span class="md-ellipsis">
2. Configure Environment
</span>
</a>
<nav class="md-nav" aria-label="2. Configure Environment">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#development-mode-configuration" class="md-nav__link">
<span class="md-ellipsis">
Development Mode Configuration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#3-auto-create-database-structure" class="md-nav__link">
<span class="md-ellipsis">
3. Auto-Create Database Structure
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#4-build-and-deploy" class="md-nav__link">
<span class="md-ellipsis">
4. Build and Deploy
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#verify-installation" class="md-nav__link">
<span class="md-ellipsis">
Verify Installation
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#initial-setup" class="md-nav__link">
<span class="md-ellipsis">
Initial Setup
</span>
</a>
<nav class="md-nav" aria-label="Initial Setup">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#1-create-admin-user" class="md-nav__link">
<span class="md-ellipsis">
1. Create Admin User
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#2-create-your-first-campaign" class="md-nav__link">
<span class="md-ellipsis">
2. Create Your First Campaign
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#3-test-representative-lookup" class="md-nav__link">
<span class="md-ellipsis">
3. Test Representative Lookup
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#development-workflow" class="md-nav__link">
<span class="md-ellipsis">
Development Workflow
</span>
</a>
<nav class="md-nav" aria-label="Development Workflow">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#email-testing-interface" class="md-nav__link">
<span class="md-ellipsis">
Email Testing Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#mailhog-web-interface" class="md-nav__link">
<span class="md-ellipsis">
MailHog Web Interface
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#switching-to-production" class="md-nav__link">
<span class="md-ellipsis">
Switching to Production
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#key-features" class="md-nav__link">
<span class="md-ellipsis">
Key Features
</span>
</a>
<nav class="md-nav" aria-label="Key Features">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#representative-lookup" class="md-nav__link">
<span class="md-ellipsis">
Representative Lookup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#campaign-system" class="md-nav__link">
<span class="md-ellipsis">
Campaign System
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#email-integration" class="md-nav__link">
<span class="md-ellipsis">
Email Integration
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#api-endpoints" class="md-nav__link">
<span class="md-ellipsis">
API Endpoints
</span>
</a>
<nav class="md-nav" aria-label="API Endpoints">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#public-endpoints" class="md-nav__link">
<span class="md-ellipsis">
Public Endpoints
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#admin-endpoints-authentication-required" class="md-nav__link">
<span class="md-ellipsis">
Admin Endpoints (Authentication Required)
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#maintenance-commands" class="md-nav__link">
<span class="md-ellipsis">
Maintenance Commands
</span>
</a>
<nav class="md-nav" aria-label="Maintenance Commands">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#update-application" class="md-nav__link">
<span class="md-ellipsis">
Update Application
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#development-mode" class="md-nav__link">
<span class="md-ellipsis">
Development Mode
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#view-logs" class="md-nav__link">
<span class="md-ellipsis">
View Logs
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#database-backup" class="md-nav__link">
<span class="md-ellipsis">
Database Backup
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#health-check" class="md-nav__link">
<span class="md-ellipsis">
Health Check
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#troubleshooting" class="md-nav__link">
<span class="md-ellipsis">
Troubleshooting
</span>
</a>
<nav class="md-nav" aria-label="Troubleshooting">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#nocodb-connection-issues" class="md-nav__link">
<span class="md-ellipsis">
NocoDB Connection Issues
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#email-not-sending" class="md-nav__link">
<span class="md-ellipsis">
Email Not Sending
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#no-representatives-found" class="md-nav__link">
<span class="md-ellipsis">
No Representatives Found
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#campaign-not-appearing" class="md-nav__link">
<span class="md-ellipsis">
Campaign Not Appearing
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#production-deployment" class="md-nav__link">
<span class="md-ellipsis">
Production Deployment
</span>
</a>
<nav class="md-nav" aria-label="Production Deployment">
<ul class="md-nav__list">
<li class="md-nav__item">
<a href="#environment-configuration" class="md-nav__link">
<span class="md-ellipsis">
Environment Configuration
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#docker-production" class="md-nav__link">
<span class="md-ellipsis">
Docker Production
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#monitoring" class="md-nav__link">
<span class="md-ellipsis">
Monitoring
</span>
</a>
</li>
</ul>
</nav>
</li>
<li class="md-nav__item">
<a href="#security-considerations" class="md-nav__link">
<span class="md-ellipsis">
Security Considerations
</span>
</a>
</li>
<li class="md-nav__item">
<a href="#support" class="md-nav__link">
<span class="md-ellipsis">
Support
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
</div>
<div class="md-content" data-md-component="content">
<article class="md-content__inner md-typeset">
<a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/mkdocs/docs/build/influence.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/build/influence.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="influence-build-guide">Influence Build Guide<a class="headerlink" href="#influence-build-guide" title="Permanent link">&para;</a></h1>
<p>Influence is BNKops campaign tool for connecting Alberta residents with their elected representatives across all levels of government.</p>
<div class="admonition info">
<p class="admonition-title">Complete Configuration</p>
<p>For detailed configuration, usage instructions, and troubleshooting, see the main <a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/influence/README.MD">Influence README</a>.</p>
</div>
<div class="admonition tip">
<p class="admonition-title">Email Testing</p>
<p>The application includes MailHog integration for safe email testing during development. All test emails are caught locally and never sent to actual representatives.</p>
</div>
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h2>
<ul>
<li>Docker and Docker Compose installed</li>
<li>NocoDB instance with API access</li>
<li>SMTP email configuration (or use MailHog for testing)</li>
<li>Domain name (optional but recommended for production)</li>
</ul>
<h2 id="quick-build-process">Quick Build Process<a class="headerlink" href="#quick-build-process" title="Permanent link">&para;</a></h2>
<h3 id="1-get-nocodb-api-token">1. Get NocoDB API Token<a class="headerlink" href="#1-get-nocodb-api-token" title="Permanent link">&para;</a></h3>
<ol>
<li>Login to your NocoDB instance</li>
<li>Click user icon → <strong>Account Settings</strong><strong>API Tokens</strong></li>
<li>Create new token with read/write permissions</li>
<li>Copy the token for the next step</li>
</ol>
<h3 id="2-configure-environment">2. Configure Environment<a class="headerlink" href="#2-configure-environment" title="Permanent link">&para;</a></h3>
<p>Navigate to the influence directory and create your environment file:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-0-1"><a id="__codelineno-0-1" name="__codelineno-0-1" href="#__codelineno-0-1"></a><span class="nb">cd</span><span class="w"> </span>influence
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>cp<span class="w"> </span>example.env<span class="w"> </span>.env
</span></code></pre></div>
<p>Edit the <code>.env</code> file with your configuration:</p>
<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># Server Configuration
</span><span id="__span-1-2"><a id="__codelineno-1-2" name="__codelineno-1-2" href="#__codelineno-1-2"></a>NODE_ENV=production
</span><span id="__span-1-3"><a id="__codelineno-1-3" name="__codelineno-1-3" href="#__codelineno-1-3"></a>PORT=3333
</span><span id="__span-1-4"><a id="__codelineno-1-4" name="__codelineno-1-4" href="#__codelineno-1-4"></a>
</span><span id="__span-1-5"><a id="__codelineno-1-5" name="__codelineno-1-5" href="#__codelineno-1-5"></a># NocoDB Configuration
</span><span id="__span-1-6"><a id="__codelineno-1-6" name="__codelineno-1-6" href="#__codelineno-1-6"></a>NOCODB_API_URL=https://your-nocodb-instance.com
</span><span id="__span-1-7"><a id="__codelineno-1-7" name="__codelineno-1-7" href="#__codelineno-1-7"></a>NOCODB_API_TOKEN=your_nocodb_api_token_here
</span><span id="__span-1-8"><a id="__codelineno-1-8" name="__codelineno-1-8" href="#__codelineno-1-8"></a>NOCODB_PROJECT_ID=your_project_id_here
</span><span id="__span-1-9"><a id="__codelineno-1-9" name="__codelineno-1-9" href="#__codelineno-1-9"></a>
</span><span id="__span-1-10"><a id="__codelineno-1-10" name="__codelineno-1-10" href="#__codelineno-1-10"></a># Email Configuration (Production SMTP)
</span><span id="__span-1-11"><a id="__codelineno-1-11" name="__codelineno-1-11" href="#__codelineno-1-11"></a>SMTP_HOST=smtp.gmail.com
</span><span id="__span-1-12"><a id="__codelineno-1-12" name="__codelineno-1-12" href="#__codelineno-1-12"></a>SMTP_PORT=587
</span><span id="__span-1-13"><a id="__codelineno-1-13" name="__codelineno-1-13" href="#__codelineno-1-13"></a>SMTP_SECURE=false
</span><span id="__span-1-14"><a id="__codelineno-1-14" name="__codelineno-1-14" href="#__codelineno-1-14"></a>SMTP_USER=your_email@gmail.com
</span><span id="__span-1-15"><a id="__codelineno-1-15" name="__codelineno-1-15" href="#__codelineno-1-15"></a>SMTP_PASS=your_app_password
</span><span id="__span-1-16"><a id="__codelineno-1-16" name="__codelineno-1-16" href="#__codelineno-1-16"></a>SMTP_FROM_NAME=BNKops Influence Campaign
</span><span id="__span-1-17"><a id="__codelineno-1-17" name="__codelineno-1-17" href="#__codelineno-1-17"></a>SMTP_FROM_EMAIL=your_email@gmail.com
</span><span id="__span-1-18"><a id="__codelineno-1-18" name="__codelineno-1-18" href="#__codelineno-1-18"></a>
</span><span id="__span-1-19"><a id="__codelineno-1-19" name="__codelineno-1-19" href="#__codelineno-1-19"></a># Rate Limiting
</span><span id="__span-1-20"><a id="__codelineno-1-20" name="__codelineno-1-20" href="#__codelineno-1-20"></a>RATE_LIMIT_WINDOW_MS=900000
</span><span id="__span-1-21"><a id="__codelineno-1-21" name="__codelineno-1-21" href="#__codelineno-1-21"></a>RATE_LIMIT_MAX_REQUESTS=100
</span></code></pre></div>
<h4 id="development-mode-configuration">Development Mode Configuration<a class="headerlink" href="#development-mode-configuration" title="Permanent link">&para;</a></h4>
<p>For development and testing, use MailHog to catch emails:</p>
<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># Development Mode
</span><span id="__span-2-2"><a id="__codelineno-2-2" name="__codelineno-2-2" href="#__codelineno-2-2"></a>NODE_ENV=development
</span><span id="__span-2-3"><a id="__codelineno-2-3" name="__codelineno-2-3" href="#__codelineno-2-3"></a>EMAIL_TEST_MODE=true
</span><span id="__span-2-4"><a id="__codelineno-2-4" name="__codelineno-2-4" href="#__codelineno-2-4"></a>
</span><span id="__span-2-5"><a id="__codelineno-2-5" name="__codelineno-2-5" href="#__codelineno-2-5"></a># MailHog SMTP (for development)
</span><span id="__span-2-6"><a id="__codelineno-2-6" name="__codelineno-2-6" href="#__codelineno-2-6"></a>SMTP_HOST=mailhog
</span><span id="__span-2-7"><a id="__codelineno-2-7" name="__codelineno-2-7" href="#__codelineno-2-7"></a>SMTP_PORT=1025
</span><span id="__span-2-8"><a id="__codelineno-2-8" name="__codelineno-2-8" href="#__codelineno-2-8"></a>SMTP_SECURE=false
</span><span id="__span-2-9"><a id="__codelineno-2-9" name="__codelineno-2-9" href="#__codelineno-2-9"></a>SMTP_USER=test
</span><span id="__span-2-10"><a id="__codelineno-2-10" name="__codelineno-2-10" href="#__codelineno-2-10"></a>SMTP_PASS=test
</span><span id="__span-2-11"><a id="__codelineno-2-11" name="__codelineno-2-11" href="#__codelineno-2-11"></a>SMTP_FROM_EMAIL=dev@albertainfluence.local
</span><span id="__span-2-12"><a id="__codelineno-2-12" name="__codelineno-2-12" href="#__codelineno-2-12"></a>SMTP_FROM_NAME=&quot;BNKops Influence Campaign (DEV)&quot;
</span><span id="__span-2-13"><a id="__codelineno-2-13" name="__codelineno-2-13" href="#__codelineno-2-13"></a>
</span><span id="__span-2-14"><a id="__codelineno-2-14" name="__codelineno-2-14" href="#__codelineno-2-14"></a># Email Testing
</span><span id="__span-2-15"><a id="__codelineno-2-15" name="__codelineno-2-15" href="#__codelineno-2-15"></a>TEST_EMAIL_RECIPIENT=developer@example.com
</span></code></pre></div>
<h3 id="3-auto-create-database-structure">3. Auto-Create Database Structure<a class="headerlink" href="#3-auto-create-database-structure" title="Permanent link">&para;</a></h3>
<p>Run the build script to create required NocoDB tables:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-3-1"><a id="__codelineno-3-1" name="__codelineno-3-1" href="#__codelineno-3-1"></a>chmod<span class="w"> </span>+x<span class="w"> </span>scripts/build-nocodb.sh
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a>./scripts/build-nocodb.sh
</span></code></pre></div>
<p>This creates six tables:
- <strong>Campaigns</strong> - Campaign configurations with email templates and settings
- <strong>Campaign Emails</strong> - Tracking of all emails sent through campaigns
- <strong>Representatives</strong> - Cached representative data by postal code
- <strong>Email Logs</strong> - System-wide email delivery logs
- <strong>Postal Codes</strong> - Canadian postal code geolocation data
- <strong>Users</strong> - Admin authentication and access control</p>
<h3 id="4-build-and-deploy">4. Build and Deploy<a class="headerlink" href="#4-build-and-deploy" title="Permanent link">&para;</a></h3>
<p>Build the Docker image and start the application:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-4-1"><a id="__codelineno-4-1" name="__codelineno-4-1" href="#__codelineno-4-1"></a><span class="c1"># Build the Docker image</span>
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>build
</span><span id="__span-4-3"><a id="__codelineno-4-3" name="__codelineno-4-3" href="#__codelineno-4-3"></a>
</span><span id="__span-4-4"><a id="__codelineno-4-4" name="__codelineno-4-4" href="#__codelineno-4-4"></a><span class="c1"># Start the application (includes MailHog in development)</span>
</span><span id="__span-4-5"><a id="__codelineno-4-5" name="__codelineno-4-5" href="#__codelineno-4-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<h2 id="verify-installation">Verify Installation<a class="headerlink" href="#verify-installation" title="Permanent link">&para;</a></h2>
<ol>
<li>
<p>Check container status:
<div class="language-bash highlight"><pre><span></span><code><span id="__span-5-1"><a id="__codelineno-5-1" name="__codelineno-5-1" href="#__codelineno-5-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps
</span></code></pre></div></p>
</li>
<li>
<p>View logs:
<div class="language-bash highlight"><pre><span></span><code><span id="__span-6-1"><a id="__codelineno-6-1" name="__codelineno-6-1" href="#__codelineno-6-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>app
</span></code></pre></div></p>
</li>
<li>
<p>Access the application:</p>
</li>
<li><strong>Main App</strong>: http://localhost:3333</li>
<li><strong>Admin Panel</strong>: http://localhost:3333/admin.html</li>
<li><strong>Email Testing</strong> (dev): http://localhost:3333/email-test.html</li>
<li><strong>MailHog UI</strong> (dev): http://localhost:8025</li>
</ol>
<h2 id="initial-setup">Initial Setup<a class="headerlink" href="#initial-setup" title="Permanent link">&para;</a></h2>
<h3 id="1-create-admin-user">1. Create Admin User<a class="headerlink" href="#1-create-admin-user" title="Permanent link">&para;</a></h3>
<p>Access the admin panel at <code>/admin.html</code> and create your first administrator account.</p>
<h3 id="2-create-your-first-campaign">2. Create Your First Campaign<a class="headerlink" href="#2-create-your-first-campaign" title="Permanent link">&para;</a></h3>
<ol>
<li>Login to the admin panel</li>
<li>Click <strong>"Create Campaign"</strong></li>
<li>Configure basic settings:</li>
<li>Campaign title and description</li>
<li>Email subject and body template</li>
<li>Upload cover photo (optional)</li>
<li>Set campaign options:</li>
<li>✅ Allow SMTP Email - Enable server-side sending</li>
<li>✅ Allow Mailto Link - Enable browser-based mailto</li>
<li>✅ Collect User Info - Request name and email</li>
<li>✅ Show Email Count - Display engagement metrics</li>
<li>✅ Allow Email Editing - Let users customize message</li>
<li>Select target government levels (Federal, Provincial, Municipal, School Board)</li>
<li>Set status to <strong>Active</strong> to make campaign public</li>
<li>Click <strong>"Create Campaign"</strong></li>
</ol>
<h3 id="3-test-representative-lookup">3. Test Representative Lookup<a class="headerlink" href="#3-test-representative-lookup" title="Permanent link">&para;</a></h3>
<ol>
<li>Visit the homepage</li>
<li>Enter an Alberta postal code (e.g., T5N4B8)</li>
<li>View representatives at all government levels</li>
<li>Test email sending functionality</li>
</ol>
<h2 id="development-workflow">Development Workflow<a class="headerlink" href="#development-workflow" title="Permanent link">&para;</a></h2>
<h3 id="email-testing-interface">Email Testing Interface<a class="headerlink" href="#email-testing-interface" title="Permanent link">&para;</a></h3>
<p>Access the email testing interface at <code>/email-test.html</code> (requires admin login):</p>
<p><strong>Features:</strong>
- 📧 <strong>Quick Test</strong> - Send test email with one click
- 👁️ <strong>Email Preview</strong> - Preview email formatting before sending
- ✏️ <strong>Custom Composition</strong> - Test with custom subject and message
- 📊 <strong>Email Logs</strong> - View all sent emails with filtering
- 🔧 <strong>SMTP Diagnostics</strong> - Test connection and troubleshoot</p>
<h3 id="mailhog-web-interface">MailHog Web Interface<a class="headerlink" href="#mailhog-web-interface" title="Permanent link">&para;</a></h3>
<p>Access MailHog at http://localhost:8025 to:
- View all caught emails during development
- Inspect email content, headers, and formatting
- Search and filter test emails
- Verify emails never leave your local environment</p>
<h3 id="switching-to-production">Switching to Production<a class="headerlink" href="#switching-to-production" title="Permanent link">&para;</a></h3>
<p>When ready to deploy to production:</p>
<ol>
<li>
<p>Update <code>.env</code> with production SMTP settings:
<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>EMAIL_TEST_MODE=false
</span><span id="__span-7-2"><a id="__codelineno-7-2" name="__codelineno-7-2" href="#__codelineno-7-2"></a>NODE_ENV=production
</span><span id="__span-7-3"><a id="__codelineno-7-3" name="__codelineno-7-3" href="#__codelineno-7-3"></a>SMTP_HOST=smtp.your-provider.com
</span><span id="__span-7-4"><a id="__codelineno-7-4" name="__codelineno-7-4" href="#__codelineno-7-4"></a>SMTP_USER=your-real-email@domain.com
</span><span id="__span-7-5"><a id="__codelineno-7-5" name="__codelineno-7-5" href="#__codelineno-7-5"></a>SMTP_PASS=your-real-password
</span></code></pre></div></p>
</li>
<li>
<p>Restart the application:
<div class="language-bash highlight"><pre><span></span><code><span id="__span-8-1"><a id="__codelineno-8-1" name="__codelineno-8-1" href="#__codelineno-8-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>restart
</span></code></pre></div></p>
</li>
</ol>
<h2 id="key-features">Key Features<a class="headerlink" href="#key-features" title="Permanent link">&para;</a></h2>
<h3 id="representative-lookup">Representative Lookup<a class="headerlink" href="#representative-lookup" title="Permanent link">&para;</a></h3>
<ul>
<li>Search by Alberta postal code (T prefix)</li>
<li>Display federal MPs, provincial MLAs, municipal representatives</li>
<li>Smart caching with NocoDB for fast performance</li>
<li>Graceful fallback to Represent API when cache unavailable</li>
</ul>
<h3 id="campaign-system">Campaign System<a class="headerlink" href="#campaign-system" title="Permanent link">&para;</a></h3>
<ul>
<li>Create unlimited advocacy campaigns</li>
<li>Upload cover photos for campaign pages</li>
<li>Customizable email templates</li>
<li>Optional user information collection</li>
<li>Toggle email count display for engagement metrics</li>
<li>Multi-level government targeting</li>
</ul>
<h3 id="email-integration">Email Integration<a class="headerlink" href="#email-integration" title="Permanent link">&para;</a></h3>
<ul>
<li>SMTP email sending with delivery confirmation</li>
<li>Mailto link support for browser-based email</li>
<li>Comprehensive email logging</li>
<li>Rate limiting for API protection</li>
<li>Test mode for safe development</li>
</ul>
<h2 id="api-endpoints">API Endpoints<a class="headerlink" href="#api-endpoints" title="Permanent link">&para;</a></h2>
<h3 id="public-endpoints">Public Endpoints<a class="headerlink" href="#public-endpoints" title="Permanent link">&para;</a></h3>
<ul>
<li><code>GET /</code> - Homepage with representative lookup</li>
<li><code>GET /campaign/:slug</code> - Individual campaign page</li>
<li><code>GET /api/public/campaigns</code> - List active campaigns</li>
<li><code>GET /api/representatives/by-postal/:postalCode</code> - Find representatives</li>
<li><code>POST /api/emails/send</code> - Send campaign email</li>
</ul>
<h3 id="admin-endpoints-authentication-required">Admin Endpoints (Authentication Required)<a class="headerlink" href="#admin-endpoints-authentication-required" title="Permanent link">&para;</a></h3>
<ul>
<li><code>GET /admin.html</code> - Campaign management dashboard</li>
<li><code>GET /email-test.html</code> - Email testing interface</li>
<li><code>POST /api/emails/preview</code> - Preview email without sending</li>
<li><code>POST /api/emails/test</code> - Send test email</li>
<li><code>GET /api/test-smtp</code> - Test SMTP connection</li>
</ul>
<h2 id="maintenance-commands">Maintenance Commands<a class="headerlink" href="#maintenance-commands" title="Permanent link">&para;</a></h2>
<h3 id="update-application">Update Application<a class="headerlink" href="#update-application" title="Permanent link">&para;</a></h3>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-9-1"><a id="__codelineno-9-1" name="__codelineno-9-1" href="#__codelineno-9-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>down
</span><span id="__span-9-2"><a id="__codelineno-9-2" name="__codelineno-9-2" href="#__codelineno-9-2"></a>git<span class="w"> </span>pull<span class="w"> </span>origin<span class="w"> </span>main
</span><span id="__span-9-3"><a id="__codelineno-9-3" name="__codelineno-9-3" href="#__codelineno-9-3"></a>docker<span class="w"> </span>compose<span class="w"> </span>build
</span><span id="__span-9-4"><a id="__codelineno-9-4" name="__codelineno-9-4" href="#__codelineno-9-4"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<h3 id="development-mode">Development Mode<a class="headerlink" href="#development-mode" title="Permanent link">&para;</a></h3>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-10-1"><a id="__codelineno-10-1" name="__codelineno-10-1" href="#__codelineno-10-1"></a><span class="nb">cd</span><span class="w"> </span>app
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>npm<span class="w"> </span>install
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>npm<span class="w"> </span>run<span class="w"> </span>dev
</span></code></pre></div>
<h3 id="view-logs">View Logs<a class="headerlink" href="#view-logs" title="Permanent link">&para;</a></h3>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-11-1"><a id="__codelineno-11-1" name="__codelineno-11-1" href="#__codelineno-11-1"></a><span class="c1"># Follow application logs</span>
</span><span id="__span-11-2"><a id="__codelineno-11-2" name="__codelineno-11-2" href="#__codelineno-11-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>app
</span><span id="__span-11-3"><a id="__codelineno-11-3" name="__codelineno-11-3" href="#__codelineno-11-3"></a>
</span><span id="__span-11-4"><a id="__codelineno-11-4" name="__codelineno-11-4" href="#__codelineno-11-4"></a><span class="c1"># View MailHog logs (development)</span>
</span><span id="__span-11-5"><a id="__codelineno-11-5" name="__codelineno-11-5" href="#__codelineno-11-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>mailhog
</span></code></pre></div>
<h3 id="database-backup">Database Backup<a class="headerlink" href="#database-backup" title="Permanent link">&para;</a></h3>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-12-1"><a id="__codelineno-12-1" name="__codelineno-12-1" href="#__codelineno-12-1"></a><span class="c1"># Backup is handled through NocoDB</span>
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a><span class="c1"># Access NocoDB admin panel to export tables</span>
</span></code></pre></div>
<h3 id="health-check">Health Check<a class="headerlink" href="#health-check" 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>curl<span class="w"> </span>http://localhost:3333/api/health
</span></code></pre></div>
<h2 id="troubleshooting">Troubleshooting<a class="headerlink" href="#troubleshooting" title="Permanent link">&para;</a></h2>
<h3 id="nocodb-connection-issues">NocoDB Connection Issues<a class="headerlink" href="#nocodb-connection-issues" title="Permanent link">&para;</a></h3>
<ul>
<li>Verify <code>NOCODB_API_URL</code> and <code>NOCODB_API_TOKEN</code> in <code>.env</code></li>
<li>Run <code>./scripts/build-nocodb.sh</code> to ensure tables exist</li>
<li>Application works without NocoDB (API fallback mode)</li>
</ul>
<h3 id="email-not-sending">Email Not Sending<a class="headerlink" href="#email-not-sending" title="Permanent link">&para;</a></h3>
<ul>
<li>In development: Check MailHog UI at http://localhost:8025</li>
<li>Verify SMTP credentials in <code>.env</code></li>
<li>Use <code>/email-test.html</code> interface for diagnostics</li>
<li>Check email logs via admin panel</li>
<li>Review <code>docker compose logs -f app</code> for errors</li>
</ul>
<h3 id="no-representatives-found">No Representatives Found<a class="headerlink" href="#no-representatives-found" title="Permanent link">&para;</a></h3>
<ul>
<li>Ensure postal code starts with 'T' (Alberta only)</li>
<li>Try different postal code format (remove spaces)</li>
<li>Check Represent API status: <code>curl http://localhost:3333/api/test-represent</code></li>
<li>Review application logs for API errors</li>
</ul>
<h3 id="campaign-not-appearing">Campaign Not Appearing<a class="headerlink" href="#campaign-not-appearing" title="Permanent link">&para;</a></h3>
<ul>
<li>Verify campaign status is set to "Active"</li>
<li>Check campaign configuration in admin panel</li>
<li>Clear browser cache and reload homepage</li>
<li>Review console for JavaScript errors</li>
</ul>
<h2 id="production-deployment">Production Deployment<a class="headerlink" href="#production-deployment" title="Permanent link">&para;</a></h2>
<h3 id="environment-configuration">Environment Configuration<a class="headerlink" href="#environment-configuration" title="Permanent link">&para;</a></h3>
<div class="language-text highlight"><pre><span></span><code><span id="__span-14-1"><a id="__codelineno-14-1" name="__codelineno-14-1" href="#__codelineno-14-1"></a>NODE_ENV=production
</span><span id="__span-14-2"><a id="__codelineno-14-2" name="__codelineno-14-2" href="#__codelineno-14-2"></a>EMAIL_TEST_MODE=false
</span><span id="__span-14-3"><a id="__codelineno-14-3" name="__codelineno-14-3" href="#__codelineno-14-3"></a>PORT=3333
</span><span id="__span-14-4"><a id="__codelineno-14-4" name="__codelineno-14-4" href="#__codelineno-14-4"></a>
</span><span id="__span-14-5"><a id="__codelineno-14-5" name="__codelineno-14-5" href="#__codelineno-14-5"></a># Use production SMTP settings
</span><span id="__span-14-6"><a id="__codelineno-14-6" name="__codelineno-14-6" href="#__codelineno-14-6"></a>SMTP_HOST=smtp.your-provider.com
</span><span id="__span-14-7"><a id="__codelineno-14-7" name="__codelineno-14-7" href="#__codelineno-14-7"></a>SMTP_PORT=587
</span><span id="__span-14-8"><a id="__codelineno-14-8" name="__codelineno-14-8" href="#__codelineno-14-8"></a>SMTP_SECURE=false
</span><span id="__span-14-9"><a id="__codelineno-14-9" name="__codelineno-14-9" href="#__codelineno-14-9"></a>SMTP_USER=your-production-email@domain.com
</span><span id="__span-14-10"><a id="__codelineno-14-10" name="__codelineno-14-10" href="#__codelineno-14-10"></a>SMTP_PASS=your-production-password
</span></code></pre></div>
<h3 id="docker-production">Docker Production<a class="headerlink" href="#docker-production" title="Permanent link">&para;</a></h3>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-15-1"><a id="__codelineno-15-1" name="__codelineno-15-1" href="#__codelineno-15-1"></a><span class="c1"># Build and start in production mode</span>
</span><span id="__span-15-2"><a id="__codelineno-15-2" name="__codelineno-15-2" href="#__codelineno-15-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>-f<span class="w"> </span>docker-compose.yml<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>--build
</span><span id="__span-15-3"><a id="__codelineno-15-3" name="__codelineno-15-3" href="#__codelineno-15-3"></a>
</span><span id="__span-15-4"><a id="__codelineno-15-4" name="__codelineno-15-4" href="#__codelineno-15-4"></a><span class="c1"># View logs</span>
</span><span id="__span-15-5"><a id="__codelineno-15-5" name="__codelineno-15-5" href="#__codelineno-15-5"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>-f<span class="w"> </span>app
</span><span id="__span-15-6"><a id="__codelineno-15-6" name="__codelineno-15-6" href="#__codelineno-15-6"></a>
</span><span id="__span-15-7"><a id="__codelineno-15-7" name="__codelineno-15-7" href="#__codelineno-15-7"></a><span class="c1"># Monitor health</span>
</span><span id="__span-15-8"><a id="__codelineno-15-8" name="__codelineno-15-8" href="#__codelineno-15-8"></a>watch<span class="w"> </span>curl<span class="w"> </span>http://localhost:3333/api/health
</span></code></pre></div>
<h3 id="monitoring">Monitoring<a class="headerlink" href="#monitoring" title="Permanent link">&para;</a></h3>
<ul>
<li>Health check endpoint: <code>/api/health</code></li>
<li>Email logs via admin panel</li>
<li>NocoDB integration status in logs</li>
<li>Rate limiting metrics in application logs</li>
</ul>
<h2 id="security-considerations">Security Considerations<a class="headerlink" href="#security-considerations" title="Permanent link">&para;</a></h2>
<ul>
<li>🔒 Always use strong passwords for admin accounts</li>
<li>🔒 Enable HTTPS in production (use reverse proxy)</li>
<li>🔒 Rotate SMTP credentials regularly</li>
<li>🔒 Monitor email logs for suspicious activity</li>
<li>🔒 Set appropriate rate limits based on expected traffic</li>
<li>🔒 Keep NocoDB API tokens secure and rotate periodically</li>
<li>🔒 Use <code>EMAIL_TEST_MODE=false</code> only in production</li>
</ul>
<h2 id="support">Support<a class="headerlink" href="#support" title="Permanent link">&para;</a></h2>
<p>For detailed configuration, troubleshooting, and usage instructions, see:
- <a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/influence/README.MD">Main Influence README</a>
- <a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/influence/CAMPAIGN_SETTINGS_GUIDE.md">Campaign Settings Guide</a>
- <a href="https://gitea.bnkops.com/admin/changemaker.lite/src/branch/main/influence/files-explainer.md">Files Explainer</a></p>
</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="../map/" class="md-footer__link md-footer__link--prev" aria-label="Previous: Build Map">
<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">
Build Map
</div>
</div>
</a>
<a href="../site/" class="md-footer__link md-footer__link--next" aria-label="Next: Build Site">
<div class="md-footer__title">
<span class="md-footer__direction">
Next
</span>
<div class="md-ellipsis">
Build Site
</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.0.1 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.0.1 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">{"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.973d3a69.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.f55a23d4.min.js"></script>
<script src="../../javascripts/home.js"></script>
<script src="../../javascripts/github-widget.js"></script>
<script src="../../javascripts/gitea-widget.js"></script>
</body>
</html>