Bunch of updates to scheduling

This commit is contained in:
2026-03-15 13:50:09 -06:00
parent 12734aca16
commit 28e4bc9475
202 changed files with 4568 additions and 226 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 98 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 167 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 119 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 110 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 106 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 91 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 73 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 136 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 179 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 82 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 92 KiB

View File

@@ -4,13 +4,13 @@
"description": "Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.",
"html_url": "https://github.com/anthropics/claude-code",
"language": "Shell",
"stars_count": 76742,
"forks_count": 6231,
"open_issues_count": 6021,
"updated_at": "2026-03-11T22:33:37Z",
"stars_count": 77129,
"forks_count": 6266,
"open_issues_count": 6171,
"updated_at": "2026-03-12T17:36:34Z",
"created_at": "2025-02-22T17:41:21Z",
"clone_url": "https://github.com/anthropics/claude-code.git",
"ssh_url": "git@github.com:anthropics/claude-code.git",
"default_branch": "main",
"last_build_update": "2026-03-11T18:26:43Z"
"last_build_update": "2026-03-12T07:12:41Z"
}

View File

@@ -4,10 +4,10 @@
"description": "VS Code in the browser",
"html_url": "https://github.com/coder/code-server",
"language": "TypeScript",
"stars_count": 76594,
"forks_count": 6545,
"open_issues_count": 169,
"updated_at": "2026-03-11T21:57:55Z",
"stars_count": 76609,
"forks_count": 6547,
"open_issues_count": 172,
"updated_at": "2026-03-12T17:13:08Z",
"created_at": "2019-02-27T16:50:41Z",
"clone_url": "https://github.com/coder/code-server.git",
"ssh_url": "git@github.com:coder/code-server.git",

View File

@@ -4,13 +4,13 @@
"description": "A highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.",
"html_url": "https://github.com/gethomepage/homepage",
"language": "JavaScript",
"stars_count": 28854,
"forks_count": 1814,
"stars_count": 28865,
"forks_count": 1813,
"open_issues_count": 1,
"updated_at": "2026-03-11T22:22:07Z",
"updated_at": "2026-03-12T15:01:15Z",
"created_at": "2022-08-24T07:29:42Z",
"clone_url": "https://github.com/gethomepage/homepage.git",
"ssh_url": "git@github.com:gethomepage/homepage.git",
"default_branch": "dev",
"last_build_update": "2026-03-11T12:22:48Z"
"last_build_update": "2026-03-12T12:22:19Z"
}

View File

@@ -4,13 +4,13 @@
"description": "Git with a cup of tea! Painless self-hosted all-in-one software development service, including Git hosting, code review, team collaboration, package registry and CI/CD",
"html_url": "https://github.com/go-gitea/gitea",
"language": "Go",
"stars_count": 54239,
"forks_count": 6462,
"stars_count": 54251,
"forks_count": 6466,
"open_issues_count": 2853,
"updated_at": "2026-03-11T20:30:04Z",
"updated_at": "2026-03-12T17:33:45Z",
"created_at": "2016-11-01T02:13:26Z",
"clone_url": "https://github.com/go-gitea/gitea.git",
"ssh_url": "git@github.com:go-gitea/gitea.git",
"default_branch": "main",
"last_build_update": "2026-03-11T00:45:58Z"
"last_build_update": "2026-03-12T08:26:47Z"
}

View File

@@ -4,13 +4,13 @@
"description": "High performance, self-hosted, newsletter and mailing list manager with a modern dashboard. Single binary app.",
"html_url": "https://github.com/knadh/listmonk",
"language": "Go",
"stars_count": 19249,
"forks_count": 1945,
"open_issues_count": 99,
"updated_at": "2026-03-11T19:52:24Z",
"stars_count": 19256,
"forks_count": 1946,
"open_issues_count": 101,
"updated_at": "2026-03-12T16:54:34Z",
"created_at": "2019-06-26T05:08:39Z",
"clone_url": "https://github.com/knadh/listmonk.git",
"ssh_url": "git@github.com:knadh/listmonk.git",
"default_branch": "master",
"last_build_update": "2026-03-09T03:05:44Z"
"last_build_update": "2026-03-12T16:54:26Z"
}

View File

@@ -4,10 +4,10 @@
"description": "Create & scan cute qr codes easily \ud83d\udc7e",
"html_url": "https://github.com/lyqht/mini-qr",
"language": "Vue",
"stars_count": 1903,
"stars_count": 1905,
"forks_count": 241,
"open_issues_count": 19,
"updated_at": "2026-03-11T20:14:32Z",
"updated_at": "2026-03-12T17:06:09Z",
"created_at": "2023-04-21T14:20:14Z",
"clone_url": "https://github.com/lyqht/mini-qr.git",
"ssh_url": "git@github.com:lyqht/mini-qr.git",

View File

@@ -4,13 +4,13 @@
"description": "Fair-code workflow automation platform with native AI capabilities. Combine visual building with custom code, self-host or cloud, 400+ integrations.",
"html_url": "https://github.com/n8n-io/n8n",
"language": "TypeScript",
"stars_count": 178720,
"forks_count": 55676,
"open_issues_count": 1407,
"updated_at": "2026-03-11T22:29:19Z",
"stars_count": 178836,
"forks_count": 55709,
"open_issues_count": 1414,
"updated_at": "2026-03-12T17:33:04Z",
"created_at": "2019-06-22T09:24:21Z",
"clone_url": "https://github.com/n8n-io/n8n.git",
"ssh_url": "git@github.com:n8n-io/n8n.git",
"default_branch": "master",
"last_build_update": "2026-03-11T22:29:32Z"
"last_build_update": "2026-03-12T16:48:37Z"
}

