first push
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/agents
|
||||
repo_url: https://git.alwisp.com/jason/agents
|
||||
language: Markdown
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# agents
|
||||
|
||||
**Repository:** [jason/agents](https://git.alwisp.com/jason/agents) · branch `main` · Markdown
|
||||
|
||||
## Summary
|
||||
|
||||
Portable drop-in markdown instruction suite for AI coding agents — provides AGENTS.md, skill index, routing hubs, and specialized skill files to copy into any repo
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# Drop-In Agent Instruction Suite
|
||||
|
||||
This repository is a portable markdown instruction pack for coding agents.
|
||||
|
||||
Copy these files into another repository to give the agent:
|
||||
- a root `AGENTS.md` entrypoint,
|
||||
- a central skill index,
|
||||
- category hubs for routing,
|
||||
- specialized skill files for common software, docs, UX, marketing, and ideation tasks.
|
||||
|
||||
## Structure
|
||||
|
||||
- `AGENTS.md` - base instructions and routing rules
|
||||
- `DEPLOYMENT-PROFILE.md` - agent-readable prefilled deployment defaults
|
||||
- `INSTALL.md` - copy and customization guide for other repositories
|
||||
- `PROJECT-PROFILE-WORKBOOK.md` - one-time questionnaire for staging defaults
|
||||
- `SKILLS.md` - canonical skill index
|
||||
- `ROUTING-EXAMPLES.md` - representative prompt-to-skill routing examples
|
||||
- `hubs/` - category-level routing guides
|
||||
- `skills/` - specialized reusable skill files
|
||||
|
||||
## Design Goals
|
||||
|
||||
- Plain markdown only
|
||||
- Cross-agent portability
|
||||
- Implementation-first defaults
|
||||
- On-demand skill loading instead of loading everything every session
|
||||
- Context-efficient routing for large skill libraries
|
||||
- Prefilled deployment defaults without per-install questioning
|
||||
- Repo-local instructions take precedence over this bundle
|
||||
|
||||
## Intended Workflow
|
||||
|
||||
1. The agent reads `AGENTS.md`.
|
||||
2. The agent reads `DEPLOYMENT-PROFILE.md` when it is filled in.
|
||||
3. The agent checks `SKILLS.md`.
|
||||
4. The agent opens only the relevant hub and skill files for the task.
|
||||
5. The agent combines multiple skills when the task spans several domains.
|
||||
|
||||
## Core Categories
|
||||
|
||||
- Software development
|
||||
- Debugging
|
||||
- Documentation
|
||||
- UI/UX
|
||||
- Marketing
|
||||
- Brainstorming
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,77 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/alwisp
|
||||
repo_url: https://git.alwisp.com/jason/alwisp
|
||||
language: Hack
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# alwisp
|
||||
|
||||
**Repository:** [jason/alwisp](https://git.alwisp.com/jason/alwisp) · branch `main` · Hack
|
||||
|
||||
## Summary
|
||||
|
||||
Dockerized LAMP stack website for ALWISP, Alabama's wireless ISP and mesh networking company
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# ALWISP – Mesh Network Solutions
|
||||
|
||||
> Dockerized LAMP stack website for Alabama's wireless ISP and mesh networking company.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Stack Overview](#stack-overview)
|
||||
- [Installation – Unraid](#installation--unraid)
|
||||
- [Environment Variables](#environment-variables)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Roadmap & Milestones](#roadmap--milestones)
|
||||
- [Updating the Site](#updating-the-site)
|
||||
- [Useful Commands](#useful-commands)
|
||||
|
||||
---
|
||||
|
||||
## Stack Overview
|
||||
|
||||
| Container | Image | Purpose |
|
||||
|---|---|---|
|
||||
| `alwisp_web` | PHP 8.2 + Apache | Serves the website |
|
||||
| `alwisp_db` | MySQL 8.0 | Database (internal only) |
|
||||
| `alwisp_pma` | phpMyAdmin (optional) | DB admin UI on port 8080 |
|
||||
|
||||
Each container is deployed individually through the Unraid Container Builder and connected via the `br0` bridge network, giving both the web container and the database container their own dedicated LAN IP addresses. The web container reaches the database by its fixed LAN IP. Data persists in a named Docker volume (`db_data`) and survives container restarts and rebuilds.
|
||||
|
||||
---
|
||||
|
||||
## Installation – Unraid
|
||||
|
||||
### Prerequisites
|
||||
|
||||
- Unraid 6.10 or later
|
||||
- **Community Applications** plugin installed
|
||||
- **Docker** enabled (Settings → Docker → Enable Docker: Yes)
|
||||
- **User Scripts** plugin (recommended, for scheduled tasks)
|
||||
- `br0` enabled — your Unraid host NIC must be bridged (Settings → Network → Enable Bridging: Yes)
|
||||
- Decide on **two free LAN IPs** before you start — one for the web container, one for the database. Example: `192.168.1.100` (web) and `192.168.1.101` (db). Reserve these in your router's DHCP settings so they are never auto-assigned.
|
||||
|
||||
---
|
||||
|
||||
### Step 1 – Clone the repository onto your Unraid cache drive
|
||||
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,75 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/breedr
|
||||
repo_url: https://git.alwisp.com/jason/breedr
|
||||
language: JavaScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# breedr
|
||||
|
||||
**Repository:** [jason/breedr](https://git.alwisp.com/jason/breedr) · branch `main` · JavaScript
|
||||
|
||||
## Summary
|
||||
|
||||
Reactive dog breeding genealogy management system — pedigree mapping, litter records, and ancestor/descendant views in a single Docker container
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# BREEDR - Dog Breeding Genealogy Management System
|
||||
|
||||
A reactive, interactive dog breeding genealogy mapping system for professional kennel management.
|
||||
|
||||
---
|
||||
|
||||
## 🌟 Recent Highlights (v0.8.0)
|
||||
- **✅ Reverse Pedigree** — Toggle between ancestors and descendants view for full lineage tracking.
|
||||
- **✅ External Dog Mapping** — Assign parents to external dogs, allowing for full genealogy of outside lines.
|
||||
- **✅ Universal Parent Selection** — Select any dog (kennel or external) as a sire/dam from any profile.
|
||||
|
||||
---
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Docker Deployment (Recommended)
|
||||
```bash
|
||||
git clone https://git.alwisp.com/jason/breedr.git
|
||||
cd breedr
|
||||
docker-compose up -d --build
|
||||
```
|
||||
Access at: `http://localhost:3000`
|
||||
|
||||
### 2. Manual Development Setup
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
> **Note:** The database initializes automatically on first boot. No manual migrations are required.
|
||||
|
||||
---
|
||||
|
||||
## 🐕 Managing Your Kennel
|
||||
|
||||
- **Adding Dogs**: Go to the **Dogs** page, click **Add New Dog**. You can mark dogs as **External** if they aren't in your kennel but are needed for pedigree mapping.
|
||||
- **Champion Tracking**: Toggle the **Champion** status to title dogs. Offspring will automatically display the "Champion Bloodline" badge.
|
||||
- **Photo Management**: Multiple high-quality photos per dog with a compact gallery view.
|
||||
- **Litter Tracking**: Link puppies to breeding records automatically to track weight and health from birth.
|
||||
|
||||
## 🧬 Breeding & Genetics
|
||||
|
||||
- **Interactive Pedigree**: 5-generation trees with zoom/pan. Toggle the **Reverse Pedigree** switch to see descendant lineage.
|
||||
- **Trial Pairing Simulator**: Calculate Wright's Inbreeding Coefficient (COI) instantly. Identifies common ancestors and providing risk badges (Low/Moderate/High).
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,84 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/codedump
|
||||
repo_url: https://git.alwisp.com/jason/codedump
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# codedump
|
||||
|
||||
**Repository:** [jason/codedump](https://git.alwisp.com/jason/codedump) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Internal dashboard for tracking AI tools and coding projects — shows completion status, links documentation, and manages team access via admin accounts and PINs
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
_Source: PROJECT.md_
|
||||
|
||||
# CODEDUMP
|
||||
|
||||
Internal dashboard for tracking AI tools and coding projects. Provides a high-level overview of what the team is building, what tools are available, and the completion status of active work — all in one place.
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
CODEDUMP gives teams a single place to:
|
||||
|
||||
- Track AI tools and coding projects with completion percentages
|
||||
- Attach markdown documentation and project files
|
||||
- Link to internal/external URLs and Google Drive sources
|
||||
- Highlight new tools available to the team
|
||||
- Manage access via admin accounts and 4-digit user PINs
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|---|---|
|
||||
| Frontend | React 18 + TypeScript + Vite |
|
||||
| Styling | Tailwind CSS (dark mode, CSS variable theming) |
|
||||
| Backend | Node.js + Express + TypeScript |
|
||||
| Database | SQLite via `better-sqlite3` |
|
||||
| Auth | JWT (12h expiry) + bcryptjs (admin passwords) + HMAC-SHA256 (user PINs) |
|
||||
| File uploads | Multer (local disk storage) |
|
||||
| Markdown | `react-markdown` + `remark-gfm` |
|
||||
| Container | Docker (multi-stage build, single container) |
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
codedump/
|
||||
├── client/ # React frontend
|
||||
│ ├── src/
|
||||
│ │ ├── api/index.ts # Typed fetch wrappers (JWT injected automatically)
|
||||
│ │ ├── hooks/
|
||||
│ │ │ ├── useAuth.ts # AuthContext — JWT storage, login/logout
|
||||
│ │ │ └── useSettings.ts # SettingsContext — branding, accent color
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── layout/
|
||||
│ │ │ │ ├── Layout.tsx # App shell (sidebar + outlet)
|
||||
│ │ │ │ └── Sidebar.tsx # Nav — auth-aware, admin section, logout
|
||||
│ │ │ ├── projects/
|
||||
│ │ │ │ ├── ProjectCard.tsx # Card with progress bar, links, tags
|
||||
│ │ │ │ └── ProjectForm.tsx # Create/edit form with color picker
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/codexium-odoo
|
||||
repo_url: https://git.alwisp.com/jason/codexium-odoo
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# codexium-odoo
|
||||
|
||||
**Repository:** [jason/codexium-odoo](https://git.alwisp.com/jason/codexium-odoo) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
CODEXIUM MRP platform (Odoo variant) — modular Manufacturing Resource Planning with React, Express, Prisma, SQLite, full CRM, inventory, and BOM management
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# CODEXIUM
|
||||
|
||||
Foundation release for a modular Manufacturing Resource Planning platform built with React, Express, Prisma, SQLite, and a single-container Docker deployment.
|
||||
|
||||
## Documentation Maintenance
|
||||
|
||||
- Keep [CHANGELOG.md](D:/CODING/mrp-codex/CHANGELOG.md) updated for shipped features, workflow changes, and notable operational updates.
|
||||
- Keep [README.md](D:/CODING/mrp-codex/README.md), [INSTRUCTIONS.md](D:/CODING/mrp-codex/INSTRUCTIONS.md), [STRUCTURE.md](D:/CODING/mrp-codex/STRUCTURE.md), [ROADMAP.md](D:/CODING/mrp-codex/ROADMAP.md), [SHIPPED.md](D:/CODING/mrp-codex/SHIPPED.md), and [UNRAID.md](D:/CODING/mrp-codex/UNRAID.md) aligned when changes affect their scope.
|
||||
|
||||
Current foundation scope includes:
|
||||
|
||||
- authentication and RBAC
|
||||
- company branding and theme settings, including startup brand-theme hydration across refresh
|
||||
- CRM customers and vendors with create/edit/detail workflows
|
||||
- CRM search, filtering, status tagging, and reseller hierarchy
|
||||
- CRM contact history, account contacts, and shared attachments
|
||||
- inventory item master, BOM, warehouse, stock-location, and stock-transaction flows
|
||||
- inventory transfers, reservations, and available-stock visibility
|
||||
- inventory SKU master builder with family-scoped sequence generation and branch-aware taxonomy management
|
||||
- staged thumbnail image attachment on inventory item create/edit workflows, with detail-page thumbnail display
|
||||
- sales quotes and sales orders with searchable customer and SKU entry
|
||||
- sales approvals, approval stamps, automatic revision history, and revision comparison on quotes and sales orders
|
||||
- purchase orders with searchable vendor and SKU entry, restricted to purchasable inventory items
|
||||
- purchase-order revision history and revision comparison across commercial and receipt changes
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
tags:
|
||||
- cpas
|
||||
- mpm-internal
|
||||
- sqlite
|
||||
- express
|
||||
- react
|
||||
- puppeteer
|
||||
- mpm
|
||||
updated: 2026-05-27
|
||||
---
|
||||
|
||||
# CPAS Violation Tracker
|
||||
|
||||
Internal MPM tool for tracking employee CPAS (Corrective Performance Action System) violations. Single Docker container, self-contained. Repo: `git.alwisp.com/jason/cpas` (also pushed to git.mpm.to as MPM internal).
|
||||
|
||||
Local path: `F:\CODING\cpas\cpas`.
|
||||
|
||||
## Stack
|
||||
|
||||
- **Backend:** Node.js + Express + `better-sqlite3` (better-sqlite3 won't compile on local Node v24 — builds fine in `node:20-alpine` Docker)
|
||||
- **Frontend:** React 18 + Vite, axios for API calls, dark theme inline styles (no Tailwind here)
|
||||
- **PDF:** Puppeteer-core driving Chromium in the container
|
||||
- **DB:** SQLite at `/data/cpas.db`, WAL mode, foreign keys ON. Schema lives in `db/schema.sql` with programmatic migrations in `db/database.js`
|
||||
- **Port:** 3001
|
||||
- **Deployment:** Single container on Unraid, volume `/data` for the DB
|
||||
|
||||
## Key architecture notes
|
||||
|
||||
- Violations carry a 90-day rolling window. Each violation stores a `prior_active_points` **snapshot** at submission so its PDF always shows the score *as it was on the incident date*. Snapshots auto-refresh on back-dated inserts and via a manual "Backfill Snapshots" button per employee.
|
||||
- Negate = soft delete (reversible). Hard delete is also supported. Both are audit-logged.
|
||||
- Append-only `audit_log` table records every write action.
|
||||
- Custom violation types stored in `violation_types` table; type_key prefixed with `custom_` to avoid collisions.
|
||||
|
||||
## Authentication (added 2026-05-27)
|
||||
|
||||
- **Login screen** gates the entire app. Every `/api/*` route except `/api/health` and `/api/auth/login` requires a `Bearer` token.
|
||||
- **Bootstrap admin** created/synced from `ADMIN_USERNAME` / `ADMIN_PASSWORD` env vars on every container start — its password is owned by Docker (cannot be changed in UI; UI changes overwritten on restart). Default `ADMIN_PASSWORD=changeme` must be overridden at deploy.
|
||||
- **Password hashing:** Node built-in `crypto.scryptSync` (no new deps). Stored as `scrypt$<saltHex>$<hashHex>`.
|
||||
- **Sessions:** DB-backed in `sessions` table, 7-day TTL, token = `crypto.randomBytes(32).toString('hex')`. Sessions survive container restarts.
|
||||
- **Roles:** `admin` and `user`. Admin sees a **Users** button in the nav to add/delete users and reset passwords.
|
||||
- **Frontend:** axios request interceptor injects `Authorization: Bearer <token>` from localStorage on every call; response interceptor clears token + falls back to login on 401. Covers all components including blob PDF downloads (which use axios with `responseType: 'blob'`, no direct anchor links).
|
||||
|
||||
## Files of note
|
||||
|
||||
- `auth.js` — auth module (hashing, sessions, user CRUD, middleware, `bootstrapAdmin()`)
|
||||
- `server.js` — `app.use('/api', auth.requireAuth)` placed after `/api/health` and `/api/auth/login` so those stay public; all routes below are protected
|
||||
- `db/database.js` — `users` and `sessions` tables added
|
||||
- `client/src/auth.js` — axios interceptors + token helpers
|
||||
- `client/src/components/LoginModal.jsx` — login popup
|
||||
- `client/src/components/UserManagementModal.jsx` — admin Users panel
|
||||
- `client/src/App.jsx` — auth gate (`authChecked`/`user` state), logout button, conditional Users button
|
||||
- `Dockerfile` — `ENV ADMIN_USERNAME=admin` and `ENV ADMIN_PASSWORD=changeme` defaults
|
||||
- `client/src/components/ReadmeModal.jsx` — in-app admin guide; updated with "Authentication & User Accounts" section
|
||||
- `README_UNRAID_INSTALL.md` — adds steps 5.5 Variables 3+4 (admin env vars), login note in Verify, troubleshooting rows for forgotten admin password
|
||||
|
||||
## Current status
|
||||
|
||||
Authentication shipped (2026-05-27). Backend syntax-checks pass; client builds clean. Could not verify locally because better-sqlite3 fails to compile on Node v24 — verification requires building/running the Docker container.
|
||||
|
||||
## Open considerations
|
||||
|
||||
- No expanded role model yet (only admin/user). Future: supervisor-scoped or read-only roles.
|
||||
- No password-change UI for non-admin users (they ask an admin to reset). Could add.
|
||||
- Sessions table has no periodic cleanup of expired tokens; expired tokens are pruned lazily on use.
|
||||
|
||||
## Roll-off model fix (2026-05-27)
|
||||
|
||||
Earlier "90-day rolling window per violation" wording above is **superseded**. The handbook actually specifies a *clean-cycle* roll-off: points only retire after 90 consecutive days with NO new violation, and any new non-negated violation resets the clock for the whole employee. Each completed clean cycle removes 5 points oldest-first; each successive 5-point roll-off needs another fresh 90 clean days.
|
||||
|
||||
The old per-violation expiry was rolling whole violations off independently 90 days from their own incident date — so a new violation didn't reset the countdown on earlier ones. Bug surfaced by Jason; fixed same session.
|
||||
|
||||
### Implementation
|
||||
|
||||
- `lib/rolloff.js` (new) — pure `computeStanding(violations, asOf)` is the **single source of truth**. Returns `{ activePoints, totalPoints, rolledOffPoints, cycles, violationCount, lastViolationDate, nextRolloffDate, perViolation, schedule }`. Verified with scenario tests (single violation, two-violation reset case, multi-cycle decay).
|
||||
- `active_cpas_scores` SQL view **retired** (dropped in `db/database.js`, removed from `schema.sql`). SQL can't cleanly express oldest-first partial allocation, so all standing computation moved to JS to avoid SQL/JS divergence.
|
||||
- `server.js` rewired: `/score`, `/dashboard`, `/expiration`, `getPriorActivePoints`, PDF endpoint, and `recomputeSnapshotsAfter` all go through the helper. Dashboard now fetches all non-negated violations once, buckets per employee, and computes in JS (fine at MPM scale).
|
||||
- `/expiration` response shape changed from a list of per-violation rows to `{ active_points, last_violation_date, next_rolloff_date, schedule: [{date, points_off, points_after, days_remaining}] }`.
|
||||
- `recomputeSnapshotsAfter` window widened: under the new model an earlier backdated insert shifts every later violation's snapshot (not just within 90 days), so it now scans all later violations.
|
||||
- Frontend: `ExpirationTimeline.jsx` re-rendered as a roll-off schedule with a "clock resets on any new violation" note. `ViolationForm.jsx` label changed from "violations in last 90 days" → "active violations".
|
||||
|
||||
### Migration / backfill posture
|
||||
|
||||
- **Automatic on restart:** every live read (dashboard, score, expiration, PDF current standing, prior points for NEW inserts).
|
||||
- **Needs manual backfill:** `prior_active_points` already stored on pre-fix violation rows — they were frozen under the old rule. Existing "Backfill Snapshots" button (`POST /api/employees/:id/recompute-snapshots`) rewrites them per employee. Skip unless historical PDFs matter.
|
||||
|
||||
### Files touched
|
||||
|
||||
- `lib/rolloff.js` (new)
|
||||
- `db/database.js` (drop view)
|
||||
- `db/schema.sql` (drop view)
|
||||
- `server.js` (helper require, `loadViolations`/`standingFor`, all 5 endpoint rewires)
|
||||
- `client/src/components/ExpirationTimeline.jsx` (full rewrite of render)
|
||||
- `client/src/components/ViolationForm.jsx` (label tweak)
|
||||
@@ -0,0 +1,74 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/email
|
||||
repo_url: https://git.alwisp.com/jason/email
|
||||
language: HTML
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# email
|
||||
|
||||
**Repository:** [jason/email](https://git.alwisp.com/jason/email) · branch `main` · HTML
|
||||
|
||||
## Summary
|
||||
|
||||
Self-hosted Dockerized Google Workspace email signature manager — syncs users from Google Directory and pushes HTML signatures directly to Gmail via API
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# Email Signature Manager
|
||||
|
||||
A self-hosted, Dockerized Google Workspace email signature manager.
|
||||
Runs as a single container — designed for Unraid but works on any Docker host.
|
||||
See [INSTALL.md](INSTALL.md) for Unraid-specific instructions.
|
||||
|
||||
## Features
|
||||
|
||||
- **Automated Directory Sync** — Pulls user data from Google Workspace Directory API
|
||||
- **HTML Signature Renderer** — Per-user signatures via Handlebars templates
|
||||
- **Gmail API Integration** — Pushes signatures directly to Gmail (web + mobile)
|
||||
- **Nightly Sync** — Automated batch push via configurable cron schedule
|
||||
- **Web Admin UI** — Management dashboard with live template editor
|
||||
- **Template Versioning** — Save multiple versions and recall them later
|
||||
- **Test Mode** — Single-user push for safe testing and onboarding
|
||||
- **Audit Logging** — SQLite-backed history of every push event
|
||||
- **Secure Access** — Basic auth protected management interface
|
||||
- **Self-Hosted** — Single container with internal SQLite, no external DB needed
|
||||
|
||||
---
|
||||
|
||||
## Logo & Image Hosting
|
||||
|
||||
All images referenced in the signature template must be publicly accessible via HTTPS.
|
||||
The default logo URL is:
|
||||
```
|
||||
https://alwisp.com/uploads/logo.png
|
||||
```
|
||||
Upload your logo and any other signature images to `https://alwisp.com/uploads/` and
|
||||
reference them by full URL in the template. The logo URL can also be changed live
|
||||
in the Template Editor UI without rebuilding the container.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
|
||||
All secrets and configuration are passed as **environment variables at runtime**.
|
||||
No `.env` file is committed to this repo — see `.env.example` for all variable names.
|
||||
|
||||
| Variable | Description | Default |
|
||||
|---|---|---|
|
||||
| `GOOGLE_ADMIN_EMAIL` | Workspace admin email (e.g. jason@messagepoint.tv) | *(required)* |
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/fabdash
|
||||
repo_url: https://git.alwisp.com/jason/fabdash
|
||||
language: JavaScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# fabdash
|
||||
|
||||
**Repository:** [jason/fabdash](https://git.alwisp.com/jason/fabdash) · branch `main` · JavaScript
|
||||
|
||||
## Summary
|
||||
|
||||
FABDASH: fabrication project management and scheduling dashboard — dark/gold-themed React + Flask + SQLite single-container app for fabrication workflow management
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# FABDASH
|
||||
|
||||
**Fabrication Dashboard** — A sleek, modern project management & scheduling application built for fabrication workflows.
|
||||
Repo: https://github.com/jasonMPM/fabdash
|
||||
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
- [Overview](#overview)
|
||||
- [Tech Stack](#tech-stack)
|
||||
- [Project Structure](#project-structure)
|
||||
- [Features](#features)
|
||||
- [Interaction Reference](#interaction-reference)
|
||||
- [Keyboard Shortcuts](#keyboard-shortcuts)
|
||||
- [API Reference](#api-reference)
|
||||
- [Component Architecture](#component-architecture)
|
||||
- [Unraid Installation](#unraid-installation)
|
||||
- [Adding Your Logo](#adding-your-logo)
|
||||
- [Updating FabDash on Unraid](#updating-fabdash-on-unraid)
|
||||
- [Local Development](#local-development)
|
||||
- [Environment Variables](#environment-variables)
|
||||
- [Database Schema](#database-schema)
|
||||
- [Roadmap](#roadmap)
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
FabDash is a self-hosted, full-stack project management dashboard built for fabrication teams. It features a large interactive calendar, multi-deliverable project tracking, drag-and-drop scheduling, a per-project Focus View timeline, a redesigned workload heatmap with per-status color-coded grids, an agenda panel, right-click context menus, keyboard shortcuts, and a collapsible branded sidebar — all wrapped in a dark/gold UI and deployed as a single Docker container with no external dependencies.
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
### Frontend
|
||||
|
||||
| Package | Version | Purpose |
|
||||
|---|---|---|
|
||||
| React | ^18.3.1 | UI framework |
|
||||
| Vite | ^5.4.11 | Build tool and dev server |
|
||||
| Tailwind CSS | ^3.4.15 | Utility-first styling |
|
||||
| @fullcalendar/core | 6.1.15 | FullCalendar core (pinned — version must match all FC packages) |
|
||||
| @fullcalendar/react | 6.1.15 | Calendar component |
|
||||
| @fullcalendar/daygrid | 6.1.15 | Month/week grid view |
|
||||
| @fullcalendar/timegrid | 6.1.15 | Time-slot view |
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/family-planner
|
||||
repo_url: https://git.alwisp.com/jason/family-planner
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# family-planner
|
||||
|
||||
**Repository:** [jason/family-planner](https://git.alwisp.com/jason/family-planner) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Self-hosted family dashboard for always-on displays — calendars, chores, shopping, meals, message board, countdowns, and photo screensaver in one Docker container
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
_Source: PROJECT.md_
|
||||
|
||||
# Family Planner — Project Reference
|
||||
|
||||
A self-hosted family dashboard designed for always-on display (wall tablet, TV, Unraid server). Manages calendars, chores, shopping, meals, a message board, countdowns, and a photo screensaver — all in one Docker container with zero external services required.
|
||||
|
||||
---
|
||||
|
||||
## Tech Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|---|---|
|
||||
| **Runtime** | Node.js 22, Docker (Alpine) |
|
||||
| **Backend** | Express 4, TypeScript 5 |
|
||||
| **Database** | Node.js built-in SQLite (`node:sqlite`), WAL mode |
|
||||
| **File uploads** | Multer |
|
||||
| **Frontend** | React 18, TypeScript 5, Vite 5 |
|
||||
| **Styling** | Tailwind CSS 3, CSS custom properties (theme tokens) |
|
||||
| **Animation** | Framer Motion 11 |
|
||||
| **State / data** | TanStack Query 5, Zustand 4 |
|
||||
| **Routing** | React Router 6 |
|
||||
| **Icons** | Lucide React |
|
||||
| **Date utils** | date-fns 3 |
|
||||
| **Package manager** | pnpm (workspaces monorepo) |
|
||||
| **CI/CD** | Gitea Actions → Docker build & push to private registry |
|
||||
| **Deployment target** | Unraid (Community Applications / CLI install) |
|
||||
|
||||
---
|
||||
|
||||
## Repository Structure
|
||||
|
||||
```
|
||||
family-planner/
|
||||
├── apps/
|
||||
│ ├── client/ # React frontend
|
||||
│ │ └── src/
|
||||
│ │ ├── components/
|
||||
│ │ │ ├── layout/
|
||||
│ │ │ │ └── AppShell.tsx # Sidebar, mobile drawer, page wrapper
|
||||
│ │ │ ├── screensaver/
|
||||
│ │ │ │ └── Screensaver.tsx # Idle screensaver w/ Ken Burns slideshow
|
||||
│ │ │ └── ui/ # Design-system primitives
|
||||
│ │ │ ├── Avatar.tsx
|
||||
│ │ │ ├── Badge.tsx
|
||||
│ │ │ ├── Button.tsx
|
||||
│ │ │ ├── Input.tsx
|
||||
│ │ │ ├── Modal.tsx
|
||||
│ │ │ ├── Select.tsx
|
||||
│ │ │ ├── Textarea.tsx
|
||||
│ │ │ └── ThemeToggle.tsx
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/inven
|
||||
repo_url: https://git.alwisp.com/jason/inven
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# inven
|
||||
|
||||
**Repository:** [jason/inven](https://git.alwisp.com/jason/inven) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Single-container inventory management for Unraid — parts, assemblies, BOMs, sales/purchase orders, invoicing, and a lightweight accounting journal on SQLite
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# Inven
|
||||
|
||||
Inven is a single-container inventory management system for Unraid-style deployments. It manages stocked parts, assemblies built from parts, sales orders and shipping, purchase orders and restocking, customers, vendors, and a lightweight accounting journal on top of SQLite.
|
||||
|
||||
## Current Scope
|
||||
|
||||
- Parts and assemblies share one item master
|
||||
- Assemblies support bill-of-material component definitions
|
||||
- Inventory is tracked through a transaction ledger
|
||||
- Sales orders can be created and shipped
|
||||
- Purchase orders can be created and received
|
||||
- Sales orders and purchase orders are created from relational inventory line selections
|
||||
- Shipping and receiving are posted from relational order-line quantity controls
|
||||
- Sales orders support partial shipments
|
||||
- Purchase orders support partial receipts
|
||||
- Invoices are generated from shipped sales orders
|
||||
- Vendor bills are generated from received purchase orders
|
||||
- Customer and vendor payments can clear receivables and payables
|
||||
- Customer and vendor directories support the order flows
|
||||
- Low-stock and suggested reorder views help drive replenishment
|
||||
- A chart of accounts, account balances, and manual journals support the first accounting pass
|
||||
- Built-in authentication protects the app with a bootstrap admin login
|
||||
|
||||
## Stack
|
||||
|
||||
- Next.js App Router
|
||||
- TypeScript
|
||||
- SQLite via `better-sqlite3`
|
||||
- Single Docker container with Next.js standalone output
|
||||
|
||||
## Quick Start
|
||||
|
||||
1. Install Node.js 22 or newer.
|
||||
2. Copy `.env.example` to `.env`.
|
||||
3. Set `AUTH_SECRET`, `ADMIN_EMAIL`, and `ADMIN_PASSWORD`.
|
||||
4. Update `DATABASE_PATH` if needed.
|
||||
5. Install dependencies:
|
||||
|
||||
```bash
|
||||
npm install
|
||||
```
|
||||
|
||||
6. Start the development server:
|
||||
|
||||
```bash
|
||||
npm run dev
|
||||
```
|
||||
|
||||
7. Open `http://localhost:3000` and sign in with the bootstrap admin credentials.
|
||||
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,79 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/memer
|
||||
repo_url: https://git.alwisp.com/jason/memer
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# memer
|
||||
|
||||
**Repository:** [jason/memer](https://git.alwisp.com/jason/memer) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Self-hosted meme gallery with quick-share for SMS and Telegram — Dockerized masonry grid with tag search, upload, and non-destructive image rescaling
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# Memer
|
||||
|
||||
A self-hosted meme gallery with quick-share for text message and Telegram. Runs as a single Docker container, designed for Unraid.
|
||||
|
||||
## Features
|
||||
|
||||
- **Masonry gallery** — responsive, dark-themed grid
|
||||
- **Upload** — drag & drop or click, supports JPG/PNG/GIF/WebP (up to 100 MB)
|
||||
- **Tags** — organize with comma-separated tags, filter by tag in the gallery
|
||||
- **Search** — full-text search across titles and descriptions
|
||||
- **Quick share** — copy link, Telegram, SMS, or download from any card or detail view
|
||||
- **Non-destructive rescale** — creates a child image at a new size without touching the original
|
||||
- **Persistent** — SQLite database + image files on Docker volumes (easy to back up or export)
|
||||
|
||||
## Quick Start
|
||||
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env: set PUBLIC_URL to your domain
|
||||
docker compose up --build -d
|
||||
```
|
||||
|
||||
Open `http://localhost:3000`.
|
||||
|
||||
## Unraid Setup
|
||||
|
||||
1. In Unraid, go to **Docker > Add Container** (or use Community Applications).
|
||||
2. Use the image `memer:latest` (build locally or push to a registry).
|
||||
3. Map port **3000** to your desired host port.
|
||||
4. Add two path mappings:
|
||||
- `/data/images` → `/mnt/user/appdata/memer/images`
|
||||
- `/data/db` → `/mnt/user/appdata/memer/db`
|
||||
5. Set environment variable `PUBLIC_URL` to `https://meme.alwisp.com`.
|
||||
6. Set up your reverse proxy (Nginx Proxy Manager, Swag, etc.) to point `meme.alwisp.com` → port 3000.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `PUBLIC_URL` | `http://localhost:3000` | Used to build absolute share links |
|
||||
| `PORT` | `3000` | Port the server listens on |
|
||||
| `DATA_DIR` | `/data` | Root for images and DB inside the container |
|
||||
|
||||
## API
|
||||
|
||||
| Method | Path | Description |
|
||||
|---|---|---|
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,65 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/mempalace
|
||||
repo_url: https://git.alwisp.com/jason/mempalace
|
||||
language: Python
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# mempalace
|
||||
|
||||
**Repository:** [jason/mempalace](https://git.alwisp.com/jason/mempalace) · branch `main` · Python
|
||||
|
||||
## Summary
|
||||
|
||||
Server-mode fork of MemPalace — shared Docker container on Unraid so Claude Code, Codex, and MCP clients can share one persistent AI memory palace over LAN
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# MemPalace — server-mode fork
|
||||
|
||||
Local-first AI memory, deployed as a shared service across machines.
|
||||
|
||||
This is a personal fork of [MemPalace](https://github.com/MemPalace/mempalace) configured for **server-mode deployment**: MemPalace runs as a Docker container (typically on Unraid) and multiple AI tools — Claude Code, Codex, Antigravity, or any MCP-compatible client — connect to a single shared palace from any machine on the network. Auto-save hooks on each client push session transcripts to the server over HTTPS with bearer auth.
|
||||
|
||||
The upstream project remains local-first by design. This fork makes one deliberate trade: data crosses the LAN to a user-controlled server instead of staying on the originating machine. Privacy, verbatim storage, no-cloud, and no-telemetry properties are otherwise unchanged. See [CLAUDE.md](CLAUDE.md) for the architectural reasoning.
|
||||
|
||||
---
|
||||
|
||||
## What's in this fork
|
||||
|
||||
```
|
||||
home LAN
|
||||
┌───────────────────────────────────┐
|
||||
│ Unraid (always on) │
|
||||
│ ┌────────────────────────────┐ │
|
||||
│ │ caddy :8443 (TLS + auth) │ │
|
||||
│ │ ├─ /sse → mcp-proxy │ │
|
||||
│ │ └─ /ingest → ingest API │ │
|
||||
│ │ mempalace (single process) │ │
|
||||
│ │ ├─ mcp-proxy :8765 │ │
|
||||
│ │ └─ ingest :8766 │ │
|
||||
│ └────────────────────────────┘ │
|
||||
└───────────────────────────────────┘
|
||||
│ │ │
|
||||
┌────┴───┐ ┌────┴───┐ ┌────┴─────┐
|
||||
│ Claude │ │ Codex │ │ Antigrav │
|
||||
└────────┘ └────────┘ └──────────┘
|
||||
```
|
||||
|
||||
* **One palace, many clients.** Search and write target the same ChromaDB index regardless of which machine you're on.
|
||||
* **Single bearer token gates everything.** Caddy sidecar terminates TLS and enforces `Authorization: Bearer <token>` at the edge.
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,52 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/mrp-qrcode
|
||||
repo_url: https://git.alwisp.com/jason/mrp-qrcode
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# mrp-qrcode
|
||||
|
||||
**Repository:** [jason/mrp-qrcode](https://git.alwisp.com/jason/mrp-qrcode) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
MRP QR Code System — fabrication shop tracker with printable QR traveler cards, phone-based operator scan flow, PDF generation, and in-browser STEP viewer
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# MRP QR Code System
|
||||
|
||||
A single-container, self-hosted Manufacturing Resource Planning (MRP) app built around printable QR-coded traveler cards. Designed for small fabrication shops running on an Unraid server with phone-based operators.
|
||||
|
||||
## Status
|
||||
|
||||
Shipped (see [`docs/BUILD-PLAN.md`](docs/BUILD-PLAN.md)): steps 1, 2, 3, 4, 5, 6, 8.
|
||||
|
||||
- **1.** Scaffold + auth (admin email/password, operator name/4-digit PIN with 12 h device session, PIN lockout, audited sessions).
|
||||
- **2.** Admin CRUD (users, machines, operation templates, projects / assemblies / parts) with content-addressed STEP / PDF / DXF / SVG file uploads.
|
||||
- **3.** Operation authoring with per-operation QR tokens (192-bit, base64url).
|
||||
- **4.** Operator scan flow — phone scan resolves `/op/scan/<token>`, single-claim enforced at DB level, Start / Pause / Done with inline QC for steps that require it, TimeLog rows for every claim.
|
||||
- **5.** PDF traveler generation — per-operation card + per-part cover sheet with the full operation list and file manifest. Printed via `pdf-lib` (no native deps).
|
||||
- **6.** Fasteners + purchase orders — per-project BOM of fasteners with unresolved-need rollups, PO lifecycle (`draft → sent → partial → received`, or `cancelled`), per-line receipt entry with auto-advance, and vendor-ready PDF downloads.
|
||||
- **8.** In-browser STEP viewer — OpenCascade (WASM, via `occt-import-js`) parses STEP/STP, `three.js` renders with OrbitControls. Thumbnails are captured from the first rendered frame, uploaded to the content-addressed file store, and displayed on the assembly parts list. No native deps, no server-side GL.
|
||||
|
||||
Planned (not yet shipped): dashboard (step 7) → dedicated QC operations (9) → OpenAPI docs + backups (10).
|
||||
|
||||
## Core concepts
|
||||
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,56 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/mrp
|
||||
repo_url: https://git.alwisp.com/jason/mrp
|
||||
language: TypeScript
|
||||
branch: master
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# mrp
|
||||
|
||||
**Repository:** [jason/mrp](https://git.alwisp.com/jason/mrp) · branch `master` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
CODEXIUM: modular Manufacturing Resource Planning platform — React, Express, Prisma, and SQLite with full CRM, inventory, BOM, and RBAC in one Docker container
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# CODEXIUM
|
||||
|
||||
Foundation release for a modular Manufacturing Resource Planning platform built with React, Express, Prisma, SQLite, and a single-container Docker deployment.
|
||||
|
||||
## Documentation Maintenance
|
||||
|
||||
- Keep [CHANGELOG.md](D:/CODING/mrp-codex/CHANGELOG.md) updated for shipped features, workflow changes, and notable operational updates.
|
||||
- Keep [README.md](D:/CODING/mrp-codex/README.md), [INSTRUCTIONS.md](D:/CODING/mrp-codex/INSTRUCTIONS.md), [STRUCTURE.md](D:/CODING/mrp-codex/STRUCTURE.md), [ROADMAP.md](D:/CODING/mrp-codex/ROADMAP.md), [SHIPPED.md](D:/CODING/mrp-codex/SHIPPED.md), and [UNRAID.md](D:/CODING/mrp-codex/UNRAID.md) aligned when changes affect their scope.
|
||||
|
||||
Current foundation scope includes:
|
||||
|
||||
- authentication and RBAC
|
||||
- company branding and theme settings, including startup brand-theme hydration across refresh
|
||||
- CRM customers and vendors with create/edit/detail workflows
|
||||
- CRM search, filtering, status tagging, and reseller hierarchy
|
||||
- CRM contact history, account contacts, and shared attachments
|
||||
- inventory item master, BOM, warehouse, stock-location, and stock-transaction flows
|
||||
- inventory transfers, reservations, and available-stock visibility
|
||||
- inventory SKU master builder with family-scoped sequence generation and branch-aware taxonomy management
|
||||
- staged thumbnail image attachment on inventory item create/edit workflows, with detail-page thumbnail display
|
||||
- sales quotes and sales orders with searchable customer and SKU entry
|
||||
- sales approvals, approval stamps, automatic revision history, and revision comparison on quotes and sales orders
|
||||
- purchase orders with searchable vendor and SKU entry, restricted to purchasable inventory items
|
||||
- purchase-order revision history and revision comparison across commercial and receipt changes
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,96 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/nyaa-crawler
|
||||
repo_url: https://git.alwisp.com/jason/nyaa-crawler
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# nyaa-crawler
|
||||
|
||||
**Repository:** [jason/nyaa-crawler](https://git.alwisp.com/jason/nyaa-crawler) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Dockerized Nyaa.si anime torrent crawler — tracks shows, polls RSS for new episodes, and auto-downloads torrent files with a dark-themed web UI and SQLite persistence
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# nyaa-crawler
|
||||
|
||||
A dockerized torrent crawler and downloader for [Nyaa.si](https://nyaa.si). Track anime shows, poll for new episodes via RSS, and automatically download `.torrent` files to a host-mounted directory.
|
||||
|
||||
## Features
|
||||
|
||||
- Search Nyaa.si and add shows to a watch list
|
||||
- Automatic polling for new episodes (configurable interval, default 15 min)
|
||||
- Auto-downloads `.torrent` files to a mapped host directory
|
||||
- Track episode status: pending, auto-downloaded, or manually marked
|
||||
- Bulk-mark episodes as already downloaded
|
||||
- Minimal dark-themed web UI
|
||||
- SQLite persistence — easy to back up and migrate
|
||||
- Unraid-friendly Docker container
|
||||
|
||||
## Stack
|
||||
|
||||
- **Backend**: Node.js + TypeScript + Express
|
||||
- **Frontend**: React + Vite
|
||||
- **Database**: SQLite (`better-sqlite3`)
|
||||
- **Scheduler**: `node-cron`
|
||||
- **Nyaa integration**: RSS via `fast-xml-parser`
|
||||
|
||||
## Quick Start (Docker)
|
||||
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
Open `http://localhost:8082` in your browser.
|
||||
|
||||
## Quick Start (Development)
|
||||
|
||||
```bash
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
- Client dev server: `http://localhost:5173` (proxies `/api` to `:3000`)
|
||||
- API server: `http://localhost:3000`
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Default | Description |
|
||||
|---|---|---|
|
||||
| `PORT` | `3000` | HTTP port |
|
||||
| `POLL_INTERVAL_SECONDS` | `900` | Polling frequency (min 60) |
|
||||
| `TORRENT_OUTPUT_DIR` | `./data/torrents` | Where `.torrent` files are saved |
|
||||
| `DATABASE_PATH` | `./data/db.sqlite` | SQLite database path |
|
||||
|
||||
## Unraid Deployment
|
||||
|
||||
```yaml
|
||||
services:
|
||||
nyaa-watcher:
|
||||
image: your-registry/nyaa-watcher:latest
|
||||
container_name: nyaa-watcher
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- PORT=3000
|
||||
- POLL_INTERVAL_SECONDS=900
|
||||
- TORRENT_OUTPUT_DIR=/data/torrents
|
||||
- DATABASE_PATH=/data/db.sqlite
|
||||
volumes:
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
+128
@@ -0,0 +1,128 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
tags: [obsidian, cowork, plugin, memory]
|
||||
updated: 2026-05-27
|
||||
---
|
||||
|
||||
# obsidian-memory Plugin
|
||||
|
||||
Claude Cowork plugin that uses Jason's Obsidian vault at 10.2.0.2 as persistent memory across sessions.
|
||||
|
||||
## Current status
|
||||
|
||||
Plugin built and installed. Vault bootstrapped 2026-05-27. Ready for daily use — memory accumulates as sessions run.
|
||||
|
||||
## Key decisions
|
||||
|
||||
- No MCP server — direct REST calls via bash/curl (simpler, fully portable in a single .plugin file)
|
||||
- API key and server hardcoded (personal plugin, not for distribution)
|
||||
- Uses `-k` flag for SSL (Obsidian Local REST API uses a self-signed cert)
|
||||
- Server: `https://10.2.0.2:27124`
|
||||
- API key: stored in skill, not to be redistributed
|
||||
- Vault layout roots at `Projects/agents/` — index → profile → memory subdirs
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
obsidian-memory.plugin
|
||||
├── .claude-plugin/plugin.json
|
||||
├── skills/obsidian-memory/
|
||||
│ ├── SKILL.md ← load/write/log instructions + curl patterns
|
||||
│ └── references/
|
||||
│ ├── api-reference.md ← all curl endpoint patterns
|
||||
│ ├── vault-layout.md ← frontmatter conventions + folder map
|
||||
│ ├── bootstrap.md ← first-run setup procedure
|
||||
│ └── session-log-template.md
|
||||
└── README.md
|
||||
```
|
||||
|
||||
## Vault layout
|
||||
|
||||
```
|
||||
Projects/agents/
|
||||
├── README.md
|
||||
├── memory/
|
||||
│ ├── profile.md
|
||||
│ ├── inbox.md
|
||||
│ ├── projects/<slug>.md
|
||||
│ ├── sessions/YYYY-MM-DD-<slug>.md
|
||||
│ ├── people/<name>.md
|
||||
│ └── decisions/YYYY-MM-DD-<slug>.md
|
||||
```
|
||||
|
||||
## Open threads
|
||||
|
||||
- [ ] Populate profile.md as facts emerge in conversations
|
||||
- [ ] Consider adding a decisions file for major project choices
|
||||
|
||||
## Log
|
||||
|
||||
- 2026-05-27: Plugin built in Cowork session. Vault bootstrapped. First session logged.
|
||||
|
||||
## Known issues
|
||||
|
||||
### PATCH with `Target-Type: heading` returns invalid-target (2026-05-28)
|
||||
|
||||
**Symptom:** Every `PATCH` request with `Operation: append|replace`, `Target-Type: heading`, and a `Target:` header (e.g. `Target: Current status`) returns:
|
||||
|
||||
```
|
||||
HTTP 400
|
||||
{ "message": "The patch you provided could not be applied to the target content.\ninvalid-target", "errorCode": 40080 }
|
||||
```
|
||||
|
||||
This happens on **all files tested** including freshly-fetched profile.md and project files with confirmed valid heading text. The documented example from `references/api-reference.md` ("Replace a heading's content entirely") reproduces the failure exactly.
|
||||
|
||||
Reading a heading via URL path (`/vault/path/file.md/heading/Heading%20Name`) **also** returns `404 Not Found` even when the heading clearly exists in the file body — so the failure is in the heading-resolution layer, not the patch-apply layer.
|
||||
|
||||
**Workaround:** Use `POST` (append-to-EOF) and `PUT` (full overwrite) instead. The skill's main flow already documents POST as the default for additive entries, so this only matters when you need targeted section editing (e.g. "replace Current status" for a project file).
|
||||
|
||||
**Impact:** Cannot do surgical section replacement. The project file for `unifi-access-dashboard.md` ended up with the new content appended to the bottom instead of replacing "Current status" inline — readable but less tidy.
|
||||
|
||||
**To investigate:**
|
||||
|
||||
- [ ] Check installed Local REST API plugin version on the vault (Obsidian → Settings → Community plugins)
|
||||
- [ ] Compare against the [coddingtonbear/obsidian-local-rest-api](https://github.com/coddingtonbear/obsidian-local-rest-api) release notes for PATCH-heading regressions
|
||||
- [ ] If recent, try downgrading; if old, try upgrading
|
||||
- [ ] Try with explicit `Target-Delimiter` header (some versions need it for top-level headings)
|
||||
- [ ] Verify the file is using LF line endings — CRLF can break heading parsing in some plugin versions
|
||||
|
||||
## Log
|
||||
|
||||
- 2026-05-28: Discovered PATCH-heading bug during the unifi-access-dashboard memory update. Logged under Known issues; working around with POST/PUT.
|
||||
|
||||
### Retest after plugin upgrade 3.6 → 4.1.1 (2026-05-28)
|
||||
|
||||
**Still broken.** Both failure modes reproduce identically after the upgrade:
|
||||
|
||||
| Test | Result |
|
||||
|---|---|
|
||||
| `PATCH` w/ `Target-Type: heading`, `Target: Communication preferences` | HTTP 400, `invalid-target` |
|
||||
| `PATCH` w/ `Target-Type: heading`, `Target: Role` (single word, no spaces) | HTTP 400, `invalid-target` |
|
||||
| `PATCH` w/ `Target-Type: heading`, `Target: Communication%20preferences` (URL-encoded) | HTTP 400, `invalid-target` |
|
||||
| `GET /vault/.../profile.md/heading/Role` (URL-path heading read) | HTTP 404, `Not Found` |
|
||||
| `GET /vault/.../profile.md` (bare file read — sanity) | HTTP 200 ✓ |
|
||||
| **`PATCH` w/ `Target-Type: frontmatter`, `Target: updated`** | **HTTP 200 ✓** |
|
||||
|
||||
**Narrowed diagnosis:** The PATCH route is healthy — `Target-Type: frontmatter` works perfectly. Only the **heading resolver** is broken. The same resolver is shared between the heading-target PATCH path and the URL-path `/heading/...` read path (both 404 on valid headings), which is consistent with a single bug in heading lookup.
|
||||
|
||||
**Ruled out:**
|
||||
|
||||
- ~~Plugin version (3.6 was old)~~ — 4.1.1 has the same bug
|
||||
- ~~Spaces in heading text~~ — single-word "Role" also fails
|
||||
- ~~URL encoding of `Target:` header~~ — both raw and `%20`-encoded fail
|
||||
- ~~Broken PATCH route generally~~ — frontmatter target works
|
||||
|
||||
**Likely culprits (narrower now):**
|
||||
|
||||
- [ ] CRLF vs LF line endings in vault files — heading parser may require LF. Files written by curl from this skill use LF, but files edited in Obsidian on Windows might get CRLF.
|
||||
- [ ] Unicode BOM at file start
|
||||
- [ ] An option in the plugin settings UI that toggles heading-mode patches
|
||||
- [ ] An upstream bug — worth opening an issue at `coddingtonbear/obsidian-local-rest-api` with this exact reproducer (it's small and easy to verify)
|
||||
|
||||
**Workarounds (in order of preference):**
|
||||
|
||||
1. For metadata: `Target-Type: frontmatter` works — use it for `updated`, `status`, `tags`.
|
||||
2. For additive section content: `POST` (append to EOF) — already the skill's documented default.
|
||||
3. For surgical section replacement: read the file, modify in code, `PUT` the whole thing back. Heavy-handed but reliable.
|
||||
- 2026-05-28: Plugin upgraded 3.6 → 4.1.1 to fix the PATCH-heading bug. Retest shows the bug **persists** in 4.1.1. Narrowed: `Target-Type: frontmatter` works, only `Target-Type: heading` (and the URL-path `/heading/...` read) is broken. Likely a heading-resolver bug. Workaround unchanged: POST/PUT/frontmatter-PATCH only.
|
||||
@@ -0,0 +1,82 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/pnger
|
||||
repo_url: https://git.alwisp.com/jason/pnger
|
||||
language: Svelte
|
||||
branch: main
|
||||
tags:
|
||||
- repo
|
||||
- jason
|
||||
- alwisp
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# pnger
|
||||
|
||||
**Repository:** [jason/pnger](https://git.alwisp.com/jason/pnger) · branch `main` · Svelte
|
||||
|
||||
## Summary
|
||||
|
||||
Modern PNG editor & resizer with live preview, drag & drop, smart presets, keyboard shortcuts, and dark/light themes. TypeScript + Svelte + Sharp. Deployed on Unraid.
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# PNGer - Modern PNG Editor & Resizer
|
||||
|
||||
A sleek, modern PNG editor and resizer with **live preview**, **drag & drop**, **smart presets**, **keyboard shortcuts**, and **dark/light mode theming**. Built with TypeScript and optimized for deployment as a single Docker container.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **🎨 Modern UI**: Beautiful dark/light mode for inspecting transparency.
|
||||
- **⚡ Live Preview**: Instant side-by-side comparison with file size analysis.
|
||||
- **🚀 Efficiency**: Drag & Drop upload, clipboard paste (`Ctrl+V`), and smart presets.
|
||||
- **🖼️ Precision**: Control width, height, quality, and crop positions (9 modes).
|
||||
- **📦 Reliable Deployment**: Multi-stage Docker build optimized for Unraid and Gitea.
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Docker/Unraid Deployment
|
||||
1. **Clone & Build**:
|
||||
```bash
|
||||
git clone https://git.alwisp.com/jason/pnger.git
|
||||
cd pnger
|
||||
docker build -t pnger:latest .
|
||||
```
|
||||
2. **Run**:
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
3. **Access**: `http://localhost:8080` (or your Unraid IP)
|
||||
|
||||
### Local Development
|
||||
1. **Install & Run Backend**: `cd backend && npm install && npm run dev`
|
||||
2. **Install & Run Frontend**: `cd frontend && npm install && npm run dev`
|
||||
3. **Access**: `http://localhost:5173`
|
||||
|
||||
## 📚 Documentation
|
||||
|
||||
For more detailed information, please refer to:
|
||||
- **[INSTRUCTIONS.md](./INSTRUCTIONS.md)**: Technical architecture, development setup, code standards, and troubleshooting.
|
||||
- **[ROADMAP.md](./ROADMAP.md)**: Project history, sprint updates, and future feature plans.
|
||||
|
||||
## ⌨️ Keyboard Shortcuts
|
||||
|
||||
- `Ctrl+V`: Paste image from clipboard
|
||||
- `Enter`: Download (when input not focused)
|
||||
- `?`: Show shortcuts help
|
||||
- `Esc`: Close dialogs
|
||||
|
||||
---
|
||||
|
||||
**License**: MIT
|
||||
**Repository**: [https://git.alwisp.com/jason/pnger](https://git.alwisp.com/jason/pnger)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,115 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/pos
|
||||
repo_url: https://git.alwisp.com/jason/pos
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags:
|
||||
- repo
|
||||
- jason
|
||||
- alwisp
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# pos
|
||||
|
||||
**Repository:** [jason/pos](https://git.alwisp.com/jason/pos) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Full-stack TypeScript point-of-sale system — Android POS frontend, Node/Express API, and React admin UI packaged in a single Docker container
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# README.md
|
||||
|
||||
## Overview
|
||||
|
||||
This project is a full-stack TypeScript point-of-sale (POS) system: an Android POS frontend, a Node/Express API backend, and a React admin UI, all packaged in a **single Docker container**.
|
||||
|
||||
The backend exposes REST APIs for the Android app and serves the React admin UI for vendor configuration and reporting.
|
||||
|
||||
***
|
||||
|
||||
## Tech Stack
|
||||
|
||||
- Node.js + TypeScript (Express or Fastify)
|
||||
- React + TypeScript (SPA)
|
||||
- SQL database (PostgreSQL in production; SQLite acceptable for local/demo)
|
||||
- Docker (single container for API + admin UI)
|
||||
|
||||
***
|
||||
|
||||
## Project Structure
|
||||
|
||||
Example layout (subject to refinement):
|
||||
|
||||
- `server/` – Node/TypeScript backend (Express/Fastify, Prisma, migrations)
|
||||
- `client/` – React/TypeScript admin UI
|
||||
- `android/` – Android POS app (separate repo or module)
|
||||
- `Dockerfile` – single-image build for backend + admin
|
||||
- `docker-compose.yml` – optional local DB wiring
|
||||
- `AGENTS.md`, `INSTRUCTIONS.md`, `ROADMAP.md` – agent and project docs
|
||||
|
||||
***
|
||||
|
||||
## Prerequisites
|
||||
|
||||
For local (non-Docker) runs:
|
||||
|
||||
- Node.js 20+ installed
|
||||
- npm or pnpm
|
||||
- PostgreSQL (or SQLite if configured)
|
||||
|
||||
For Docker runs:
|
||||
|
||||
- Docker Engine (and optionally Docker Compose)
|
||||
|
||||
***
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Backend expects:
|
||||
|
||||
- `PORT` – HTTP port (default: 8080)
|
||||
- `NODE_ENV` – `development` or `production`
|
||||
- `DATABASE_URL` – connection string (e.g., Postgres)
|
||||
- `JWT_SECRET` – secret for JWT signing
|
||||
- `LOG_LEVEL` – optional (`info`, `debug`, etc.)
|
||||
|
||||
Document any additional env vars you introduce in this section.
|
||||
|
||||
***
|
||||
|
||||
## Local Development (Without Docker)
|
||||
|
||||
Backend:
|
||||
|
||||
```bash
|
||||
# from /server
|
||||
npm install
|
||||
npm run dev # or equivalent, e.g. ts-node-dev / nodemon
|
||||
```
|
||||
|
||||
Admin UI:
|
||||
|
||||
```bash
|
||||
# from /client
|
||||
npm install
|
||||
npm run dev # Vite/CRA dev server
|
||||
```
|
||||
|
||||
You can either:
|
||||
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,57 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: qrknit/qrknit
|
||||
repo_url: https://git.alwisp.com/qrknit/qrknit
|
||||
language: HTML
|
||||
branch: master
|
||||
tags: [repo, qrknit]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# qrknit
|
||||
|
||||
**Repository:** [qrknit/qrknit](https://git.alwisp.com/qrknit/qrknit) · branch `master` · HTML
|
||||
|
||||
## Summary
|
||||
|
||||
QRKnit: commercial QR code generator and URL shortener — create, manage, and track branded QR codes and short links
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# QRknit — URL Shortener & QR Code Generator
|
||||
|
||||
A managed URL shortener with QR code generation, deep click analytics, and tag-based link organization.
|
||||
|
||||
- **Multi-user** — admin account seeded from env vars; admin can create/delete/manage accounts via the UI
|
||||
- **Per-user isolation** — each user sees only their own links and tags; admin has its own isolated workspace separate from all other accounts
|
||||
- **Organizations** — group users into orgs that share link/tag visibility and pool usage quotas under a shared plan
|
||||
- **Plan tiers** — Admin / Free / Starter / Pro / Team with enforced limits on active links, monthly clicks, and analytics history window; org members inherit their org's plan
|
||||
- **Scoped tags** — tags are owned by the user who creates them; org members share a tag namespace, solo users and admins each have their own isolated namespace
|
||||
- **Deep analytics** — daily charts, referrer/device/browser/country breakdowns, hourly 7×24 heatmap, raw click CSV export
|
||||
- **Private instance** — Pro and Team plans include a dedicated private deployment on your own infrastructure
|
||||
|
||||
---
|
||||
|
||||
## 🗺 Feature Map
|
||||
|
||||
### Shipped
|
||||
|
||||
| Feature area | What's included |
|
||||
|---|---|
|
||||
| **Short links** | Random & custom codes, link expiry, pinned links, one-click copy, auto-fetch page title |
|
||||
| **QR codes** | QR generation for any link or URL, logo overlay, dot-shape presets, inline thumbnail, copy to clipboard |
|
||||
| **Analytics** | Per-link daily click charts, referrer / device / browser / country breakdowns, hourly 7×24 heatmap, raw click CSV export |
|
||||
| **Tags** | Tag links for filtering; tags are scoped per user — org members share a namespace, solo users and admins each have their own |
|
||||
| **Bulk tools** | Bulk delete, bulk tag, bulk expire; CSV import & export |
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/rack-planner
|
||||
repo_url: https://git.alwisp.com/jason/rack-planner
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# rack-planner
|
||||
|
||||
**Repository:** [jason/rack-planner](https://git.alwisp.com/jason/rack-planner) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
RackMapper: self-hosted dark-mode web app for visualizing and managing network rack infrastructure — drag-and-drop rack planner and service dependency mapper for Unraid
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# RackMapper
|
||||
|
||||
A self-hosted, dark-mode web app for visualising and managing network rack infrastructure. Built for Unraid / Docker single-container deployment.
|
||||
|
||||
## Features
|
||||
|
||||
### Rack Planner (`/rack`)
|
||||
- Drag-and-drop module placement from a device palette onto U-slots
|
||||
- Drag modules between racks or reorder racks via header grip
|
||||
- Resize modules by dragging the bottom handle
|
||||
- Click any module to edit name, IP, manufacturer, model, notes, uSize
|
||||
- Port indicator dots — click any dot to open the port configuration modal
|
||||
- Set mode (Access / Trunk / Hybrid), native VLAN, tagged VLANs
|
||||
- Quick-create VLANs without leaving the modal
|
||||
- Export the full rack view as PNG
|
||||
|
||||
### Service Mapper (`/map`)
|
||||
- React Flow canvas for mapping service dependencies and traffic flows
|
||||
- Right-click canvas → add any node type at cursor position
|
||||
- Right-click node → Edit, Duplicate, Delete
|
||||
- Right-click edge → Toggle animation, change edge type, Delete
|
||||
- Double-click a node → edit label, accent colour, logical IP/Port, and rack module link
|
||||
- Logical Address mapping — assign IP and Port to any node type via metadata (stored as JSON)
|
||||
- Persistent storage — all node details and logical addresses are saved to the SQLite database
|
||||
- Auto-populate nodes from all rack modules ("Import Rack" button)
|
||||
- Connect nodes by dragging from handles; Delete key removes selected items
|
||||
- Minimap, zoom controls, snap-to-grid (15px), PNG export
|
||||
|
||||
### VLAN Management (`/vlans`)
|
||||
- Create, edit, and delete VLANs with ID, name, description, and colour
|
||||
- VLANs defined here are available in all port configuration modals
|
||||
|
||||
---
|
||||
|
||||
## Quick Start (Docker Compose)
|
||||
|
||||
**1. Create a `docker-compose.yml`:**
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
services:
|
||||
rackmapper:
|
||||
image: rackmapper
|
||||
build: .
|
||||
container_name: rackmapper
|
||||
ports:
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/stepview
|
||||
repo_url: https://git.alwisp.com/jason/stepview
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags:
|
||||
- repo
|
||||
- jason
|
||||
- mpm
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# stepview
|
||||
|
||||
**Repository:** [jason/stepview](https://git.alwisp.com/jason/stepview) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
StepView: self-hosted in-browser 3D STEP file viewer — renders .step/.stp files via OpenCascade (WASM) and three.js, deployed as a Docker container on Unraid
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
_Source: INSTALL.md_
|
||||
|
||||
# StepView — Unraid Installation Guide
|
||||
|
||||
This guide covers the full deployment path: building the Docker image via the Gitea CI runner, then installing and configuring the container through the Unraid Docker GUI.
|
||||
|
||||
---
|
||||
|
||||
## Table of Contents
|
||||
|
||||
1. [Prerequisites](#1-prerequisites)
|
||||
2. [Build Pipeline — Gitea Actions](#2-build-pipeline--gitea-actions)
|
||||
3. [Unraid — Add the Registry](#3-unraid--add-the-registry)
|
||||
4. [Unraid — Install the Container](#4-unraid--install-the-container)
|
||||
5. [Environment Variables Reference](#5-environment-variables-reference)
|
||||
6. [Volume Paths Reference](#6-volume-paths-reference)
|
||||
7. [First-Run Steps](#7-first-run-steps)
|
||||
8. [Upgrading](#8-upgrading)
|
||||
9. [Backups](#9-backups)
|
||||
10. [Troubleshooting](#10-troubleshooting)
|
||||
|
||||
---
|
||||
|
||||
## 1. Prerequisites
|
||||
|
||||
| Requirement | Notes |
|
||||
|---|---|
|
||||
| Unraid 6.12 or later | Earlier versions work but UI steps may differ slightly |
|
||||
| Gitea instance | Any version with Actions support (1.19+) |
|
||||
| Gitea Actions runner | Registered to your Gitea instance, labeled `ubuntu-latest` |
|
||||
| Docker runner image | `catthehacker/ubuntu:act-latest` (already in your workflow) |
|
||||
| `REGISTRY_USER` secret | Set in Gitea repo → Settings → Secrets |
|
||||
| `REGISTRY_TOKEN` secret | An access token with `package:write` scope on `registry.alwisp.com` |
|
||||
|
||||
---
|
||||
|
||||
## 2. Build Pipeline — Gitea Actions
|
||||
|
||||
The workflow at `.gitea/workflows/docker-build.yml` runs automatically on every push to `main`. It builds the image and pushes it to:
|
||||
|
||||
```
|
||||
registry.alwisp.com/<OWNER>/stepview:latest
|
||||
```
|
||||
|
||||
### Verify the secrets exist
|
||||
|
||||
In your Gitea repository, go to **Settings → Secrets and Variables → Actions** and confirm both of these are set:
|
||||
|
||||
| Secret name | Value |
|
||||
|---|---|
|
||||
| `REGISTRY_USER` | Your registry username |
|
||||
| `REGISTRY_TOKEN` | Registry access token (read/write) |
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,95 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/storybid
|
||||
repo_url: https://git.alwisp.com/jason/storybid
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags:
|
||||
- repo
|
||||
- jason
|
||||
- stroybook
|
||||
- storybid
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# storybid
|
||||
|
||||
**Repository:** [jason/storybid](https://git.alwisp.com/jason/storybid) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Self-hosted charity auction platform — live and silent auctions with offline-first PWA bidding, Socket.io real-time updates, Stripe payments, and SMS OTP auth
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# Storybid
|
||||
|
||||
Self-hosted charity auction platform supporting live and silent auctions in the
|
||||
same event, with offline-first PWA bidding and automatic LAN failover for
|
||||
event-night resilience.
|
||||
|
||||
## Stack
|
||||
|
||||
| Layer | Choice |
|
||||
|------------|---------------------------------------------|
|
||||
| Client | React 18 + TypeScript + Vite + Tailwind |
|
||||
| PWA/Offline| Workbox (vite-plugin-pwa) + Dexie/IndexedDB |
|
||||
| Real-time | Socket.io |
|
||||
| Server | Node.js + Express + TypeScript |
|
||||
| ORM | Prisma |
|
||||
| Database | PostgreSQL (SQLite optional for dev) |
|
||||
| Cache/Queue| Redis (optional) |
|
||||
| Auth | Email magic links + Twilio Verify SMS OTP |
|
||||
| Payments | Stripe Payment Element / Payment Intents |
|
||||
| Media | Local disk (multer) served as static files |
|
||||
| Deploy | Docker Compose (Unraid / Linux VM) |
|
||||
|
||||
## Quick Start (development)
|
||||
|
||||
```bash
|
||||
# 1. Clone and install
|
||||
git clone <repo>
|
||||
cd storybid
|
||||
npm install
|
||||
|
||||
# 2. Start DB + Redis
|
||||
docker compose -f docker-compose.dev.yml up -d
|
||||
|
||||
# 3. Configure environment
|
||||
cp .env.example .env
|
||||
# Edit .env with your Stripe, Twilio, and SMTP keys
|
||||
|
||||
# 4. Migrate database and seed demo data
|
||||
npm run db:migrate
|
||||
npm run db:seed
|
||||
|
||||
# 5. Start dev servers
|
||||
npm run dev
|
||||
# Client → http://localhost:5173
|
||||
# Server → http://localhost:3001
|
||||
```
|
||||
|
||||
## Production Deployment
|
||||
|
||||
See [`ops/README.md`](./ops/README.md).
|
||||
|
||||
## Event-Night Network
|
||||
|
||||
See [`ops/unifi-dns.md`](./ops/unifi-dns.md) for UniFi local DNS setup and
|
||||
WAN-failover testing.
|
||||
|
||||
## Staff Runbook
|
||||
|
||||
See [`event-runbook/preflight.md`](./event-runbook/preflight.md) for the
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,88 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/totalmcp
|
||||
repo_url: https://git.alwisp.com/jason/totalmcp
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags:
|
||||
- repo
|
||||
- jason
|
||||
- mcp
|
||||
- ai
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# totalmcp
|
||||
|
||||
**Repository:** [jason/totalmcp](https://git.alwisp.com/jason/totalmcp) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
TotalMCP: unified MCP gateway for the ALPHA stack — hot-reloadable Dockerized server connecting Claude Code, Codex, and Antigravity to one stable endpoint on Unraid
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# totalmcp
|
||||
|
||||
Unified MCP gateway for Jason's ALPHA stack. One Dockerized server, hot-reloadable plugin architecture, three agent clients (Claude Code, Codex, Antigravity) all connecting to one stable endpoint.
|
||||
|
||||
- **Port:** `8811`
|
||||
- **Static IP:** `10.2.0.35` (Unraid `br0`)
|
||||
- **Registry:** `git.alwisp.com/jason/totalmcp`
|
||||
- **Spec:** see [`PLAN.md`](PLAN.md) for the full architecture and phased roadmap
|
||||
- **Service inventory:** see [`SERVICES.md`](SERVICES.md) for the catalog this gateway plugs into
|
||||
|
||||
## Quick Start (local dev)
|
||||
|
||||
```bash
|
||||
cp .env.example .env # then fill in tokens
|
||||
npm install
|
||||
npm run prisma:generate
|
||||
npm run dev # starts tsx watch on src/server.ts
|
||||
```
|
||||
|
||||
Verify:
|
||||
|
||||
```bash
|
||||
curl http://localhost:8811/health
|
||||
# → { "status": "ok", "version": "0.1.0", "plugins": 0, "enabled": [] }
|
||||
```
|
||||
|
||||
## Build & run
|
||||
|
||||
```bash
|
||||
npm run build # tsc → dist/
|
||||
npm start # node dist/server.js
|
||||
```
|
||||
|
||||
## Docker (local dev)
|
||||
|
||||
```bash
|
||||
docker compose up --build -d
|
||||
docker compose logs -f totalmcp
|
||||
```
|
||||
|
||||
## Unraid deployment
|
||||
|
||||
Step-by-step GUI walkthrough — paths, variables, ports, network — lives in [`INSTALL-UNRAID.md`](INSTALL-UNRAID.md). Covers the full deploy at `10.2.0.35:8811` plus a minimal "Gitea-plugin-only" starter config.
|
||||
|
||||
## Endpoints
|
||||
|
||||
| Method | Path | Auth | Purpose |
|
||||
|--------|-------------|----------|--------------------------------------|
|
||||
| GET | `/health` | none | Liveness — used by Unraid HEALTHCHECK |
|
||||
| GET | `/plugins` | bearer | Loaded plugin list + tool counts |
|
||||
| POST | `/mcp` | bearer | Streamable HTTP — primary MCP transport |
|
||||
| GET | `/mcp` | bearer | Streamable HTTP server-sent stream |
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
@@ -0,0 +1,87 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/ui-tracker
|
||||
repo_url: https://git.alwisp.com/jason/ui-tracker
|
||||
language: TypeScript
|
||||
branch: main
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# ui-tracker
|
||||
|
||||
**Repository:** [jason/ui-tracker](https://git.alwisp.com/jason/ui-tracker) · branch `main` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Unifi Store stock monitor — watches store.ui.com for product restocks and sends Telegram alerts; single Docker container for Unraid with a React admin UI
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
_Source: PROJECT.md_
|
||||
|
||||
# UI Stock Tracker — Project Documentation
|
||||
|
||||
**Status:** ✅ Complete and running
|
||||
**Last updated:** 2026-03-29
|
||||
|
||||
---
|
||||
|
||||
## Purpose
|
||||
|
||||
Monitors product pages on [store.ui.com](https://store.ui.com/us/en) for stock availability and sends a Telegram alert the moment a watched item comes back in stock. Runs as a single persistent Docker container on Unraid with a clean web UI for managing tracked products.
|
||||
|
||||
---
|
||||
|
||||
## Stack
|
||||
|
||||
| Layer | Technology |
|
||||
|---|---|
|
||||
| Frontend | React 18 + TypeScript, Vite, Lucide icons |
|
||||
| Backend | Node.js 20 + TypeScript, Express |
|
||||
| Database | SQLite via `better-sqlite3` (WAL mode) |
|
||||
| Scraper | Puppeteer-core + system Chromium |
|
||||
| Alerts | Telegram Bot API (direct HTTP) |
|
||||
| Container | Single Docker container — nginx + Node.js managed by supervisord |
|
||||
| Web server | nginx — serves frontend, proxies `/api/` to Node.js on port 3001 |
|
||||
|
||||
---
|
||||
|
||||
## Container Architecture
|
||||
|
||||
One container runs three processes via **supervisord**:
|
||||
|
||||
```
|
||||
supervisord
|
||||
├── nginx → serves React build on :8080, proxies /api/ → localhost:3001
|
||||
└── node → Express API, SQLite, Puppeteer scheduler, Telegram sender
|
||||
```
|
||||
|
||||
The SQLite database is stored on a mounted volume at `/app/data/tracker.db` so it persists across rebuilds.
|
||||
|
||||
---
|
||||
|
||||
## Key Features
|
||||
|
||||
### Stock Detection
|
||||
Puppeteer navigates to each product URL and waits for React hydration (2.5s delay), then scans all `<span>` elements for exact text matches:
|
||||
- `"Add to Cart"` → `in_stock`
|
||||
- `"Sold Out"` → `sold_out`
|
||||
- Neither found → `unknown`
|
||||
|
||||
Product name is pulled from the `og:title` meta tag (with Ubiquiti store suffix stripped). Thumbnail is pulled from `og:image`.
|
||||
|
||||
### Alert Logic
|
||||
- Alert fires **once** when an item transitions to `in_stock` and `alert_sent = 0`
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
+118
@@ -0,0 +1,118 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
tags:
|
||||
- unifi
|
||||
- access
|
||||
- flask
|
||||
- docker
|
||||
- attendance
|
||||
- multi-tenant
|
||||
- mpm
|
||||
updated: 2026-05-28
|
||||
---
|
||||
|
||||
# UniFi Access Badge-In Dashboard
|
||||
|
||||
Repo: `F:\CODING\unifi-access-dashboard` · Unraid IP `10.2.0.11:8000` · Data at `/mnt/user/appdata/unifi-access-dashboard/`. See [[unraid-deployment]] for the deploy pipeline.
|
||||
|
||||
Flask + SQLite app that ingests UniFi Access `access.door.unlock` webhooks and shows a daily attendance table (first/latest badge per person, ON TIME / LATE vs cutoff).
|
||||
|
||||
## Current status
|
||||
|
||||
Multi-controller support shipped 2026-05-28. The app now supports adding N UniFi Access controllers from the UI (⚙ Controllers button); each controller's webhook is auto-registered via the Access API. Driven by a client engagement where one on-site server has LAN reach to multiple Access controllers on a meshed network and wants a unified attendance view.
|
||||
|
||||
## Architecture decisions
|
||||
|
||||
- **Storage model**: tables `controllers`, `badge_events` (with `controller_id`), `user_cache` (composite PK `(controller_id, actor_id)`). The same physical person on two controllers shows as two rows distinguished by the Source column — no cross-controller identity merge (out of scope).
|
||||
- **Webhook URLs**: `/api/unifi-access/<controller_id>` per-controller. Legacy `/api/unifi-access` kept as alias that routes to the oldest controller, so pre-multi-controller installs keep working without re-registering.
|
||||
- **Auth & encryption**: explicitly NOT added. Jason picked LAN-only trust + plaintext tokens in SQLite. Filesystem permissions on `./data/dashboard.db` are the only thing protecting API tokens. Any future external exposure must put a reverse proxy with auth in front.
|
||||
- **Webhook auto-registration**: adding a controller via UI POSTs to `/api/v1/developer/webhooks/endpoints` on that controller and stores the returned `secret` + `id`. Removing a controller calls Access to delete the webhook.
|
||||
- **`DASHBOARD_BASE_URL` env var**: optional override for the URL the dashboard tells controllers to call back to. Defaults to `request.host_url` (the browser's origin when admin adds a controller). Set this if the controller can't reach that address.
|
||||
|
||||
**Why:** these were active choices Jason made during the 2026-05-28 update — not omissions. Re-proposing auth or encryption needs new context, not a do-over.
|
||||
**How to apply:** if future work touches admin endpoints or token storage, don't silently bolt on auth or encryption — flag it as a scope change first.
|
||||
|
||||
## Configuration model
|
||||
|
||||
- **Fresh installs**: leave `UNIFI_HOST`/`UNIFI_API_TOKEN`/`UNIFI_PORT`/`WEBHOOK_SECRET` blank in the Unraid template. Only set `TZ` and the `/data` mapping. Add every controller via the UI — that path auto-registers webhooks.
|
||||
- **Upgrades from single-controller installs**: leave the env vars alone. Migration on first boot seeds a "Default" controller from them and backfills existing `badge_events` rows. After verifying the UI shows Default, the env vars are dead weight and can be removed, but keeping them is harmless and defensive (re-seeds if `./data` is wiped).
|
||||
- **Gotcha**: a seeded Default controller has no `webhook_id` stored (the webhook was registered manually before the multi-controller refactor). If someone removes Default in the UI and re-adds via the form, the OLD webhook on the Access side is not deleted (we don't know its id) and the NEW one is added on top — every badge event arrives twice until the old webhook is manually deleted on the Access controller.
|
||||
|
||||
## Operational details
|
||||
|
||||
- User-cache auto-sync runs hourly (`scheduler.add_job(sync_all_controllers, "interval", hours=1)`). Badge events themselves are real-time via webhook — this interval only affects how fast renamed users show new display names.
|
||||
- HMAC-SHA256 signature verification is per-controller (each controller's `webhook_secret` is enforced on its own endpoint). A controller with an empty stored secret accepts unsigned posts — intentional for LAN-trust mode.
|
||||
- Cutoff comparison is string-based on `HH:MM:SS`; cutoff input is sanitized to `HH:MM` and compared as `<= "{cutoff}:59"`. Don't change this to time-object parsing without verifying the SQL still groups correctly.
|
||||
|
||||
---
|
||||
|
||||
## Update 2026-05-28 (pm): tenant filtering + identity merging
|
||||
|
||||
Same-day follow-up to the multi-controller ship. Two related features added together. The earlier "Architecture decisions" note that cross-controller identity merging was out of scope is **superseded** — it's now in scope and shipped.
|
||||
|
||||
### Tenant filtering
|
||||
|
||||
- New column `user_cache.filtered INTEGER NOT NULL DEFAULT 0`. Additive migration via `ALTER TABLE` for existing DBs.
|
||||
- Sync code at `app.py:194-203` already only updates `full_name`/`updated_at` on conflict, so the filter flag survives every hourly sync naturally — no defensive logic needed.
|
||||
- `/api/first-badge-status` excludes filtered actors by default; pass `?include_filtered=1` to include them (UI uses this for the "Show filtered" toggle that dims filtered rows and tags them with a FILTERED pill).
|
||||
- Webhook ingest is **unchanged** — filtering is purely display-time. Unfiltering instantly restores history with no gaps.
|
||||
- New endpoints: `GET /api/users`, `PATCH /api/users/<controller_id>/<actor_id>` (`{filtered: bool}`). The PATCH upserts a placeholder cache row if the actor isn't yet known so the flag has somewhere to live (covers the "Unknown user" case).
|
||||
|
||||
### Identity merging across controllers
|
||||
|
||||
Driver: same physical person on two controllers gets two UUIDs, so badging into Controller A at 8:45 and Controller B at 9:15 produces one ON TIME row + one LATE row even though arrival was 8:45. Merging fixes this.
|
||||
|
||||
**Schema** — two new tables, both purely additive:
|
||||
```sql
|
||||
CREATE TABLE persons (
|
||||
id TEXT PRIMARY KEY,
|
||||
display_name TEXT NOT NULL,
|
||||
filtered INTEGER NOT NULL DEFAULT 0,
|
||||
created_at TEXT NOT NULL
|
||||
);
|
||||
CREATE TABLE person_members (
|
||||
person_id TEXT NOT NULL,
|
||||
controller_id TEXT NOT NULL,
|
||||
actor_id TEXT NOT NULL,
|
||||
PRIMARY KEY (controller_id, actor_id), -- one actor → one person
|
||||
FOREIGN KEY (person_id) REFERENCES persons(id) ON DELETE CASCADE
|
||||
);
|
||||
```
|
||||
|
||||
**Why two tables, not a `merge_group` column on `user_cache`:** chosen for headroom. `user_cache` is a sync cache (overwritten from UniFi); `persons` is the editorial layer where the user owns display name, filter flag, and any future per-person fields (notes, department, photo). Picked Option A from the design brainstorm; rejected Options B (shared group_id column) and C (self-referential `merged_into`).
|
||||
|
||||
**Query change** in `/api/first-badge-status`: groups by `COALESCE(pm.person_id, b.controller_id || '|' || b.actor_id)` so unmerged rows still group by `(controller, actor)`. Sources column becomes a `GROUP_CONCAT(DISTINCT c.name)` list. Filter promotes via `COALESCE(p.filtered, u.filtered, 0)`.
|
||||
|
||||
**Hide button dispatch**: if the row is merged, UI calls `PATCH /api/persons/<id>` with `{filtered: bool}`; if not, it calls `PATCH /api/users/<cid>/<aid>` (old behavior).
|
||||
|
||||
**Filter-on-unmerge decision**: when a member is split off from a merged person, the member returns **unfiltered**. Person-level filter dies with the merge. Picked for simpler mental model — re-hide individually if needed. Alternative (inherit filter on split) was rejected as surprising.
|
||||
|
||||
**Auto-suggestions** (`GET /api/persons/suggestions`): groups `user_cache` rows by exact-name match (case-insensitive, trimmed, excluding "User xxxxx" placeholders) where the same name spans ≥2 distinct controllers and none of the members are already part of a person. UI shows these at the top of the People modal with a one-click confirm per suggestion — never auto-applied.
|
||||
|
||||
**UI**: per-row Merge button (becomes "Manage" on already-merged rows, opens the People modal scrolled to that person); a new "👥 People" header button opens a modal with suggested merges + management actions (Rename, Split off, Dissolve). Merged rows in the attendance table get multiple Source chips and a "MERGED" pill.
|
||||
|
||||
### New endpoints (full list)
|
||||
|
||||
- `GET /api/users` — list cached actors with filter flag
|
||||
- `PATCH /api/users/<cid>/<aid>` — hide/unhide one actor
|
||||
- `GET /api/persons` — list merged people with members
|
||||
- `POST /api/persons` — create with `{display_name, members:[{controller_id, actor_id},...]}`
|
||||
- `PATCH /api/persons/<id>` — rename or toggle filtered
|
||||
- `DELETE /api/persons/<id>` — dissolve
|
||||
- `POST /api/persons/<id>/members` — add a member
|
||||
- `DELETE /api/persons/<id>/members/<cid>/<aid>` — split off (auto-dissolves on last member)
|
||||
- `GET /api/persons/suggestions` — exact-name matches across controllers
|
||||
|
||||
### Sharp edges to remember
|
||||
|
||||
- **Source chip is now a list per row.** Anything that consumed `row.source` as a single string still works (we kept the first chip there for backwards compat), but the new field is `row.sources` (array) plus `row.merged` (bool).
|
||||
- **Hide button on a merged row toggles `persons.filtered`**, not member-level flags. Splitting a member off later returns it unfiltered by design.
|
||||
- **Merge can't span 3+ identities in one shot from the inline picker** — only pairwise. To merge a third controller into an existing person, use the People modal → that person → add member. (Or split + remerge.)
|
||||
- **Webhook ingest is still untouched.** Both filtering and merging are display-time only. The DB never loses an event; unmerging/unfiltering always restores complete history.
|
||||
|
||||
**Repo path note:** Jason was working from `D:\REMOTE CODING\unifi-access-dashboard` this session, not the `F:\CODING\` path recorded at the top of this file. Not changing the canonical path automatically — flag if this is a permanent move.
|
||||
|
||||
### Repo path clarification (per Jason, 2026-05-28)
|
||||
|
||||
The earlier note about working from `D:\REMOTE CODING\unifi-access-dashboard` vs the canonical `F:\CODING\` is **expected** — this repo is checked out on multiple machines with different folder structures. Don't treat divergent local paths as a red flag; the canonical reference is the Gitea repo and the deployed container, not any one machine's checkout location.
|
||||
+86
@@ -0,0 +1,86 @@
|
||||
---
|
||||
type: project
|
||||
status: reference
|
||||
tags: [infrastructure, docker, unraid, deployment]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# Preferred Deployment Workflow
|
||||
|
||||
Reference: [[deployment-guide]] (saved to F:\CLAUDE\COWORK\COWORK\deployment-guide.md)
|
||||
|
||||
## Pipeline summary
|
||||
|
||||
```
|
||||
Code (Claude Code / Antigravity / VSCode)
|
||||
→ git push main to git.alwisp.com
|
||||
→ Gitea Actions triggers .gitea/workflows/docker-build.yml
|
||||
→ Runner builds & pushes to registry.alwisp.com/{owner}/{repo}:latest
|
||||
→ Unraid Docker GUI: add container manually
|
||||
```
|
||||
|
||||
## Gitea Actions workflow pattern
|
||||
|
||||
- Runner image: `catthehacker/ubuntu:act-latest`
|
||||
- Registry: `registry.alwisp.com`
|
||||
- Secrets: `REGISTRY_USER`, `REGISTRY_TOKEN`
|
||||
- Tag pattern: `registry.alwisp.com/{owner}/{repo}:latest`
|
||||
- Trigger: push to `main` branch only
|
||||
|
||||
## Unraid container standards
|
||||
|
||||
### Network
|
||||
- Always **Custom: br0** (not bridge)
|
||||
- Subnet: `10.2.0.0/24`
|
||||
- Each app gets a fixed dedicated IP
|
||||
|
||||
### Known fixed IPs
|
||||
| App | IP | Notes |
|
||||
|---|---|---|
|
||||
| adminer | 10.2.0.2:7070 | bridge |
|
||||
| alwisp_db | 10.2.0.7 | |
|
||||
| alwisp_web | 10.2.0.8 | |
|
||||
| breedr | 10.2.0.17 | |
|
||||
| codedump | 10.2.0.34 | |
|
||||
| cpas | 10.2.0.14 | |
|
||||
| email-sigs | 10.2.0.10 | |
|
||||
| fabdash | 10.2.0.13 | |
|
||||
| Gitea | 10.2.0.15 | |
|
||||
| gitea-mcp | 10.2.0.16 | |
|
||||
| Gitea-Runner | 172.17.0.7 | bridge |
|
||||
| inven | 10.2.0.25 | |
|
||||
| invoiceninja-v5 | 10.2.0.2:8000, 10.2.0.2:8444 | bridge |
|
||||
| MariaDB-Official | 10.2.0.2:3306 | bridge |
|
||||
| matter-server | 10.2.0.2 | host network |
|
||||
| memer | 10.2.0.30 | |
|
||||
| mrp | 10.2.0.19 | |
|
||||
| mrp-qrcode | 10.2.0.32 | |
|
||||
| n8n | — | stopped |
|
||||
| NEBULA | 10.2.0.5 | |
|
||||
| NGINX | 10.2.0.3 | |
|
||||
| nyaa | 10.2.0.21 | |
|
||||
| obsidian | 10.2.0.2:3000, 10.2.0.2:3001 | bridge |
|
||||
| OpenClaw | — | br0, IP not shown |
|
||||
| plex | 10.2.0.2 | host network |
|
||||
| postgresql16 | 10.2.0.2:5432 | bridge |
|
||||
| QR.knit | 10.2.0.9 | |
|
||||
| rackmapper | 10.2.0.23 | |
|
||||
| Redis | 10.2.0.2:6379 | bridge |
|
||||
| stepview | 10.2.0.33 | |
|
||||
| syncthing | 10.2.0.2:8384, 10.2.0.2:21027 | bridge |
|
||||
| ui-tracker | 10.2.0.29 | |
|
||||
| UISP | 10.2.0.4 | |
|
||||
| unifi-access-dashboard | 10.2.0.11 | |
|
||||
| wfh | 10.2.0.18 | |
|
||||
|
||||
### Volume convention
|
||||
- Host: `/mnt/user/appdata/{app-name}/`
|
||||
- Container: `/app/data`, `/data`, `/app/uploads`, `/app/static`, `/app/secrets`
|
||||
|
||||
### Standard env vars
|
||||
`PORT`, `NODE_ENV=production`, `ADMIN_USERNAME`/`ADMIN_USER`, `ADMIN_PASSWORD`/`ADMIN_PASS`, `DB_PATH`, `DATA_DIR`, `PUBLIC_URL`, `CRON_SCHEDULE`, `TZ=America/Chicago`, `STATIC_PATH`
|
||||
|
||||
### Defaults
|
||||
- Privileged: OFF
|
||||
- Tailscale: OFF
|
||||
- Console: Shell
|
||||
@@ -0,0 +1,76 @@
|
||||
---
|
||||
type: project
|
||||
status: active
|
||||
source: git.alwisp.com
|
||||
repo: jason/wfh
|
||||
repo_url: https://git.alwisp.com/jason/wfh
|
||||
language: TypeScript
|
||||
branch: master
|
||||
tags: [repo, jason]
|
||||
updated: 2026-05-29
|
||||
---
|
||||
|
||||
# wfh
|
||||
|
||||
**Repository:** [jason/wfh](https://git.alwisp.com/jason/wfh) · branch `master` · TypeScript
|
||||
|
||||
## Summary
|
||||
|
||||
Work From Home - Progress Tracker
|
||||
|
||||
## Current status
|
||||
|
||||
Active. Synced from Gitea on 2026-05-29.
|
||||
|
||||
## Documentation overview
|
||||
|
||||
# WFH Daily Report App
|
||||
|
||||
A sleek, modern, and dockerized web application for employees to track and submit their daily work-from-home reports. Features a stunning glassmorphic design and seamless integration with Google Workspace.
|
||||
|
||||
## ✨ Features
|
||||
|
||||
- **Premium UI**: Modern glassmorphism aesthetics with smooth animations and responsive design.
|
||||
- **Google OAuth 2.0**: Secure authentication using your company's Google Workspace accounts.
|
||||
- **Multi-Step Reporting**:
|
||||
- **Morning**: Log planned tasks, time estimates, and initial notes.
|
||||
- **Evening**: Review achievements, update statuses, and submit links to completed work.
|
||||
- **Smart Admin Logic**:
|
||||
- The first user to log in is automatically granted the **ADMIN** role.
|
||||
- Exclusive **Admin Panel** to search and review all employee reports.
|
||||
- **Google Drive Integration**:
|
||||
- Automatically exports completed reports as Google Docs.
|
||||
- Admins can designate a specific folder for all exports.
|
||||
- **Single-Container Architecture**: Uses SQLite for persistent storage, making it ideal for "drop-in" deployments (e.g., Unraid, Synology).
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### 1. Prerequisites
|
||||
- [Google Cloud Console](https://console.cloud.google.com/) Project with:
|
||||
- OAuth 2.0 Credentials (Web Application)
|
||||
- Google Drive API enabled
|
||||
- Docker installed on your host.
|
||||
|
||||
### 2. Environment Setup
|
||||
Copy `.env.example` to `.env` and provide your credentials:
|
||||
```bash
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
### 3. Run with Docker
|
||||
```bash
|
||||
# Build and run the container
|
||||
docker build -t wfh-report .
|
||||
docker run -p 3000:3000 \
|
||||
--env-file .env \
|
||||
-v $(pwd)/data:/app/data \
|
||||
wfh-report
|
||||
```
|
||||
|
||||
## 🏡 Unraid Installation
|
||||
|
||||
…(truncated — see repo)
|
||||
|
||||
## Notes
|
||||
|
||||
- Project file auto-created from repo documentation.
|
||||
Reference in New Issue
Block a user