DCSG Open Items List

DCSG Open Items List

DCSG Open Items List

Date

Date

Date

August 2025 – Present

August 2025 – Present

August 2025 – Present

Service

Service

Service

Infrastructure Engineering & DevOps, Full-Stack Web App

Infrastructure Engineering & DevOps, Full-Stack Web App

Infrastructure Engineering & DevOps, Full-Stack Web App

Client

Client

Client

Data Center Service Group (DCSG)

Data Center Service Group (DCSG)

Data Center Service Group (DCSG)

Tech Stack

TrueNAS SCALE (Kubernetes, NodePort), Docker (Apache), Deno (Supabase Edge Functions), Supabase (Postgres + Realtime), n8n (webhooks), Vite + React (JS), Tailwind CSS, TanStack Query, Tailscale, Netlify (read-only client)

Overview

Field engineers used to track bad UPS batteries in Word, then blast email chains to coordinate replacements. I replaced that manual flow with a centralized web app that parses UPS report summaries, lists open items in a sortable table, and moves completed work to history—with lightweight, path-based hosting and secure access for the whole team.

Solution

1. Server & Infrastructure Setup

  • Hosted on TrueNAS SCALE, exposed via NodePort and served through an Apache (Docker) container alongside other internal apps.

  • Path-based routing under /openitems keeps deployment simple and avoids extra subdomains/certs.

  • Production build artifacts are static, making the site extremely stable and low-maintenance.

2. Kubernetes & Docker Orchestration

  • Containerized frontend is deployed as a simple pod; Apache handles static assets and path routing.

  • TrueNAS Apps + NodePort provide a clean interface to expose the service internally without external ingress complexity.

3. Secure Remote Access

  • Company-wide access through Tailscale; employees on the tailnet reach the app reliably from any location.

  • Access scoping is controlled by tailnet ACLs rather than app-level auth (keeps v1 friction-free).

4. Backend & Data Flow

  • Supabase Postgres stores ups_items (parent) and bad_batteries (children).

  • Deno (Supabase Edge Function) /ingest-report:

    • Parses pasted report text (UPS Identifier, test date, cabinets/jars, building, tech, and per-battery details).

    • Normalizes units to and captures a severity label (e.g., “Moderately High”).

    • Creates a content fingerprint (SHA-256) combining UPS ID + date + normalized report to prevent exact duplicates.

    • Inserts parent + child rows in a single transaction and then fires a webhook to n8n (best-effort) to generate a ticket.

  • Enrichment loop: frontend polls the row for a ticket_number for up to ~45 seconds; Supabase Realtime also invalidates the open-items query when ticket_number updates.

5. Frontend UX (Vite + React + Tailwind)

  • Open Items table with sorting (Ticket #, UPS ID, Highest Severity, Date, # Bad, Status).

  • Accordion details show strings/jars with resistance and severity.

  • Add Open Item modal accepts raw report text; on submit:

    • Shows a full-screen Saving… overlay while the edge function parses & inserts.

    • Immediately refreshes the table and background-polls for the new ticket_number.

  • Inline status editing (Must Schedule / Scheduled / In Progress / Completed) with Save/Cancel batching.

  • Mark Completed stamps a completion_timestamp and moves the item to Closed Items (kept for history).

  • Typography, spacing, and interactions were tuned for fast triage by operations.

6. Read-Only Client

  • A second client build is deployed on Netlify for view-only access—no Add or Edit controls—so stakeholders can check live status without risking data changes.

Results

  • Single source of truth for open UPS items—no more scattered Word docs or email threads.

  • Consistent parsing eliminates hand-entry errors and standardizes severity & resistance units.

  • Faster handoffs: ticket numbers appear automatically post-ingest via the n8n webhook loop.

  • Low-ops hosting: static frontend under /openitems, one edge function, and Supabase as a managed datastore.

Key Takeaways

  • Start simple: static client + one edge function + managed Postgres goes a long way.

  • Path-based routing under an existing Apache container keeps infra lean and predictable.

  • Realtime invalidation + short polling makes async enrichment feel instant to users.

  • A separate read-only build is an easy way to widen access without adding auth in v1.

More projects

Got questions?

I’m always excited to collaborate on innovative and exciting projects!

E-mail

samhill7738@gmail.com

Phone

(443) 591-0103

Got questions?

I’m always excited to collaborate on innovative and exciting projects!

E-mail

samhill7738@gmail.com

Phone

(443) 591-0103

Got questions?

I’m always excited to collaborate on innovative and exciting projects!

E-mail

samhill7738@gmail.com

Phone

(443) 591-0103