View File

@@ -4,13 +4,13 @@
"description": "\ud83d\udd25 \ud83d\udd25 \ud83d\udd25 A Free & Self-hostable Airtable Alternative",
"html_url": "https://github.com/nocodb/nocodb",
"language": "TypeScript",
"stars_count": 62469,
"forks_count": 4660,
"open_issues_count": 631,
"updated_at": "2026-03-11T20:56:04Z",
"stars_count": 62459,
"forks_count": 4662,
"open_issues_count": 636,
"updated_at": "2026-03-12T17:22:54Z",
"created_at": "2017-10-29T18:51:48Z",
"clone_url": "https://github.com/nocodb/nocodb.git",
"ssh_url": "git@github.com:nocodb/nocodb.git",
"default_branch": "develop",
"last_build_update": "2026-03-11T16:21:00Z"
"last_build_update": "2026-03-12T15:47:46Z"
}

View File

@@ -4,13 +4,13 @@
"description": "Get up and running with Kimi-K2.5, GLM-5, MiniMax, DeepSeek, gpt-oss, Qwen, Gemma and other models.",
"html_url": "https://github.com/ollama/ollama",
"language": "Go",
"stars_count": 164878,
"forks_count": 14911,
"stars_count": 164918,
"forks_count": 14922,
"open_issues_count": 2623,
"updated_at": "2026-03-11T21:51:46Z",
"updated_at": "2026-03-12T17:11:02Z",
"created_at": "2023-06-26T19:39:32Z",
"clone_url": "https://github.com/ollama/ollama.git",
"ssh_url": "git@github.com:ollama/ollama.git",
"default_branch": "main",
"last_build_update": "2026-03-11T21:51:41Z"
"last_build_update": "2026-03-12T08:42:26Z"
}

View File

@@ -4,10 +4,10 @@
"description": "Documentation that simply works",
"html_url": "https://github.com/squidfunk/mkdocs-material",
"language": "Python",
"stars_count": 26246,
"stars_count": 26261,
"forks_count": 4053,
"open_issues_count": 2,
"updated_at": "2026-03-11T21:16:34Z",
"updated_at": "2026-03-12T17:20:59Z",
"created_at": "2016-01-28T22:09:23Z",
"clone_url": "https://github.com/squidfunk/mkdocs-material.git",
"ssh_url": "git@github.com:squidfunk/mkdocs-material.git",

View File

@@ -3052,6 +3052,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="advocacy-campaigns">Advocacy Campaigns<a class="headerlink" href="#advocacy-campaigns" title="Permanent link">&para;</a></h1>
<p>Help supporters contact their elected representatives through email campaigns.</p>
<p><img alt="Campaigns Management" loading="lazy" src="../../../../assets/images/screenshots/admin/campaigns.png" /></p>
<hr />
<h2 id="how-it-works">How It Works<a class="headerlink" href="#how-it-works" title="Permanent link">&para;</a></h2>
<ol>

View File

@@ -2942,6 +2942,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="email-queue">Email Queue<a class="headerlink" href="#email-queue" title="Permanent link">&para;</a></h1>
<p>Monitor outgoing advocacy emails processed through the BullMQ queue.</p>
<p><img alt="Email Queue Monitor" loading="lazy" src="../../../../assets/images/screenshots/admin/email-queue.png" /></p>
<hr />
<h2 id="key-features">Key Features<a class="headerlink" href="#key-features" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -2942,6 +2942,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="representatives">Representatives<a class="headerlink" href="#representatives" title="Permanent link">&para;</a></h1>
<p>The platform uses the <a href="https://represent.opennorth.ca/">Represent API</a> to look up elected representatives by postal code across all government levels.</p>
<p><img alt="Representatives Cache" loading="lazy" src="../../../../assets/images/screenshots/admin/representatives.png" /></p>
<hr />
<h2 id="how-it-works">How It Works<a class="headerlink" href="#how-it-works" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -2942,6 +2942,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="response-moderation">Response Moderation<a class="headerlink" href="#response-moderation" title="Permanent link">&para;</a></h1>
<p>Review and moderate representative responses submitted by supporters on the public response wall.</p>
<p><img alt="Response Moderation" loading="lazy" src="../../../../assets/images/screenshots/admin/responses.png" /></p>
<hr />
<h2 id="key-features">Key Features<a class="headerlink" href="#key-features" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3000,6 +3000,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="email-templates">Email Templates<a class="headerlink" href="#email-templates" title="Permanent link">&para;</a></h1>
<p>Create reusable email templates with variable substitution for campaign communications. Templates are used by advocacy campaigns, shift confirmations, volunteer re-engagement emails, and other automated communications.</p>
<p><img alt="Email Templates" loading="lazy" src="../../../../assets/images/screenshots/admin/email-templates.png" /></p>
<hr />
<h2 id="template-categories">Template Categories<a class="headerlink" href="#template-categories" title="Permanent link">&para;</a></h2>
<p>Each template belongs to a category that determines where it can be used:</p>

View File

