<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Karlis</title>
    <description>The latest articles on DEV Community by Karlis (@acaciaman).</description>
    <link>https://dev.to/acaciaman</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3791733%2F70065550-3638-41d8-b409-07d25312f4e8.png</url>
      <title>DEV Community: Karlis</title>
      <link>https://dev.to/acaciaman</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/acaciaman"/>
    <language>en</language>
    <item>
      <title>Acacia DB for VS Code: Map your database usage in source code (1.0.0 1.2.0)</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Thu, 30 Apr 2026 12:25:11 +0000</pubDate>
      <link>https://dev.to/acaciaman/acacia-db-for-vs-code-map-your-database-usage-in-source-code-100-120-93a</link>
      <guid>https://dev.to/acaciaman/acacia-db-for-vs-code-map-your-database-usage-in-source-code-100-120-93a</guid>
      <description>&lt;p&gt;If you've ever inherited a legacy system and asked &lt;em&gt;"which tables are actually used, where, and how do they connect?"&lt;/em&gt; — that's the question &lt;a href="https://marketplace.visualstudio.com/items?itemName=manacacia.acacia-db" rel="noopener noreferrer"&gt;Acacia DB&lt;/a&gt; tries to answer.&lt;/p&gt;

&lt;p&gt;It's a VS Code extension that scans your workspace for references to database tables and columns, then turns the raw matches into something you can navigate, rank, and diagram. No LLMs, no cloud calls — just a deterministic pipeline over your source tree and a &lt;code&gt;tables_views.json&lt;/code&gt; schema file.&lt;/p&gt;

&lt;p&gt;The last three releases (1.0.0, 1.1.0, 1.2.0) reshaped the extension from a workspace scanner into a small analysis suite. Here's what landed.&lt;/p&gt;




&lt;h2&gt;
  
  
  1.0.0 — The pipeline rewrite
&lt;/h2&gt;

&lt;p&gt;1.0.0 is the first stable release. The headline change is that the column-relationship analysis pipeline was rewritten end-to-end for both performance and correctness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Parallel column-link analysis.&lt;/strong&gt; Column matching now runs in a &lt;code&gt;worker_threads&lt;/code&gt; pool (&lt;code&gt;min(cpus, 8)&lt;/code&gt; workers), with an in-process async fallback when the worker bundle isn't available. File I/O and matching overlap across cores instead of stalling on a single thread.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Targeted line scanning.&lt;/strong&gt; Workers no longer read every line of every file. They open only the line numbers already recorded in &lt;code&gt;table_refs.json&lt;/code&gt; for each file, so the second pass costs a fraction of the first.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;One global matcher instead of many.&lt;/strong&gt; Previously a fresh column matcher was rebuilt per table and per file. Now a single matcher is built once at the start of analysis and shared across all workers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Trie-level fast paths.&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;An ASCII first-character bitset gives O(1) reject for non-candidate characters before any trie walk.&lt;/li&gt;
&lt;li&gt;The matcher operates on &lt;code&gt;charCodeAt&lt;/code&gt; directly instead of &lt;code&gt;text.split('')&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;The quote-skip state machine is bypassed on lines with no &lt;code&gt;"&lt;/code&gt; or &lt;code&gt;'&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;On rejection, the matcher skips the rest of the current word in one pass.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Pre-filter for impossible files.&lt;/strong&gt; Files whose in-scope tables can't contribute at least two candidate columns are skipped before any I/O.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;O(1) link recording.&lt;/strong&gt; Each &lt;code&gt;LinkedTableInfo&lt;/code&gt; now carries a &lt;code&gt;Map&amp;lt;key, ColumnLink&amp;gt;&lt;/code&gt; plus per-link/per-info &lt;code&gt;Set&amp;lt;string&amp;gt;&lt;/code&gt; file caches, so &lt;code&gt;recordColumnLink&lt;/code&gt; is O(1) per call instead of O(k) over the link array and O(n) over the file array.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Correctness fix: case-sensitive matching with shared lowercased prefix.&lt;/strong&gt; Adding two column names that lowercased to the same string (e.g. &lt;code&gt;"ABC"&lt;/code&gt; and &lt;code&gt;"abc"&lt;/code&gt;) used to clobber each other on the shared trie path — case-sensitive lookup could return the wrong canonical name or no match at all. Each terminal node now stores all case variants, and case-sensitive lookup resolves to the variant that actually appears in the text.&lt;/p&gt;

&lt;p&gt;The dead pairwise per-file analyzer and the legacy &lt;code&gt;processLines&lt;/code&gt; / &lt;code&gt;processFileStream&lt;/code&gt; / &lt;code&gt;processLine&lt;/code&gt; helpers were removed; the orchestrator now drives a single unified pipeline.&lt;/p&gt;




&lt;h2&gt;
  
  
  1.1.0 — Hot-Path analysis and a leaner JSON format
&lt;/h2&gt;

&lt;p&gt;1.1.0 added an insight layer on top of the raw usage index, and reshaped the persisted analysis file.&lt;/p&gt;

&lt;h3&gt;
  
  
  Hot-Path Analysis
&lt;/h3&gt;

&lt;p&gt;A new module, &lt;code&gt;src/hotPathAnalyzer.ts&lt;/code&gt;, exposes pure functions: &lt;code&gt;computeTableMetrics&lt;/code&gt;, &lt;code&gt;computeEdgeMetrics&lt;/code&gt;, &lt;code&gt;suggestIndexes&lt;/code&gt;, &lt;code&gt;suggestCaches&lt;/code&gt;, and &lt;code&gt;buildHotPathReport&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-table metrics:&lt;/strong&gt; &lt;code&gt;usageCount&lt;/code&gt;, &lt;code&gt;fileFanOut&lt;/code&gt;, &lt;code&gt;joinDegreeIn/Out&lt;/code&gt;, weighted PageRank &lt;code&gt;centrality&lt;/code&gt;, and a tunable &lt;code&gt;hotScore&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;$$\text{hotScore} = \log(1 + \text{usageCount}) \cdot (1 + \text{joinDegree}) \cdot \sqrt{\text{fileFanOut}}$$&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Per-edge metrics:&lt;/strong&gt; &lt;code&gt;coOccurrenceCount&lt;/code&gt;, &lt;code&gt;linkConfidence&lt;/code&gt;, and &lt;code&gt;edgeScore = coOccurrenceCount * linkConfidence&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Suggestions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Index suggestions&lt;/strong&gt; for join keys on top-quantile edges, emitted as ready-to-paste DDL: &lt;code&gt;CREATE INDEX IX_&amp;lt;table&amp;gt;_&amp;lt;col&amp;gt; ON &amp;lt;table&amp;gt;(&amp;lt;col&amp;gt;)&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cache suggestions&lt;/strong&gt; for read-heavy leaf tables (high usage, low join degree).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Cold-table&lt;/strong&gt; report (&lt;code&gt;usageCount === 0&lt;/code&gt;).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A &lt;strong&gt;Hot Paths tree view&lt;/strong&gt; in the sidebar surfaces five sections: Top Hot Tables, Top Join Paths, Index Suggestions, Cache Candidates, and Cold / Unused Tables. Hot-table and edge leaves reveal the related table in the Database Explorer; index suggestions support a &lt;code&gt;Copy DDL&lt;/code&gt; context action.&lt;/p&gt;

