update project entries

This commit is contained in:
SowinskiBraeden committed 2026-07-08 10:26:45 -07:00
1 parent 7c1c049148
commit 051f95f00d
4 files changed
+105 -89

No files matched your search

+56 -84
View File
@@ -1,24 +1,26 @@
{
"projects": [
{
"title": "Schedule Generator App",
"slug": "schedule-generator-app",
"title": "Reforger Mods API",
"slug": "reforger-mods-api",
"type": "projects",
"summary": "A desktop application to interact with my schedule generator algorithm. The algorithm is written in Python and generates master and student timetables.",
"summary": "A public, unofficial REST API for Arma Reforger Workshop metadata, built with caching, background refresh jobs, rate limiting, and production reliability in mind.",
"label": "Project",
"date": "2023-08-01",
"status": "Completed",
"github": "https://github.com/SowinskiBraeden/ScheduleGeneratorApp",
"demo": null,
"date": "2026-07-06",
"status": "Active",
"github": "https://github.com/SowinskiBraeden/ReforgerWorkshopAPI",
"demo": "https://api.reforgermods.net",
"featured": true,
"order": 1,
"tags": [
"Python",
"Desktop App",
"Scheduling",
"Data Processing"
"Go",
"REST API",
"Caching",
"Web Scraping",
"Observability",
"Documentation"
],
"path": "./public/content/projects/schedule-generator-app.md"
"path": "./public/content/projects/reforger-mods-api.md"
},
{
"title": "myboker.org",
@@ -28,7 +30,7 @@
"label": "Project",
"date": "2026-06-28",
"status": "Active",
"github": null,
"github": "https://github.com/SowinskiBraeden/boker",
"demo": "https://myboker.org",
"featured": true,
"order": 2,
@@ -42,6 +44,21 @@
],
"path": "./public/content/projects/myboker-org.md"
},
{
"title": "Schedule Generator App",
"slug": "schedule-generator-app",
"type": "projects",
"summary": "A desktop application to interact with my schedule generator algorithm. The algorithm is written in Python and generates master and student timetables.",
"label": "Project",
"date": "2023-08-01",
"status": "Completed",
"github": "https://github.com/SowinskiBraeden/ScheduleGeneratorApp",
"demo": null,
"featured": true,
"order": 3,
"tags": ["Python", "Desktop App", "Scheduling", "Data Processing"],
"path": "./public/content/projects/schedule-generator-app.md"
},
{
"title": "DayZ Reforger Bot",
"slug": "dayz-reforger-bot",
@@ -53,35 +70,9 @@
"github": "https://github.com/SowinskiBraeden/dayz-reforger",
"demo": null,
"featured": true,
"order": 3,
"tags": [
"Node.js",
"Discord.js",
"MongoDB",
"Analytics",
"Nitrado"
],
"path": "./public/content/projects/dayz-reforger-bot.md"
},
{
"title": "Vairo Performance Website",
"slug": "vairo-performance-website",
"type": "projects",
"summary": "A freelance website project for Vairo Performance, including site design, content structure, domain setup, and launch support for a professional online presence.",
"label": "Project",
"date": "2026-03-01",
"status": "Client Work",
"github": null,
"demo": "https://vairo-performance.com",
"featured": true,
"order": 4,
"tags": [
"Freelance",
"Web Design",
"Domain Setup",
"Client Work"
],
"path": "./public/content/projects/vairo-performance-website.md"
"tags": ["Node.js", "Discord.js", "MongoDB", "Analytics", "Nitrado"],
"path": "./public/content/projects/dayz-reforger-bot.md"
},
{
"title": "Lines Police CAD",
@@ -95,12 +86,7 @@
"demo": "https://www.linespolice-cad.com/",
"featured": false,
"order": 5,
"tags": [
"Node.js",
"Express",
"MongoDB",
"Web App"
],
"tags": ["Node.js", "Express", "MongoDB", "Web App"],
"path": "./public/content/projects/lines-police-cad.md"
},
{
@@ -115,14 +101,24 @@
"demo": null,
"featured": false,
"order": 6,
"tags": [
"HTML",
"CSS",
"JavaScript",
"Portfolio"
],
"tags": ["HTML", "CSS", "JavaScript", "Portfolio"],
"path": "./public/content/projects/portfolio.md"
},
{
"title": "Vairo Performance Website",
"slug": "vairo-performance-website",
"type": "projects",
"summary": "A freelance website project for Vairo Performance, including site design, content structure, domain setup, and launch support for a professional online presence.",
"label": "Project",
"date": "2026-03-01",
"status": "Client Work",
"github": null,
"demo": "https://vairo-performance.com",
"featured": false,
"order": 7,
"tags": ["Freelance", "Web Design", "Domain Setup", "Client Work"],
"path": "./public/content/projects/vairo-performance-website.md"
},
{
"title": "School Management API",
"slug": "school-management-api",
@@ -134,13 +130,8 @@
"github": "https://github.com/SowinskiBraeden/school-management-api",
"demo": null,
"featured": false,
"order": 7,
"tags": [
"Go",
"API",
"Documentation",
"Education Tech"
],
"order": 8,
"tags": ["Go", "API", "Documentation", "Education Tech"],
"path": "./public/content/projects/school-management-api.md"
},
{
@@ -154,12 +145,8 @@
"github": "https://github.com/SowinskiBraeden/XP-System",
"demo": null,
"featured": false,
"order": 8,
"tags": [
"Web App",
"Education Tech",
"Gamification"
],
"order": 9,
"tags": ["Web App", "Education Tech", "Gamification"],
"path": "./public/content/projects/xp-system.md"
}
],
@@ -176,13 +163,7 @@
"demo": null,
"featured": true,
"order": 2,
"tags": [
"Hackathon",
"RF",
"Machine Learning",
"Geolocation",
"BCIT"
],
"tags": ["Hackathon", "RF", "Machine Learning", "Geolocation", "BCIT"],
"path": "./public/content/updates/red-team-hackathon-2026.md"
},
{
@@ -197,11 +178,7 @@
"demo": null,
"featured": true,
"order": 3,
"tags": [
"Computing Club",
"Executive Member",
"BCIT"
],
"tags": ["Computing Club", "Executive Member", "BCIT"],
"path": "./public/content/updates/joined-bcit-computing-club.md"
},
{
@@ -216,12 +193,7 @@
"demo": null,
"featured": true,
"order": 1,
"tags": [
"Leadership",
"BCIT",
"Community",
"C4A"
],
"tags": ["Leadership", "BCIT", "Community", "C4A"],
"path": "./public/content/updates/appointed-president-c4a.md"
}
]
+1
View File
@@ -7,6 +7,7 @@ date: 2026-06-28
status: Active
featured: true
order: 2
github: https://github.com/SowinskiBraeden/boker
live: https://myboker.org
tags: Python, Flask, Jinja, Chart.js, PostgreSQL, Analytics
---
@@ -0,0 +1,45 @@
---
title: Reforger Mods API
slug: reforger-mods-api
summary: A public, unofficial REST API for Arma Reforger Workshop metadata, built with caching, background refresh jobs, rate limiting, and production reliability in mind.
label: Project
date: 2026-07-06
status: Active
featured: true
order: 1
github: https://github.com/SowinskiBraeden/ReforgerWorkshopAPI
live: https://api.reforgermods.net
tags: Go, REST API, Web Scraping, Observability, Documentation
---
## Overview
The Arma Reforger Workshop is primarily a website, not a developer API. Panels, hosting tools, bots, and dashboards that need structured mod data have no clean way to get it. I built Reforger Mods API to fill that gap.
It is a public REST API, live at [api.reforgermods.net](https://api.reforgermods.net), that fetches and normalizes Workshop metadata into predictable, documented responses for developers. After the most recent relaunch, it started receiving identified traffic from third-party, which makes it one of the first projects I have built that is genuinely used beyond my own stack.
## What It Does
- Search and list Workshop mods with structured, filterable responses
- Retrieve detailed mod metadata normalized from raw Workshop pages
- Cache responses to avoid hammering upstream on repeated lookups
- Serve stale data while background refresh jobs revalidate it
- Return `202 Accepted` on cold cache misses so consumers are not blocked waiting on a full upstream scrape
## Reliability and API Design
A scraper-backed API has an obvious weak point: if the upstream source is slow or flaky, every request suffers. I treated reliability as a first-class concern from the start.
Cached responses return fast. When data is stale, it gets served immediately while a refresh job runs in the background. On a cold miss, the API returns `202 Accepted` with a job reference instead of making the caller wait. Rate limiting and defensive scraper error handling mean that one bad upstream page does not cascade into a broken API response.
Internal metrics track traffic, cache hit rates, refresh job behavior, and errors, so I can actually tell what the service is doing in production rather than guessing.
## Documentation
The API includes public-facing documentation covering all endpoints, response shapes, cache behavior, and how to handle `202 Accepted` responses correctly. Getting the docs right felt important, if external tools are depending on this, they need to be able to understand it without digging through source code.
Live API and docs: [api.reforgermods.net](https://api.reforgermods.net)
## Notes
This project sits at the intersection of a few things I am consistently interested in: backend infrastructure, reliability engineering, and practical tooling for game communities. It is also the first project where I have had to think seriously about backwards compatibility and defensive API design — once external consumers exist, breaking changes have real consequences. That constraint pushed me to build it more carefully than I would have if it were purely internal.
+3 -5
View File
@@ -137,12 +137,10 @@
links.push(`<a class="${className} ${className}-primary" href="./entry.html?type=${encodeURIComponent(entry.type)}&slug=${encodeURIComponent(entry.slug)}">Read More</a>`);
if (entry.github) {
links.push(`<a class="${className}" href="${escapeHtml(entry.github)}" target="_blank" rel="noopener noreferrer">GitHub</a>`);
}
if (entry.demo) {
links.push(`<a class="${className}" href="${escapeHtml(entry.demo)}" target="_blank" rel="noopener noreferrer">Live</a>`);
} else if (entry.github) {
links.push(`<a class="${className}" href="${escapeHtml(entry.github)}" target="_blank" rel="noopener noreferrer">GitHub</a>`);
}
return `<div class="${className.replace("card-link", "card-links")}">${links.join("")}</div>`;
@@ -316,8 +314,8 @@
<p class="entry-summary">${escapeHtml(entry.summary || "")}</p>
${renderTags(entry.tags || [], "entry-tag-list")}
<div class="entry-links">
${entry.github ? `<a class="inline-button" href="${escapeHtml(entry.github)}" target="_blank" rel="noopener noreferrer">GitHub</a>` : ""}
${entry.demo ? `<a class="inline-button inline-button-primary" href="${escapeHtml(entry.demo)}" target="_blank" rel="noopener noreferrer">Live</a>` : ""}
${entry.github ? `<a class="inline-button" href="${escapeHtml(entry.github)}" target="_blank" rel="noopener noreferrer">GitHub</a>` : ""}
</div>
</div>
<article class="entry-content">