@@ -2956,6 +2956,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="newsletter-listmonk">Newsletter (Listmonk)<a class="headerlink" href="#newsletter-listmonk" title="Permanent link">&para;</a></h1>
<p>Integrated with <a href="https://listmonk.app/">Listmonk</a> for opt-in mailing lists and newsletter campaigns. Enable with <code>LISTMONK_SYNC_ENABLED=true</code>.</p>
<p><img alt="Newsletter Sync" loading="lazy" src="../../../../assets/images/screenshots/admin/newsletter.png" /></p>
<hr />
<h2 id="managed-lists">Managed Lists<a class="headerlink" href="#managed-lists" title="Permanent link">&para;</a></h2>
<p>The platform automatically creates and maintains 13 subscriber lists in Listmonk:</p>

View File

@@ -3744,6 +3744,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="sms-campaigns">SMS Campaigns<a class="headerlink" href="#sms-campaigns" title="Permanent link">&para;</a></h1>
<p>Text message outreach via a Termux Android bridge. Uses a real Android phone to send and receive SMS — no third-party SMS gateway or Twilio account needed.</p>
<p><img alt="SMS Dashboard" loading="lazy" src="../../../../assets/images/screenshots/admin/sms.png" /></p>
<p>Enable with <code>ENABLE_SMS=true</code> or via the setup wizard.</p>
<hr />
<h2 id="architecture-overview">Architecture Overview<a class="headerlink" href="#architecture-overview" title="Permanent link">&para;</a></h2>

View File

@@ -2761,6 +2761,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="dashboard">Dashboard<a class="headerlink" href="#dashboard" title="Permanent link">&para;</a></h1>
<p>The admin dashboard (<code>/app</code>) provides a real-time overview of platform activity.</p>
<p><img alt="Admin Dashboard" loading="lazy" src="../../../assets/images/screenshots/admin/dashboard.png" /></p>
<hr />
<h2 id="dashboard-cards">Dashboard Cards<a class="headerlink" href="#dashboard-cards" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3024,6 +3024,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="areas-cuts">Areas (Cuts)<a class="headerlink" href="#areas-cuts" title="Permanent link">&para;</a></h1>
<p>Draw polygon regions on the map to define canvassing territories. Areas organize locations into manageable chunks for volunteers.</p>
<p><img alt="Areas (Cuts)" loading="lazy" src="../../../../assets/images/screenshots/admin/areas.png" /></p>
<hr />
<h2 id="key-features">Key Features<a class="headerlink" href="#key-features" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3046,6 +3046,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="canvassing">Canvassing<a class="headerlink" href="#canvassing" title="Permanent link">&para;</a></h1>
<p>Coordinate and monitor volunteer door-to-door outreach with the canvass dashboard, walk sheets, and contact export tools.</p>
<p><img alt="Canvass Dashboard" loading="lazy" src="../../../../assets/images/screenshots/admin/canvassing.png" /></p>
<hr />
<h2 id="canvass-dashboard">Canvass Dashboard<a class="headerlink" href="#canvass-dashboard" title="Permanent link">&para;</a></h2>
<p>From <code>/app/map/canvass</code>:</p>

View File

@@ -3002,6 +3002,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="data-quality">Data Quality<a class="headerlink" href="#data-quality" title="Permanent link">&para;</a></h1>
<p>Monitor geocoding accuracy and coverage from <code>/app/map/data-quality</code>.</p>
<p><img alt="Data Quality Dashboard" loading="lazy" src="../../../../assets/images/screenshots/admin/data-quality.png" /></p>
<hr />
<h2 id="key-metrics">Key Metrics<a class="headerlink" href="#key-metrics" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3046,6 +3046,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="locations">Locations<a class="headerlink" href="#locations" title="Permanent link">&para;</a></h1>
<p>Import addresses via CSV or the Canadian National Address Register (NAR), geocode them with multiple providers, and manage the location database.</p>
<p><img alt="Map Locations" loading="lazy" src="../../../../assets/images/screenshots/admin/locations.png" /></p>
<hr />
<h2 id="adding-locations">Adding Locations<a class="headerlink" href="#adding-locations" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3002,6 +3002,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="map-settings">Map Settings<a class="headerlink" href="#map-settings" title="Permanent link">&para;</a></h1>
<p>Configure the default map view and QR code links from <code>/app/map/settings</code>.</p>
<p><img alt="Map Settings" loading="lazy" src="../../../../assets/images/screenshots/admin/map-settings.png" /></p>
<hr />
<h2 id="settings">Settings<a class="headerlink" href="#settings" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3046,6 +3046,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="shifts">Shifts<a class="headerlink" href="#shifts" title="Permanent link">&para;</a></h1>
<p>Schedule volunteer time slots and let people sign up through a public page. Shifts can be linked to specific areas so volunteers know where they'll be canvassing.</p>
<p><img alt="Volunteer Shifts" loading="lazy" src="../../../../assets/images/screenshots/admin/shifts.png" /></p>
<hr />
<h2 id="creating-shifts">Creating Shifts<a class="headerlink" href="#creating-shifts" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3016,6 +3016,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="analytics">Analytics<a class="headerlink" href="#analytics" title="Permanent link">&para;</a></h1>
<p>Track video engagement with GDPR-compliant analytics (IP hashing, 90-day retention).</p>
<p><img alt="Media Analytics" loading="lazy" src="../../../../assets/images/screenshots/admin/media-analytics.png" /></p>
<hr />
<h2 id="per-video-metrics">Per-Video Metrics<a class="headerlink" href="#per-video-metrics" title="Permanent link">&para;</a></h2>
<p>Each video tracks:</p>

View File