&lt;p&gt;New commands: &lt;code&gt;acacia-db.exportHotPathReport&lt;/code&gt;, &lt;code&gt;acacia-db.hotPath.refresh&lt;/code&gt;, &lt;code&gt;acacia-db.hotPath.diagnose&lt;/code&gt;, &lt;code&gt;acacia-db.hotPath.copyIndexSuggestion&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Configuration lives under &lt;code&gt;acaciaDb.hotPath.*&lt;/code&gt;: &lt;code&gt;topN&lt;/code&gt;, &lt;code&gt;weights.usage&lt;/code&gt;, &lt;code&gt;weights.joins&lt;/code&gt;, &lt;code&gt;weights.fanOut&lt;/code&gt;, &lt;code&gt;minLinkConfidence&lt;/code&gt;, &lt;code&gt;indexSuggestionQuantile&lt;/code&gt;, &lt;code&gt;cacheCandidateQuantile&lt;/code&gt;, &lt;code&gt;cacheCandidateMaxJoinDegree&lt;/code&gt;. Changing any setting refreshes the view without a reload.&lt;/p&gt;

&lt;h3&gt;
  
  
  Relationship-only filtering
&lt;/h3&gt;

&lt;p&gt;A new &lt;code&gt;filterToRelationshipsOnly&lt;/code&gt; setting saves only references that participate in table relationships. On large codebases this drops file size by 80–95% and is &lt;strong&gt;enabled by default&lt;/strong&gt;. Tables with zero references are no longer saved or shown.&lt;/p&gt;

&lt;p&gt;The filtering algorithm itself was rewritten: complexity went from roughly O(n² × m²) to O(n×m + f×r log r + f×r×w) by grouping references per file, sorting for early termination on proximity checks, and skipping single-table files. Filtering time on a 477-table codebase dropped from 10–20 s to 0.5–2 s. Results are cached after the first computation, so the JSON export no longer re-runs the filter.&lt;/p&gt;

&lt;h3&gt;
  
  
  File-based JSON format
&lt;/h3&gt;

&lt;p&gt;The persisted &lt;code&gt;table_refs.json&lt;/code&gt; was reorganized from table-keyed to file-keyed: each entry is a file with a list of references (&lt;code&gt;line&lt;/code&gt;, &lt;code&gt;column&lt;/code&gt;, &lt;code&gt;tableName&lt;/code&gt;). The new shape is ~40% smaller, doesn't trip &lt;code&gt;JSON.stringify&lt;/code&gt; on very large workspaces, loads faster via direct object access, and diffs cleanly in version control. Relationships are simplified to table pairs and counts.&lt;/p&gt;

&lt;p&gt;Tree-view sorting was tightened across all levels — files by reference count, relationship files by instance count, proximity instances by distance (closest first) — while the JSON keeps an alphabetical file order for stable diffs.&lt;/p&gt;




&lt;h2&gt;
  
  
  1.2.0 — Heatmap and Mermaid ER export
&lt;/h2&gt;

&lt;p&gt;1.2.0 adds two visualization paths over the data Acacia DB already collects.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database Usage Heatmap
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;src/heatmapView.ts&lt;/code&gt; renders a tables × files matrix in a webview panel:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;SVG with a log/linear color-scale toggle and adjustable cell size.&lt;/li&gt;
&lt;li&gt;Hover tooltip showing table, file, and reference count.&lt;/li&gt;
&lt;li&gt;Click-to-open: jumps to the first line where the table appears in the file.&lt;/li&gt;
&lt;li&gt;Row totals on the right and column totals on the bottom as bar sparklines, plus a legend gradient with min/max.&lt;/li&gt;
&lt;li&gt;Driven by the in-memory &lt;code&gt;tableUsageMap&lt;/code&gt;, with &lt;code&gt;.vscode/table_refs.json&lt;/code&gt; as a no-scan fallback.&lt;/li&gt;
&lt;li&gt;Truncation warning when the matrix exceeds the configured caps.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Caps are configurable: &lt;code&gt;acaciaDb.heatmap.maxTables&lt;/code&gt; (default 50, max 1000) and &lt;code&gt;acaciaDb.heatmap.maxFiles&lt;/code&gt; (default 100, max 2000). Tables and files are ranked by total reference count before truncation.&lt;/p&gt;

&lt;p&gt;The command &lt;code&gt;acacia-db.showUsageHeatmap&lt;/code&gt; is wired into the Database Explorer view title bar.&lt;/p&gt;

&lt;h3&gt;
  
  
  Mermaid ER Diagram Export