@@ -2994,6 +2994,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="curated-gallery">Curated Gallery<a class="headerlink" href="#curated-gallery" title="Permanent link">&para;</a></h1>
<p>Curate the public gallery experience with playlists, a shorts feed, and featured content.</p>
<p><img alt="Curated Gallery" loading="lazy" src="../../../../assets/images/screenshots/admin/media-curated.png" /></p>
<hr />
<h2 id="playlists">Playlists<a class="headerlink" href="#playlists" title="Permanent link">&para;</a></h2>
<p>From <code>/app/media/curated</code>:</p>

View File

@@ -3038,6 +3038,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="library">Library<a class="headerlink" href="#library" title="Permanent link">&para;</a></h1>
<p>The media library at <code>/app/media/library</code> is where you upload, organize, and publish video and photo content.</p>
<p><img alt="Media Library" loading="lazy" src="../../../../assets/images/screenshots/admin/media-library.png" /></p>
<hr />
<h2 id="video-upload">Video Upload<a class="headerlink" href="#video-upload" title="Permanent link">&para;</a></h2>
<ul>

View File

@@ -3137,6 +3137,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="people-access">People &amp; Access<a class="headerlink" href="#people-access" title="Permanent link">&para;</a></h1>
<p>Manage platform user accounts and roles, and use the People CRM to get a unified view of every supporter, donor, and volunteer across all modules.</p>
<p><img alt="Users Management" loading="lazy" src="../../../assets/images/screenshots/admin/users.png" /></p>
<hr />
<h2 id="user-management">User Management<a class="headerlink" href="#user-management" title="Permanent link">&para;</a></h2>
<h3 id="creating-users">Creating Users<a class="headerlink" href="#creating-users" title="Permanent link">&para;</a></h3>

View File

@@ -3060,6 +3060,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="monitoring">Monitoring<a class="headerlink" href="#monitoring" title="Permanent link">&para;</a></h1>
<p>The monitoring stack runs as a Docker Compose profile and provides metrics collection, visualization, and alerting.</p>
<p><img alt="Observability Dashboard" loading="lazy" src="../../../../assets/images/screenshots/admin/monitoring.png" /></p>
<hr />
<h2 id="starting-the-stack">Starting the Stack<a class="headerlink" href="#starting-the-stack" title="Permanent link">&para;</a></h2>
<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>docker<span class="w"> </span>compose<span class="w"> </span>--profile<span class="w"> </span>monitoring<span class="w"> </span>up<span class="w"> </span>-d

View File

@@ -3038,6 +3038,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="tunnel-pangolin">Tunnel (Pangolin)<a class="headerlink" href="#tunnel-pangolin" title="Permanent link">&para;</a></h1>
<p>Pangolin provides secure tunneling to expose your self-hosted services to the internet without port forwarding or a static IP.</p>
<p><img alt="Tunnel Management" loading="lazy" src="../../../../assets/images/screenshots/admin/tunnel.png" /></p>
<hr />
<h2 id="setup">Setup<a class="headerlink" href="#setup" title="Permanent link">&para;</a></h2>
<p>From <code>/app/pangolin</code>:</p>

View File

@@ -2905,6 +2905,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="platform-settings">Platform Settings<a class="headerlink" href="#platform-settings" title="Permanent link">&para;</a></h1>
<p>Centralized configuration for organization identity, theming, email delivery, feature modules, and automated notifications.</p>
<p><img alt="Settings Page" loading="lazy" src="../../../assets/images/screenshots/admin/settings.png" /></p>
<hr />
<h2 id="settings-tabs">Settings Tabs<a class="headerlink" href="#settings-tabs" title="Permanent link">&para;</a></h2>
<h3 id="organization">Organization<a class="headerlink" href="#organization" title="Permanent link">&para;</a></h3>

View File

@@ -2964,6 +2964,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="landing-pages">Landing Pages<a class="headerlink" href="#landing-pages" title="Permanent link">&para;</a></h1>
<p>Build campaign microsites with a drag-and-drop visual editor.</p>
<p><img alt="Landing Pages" loading="lazy" src="../../../../assets/images/screenshots/admin/landing-pages.png" /></p>
<hr />
<h2 id="how-it-works">How It Works<a class="headerlink" href="#how-it-works" title="Permanent link">&para;</a></h2>
<ol>

View File

@@ -2570,6 +2570,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<hr />
<h2 id="1-log-in">1. Log In<a class="headerlink" href="#1-log-in" title="Permanent link">&para;</a></h2>
<p>Open the admin panel at <code>http://localhost:3000</code> (or <code>app.DOMAIN</code> in production) and sign in with the admin email and password you configured during setup.</p>
<p><img alt="Login Page" loading="lazy" src="../../../assets/images/screenshots/getting-started/login.png" /></p>
<div class="admonition warning">
<p class="admonition-title">Change your password</p>
<p>If you used the wizard's generated password, change it immediately from <strong>Settings &gt; Organization</strong>.</p>
@@ -2577,6 +2578,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<hr />
<h2 id="2-explore-the-dashboard">2. Explore the Dashboard<a class="headerlink" href="#2-explore-the-dashboard" title="Permanent link">&para;</a></h2>
<p>The dashboard gives you an at-a-glance view of platform activity. Initially it will be empty — that's normal.</p>
<p><img alt="Admin Dashboard" loading="lazy" src="../../../assets/images/screenshots/getting-started/dashboard.png" /></p>
<hr />
<h2 id="3-configure-settings">3. Configure Settings<a class="headerlink" href="#3-configure-settings" title="Permanent link">&para;</a></h2>
<p>Visit <strong>Settings</strong> (<code>/app/settings</code>) to:</p>
@@ -2587,6 +2589,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<li>Configure email delivery (MailHog for testing, production SMTP for live use)</li>
<li>Check the <strong>System</strong> tab to verify your installation and check for updates</li>
</ul>
<p><img alt="Settings Page" loading="lazy" src="../../../assets/images/screenshots/getting-started/settings-organization.png" /></p>
<hr />
<h2 id="4-create-your-first-campaign">4. Create Your First Campaign<a class="headerlink" href="#4-create-your-first-campaign" title="Permanent link">&para;</a></h2>
<p>Go to <strong>Campaigns</strong> (<code>/app/campaigns</code>) and click <strong>Create Campaign</strong>:</p>
@@ -2596,6 +2599,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<li>Select government levels to target</li>
<li>Publish — the campaign appears at <code>/campaigns</code></li>
</ol>
<p><img alt="Campaigns Page" loading="lazy" src="../../../assets/images/screenshots/getting-started/campaigns.png" /></p>
<hr />
<h2 id="5-add-locations">5. Add Locations<a class="headerlink" href="#5-add-locations" title="Permanent link">&para;</a></h2>
<p>Go to <strong>Locations</strong> (<code>/app/map</code>) and add addresses:</p>
@@ -2604,6 +2608,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<li>Import a CSV of addresses</li>
<li>Use the NAR (National Address Register) import for Canadian data</li>
</ul>
<p><img alt="Locations Page" loading="lazy" src="../../../assets/images/screenshots/getting-started/locations.png" /></p>
<hr />
<h2 id="6-schedule-a-shift">6. Schedule a Shift<a class="headerlink" href="#6-schedule-a-shift" title="Permanent link">&para;</a></h2>
<p>Go to <strong>Shifts</strong> (<code>/app/map/shifts</code>) and create your first volunteer shift:</p>
@@ -2612,6 +2617,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<li>Optionally link it to a canvassing area</li>
<li>Share the public shifts page (<code>/shifts</code>) with volunteers</li>
</ol>
<p><img alt="Shifts Page" loading="lazy" src="../../../assets/images/screenshots/getting-started/shifts.png" /></p>
<hr />
<h2 id="7-invite-volunteers">7. Invite Volunteers<a class="headerlink" href="#7-invite-volunteers" title="Permanent link">&para;</a></h2>
<p>Share the shifts page link or generate QR codes for in-person events. Volunteers sign up with just an email address.</p>

View File

@@ -2395,6 +2395,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<h1 id="getting-started">Getting Started<a class="headerlink" href="#getting-started" title="Permanent link">&para;</a></h1>
<p>This guide walks you through installing Changemaker Lite, running your first deployment, and logging into the admin dashboard.</p>
<p><img alt="Admin Dashboard" loading="lazy" src="../../assets/images/screenshots/getting-started/dashboard.png" /></p>
<h2 id="prerequisites">Prerequisites<a class="headerlink" href="#prerequisites" title="Permanent link">&para;</a></h2>
<ul>
<li><strong>Docker</strong> 24+ and <strong>Docker Compose</strong> v2</li>
@@ -2407,10 +2408,10 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<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>git<span class="w"> </span>clone<span class="w"> </span>https://gitea.bnkops.com/admin/changemaker.lite
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="nb">cd</span><span class="w"> </span>changemaker.lite
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>git<span class="w"> </span>checkout<span class="w"> </span>v2
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>bash<span class="w"> </span>config.sh
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>bash<span class="w"> </span>config.sh
</span></code></pre></div>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<p>Open <strong>http://localhost:3000</strong> and sign in with the admin email and password you configured. The API container automatically runs database migrations and seeding on first startup — no manual steps needed.</p>
<div class="admonition warning">

View File