&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;src/mermaidErExport.ts&lt;/code&gt; exposes a pure &lt;code&gt;buildMermaidEr&lt;/code&gt; function (no &lt;code&gt;vscode&lt;/code&gt; import) that turns detected column relationships into a Mermaid ER diagram:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Relationships are deduplicated by unordered table pair, and &lt;code&gt;forward&lt;/code&gt; / &lt;code&gt;backward&lt;/code&gt; / &lt;code&gt;bidirectional&lt;/code&gt; directions are aggregated into a single Mermaid cardinality (&lt;code&gt;}o--||&lt;/code&gt;, &lt;code&gt;||--o{&lt;/code&gt;, or &lt;code&gt;}o--o{&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Optional per-entity column blocks pulled from &lt;code&gt;tables_views.json&lt;/code&gt;, capped per table for readability.&lt;/li&gt;
&lt;li&gt;Identifiers are sanitized for Mermaid's &lt;code&gt;[A-Za-z_][A-Za-z0-9_]*&lt;/code&gt; rule; columns named &lt;code&gt;PK&lt;/code&gt; / &lt;code&gt;FK&lt;/code&gt; / &lt;code&gt;UK&lt;/code&gt; are renamed (&lt;code&gt;PK_col&lt;/code&gt;, etc.) to avoid colliding with Mermaid's reserved attribute-key tokens.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Three export targets via Quick Pick: open as Markdown preview, save to &lt;code&gt;.vscode/erDiagram.md&lt;/code&gt;, or copy Mermaid source to clipboard. The command &lt;code&gt;acacia-db.exportMermaidEr&lt;/code&gt; lives on the Column Explorer view title bar.&lt;/p&gt;

&lt;p&gt;Configuration: &lt;code&gt;acaciaDb.mermaidEr.maxTables&lt;/code&gt; (60), &lt;code&gt;acaciaDb.mermaidEr.omitIsolated&lt;/code&gt; (true), &lt;code&gt;acaciaDb.mermaidEr.includeColumns&lt;/code&gt; (true), &lt;code&gt;acaciaDb.mermaidEr.maxColumnsPerTable&lt;/code&gt; (20).&lt;/p&gt;




&lt;h2&gt;
  
  
  Try it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Marketplace:&lt;/strong&gt; &lt;code&gt;manacacia.acacia-db&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Repo:&lt;/strong&gt; &lt;a href="https://github.com/AcaciaMan/acacia-db" rel="noopener noreferrer"&gt;github.com/AcaciaMan/acacia-db&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Point it at a &lt;code&gt;tables_views.json&lt;/code&gt; and a source folder, run the analysis, and you'll get a usage tree, a relationship graph, hot-path suggestions, an ER diagram, and a heatmap — all from the same scan, all stored locally in &lt;code&gt;.vscode/&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Feedback and issues welcome.&lt;/p&gt;

</description>
      <category>vscode</category>
      <category>database</category>
      <category>sql</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Building Repo Promoter Agent for the DigitalOcean Gradient™ AI Hackathon</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Thu, 09 Apr 2026 08:39:55 +0000</pubDate>
      <link>https://dev.to/acaciaman/building-repo-promoter-agent-for-the-digitalocean-gradient-ai-hackathon-32of</link>
      <guid>https://dev.to/acaciaman/building-repo-promoter-agent-for-the-digitalocean-gradient-ai-hackathon-32of</guid>
      <description>&lt;p&gt;I recently participated in the &lt;a href="https://devpost.com/software/repo-promoter-agent?ref_content=user-portfolio&amp;amp;ref_feature=in_progress" rel="noopener noreferrer"&gt;DigitalOcean Gradient™ AI Hackathon&lt;/a&gt; with a project I’m pretty excited about — &lt;strong&gt;Repo Promoter Agent&lt;/strong&gt;. The idea came from a simple but recurring problem: promoting open-source projects on GitHub is often harder than building them.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Inspiration
&lt;/h3&gt;

&lt;p&gt;As someone who maintains several open source repositories, I noticed that my projects often struggle to reach the right audience. Writing promotional content — tweets, summaries, posts — takes time that could otherwise go into building features. I wanted a tool that could take a repository URL and instantly generate reusable marketing copy for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  🚀 What It Does
&lt;/h3&gt;

&lt;p&gt;Repo Promoter Agent does exactly that. Paste any &lt;strong&gt;public GitHub repo URL&lt;/strong&gt; into the app, and it generates a complete &lt;strong&gt;promo pack&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A catchy headline
&lt;/li&gt;
&lt;li&gt;A short summary and key benefits
&lt;/li&gt;
&lt;li&gt;Tweet-sized snippets
&lt;/li&gt;
&lt;li&gt;A LinkedIn-style post
&lt;/li&gt;
&lt;li&gt;A call to action
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All generated content is stored, indexed, and searchable — so you can quickly reuse good material across different projects.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧩 How I Built It
&lt;/h3&gt;

&lt;p&gt;The app combines several components:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; A simple web UI with “Generate” and “Search” screens
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Written in &lt;strong&gt;Go&lt;/strong&gt;, it fetches repo data and structures input for the AI agent
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;AI Layer:&lt;/strong&gt; A &lt;strong&gt;Gradient AI agent&lt;/strong&gt; processes the input and returns well‑structured JSON output
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Search Engine:&lt;/strong&gt; &lt;strong&gt;Apache Solr 10&lt;/strong&gt; indexes the generated content for fast retrieval
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Once the agent returns the JSON promo pack, it’s stored and instantly searchable in Solr.&lt;/p&gt;

&lt;h3&gt;
  
  
  🧠 What I Learned
&lt;/h3&gt;

&lt;p&gt;Using DigitalOcean’s &lt;strong&gt;Gradient AI platform&lt;/strong&gt; was surprisingly smooth. The key insight was to think of &lt;strong&gt;prompt design as a contract&lt;/strong&gt; — if the backend can trust the JSON format, the rest of the pipeline becomes predictable. It’s a great exercise in bridging LLM creativity with backend reliability.&lt;/p&gt;

&lt;h3&gt;
  
  
  ⚙️ Challenges
&lt;/h3&gt;

&lt;p&gt;Getting &lt;strong&gt;Solr 10&lt;/strong&gt; configured correctly took significant tuning, especially for schema and query logic. Another tricky aspect was finding the right balance between &lt;strong&gt;AI creativity and structure&lt;/strong&gt; — ensuring the agent’s output stayed valid JSON without sounding robotic.&lt;/p&gt;

&lt;h3&gt;
  
  
  💰 Costs
&lt;/h3&gt;

&lt;p&gt;Here’s what the first day of testing looked like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;App (29 hours): &lt;strong&gt;$1.07&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Droplet (34 hours): &lt;strong&gt;$1.62&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Database (58 hours): &lt;strong&gt;$1.69&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Agents: &lt;strong&gt;$0.15&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Total: &lt;strong&gt;$4.53&lt;/strong&gt; for a live day of experimenting. The cost will increase as I test more agents and models.&lt;/p&gt;

&lt;h3&gt;
  
  
  🛠️ Built With
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GitHub
&lt;/li&gt;
&lt;li&gt;Go
&lt;/li&gt;
&lt;li&gt;Solr
&lt;/li&gt;
&lt;li&gt;Gradient AI
&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;If you want to explore the project or see it in action, check out the &lt;a href="https://devpost.com/software/repo-promoter-agent?ref_content=user-portfolio&amp;amp;ref_feature=in_progress" rel="noopener noreferrer"&gt;Devpost page here&lt;/a&gt;.&lt;/p&gt;




</description>
      <category>ai</category>
      <category>opensource</category>
    </item>
    <item>
      <title>How can we effectively combine Go, TypeScript, Python, and WebGL in a single application?</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Thu, 02 Apr 2026 11:04:43 +0000</pubDate>
      <link>https://dev.to/acaciaman/how-can-we-effectively-combine-go-typescript-python-and-webgl-in-a-single-application-2g7g</link>
      <guid>https://dev.to/acaciaman/how-can-we-effectively-combine-go-typescript-python-and-webgl-in-a-single-application-2g7g</guid>
      <description>&lt;p&gt;I’ve been thinking about how different programming languages shine in their own areas:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Python is perfect for scientific computation, machine learning, and quick prototyping.&lt;/li&gt;
&lt;li&gt;TypeScript dominates when building rich web or desktop apps (and has great tooling through VS Code).&lt;/li&gt;
&lt;li&gt;Go is excellent for backend services, concurrency, and deployment speed.&lt;/li&gt;
&lt;li&gt;WebGL (via JavaScript or TypeScript) makes it possible to render interactive graphics and video directly in the browser.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each of these ecosystems is powerful on its own — but real-world applications often need the strengths of several. For example:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using Python for AI model inference,&lt;/li&gt;
&lt;li&gt;Go to handle fast concurrent servers,&lt;/li&gt;
&lt;li&gt;TypeScript/WebGL for an interactive front end.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So here’s the core question:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;What are effective modern strategies, tools, or architectures for connecting these languages together in one cohesive project?&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;I have a few ideas, but I’d love to get insights from others who’ve built multi-language systems:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Should something like gRPC/Protobuf be the glue between Go and Python?&lt;/li&gt;
&lt;li&gt;Can we use WebAssembly (WASM) to share logic between browser and backend?&lt;/li&gt;
&lt;li&gt;What about using message queues (e.g., Redis, Kafka) for structured language-agnostic communication?&lt;/li&gt;
&lt;li&gt;Are there practical workflows to make multi-language development not a maintenance nightmare?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Any examples, open-source frameworks, or architectural patterns would be really helpful.&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>programming</category>
      <category>architecture</category>
    </item>
    <item>
      <title>Acacia Log 4.0.0 – Stop Grepping, Start Navigating Your Logs</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Tue, 24 Mar 2026 17:18:58 +0000</pubDate>
      <link>https://dev.to/acaciaman/acacia-log-400-stop-grepping-start-navigating-your-logs-bgb</link>
      <guid>https://dev.to/acaciaman/acacia-log-400-stop-grepping-start-navigating-your-logs-bgb</guid>
      <description>&lt;p&gt;Working with logs should feel like debugging, not archaeology. &lt;/p&gt;

&lt;p&gt;Most of us still scroll, grep, and mentally replay a system’s history from a flat text file where the only real structure is the &lt;strong&gt;timestamp&lt;/strong&gt; and the fact that lines arrive in order. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Acacia Log&lt;/strong&gt; is a Visual Studio Code extension that leans into that simple idea: logs are time-ordered records with timestamps, so let’s treat them as a queryable time series instead of a wall of text. &lt;/p&gt;

&lt;p&gt;Version &lt;strong&gt;4.0.0&lt;/strong&gt; is out now, and it turns that idea into a full workflow for navigating, visualizing, and comparing massive log files without leaving VS Code. &lt;/p&gt;




&lt;h2&gt;
  
  
  What is Acacia Log?
&lt;/h2&gt;

&lt;p&gt;Acacia Log is an advanced log file analyzer and visualizer for VS Code. &lt;br&gt;
It helps you navigate huge &lt;code&gt;.log&lt;/code&gt;, &lt;code&gt;.txt&lt;/code&gt;, &lt;code&gt;.jsonl&lt;/code&gt;, and &lt;code&gt;.ndjson&lt;/code&gt; files by timestamp, detect time gaps, visualize activity timelines, search with regex patterns, analyze similar lines, and compare multiple files – all inside the editor. &lt;/p&gt;

&lt;p&gt;Key capabilities:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Jump directly to any timestamp using binary search on the log’s time index. &lt;/li&gt;
&lt;li&gt;Visualize activity as interactive bar, area, or line charts with zoom and pan. &lt;/li&gt;
&lt;li&gt;Find the most frequent messages via structural “similar line” grouping. &lt;/li&gt;
&lt;li&gt;Search multiple regex patterns in parallel and see counts + charts. &lt;/li&gt;
&lt;li&gt;Compare throughput and latency across 2–20 log files. &lt;/li&gt;
&lt;li&gt;Convert between JSONL/NDJSON and plain-text logs with guided wizards. &lt;/li&gt;
&lt;li&gt;Supports 20+ timestamp formats with automatic detection (ISO, Apache, Syslog, Log4j, Windows Event Log, UNIX timestamps, and more).&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If your logs have timestamps and grow over time, Acacia Log treats them like a time-series you can explore.&lt;/p&gt;

&lt;p&gt;If you end up using Acacia Log 4.0.0 in your own debugging, DevOps, or performance workflows, I would love feedback to keep improving the time-based analysis features.&lt;/p&gt;




</description>
      <category>vscode</category>
      <category>analytics</category>
    </item>
    <item>
      <title>Weather‑Smart Merchandiser: Using Notion MCP + Claude to Turn DIY Sales &amp; Weather Data into Layout Actions</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Fri, 06 Mar 2026 18:41:41 +0000</pubDate>
      <link>https://dev.to/acaciaman/weather-smart-merchandiser-using-notion-mcp-claude-to-turn-diy-sales-weather-data-into-layout-2684</link>
      <guid>https://dev.to/acaciaman/weather-smart-merchandiser-using-notion-mcp-claude-to-turn-diy-sales-weather-data-into-layout-2684</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/notion-2026-03-04"&gt;Notion MCP Challenge&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;I built &lt;strong&gt;Weather‑Smart Merchandiser&lt;/strong&gt;, a weather‑driven merchandising tool that analyses historical sales–weather data, forecasts demand by temperature bucket, and then generates &lt;strong&gt;store layout‑change suggestions&lt;/strong&gt; for a DIY store.&lt;/p&gt;

&lt;p&gt;Under the hood, it’s a Python project exposed as an &lt;strong&gt;MCP server&lt;/strong&gt;, so AI assistants (like Claude Desktop) can call high‑level tools such as &lt;code&gt;layout_actions&lt;/code&gt; or &lt;code&gt;top_categories&lt;/code&gt; instead of manually running scripts. The workflow is: the assistant looks at recent DIY sales and temperatures, classifies upcoming days as cold / mild / warm, and then proposes concrete layout moves (e.g., “move garden tools to front endcap for the warm weekend” or “highlight insulation at the entrance for a cold spell”).&lt;/p&gt;

&lt;p&gt;On top of that, I use a Notion workspace as the &lt;strong&gt;control center&lt;/strong&gt;:  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A “Sales &amp;amp; Weather (Daily)” database holds the input data.
&lt;/li&gt;
&lt;li&gt;A “DIY Categories &amp;amp; Layout” database describes where each category currently lives in the store.
&lt;/li&gt;
&lt;li&gt;A “Layout Actions” database is automatically populated by the MCP tools with suggested moves, dates, and expected uplift.
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The result is a small but realistic “weather‑smart” merchandising assistant for a DIY store that feels like a real workflow, not just a toy script.&lt;/p&gt;

&lt;h3&gt;
  
  
  Incremental updates
&lt;/h3&gt;

&lt;p&gt;I am used to develop things incrementally. As there is still time left in the challenge, I will improve the solution and in this section will write my updates.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;First incremental update&lt;/strong&gt;: Added a &lt;strong&gt;Kanban view&lt;/strong&gt; to the Layout Actions database in the DIY dashboard. Now store managers can instantly see actions flowing from &lt;strong&gt;Planned → In Progress → Done&lt;/strong&gt; at a glance, making the workflow feel even more production-ready.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Added SQLite database for Python MCP server&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Switched from CSV to JSON data exchange format&lt;/strong&gt;: Discovered an issue. &lt;strong&gt;FastMCP&lt;/strong&gt;'s _convert_to_content function iterates over list results and converts each item separately into its own TextContent block. So when your tool returned list[dict], each dict became a separate JSON text block — producing {...}{...}{...} (concatenated objects) instead of &lt;a href="https://dev.toa%20proper%20array"&gt;{...}, {...}, {...}&lt;/a&gt;. &lt;strong&gt;The fix&lt;/strong&gt;: all three tools (demand_signals, forecast, layout_actions) now return json.dumps(result, indent=2) — a single JSON string that &lt;strong&gt;FastMCP&lt;/strong&gt; wraps in one TextContent block. Restarted Claude Desktop to pick up the change.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Added Sales insights subpage in DIY dashboard&lt;/strong&gt;: Added also Claude Desktop prompt in GitHub repository to fill in Sales insights subpage.&lt;/p&gt;

&lt;h2&gt;
  
  
  Video Demo
&lt;/h2&gt;

&lt;p&gt;&lt;a href="https://github.com/user-attachments/assets/bdb07f87-5e2a-4974-be23-12ba47560132" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/bdb07f87-5e2a-4974-be23-12ba47560132&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Public Notion project page:&lt;br&gt;
&lt;a href="https://neighborly-fridge-ea2.notion.site/Weather-smart-merchandiser-31a4fffb13a880618b7fd4198be66b30" rel="noopener noreferrer"&gt;https://neighborly-fridge-ea2.notion.site/Weather-smart-merchandiser-31a4fffb13a880618b7fd4198be66b30&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Public Notion DIY dashboard:&lt;br&gt;
&lt;a href="https://neighborly-fridge-ea2.notion.site/DIY-Weather-Smart-Merchandising-fffb7fe844f841bda431202321e29ac9" rel="noopener noreferrer"&gt;https://neighborly-fridge-ea2.notion.site/DIY-Weather-Smart-Merchandising-fffb7fe844f841bda431202321e29ac9&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I recorded a short video walkthrough showing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How I trigger the workflow from Claude Desktop by asking:
“Generate layout actions from Sales &amp;amp; Weather for the next 3 days and write them into Notion.”&lt;/li&gt;
&lt;li&gt;How the MCP server returns suggested actions (per store, date, category, and temperature bucket).&lt;/li&gt;
&lt;li&gt;How Claude then uses Notion’s MCP integration to create new rows in the “Layout Actions” database and generate a “Store Playbook” summary page in Notion.&lt;/li&gt;
&lt;li&gt;How I can also ask Claude to &lt;strong&gt;summarize the weekend layout actions&lt;/strong&gt; into a concise briefing, so store staff get a quick “weekend plan” without reading every individual row.&lt;/li&gt;
&lt;li&gt;The final Notion DIY dashboard that shows weather, recent sales, and planned layout changes in one place.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Show us the code
&lt;/h2&gt;

&lt;p&gt;The full source code is available here:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;GitHub repo:&lt;/strong&gt; &lt;a href="https://github.com/AcaciaMan/weather-smart-merchandiser" rel="noopener noreferrer"&gt;https://github.com/AcaciaMan/weather-smart-merchandiser&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Key pieces:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;first_python_module.py&lt;/code&gt; – core library with reusable functions for:

&lt;ul&gt;
&lt;li&gt;loading the &lt;code&gt;sales_weather_daily.csv&lt;/code&gt; dataset
&lt;/li&gt;
&lt;li&gt;computing demand signals by temperature bucket
&lt;/li&gt;
&lt;li&gt;generating a simple forecast
&lt;/li&gt;
&lt;li&gt;producing layout‑change suggestions&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;server.py&lt;/code&gt; – MCP server entry point that wraps these functions as MCP tools.
&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;sales_weather_daily.csv&lt;/code&gt; – example dataset with Date, Store, Temp °C, Weather, Category, Units Sold, Revenue €.
&lt;/li&gt;

&lt;li&gt;
&lt;code&gt;requirements.txt&lt;/code&gt; – Python dependencies.&lt;/li&gt;

&lt;/ul&gt;

&lt;p&gt;You can run it in three ways:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;As an MCP server from a client (e.g., Claude Desktop).
&lt;/li&gt;
&lt;li&gt;With an MCP inspector / dev CLI for testing.
&lt;/li&gt;
&lt;li&gt;As a standalone script to generate layout actions into &lt;code&gt;layout_actions_suggested.csv&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Used Notion MCP
&lt;/h2&gt;

&lt;p&gt;My goal was: &lt;strong&gt;say one prompt, get real layout actions written into Notion automatically, and optionally get a weekend summary.&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;I used Notion’s MCP integration together with my custom Python MCP server so an AI assistant can orchestrate the whole chain:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Custom MCP server (Python)&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I implemented tools such as:

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;list_stores&lt;/code&gt; – list unique stores in the dataset.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;demand_signals&lt;/code&gt; – average units sold per temperature bucket and category.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;top_categories&lt;/code&gt; – top sellers for cold / mild / warm conditions.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;classify_temperature&lt;/code&gt; – classify any °C value into a bucket.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;forecast&lt;/code&gt; – a simple temperature forecast for upcoming days.
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;layout_actions&lt;/code&gt; – an end‑to‑end tool that takes a store and days‑ahead and returns layout suggestions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;This server runs locally and is registered as a custom MCP server in my client.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;AI client (Claude Desktop) calls the MCP tools&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;From Claude, I can ask:

&lt;ul&gt;
&lt;li&gt;“For store ‘Riga 1’, generate layout actions for the next 3 days based on the existing sales_weather_daily.csv data.”
&lt;/li&gt;
&lt;li&gt;“Summarize this weekend’s layout actions into a short briefing for store staff.”
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Claude calls my &lt;code&gt;layout_actions&lt;/code&gt; tool, which:

&lt;ul&gt;
&lt;li&gt;reads the CSV (or, in a more advanced setup, reads from Notion)
&lt;/li&gt;
&lt;li&gt;computes demand signals per temperature bucket
&lt;/li&gt;
&lt;li&gt;fakes or consumes a short‑term forecast
&lt;/li&gt;
&lt;li&gt;outputs structured layout actions (Store, Start/End Date, Category, Suggested Move, Expected Uplift, Forecast Temp, Bucket).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Then, using the actions already written into Notion, I can ask Claude to &lt;strong&gt;summarize the weekend plan&lt;/strong&gt;, producing a concise natural‑language overview (“This weekend: promote Garden and Cooling near the entrance, de‑emphasize Insulation”).&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Notion MCP writes the results into Notion&lt;/strong&gt;  &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;In the same conversation, I ask Claude to “take these layout actions and insert them into my Notion ‘Layout Actions’ database, and create a summary page.”
&lt;/li&gt;
&lt;li&gt;Using Notion’s MCP integration, Claude:

&lt;ul&gt;
&lt;li&gt;creates new rows in the &lt;strong&gt;Layout Actions&lt;/strong&gt; database (one per suggested move)
&lt;/li&gt;
&lt;li&gt;updates or creates a &lt;strong&gt;“DIY Weather‑Smart Merchandising” dashboard&lt;/strong&gt; view
&lt;/li&gt;
&lt;li&gt;generates a “Weekend Store Playbook” page summarizing:&lt;/li&gt;
&lt;li&gt;upcoming temperature buckets
&lt;/li&gt;
&lt;li&gt;key categories to promote
&lt;/li&gt;
&lt;li&gt;concrete moves for staff
&lt;/li&gt;
&lt;li&gt;a short summary of the weekend layout actions.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Why Notion MCP matters here&lt;/strong&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Notion MCP turns Notion into the &lt;strong&gt;front end&lt;/strong&gt; for the system:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;I don’t have to build a custom UI; everything lives in Notion pages and databases.
&lt;/li&gt;
&lt;li&gt;The AI can both &lt;strong&gt;read&lt;/strong&gt; (past actions, sales context) and &lt;strong&gt;write&lt;/strong&gt; (new layout actions, summaries) in a structured, permission‑aware way.
&lt;/li&gt;
&lt;li&gt;My Python MCP server stays focused on the “brains” (weather + sales logic), while Notion is the “workspace” where humans see and act on the plan—and even get an auto‑written weekend summary they can quickly share with the team.&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>devchallenge</category>
      <category>notionchallenge</category>
      <category>mcp</category>
      <category>ai</category>
    </item>
    <item>
      <title>What do you do when your side project has almost no users?</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Wed, 04 Mar 2026 16:55:03 +0000</pubDate>
      <link>https://dev.to/acaciaman/what-do-you-do-when-your-side-project-has-almost-no-users-22i3</link>
      <guid>https://dev.to/acaciaman/what-do-you-do-when-your-side-project-has-almost-no-users-22i3</guid>
      <description>&lt;p&gt;Imagine you build a side project for people on the internet, but almost nobody uses it for a long time. What do you do next? Take a break, put it away, change its name, or try something else?&lt;/p&gt;

</description>
      <category>explainlikeimfive</category>
    </item>
    <item>
      <title>As AI boosts developer productivity, how will expectations change?</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Tue, 03 Mar 2026 17:04:51 +0000</pubDate>
      <link>https://dev.to/acaciaman/as-ai-boosts-developer-productivity-how-will-expectations-change-1j92</link>
      <guid>https://dev.to/acaciaman/as-ai-boosts-developer-productivity-how-will-expectations-change-1j92</guid>
      <description>&lt;p&gt;With AI accelerating coding and debugging, I’m curious how this will reshape expectations for developers. Will roles shift toward higher-level problem solving and system design, or will productivity gains mainly raise delivery pressure and standards?&lt;/p&gt;

</description>
      <category>discuss</category>
      <category>ai</category>
      <category>career</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Bringing Local Slalom Races Online with Canoe Slalom Live</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Sun, 01 Mar 2026 13:57:23 +0000</pubDate>
      <link>https://dev.to/acaciaman/bringing-local-slalom-races-online-with-canoe-slalom-live-4i6</link>
      <guid>https://dev.to/acaciaman/bringing-local-slalom-races-online-with-canoe-slalom-live-4i6</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the DEV Weekend Challenge: Community.&lt;/em&gt;&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;Canoe and kayak slalom has a strong grassroots scene: small clubs, volunteer judges, parents on the riverbank, and athletes who travel long distances for a single race run. Yet many local events still run on paper start lists, handwritten penalties, and spreadsheets that never leave the timing laptop.&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;I built Canoe Slalom Live for that community: local organizers who want something lightweight they can run on a single laptop at the course, judges who need a simple way to record runs, commentators who want quick access to athlete stories, and spectators who just want to understand what is happening on the water in real time.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Canoe Slalom Live is a tiny live-timing and results web app for canoe/water slalom competitions. It runs as a Go web server with an embedded SQLite database and server-rendered HTML, so an organizer can start it on a laptop at the riverside and let everyone else follow the event from their phones.&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;The app provides a public event page with a start list grouped by category, a live leaderboard with penalties, a photo gallery, dedicated commentator and athlete profile views, plus a mobile-friendly judge panel for entering runs and penalties. It focuses on making results understandable for spectators while giving judges and commentators tools that fit how small events actually work.&lt;br&gt;
​&lt;br&gt;
It’s a single Go + SQLite binary that can run on a small VPS or services like Google Cloud Run.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;GitHub repository (code + README + screenshots):&lt;br&gt;


&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/AcaciaMan" rel="noopener noreferrer"&gt;
        AcaciaMan
      &lt;/a&gt; / &lt;a href="https://github.com/AcaciaMan/canoe-slalom-live" rel="noopener noreferrer"&gt;
        canoe-slalom-live
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Weekend-built sports app for canoe/water slalom meets. Supports creating events, managing start lists and athlete bios, recording runs and penalties, and showing a live leaderboard for the whole community.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🛶 Canoe Slalom Live&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;Live timing and results for canoe/water slalom competitions. Built for grassroots events — run it on a laptop at the riverside, let spectators follow on their phones.&lt;/p&gt;
&lt;p&gt;Short introduction video
&lt;a href="https://github.com/user-attachments/assets/90fe481d-032e-493f-acd4-5c0e1be7cca1" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/90fe481d-032e-493f-acd4-5c0e1be7cca1&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Prerequisites: Go 1.22+, GCC (for SQLite CGo driver)&lt;/span&gt;
go mod tidy
go run main.go -seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Opens at http://localhost:8080&lt;/span&gt;
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Judge panel at http://localhost:8080/judge/events/demo-slalom-2026&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To enable authentication for judge routes:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Windows&lt;/span&gt;
&lt;span class="pl-c1"&gt;set&lt;/span&gt; ADMIN_TOKEN=secret123
go run main.go -seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Linux/macOS&lt;/span&gt;
ADMIN_TOKEN=secret123 go run main.go -seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Judge panel: http://localhost:8080/judge/events/demo-slalom-2026?token=secret123&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Stack&lt;/h2&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go&lt;/strong&gt; — &lt;code&gt;net/http&lt;/code&gt; with Go 1.22+ pattern routing, &lt;code&gt;html/template&lt;/code&gt; for server-rendered HTML&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite&lt;/strong&gt; — embedded via &lt;code&gt;github.com/mattn/go-sqlite3&lt;/code&gt; (CGo), WAL mode, single &lt;code&gt;data.db&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vanilla HTML/CSS/JS&lt;/strong&gt; — no build step, no framework, no bundler&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It’s a single Go + SQLite binary that can run on a small VPS or services like Google Cloud Run.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Pages&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;/events/{slug}&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Event&lt;/td&gt;
&lt;td&gt;Start list grouped&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/AcaciaMan/canoe-slalom-live" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;p&gt;Short intro video (live walk-through of the seeded demo event):&lt;br&gt;
&lt;a href="https://github.com/user-attachments/assets/90fe481d-032e-493f-acd4-5c0e1be7cca1" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/90fe481d-032e-493f-acd4-5c0e1be7cca1&lt;/a&gt;&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;To try it locally:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;bash
go mod tidy
go run main.go -seed
# Opens at http://localhost:8080
# Judge panel at http://localhost:8080/judge/events/demo-slalom-2026
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The full source code is available here:&lt;/p&gt;

&lt;p&gt;

&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/AcaciaMan" rel="noopener noreferrer"&gt;
        AcaciaMan
      &lt;/a&gt; / &lt;a href="https://github.com/AcaciaMan/canoe-slalom-live" rel="noopener noreferrer"&gt;
        canoe-slalom-live
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Weekend-built sports app for canoe/water slalom meets. Supports creating events, managing start lists and athlete bios, recording runs and penalties, and showing a live leaderboard for the whole community.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;🛶 Canoe Slalom Live&lt;/h1&gt;
&lt;/div&gt;

&lt;p&gt;Live timing and results for canoe/water slalom competitions. Built for grassroots events — run it on a laptop at the riverside, let spectators follow on their phones.&lt;/p&gt;

&lt;p&gt;Short introduction video
&lt;a href="https://github.com/user-attachments/assets/90fe481d-032e-493f-acd4-5c0e1be7cca1" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/90fe481d-032e-493f-acd4-5c0e1be7cca1&lt;/a&gt;&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;

&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Prerequisites: Go 1.22+, GCC (for SQLite CGo driver)&lt;/span&gt;
go mod tidy
go run main.go -seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Opens at http://localhost:8080&lt;/span&gt;
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Judge panel at http://localhost:8080/judge/events/demo-slalom-2026&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;To enable authentication for judge routes:&lt;/p&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Windows&lt;/span&gt;
&lt;span class="pl-c1"&gt;set&lt;/span&gt; ADMIN_TOKEN=secret123
go run main.go -seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Linux/macOS&lt;/span&gt;
ADMIN_TOKEN=secret123 go run main.go -seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Judge panel: http://localhost:8080/judge/events/demo-slalom-2026?token=secret123&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Stack&lt;/h2&gt;

&lt;/div&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Go&lt;/strong&gt; — &lt;code&gt;net/http&lt;/code&gt; with Go 1.22+ pattern routing, &lt;code&gt;html/template&lt;/code&gt; for server-rendered HTML&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SQLite&lt;/strong&gt; — embedded via &lt;code&gt;github.com/mattn/go-sqlite3&lt;/code&gt; (CGo), WAL mode, single &lt;code&gt;data.db&lt;/code&gt; file&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Vanilla HTML/CSS/JS&lt;/strong&gt; — no build step, no framework, no bundler&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It’s a single Go + SQLite binary that can run on a small VPS or services like Google Cloud Run.&lt;/p&gt;

&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Pages&lt;/h2&gt;

&lt;/div&gt;

&lt;p&gt;&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;br&gt;
&lt;thead&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;th&gt;Route&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Page&lt;/th&gt;
&lt;br&gt;
&lt;th&gt;Description&lt;/th&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/thead&gt;
&lt;br&gt;
&lt;tbody&gt;
&lt;br&gt;
&lt;tr&gt;
&lt;br&gt;
&lt;td&gt;&lt;code&gt;/events/{slug}&lt;/code&gt;&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Event&lt;/td&gt;
&lt;br&gt;
&lt;td&gt;Start list grouped&lt;/td&gt;
&lt;br&gt;
&lt;/tr&gt;
&lt;br&gt;
&lt;/tbody&gt;
&lt;br&gt;
&lt;/table&gt;&lt;/div&gt;…&lt;/p&gt;
&lt;/div&gt;
&lt;br&gt;
  &lt;/div&gt;
&lt;br&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/AcaciaMan/canoe-slalom-live" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;br&gt;
&lt;/div&gt;



&lt;p&gt;&lt;br&gt;&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;Key routes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;/events/{slug} – event overview with start list and athlete bios&lt;/li&gt;
&lt;li&gt;/events/{slug}/leaderboard – live leaderboard with auto-refresh and penalty sparklines&lt;/li&gt;
&lt;li&gt;/events/{slug}/photos – photo gallery with photographer credits&lt;/li&gt;
&lt;li&gt;/events/{slug}/commentator – big-screen commentator view&lt;/li&gt;
&lt;li&gt;/events/{slug}/athletes/{id} – athlete profile with run history and linked photos&lt;/li&gt;
&lt;li&gt;/judge/events/{slug} – judge panel for recording runs (auth-protected via admin token) ​&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;Stack and architecture&lt;br&gt;
I used Go 1.22 with net/http pattern routing and html/template for fully server-rendered pages, backed by a single SQLite database file accessed through github.com/mattn/go-sqlite3. There is no build pipeline or frontend framework: just vanilla HTML, CSS, and a tiny bit of JavaScript for auto-refresh.&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;The project is split into small packages: domain for core types (events, athletes, runs, sponsors, photos), store for SQLite queries, and handler for public and judge HTTP handlers plus authentication and logging middleware. Templates live in templates/ and are composed around a shared layout with a simple nav bar linking Event, Leaderboard, Photos, and Judge.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  Data model and scoring
&lt;/h2&gt;

&lt;p&gt;The SQLite schema has seven tables: events, categories, athletes, entries, runs, sponsors, and photos. Entries link athletes to an event and category with a bib number; runs store raw time, touches, missed gates, and computed total time, and a UNIQUE(entry_id, run_number) constraint prevents duplicate runs. Scoring follows standard ICF rules: +2 seconds per gate touch, +50 seconds per missed gate, ranking athletes by their best single-run total time.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  UX for each role
&lt;/h2&gt;

&lt;p&gt;For spectators, the leaderboard auto-refreshes every 10 seconds and highlights medals, “NEW” runs, time-behind-leader, and tiny CSS sparklines that compare raw time vs penalties. Commentators get a dedicated view that shows the latest result in huge type with bio and penalties plus current top three for each category, optimized for projection. Judges use a mobile-friendly panel with large tap targets, penalty steppers, confirmation before saving, recent runs, and run-status indicators so they can work quickly in a noisy outdoor environment.&lt;br&gt;
​&lt;/p&gt;

&lt;h2&gt;
  
  
  Safety and polish
&lt;/h2&gt;

&lt;p&gt;To keep things safe without overbuilding auth, judge routes are protected with an ADMIN_TOKEN environment variable and a simple session cookie once the token is used. There is server-side validation for time ranges and maximum penalties, basic security headers, and structured request logging with method, path, status, and duration. I also seeded a complete demo event (Demo Slalom 2026) so anyone cloning the repo can see realistic data, categories, and sponsors immediately&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>Village Square: A Tiny Go‑Powered Hub for My Rural Community</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Sat, 28 Feb 2026 08:54:06 +0000</pubDate>
      <link>https://dev.to/acaciaman/village-square-a-tiny-go-powered-hub-for-my-rural-community-40f3</link>
      <guid>https://dev.to/acaciaman/village-square-a-tiny-go-powered-hub-for-my-rural-community-40f3</guid>
      <description>&lt;p&gt;&lt;em&gt;This is a submission for the DEV Weekend Challenge: Community&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Community
&lt;/h2&gt;

&lt;p&gt;I built Village Square for my own rural village community.&lt;br&gt;
Most people are neighbors, small local producers (fishermen, farmers, crafters), and families who meet several times a year, especially during our annual Village Day.&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;Right now, coordination happens through word of mouth, scattered chat groups, and printed posters. It’s easy to miss who is selling what, which events are happening when, or who needs help with something practical. Village Square tries to give us one simple place to share offers, requests, and Village Day activities.&lt;br&gt;
​&lt;/p&gt;
&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;Village Square is a small community web app that acts like a digital village square. Logged‑in villagers can:&lt;br&gt;
​&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Register and log in with a simple account.&lt;/li&gt;
&lt;li&gt;Post offers, requests, and announcements (e.g., fresh fish, potatoes, help with a fence, road closure).&lt;/li&gt;
&lt;li&gt;Filter the feed by type and category (fish, produce, crafts, services, other).&lt;/li&gt;
&lt;li&gt;Use a dedicated Village Day view to see garage sales, sports, and gatherings in a time‑based timeline.
​&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;For the challenge, I focused on a clean, mobile‑friendly interface and realistic seeded data so it feels like a real village snapshot rather than an empty prototype.&lt;br&gt;
​&lt;br&gt;
It’s a single Go + SQLite binary that can run on a small VPS or services like Google Cloud Run.&lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;Here’s a short intro video of Village Square in action (login, feed, and Village Day screens):&lt;br&gt;
&lt;a href="https://github.com/user-attachments/assets/cd99a68b-b613-4101-8467-571a12c5924e" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/cd99a68b-b613-4101-8467-571a12c5924e&lt;/a&gt;&lt;br&gt;
​&lt;/p&gt;

&lt;p&gt;You can also run it locally:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Start the server and open &lt;a href="http://localhost:8080" rel="noopener noreferrer"&gt;http://localhost:8080&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Use the demo login: &lt;a href="mailto:jan@village.nl"&gt;jan@village.nl&lt;/a&gt; / jan123.
​&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;
  
  
  Code
&lt;/h2&gt;

&lt;p&gt;The full source code is on GitHub:&lt;br&gt;


&lt;/p&gt;
&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/AcaciaMan" rel="noopener noreferrer"&gt;
        AcaciaMan
      &lt;/a&gt; / &lt;a href="https://github.com/AcaciaMan/village-square" rel="noopener noreferrer"&gt;
        village-square
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      Digital village square for local announcements, garage sales, and connections between neighbors and suppliers.
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Village Square&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;A community web app for a rural village — connecting villagers, local producers (fishermen, farmers, crafters), and the yearly &lt;strong&gt;Village Day&lt;/strong&gt; celebration.&lt;/p&gt;
&lt;p&gt;Built with &lt;strong&gt;Go&lt;/strong&gt; (stdlib only) + &lt;strong&gt;SQLite&lt;/strong&gt; + plain &lt;strong&gt;HTML/CSS/JS&lt;/strong&gt; — no frameworks, no build step.&lt;/p&gt;
&lt;p&gt;Short introduction video
&lt;a href="https://github.com/user-attachments/assets/cd99a68b-b613-4101-8467-571a12c5924e" rel="noopener noreferrer"&gt;https://github.com/user-attachments/assets/cd99a68b-b613-4101-8467-571a12c5924e&lt;/a&gt;&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Quick Start&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="highlight highlight-source-shell notranslate position-relative overflow-auto js-code-highlight"&gt;
&lt;pre&gt;&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Prerequisites: Go 1.22+, GCC (for SQLite cgo)&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Clone and build&lt;/span&gt;
git clone https://github.com/&lt;span class="pl-k"&gt;&amp;lt;&lt;/span&gt;you&lt;span class="pl-k"&gt;&amp;gt;&lt;/span&gt;/village-square.git
&lt;span class="pl-c1"&gt;cd&lt;/span&gt; village-square
go build -o village-square.exe &lt;span class="pl-c1"&gt;.&lt;/span&gt;

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Seed with demo data (8 users, 18 posts, 6 events)&lt;/span&gt;
./village-square.exe --seed

&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; Start the server&lt;/span&gt;
./village-square.exe
&lt;span class="pl-c"&gt;&lt;span class="pl-c"&gt;#&lt;/span&gt; → http://localhost:8080&lt;/span&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;Demo login:&lt;/strong&gt; &lt;code&gt;jan@village.nl&lt;/code&gt; / &lt;code&gt;jan123&lt;/code&gt; (or any seeded user — see &lt;code&gt;db/seed.go&lt;/code&gt;)&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;

&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Phase 1 — Foundation &amp;amp; Auth&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;User registration and login with bcrypt-hashed passwords&lt;/li&gt;
&lt;li&gt;Server-side sessions via secure HttpOnly cookies&lt;/li&gt;
&lt;li&gt;Auth guard on protected pages (auto-redirect if not logged in)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /api/me&lt;/code&gt; returns the current user&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Phase 2 — Posts &amp;amp; Marketplace&lt;/h3&gt;

&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;Create, view…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/AcaciaMan/village-square" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;




&lt;h2&gt;
  
  
  How I Built It
&lt;/h2&gt;

&lt;p&gt;I wanted to keep the stack minimal and approachable for small communities to self‑host, so I went with:&lt;br&gt;
​&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Backend:&lt;/strong&gt; Go standard library (net/http, database/sql, crypto/rand, bcrypt) with a small handler + middleware structure.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database:&lt;/strong&gt; SQLite via github.com/mattn/go-sqlite3, with migrations and a seeding command that creates demo users, posts, and Village Day events.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Frontend:&lt;/strong&gt; Plain HTML, CSS, and vanilla JavaScript served from a /static folder (no frameworks, no build step).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auth:&lt;/strong&gt; Email + password with bcrypt hashing and server‑side session tokens stored in HttpOnly cookies, plus an auth guard for the dashboard and Village Day pages.
​&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;I structured the work in phases: foundation/auth, posts &amp;amp; marketplace, Village Day events, and finally polish/hardening (shared CSS/JS, toast notifications, responsive layout, logging, and limits). That made it achievable within a weekend while still feeling like a complete, coherent app for my village.&lt;/p&gt;

&lt;p&gt;Since I had a bit more time, I didn’t just build a marketplace—I also added small features that nudge villagers to talk and help each other, like the new ‘I’m interested / I can help’ buttons.&lt;/p&gt;

</description>
      <category>devchallenge</category>
      <category>weekendchallenge</category>
      <category>showdev</category>
    </item>
    <item>
      <title>My 60 USD/month dev environment (Copilot Pro, Claude, Gemini, Perplexity PRO)</title>
      <dc:creator>Karlis</dc:creator>
      <pubDate>Wed, 25 Feb 2026 15:20:02 +0000</pubDate>
      <link>https://dev.to/acaciaman/my-60-usdmonth-dev-environment-copilot-pro-claude-gemini-perplexity-pro-4ij2</link>
      <guid>https://dev.to/acaciaman/my-60-usdmonth-dev-environment-copilot-pro-claude-gemini-perplexity-pro-4ij2</guid>
      <description>&lt;p&gt;I’m an indie developer, and I wanted a reasonably priced, powerful setup for AI‑assisted coding that still keeps me in control of the work. After some experimentation, I’ve ended up with a roughly 60 USD/month stack that lives mostly inside VS Code and covers planning, coding, refactoring, and research.&lt;/p&gt;

&lt;p&gt;The core stack&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;GitHub Copilot Pro – Inline completions, small refactors, and “fill in the obvious code” while I’m in the editor. It’s my default background assistant that keeps momentum going.&lt;/li&gt;
&lt;li&gt;Claude Opus 4.6 – For higher‑level thinking: architecture discussions, planning the next steps, and non‑trivial refactors where I need long‑context reasoning and a more careful explanation.&lt;/li&gt;
&lt;li&gt;Gemini 3.1 Pro – For alternative solutions and explanations. I use it when I want a second opinion on an approach, or a clearer explanation of complex code or algorithms.&lt;/li&gt;
&lt;li&gt;Perplexity Pro (deep research) – For research and verification: comparing libraries, checking claims against multiple sources, and quickly collecting links I can inspect myself.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Open questions for you&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Do you also stack multiple AI tools for development, or do you prefer going all‑in on a single provider?&lt;/li&gt;
&lt;li&gt;How do you manage prompts and context across tools (especially inside an editor like VS Code) without drowning in windows and tabs?&lt;/li&gt;
&lt;li&gt;If you had to cut this down to two AI services, which ones would you keep and why?&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Drafted with the help of an AI assistant, edited by me.&lt;/p&gt;

</description>
      <category>ai</category>
      <category>programming</category>
      <category>opensource</category>
      <category>productivity</category>
    </item>
  </channel>
</rss>