@@ -2954,16 +2954,16 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
</ul>
<hr />
<h2 id="quick-start">Quick Start<a class="headerlink" href="#quick-start" title="Permanent link">&para;</a></h2>
<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="c1"># Clone the repository</span>
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a>git<span class="w"> </span>clone<span class="w"> </span>https://gitea.bnkops.com/admin/changemaker.lite
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a><span class="nb">cd</span><span class="w"> </span>changemaker.lite
</span><span id="__span-0-4"><a id="__codelineno-0-4" name="__codelineno-0-4" href="#__codelineno-0-4"></a>git<span class="w"> </span>checkout<span class="w"> </span>v2
</span><span id="__span-0-5"><a id="__codelineno-0-5" name="__codelineno-0-5" href="#__codelineno-0-5"></a>
</span><span id="__span-0-6"><a id="__codelineno-0-6" name="__codelineno-0-6" href="#__codelineno-0-6"></a><span class="c1"># Run the configuration wizard</span>
</span><span id="__span-0-7"><a id="__codelineno-0-7" name="__codelineno-0-7" href="#__codelineno-0-7"></a>bash<span class="w"> </span>config.sh
</span><span id="__span-0-8"><a id="__codelineno-0-8" name="__codelineno-0-8" href="#__codelineno-0-8"></a>
</span><span id="__span-0-9"><a id="__codelineno-0-9" name="__codelineno-0-9" href="#__codelineno-0-9"></a><span class="c1"># Start all services</span>
</span><span id="__span-0-10"><a id="__codelineno-0-10" name="__codelineno-0-10" href="#__codelineno-0-10"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
<p>Clone the repository:</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>git<span class="w"> </span>clone<span class="w"> </span>https://gitea.bnkops.com/admin/changemaker.lite
</span><span id="__span-0-2"><a id="__codelineno-0-2" name="__codelineno-0-2" href="#__codelineno-0-2"></a><span class="nb">cd</span><span class="w"> </span>changemaker.lite
</span><span id="__span-0-3"><a id="__codelineno-0-3" name="__codelineno-0-3" href="#__codelineno-0-3"></a>git<span class="w"> </span>checkout<span class="w"> </span>v2
</span></code></pre></div>
<p>Run the configuration wizard:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-1-1"><a id="__codelineno-1-1" name="__codelineno-1-1" href="#__codelineno-1-1"></a>bash<span class="w"> </span>config.sh
</span></code></pre></div>
<p>Start all services:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<p>Open <strong>http://localhost:3000</strong> and sign in with the admin credentials you configured. Database migrations and seeding run automatically on first startup.</p>
<div class="admonition warning">
@@ -3200,7 +3200,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<p>Complete tunnel setup is done from the admin GUI at <strong>Settings &gt; Tunnel</strong> after services are running.</p>
<h3 id="step-9-cors-origins">Step 9: CORS Origins<a class="headerlink" href="#step-9-cors-origins" title="Permanent link">&para;</a></h3>
<p>Automatically calculates allowed origins from your domain:</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>http://app.DOMAIN,https://app.DOMAIN,http://DOMAIN,https://DOMAIN,http://localhost:3000,http://localhost,http://localhost:4003
<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>http://app.DOMAIN,https://app.DOMAIN,http://DOMAIN,https://DOMAIN,http://localhost:3000,http://localhost,http://localhost:4003
</span></code></pre></div>
<h3 id="step-10-nginx-config-generation">Step 10: Nginx Config Generation<a class="headerlink" href="#step-10-nginx-config-generation" title="Permanent link">&para;</a></h3>
<p>Renders all <code>.conf.template</code> files in <code>nginx/conf.d/</code> by substituting <code>${DOMAIN}</code> with your configured domain. This produces the nginx configuration files that handle subdomain routing.</p>
@@ -3315,19 +3315,19 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<hr />
<h2 id="manual-setup-alternative">Manual Setup (Alternative)<a class="headerlink" href="#manual-setup-alternative" title="Permanent link">&para;</a></h2>
<p>If you prefer to configure by hand instead of using the wizard:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-2-1"><a id="__codelineno-2-1" name="__codelineno-2-1" href="#__codelineno-2-1"></a>cp<span class="w"> </span>.env.example<span class="w"> </span>.env
<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>cp<span class="w"> </span>.env.example<span class="w"> </span>.env
</span></code></pre></div>
<p>At minimum, set these required secrets:</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><span class="c1"># Generate cryptographic secrets</span>
</span><span id="__span-3-2"><a id="__codelineno-3-2" name="__codelineno-3-2" href="#__codelineno-3-2"></a><span class="nv">V2_POSTGRES_PASSWORD</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-base64<span class="w"> </span><span class="m">48</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-dc<span class="w"> </span><span class="s1">&#39;a-zA-Z0-9&#39;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>head<span class="w"> </span>-c<span class="w"> </span><span class="m">24</span><span class="k">)</span>
</span><span id="__span-3-3"><a id="__codelineno-3-3" name="__codelineno-3-3" href="#__codelineno-3-3"></a><span class="nv">REDIS_PASSWORD</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-base64<span class="w"> </span><span class="m">48</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-dc<span class="w"> </span><span class="s1">&#39;a-zA-Z0-9&#39;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>head<span class="w"> </span>-c<span class="w"> </span><span class="m">24</span><span class="k">)</span>
</span><span id="__span-3-4"><a id="__codelineno-3-4" name="__codelineno-3-4" href="#__codelineno-3-4"></a><span class="nv">JWT_ACCESS_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span><span id="__span-3-5"><a id="__codelineno-3-5" name="__codelineno-3-5" href="#__codelineno-3-5"></a><span class="nv">JWT_REFRESH_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span><span id="__span-3-6"><a id="__codelineno-3-6" name="__codelineno-3-6" href="#__codelineno-3-6"></a><span class="nv">ENCRYPTION_KEY</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
<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><span class="c1"># Generate cryptographic secrets</span>
</span><span id="__span-5-2"><a id="__codelineno-5-2" name="__codelineno-5-2" href="#__codelineno-5-2"></a><span class="nv">V2_POSTGRES_PASSWORD</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-base64<span class="w"> </span><span class="m">48</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-dc<span class="w"> </span><span class="s1">&#39;a-zA-Z0-9&#39;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>head<span class="w"> </span>-c<span class="w"> </span><span class="m">24</span><span class="k">)</span>
</span><span id="__span-5-3"><a id="__codelineno-5-3" name="__codelineno-5-3" href="#__codelineno-5-3"></a><span class="nv">REDIS_PASSWORD</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-base64<span class="w"> </span><span class="m">48</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>tr<span class="w"> </span>-dc<span class="w"> </span><span class="s1">&#39;a-zA-Z0-9&#39;</span><span class="w"> </span><span class="p">|</span><span class="w"> </span>head<span class="w"> </span>-c<span class="w"> </span><span class="m">24</span><span class="k">)</span>
</span><span id="__span-5-4"><a id="__codelineno-5-4" name="__codelineno-5-4" href="#__codelineno-5-4"></a><span class="nv">JWT_ACCESS_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span><span id="__span-5-5"><a id="__codelineno-5-5" name="__codelineno-5-5" href="#__codelineno-5-5"></a><span class="nv">JWT_REFRESH_SECRET</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span><span id="__span-5-6"><a id="__codelineno-5-6" name="__codelineno-5-6" href="#__codelineno-5-6"></a><span class="nv">ENCRYPTION_KEY</span><span class="o">=</span><span class="k">$(</span>openssl<span class="w"> </span>rand<span class="w"> </span>-hex<span class="w"> </span><span class="m">32</span><span class="k">)</span>
</span></code></pre></div>
<p>Set your admin credentials (password must meet the 12+ char complexity requirement):</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="nv">INITIAL_ADMIN_EMAIL</span><span class="o">=</span>admin@yourdomain.org
</span><span id="__span-4-2"><a id="__codelineno-4-2" name="__codelineno-4-2" href="#__codelineno-4-2"></a><span class="nv">INITIAL_ADMIN_PASSWORD</span><span class="o">=</span>YourStrongPassword1
<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><span class="nv">INITIAL_ADMIN_EMAIL</span><span class="o">=</span>admin@yourdomain.org
</span><span id="__span-6-2"><a id="__codelineno-6-2" name="__codelineno-6-2" href="#__codelineno-6-2"></a><span class="nv">INITIAL_ADMIN_PASSWORD</span><span class="o">=</span>YourStrongPassword1
</span></code></pre></div>
<p>Then configure optional sections:</p>
<ul>
@@ -3340,7 +3340,7 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<hr />
<h2 id="full-stack-startup">Full Stack Startup<a class="headerlink" href="#full-stack-startup" title="Permanent link">&para;</a></h2>
<p>After configuration, start the entire platform:</p>
<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>up<span class="w"> </span>-d
<div class="language-bash highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<p>That's it. Docker handles the startup order automatically:</p>
<ol>
@@ -3351,40 +3351,40 @@ body.cm-search-active .md-header--cm-hidden .md-search__output {
<li><strong>Init containers</strong> (nocodb-init, listmonk-init, etc.) run once and exit</li>
</ol>
<p>Watch the startup progress:</p>
<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>api<span class="w"> </span>--tail<span class="w"> </span><span class="m">20</span>
<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>logs<span class="w"> </span>-f<span class="w"> </span>api<span class="w"> </span>--tail<span class="w"> </span><span class="m">20</span>
</span></code></pre></div>
<p>Once you see <code>Starting server on port 4000</code>, open <strong>http://localhost:3000</strong> and log in.</p>
<h3 id="include-monitoring">Include Monitoring<a class="headerlink" href="#include-monitoring" title="Permanent link">&para;</a></h3>
<p>The monitoring stack (Prometheus, Grafana, Alertmanager) uses a Docker Compose profile and isn't included by default:</p>
<div class="language-bash highlight"><pre><span></span><code><span id="__span-7-1"><a id="__codelineno-7-1" name="__codelineno-7-1" href="#__codelineno-7-1"></a>docker<span class="w"> </span>compose<span class="w"> </span>--profile<span class="w"> </span>monitoring<span class="w"> </span>up<span class="w"> </span>-d
<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>--profile<span class="w"> </span>monitoring<span class="w"> </span>up<span class="w"> </span>-d
</span></code></pre></div>
<h3 id="start-only-core-services">Start Only Core Services<a class="headerlink" href="#start-only-core-services" title="Permanent link">&para;</a></h3>
<p>If you prefer a minimal startup (lower resource usage):</p>
<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>up<span class="w"> </span>-d<span class="w"> </span>v2-postgres<span class="w"> </span>redis<span class="w"> </span>api<span class="w"> </span>admin<span class="w"> </span>nginx
<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>docker<span class="w"> </span>compose<span class="w"> </span>up<span class="w"> </span>-d<span class="w"> </span>v2-postgres<span class="w"> </span>redis<span class="w"> </span>api<span class="w"> </span>admin<span class="w"> </span>nginx
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title">Manual migrations</p>
<p>The API container runs migrations and seeding automatically on startup via its
entrypoint script. You only need to run them manually if you're developing
locally without Docker:</p>
<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><span class="nb">cd</span><span class="w"> </span>api<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>migrate<span class="w"> </span>deploy<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>db<span class="w"> </span>seed
<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="nb">cd</span><span class="w"> </span>api<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>migrate<span class="w"> </span>deploy<span class="w"> </span><span class="o">&amp;&amp;</span><span class="w"> </span>npx<span class="w"> </span>prisma<span class="w"> </span>db<span class="w"> </span>seed
</span></code></pre></div>
</div>
<p>See <a href="../services/">Services Overview</a> for the complete service catalog.</p>
<hr />
<h2 id="verifying-installation">Verifying Installation<a class="headerlink" href="#verifying-installation" title="Permanent link">&para;</a></h2>
<p>After starting services, verify everything is healthy:</p>
<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="c1"># Check running containers</span>
</span><span id="__span-10-2"><a id="__codelineno-10-2" name="__codelineno-10-2" href="#__codelineno-10-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps
</span><span id="__span-10-3"><a id="__codelineno-10-3" name="__codelineno-10-3" href="#__codelineno-10-3"></a>
</span><span id="__span-10-4"><a id="__codelineno-10-4" name="__codelineno-10-4" href="#__codelineno-10-4"></a><span class="c1"># API health check</span>
</span><span id="__span-10-5"><a id="__codelineno-10-5" name="__codelineno-10-5" href="#__codelineno-10-5"></a>curl<span class="w"> </span>-s<span class="w"> </span>http://localhost:4000/api/health<span class="w"> </span><span class="p">|</span><span class="w"> </span>python3<span class="w"> </span>-m<span class="w"> </span>json.tool
</span><span id="__span-10-6"><a id="__codelineno-10-6" name="__codelineno-10-6" href="#__codelineno-10-6"></a>
</span><span id="__span-10-7"><a id="__codelineno-10-7" name="__codelineno-10-7" href="#__codelineno-10-7"></a><span class="c1"># View API logs</span>
</span><span id="__span-10-8"><a id="__codelineno-10-8" name="__codelineno-10-8" href="#__codelineno-10-8"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span>--tail<span class="w"> </span><span class="m">20</span>
</span><span id="__span-10-9"><a id="__codelineno-10-9" name="__codelineno-10-9" href="#__codelineno-10-9"></a>
</span><span id="__span-10-10"><a id="__codelineno-10-10" name="__codelineno-10-10" href="#__codelineno-10-10"></a><span class="c1"># Check for containers in restart loops</span>
</span><span id="__span-10-11"><a id="__codelineno-10-11" name="__codelineno-10-11" href="#__codelineno-10-11"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>-i<span class="w"> </span>restarting
<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"># Check running containers</span>
</span><span id="__span-12-2"><a id="__codelineno-12-2" name="__codelineno-12-2" href="#__codelineno-12-2"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps
</span><span id="__span-12-3"><a id="__codelineno-12-3" name="__codelineno-12-3" href="#__codelineno-12-3"></a>
</span><span id="__span-12-4"><a id="__codelineno-12-4" name="__codelineno-12-4" href="#__codelineno-12-4"></a><span class="c1"># API health check</span>
</span><span id="__span-12-5"><a id="__codelineno-12-5" name="__codelineno-12-5" href="#__codelineno-12-5"></a>curl<span class="w"> </span>-s<span class="w"> </span>http://localhost:4000/api/health<span class="w"> </span><span class="p">|</span><span class="w"> </span>python3<span class="w"> </span>-m<span class="w"> </span>json.tool
</span><span id="__span-12-6"><a id="__codelineno-12-6" name="__codelineno-12-6" href="#__codelineno-12-6"></a>
</span><span id="__span-12-7"><a id="__codelineno-12-7" name="__codelineno-12-7" href="#__codelineno-12-7"></a><span class="c1"># View API logs</span>
</span><span id="__span-12-8"><a id="__codelineno-12-8" name="__codelineno-12-8" href="#__codelineno-12-8"></a>docker<span class="w"> </span>compose<span class="w"> </span>logs<span class="w"> </span>api<span class="w"> </span>--tail<span class="w"> </span><span class="m">20</span>
</span><span id="__span-12-9"><a id="__codelineno-12-9" name="__codelineno-12-9" href="#__codelineno-12-9"></a>
</span><span id="__span-12-10"><a id="__codelineno-12-10" name="__codelineno-12-10" href="#__codelineno-12-10"></a><span class="c1"># Check for containers in restart loops</span>
</span><span id="__span-12-11"><a id="__codelineno-12-11" name="__codelineno-12-11" href="#__codelineno-12-11"></a>docker<span class="w"> </span>compose<span class="w"> </span>ps<span class="w"> </span><span class="p">|</span><span class="w"> </span>grep<span class="w"> </span>-i<span class="w"> </span>restarting
</span></code></pre></div>
<p>You should see the API return <code>{"status":"ok"}</code> and all started containers in a "running" state.</p>
<hr />

File diff suppressed because one or more lines are too long

View File

@@ -2,322 +2,322 @@
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>https://bnkserve.org/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/lander/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/main/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/test-page/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/test/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/testing/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/blog/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/comments/callback/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/phil/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/dashboard/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/people-access/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/settings/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/advocacy/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/advocacy/campaigns/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/advocacy/email-queue/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/advocacy/representatives/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/advocacy/responses/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/broadcast/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/broadcast/email-templates/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/broadcast/newsletter/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/broadcast/sms/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/areas/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/canvassing/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/data-quality/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/locations/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/settings/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/map/shifts/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/media/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/media/ads/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/media/analytics/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/media/curated/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/media/library/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/media/moderation/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/payments/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/payments/donations/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/payments/plans/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/payments/products/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/payments/settings/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/services/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/services/crowdsec/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/services/integrations/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/services/monitoring/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/services/tunnel/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/services/user-provisioning/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/web/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/web/documentation/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/web/homepage/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/web/landing-pages/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/admin/web/navigation/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/api/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/architecture/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/deployment/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/control-panel/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/environment-variables/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/features/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/first-steps/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/installation/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/services/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/getting-started/upgrades/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/services/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/troubleshooting/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/campaigns/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/donations/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/events/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/gallery/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/map/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/profile/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/shifts/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/user-guide/shop/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/volunteer/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/volunteer/achievements/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/volunteer/canvassing/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/volunteer/shifts/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/docs/volunteer/social/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
<url>
<loc>https://bnkserve.org/partials/integrations/analytics/custom/</loc>
<lastmod>2026-03-11</lastmod>
<lastmod>2026-03-12</lastmod>
</url>
</urlset>

Binary file not shown.