Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> |
||
|---|---|---|
| .githooks | ||
| assets | ||
| docs | ||
| public | ||
| scripts | ||
| server | ||
| src | ||
| .dockerignore | ||
| .env.example | ||
| .gitignore | ||
| Dockerfile | ||
| README.md | ||
| docker-compose.yml | ||
| docker-entrypoint.sh | ||
| index.html | ||
| package-lock.json | ||
| package.json | ||
| postcss.config.js | ||
| tailwind.config.js | ||
| vite.config.js | ||
README.md
Queue North Website
Status: Current
Owner: _null
Last reviewed: 2026-08-18
Governs: package.json, src/routes.jsx, Dockerfile, docker-compose.yml — the
project-facing overview, whose stack, route list and Docker story
all describe those files
Review trigger: Any change to the stack, the route list, the Docker or
deployment story, the agent pipeline, or where a document lives
The business website for Queue North Technologies — an 8x8 Certified Partner delivering UCaaS, contact centre, networking and managed support for SMB and enterprise organisations. Live at queuenorth.com, with qn.isnull.dev reaching the same container through a second ingress.
Objective
Queue North Website is the modern rebuild of the Queue North Technologies business website.
The goal is to replace the current static early-2000s-style HTML/CSS/JS site with a polished 2026 business website that clearly presents Queue North as a trustworthy communications, contact center, networking, and managed support partner.
The site should feel:
- Bright and professional
- Modern but not flashy
- Business-first, not cyber/gaming/crypto
- Easy to navigate
- Clear about Queue North's 8x8 partnership and service expertise
- Optimized for consultation and support request conversion
Target Stack
- Vite — build tool, not Next.js
- React — SPA frontend
- React Router — client-side routing
- Tailwind CSS — utility-first styling
- shadcn/ui — component primitives
- Sonner — toast notifications
- TanStack Query — server state management
- Express — backend API
- better-sqlite3 — SQLite database
Layout Direction
The design direction is a light-first B2B technology layout with strategic dark navy sections.
Primary structure:
-
Hero
- Dark navy section
- Clear headline and value proposition
- Primary CTA:
Request Consultation - Secondary CTA:
Explore Services - Trust chips: 8x8 Certified Partner, Veteran Owned, 25+ Years Experience, SMB to Enterprise
-
Trust / Certification Bar
- Light section
- Reinforces 8x8 partner credibility
-
Services Preview
- White cards on a bright background
- Concise service explanations
- Links to service detail pages
-
Why Queue North
- Three-pillar section:
- Architecture
- Deployment
- Lifecycle Support
- Three-pillar section:
-
Industries
- Healthcare
- Retail
- Manufacturing
- Education & Finance
-
Final CTA
- Dark navy conversion band
- Consultation-focused message
Routes
/ Home
/about About
/services Services index
/services/:slug 7 service detail pages
/industries Industries index
/industries/:slug 4 industry detail pages
/contact Contact form → POST /api/leads
/support Support form → POST /api/support
/privacy-policy Privacy policy
* 404
Defined in src/routes.jsx. Every one of them is prerendered to static HTML at
build time by scripts/prerender.js — the SPA hydrates on top. /privacy-policy
additionally has a server-rendered fallback because Meta's crawler does not run
JavaScript.
The standalone /8x8 route was removed at 0.6.6; that content now lives inside
the UCaaS and contact-centre service pages.
Where the work is
Open work lives in the issue tracker, not in this file. Milestones are batches, issues are deliverables. There used to be a phase checklist here and in four other documents; by the time it was removed it said "Phase 5 — In Progress" while the last four commits said batch 0.9.3. That is the second record this convention exists to remove.
- What is left, and what is next: the milestones at dream.scheller.ltd/null/Queue-North-Website
- What is broken: issues labelled
P0,P1,P2 - What the batches were, before the tracker held them: docs/history/BATCH_LEDGER.md
The rebuild itself is done: phases 1 through 10 completed between May and August
2026, from the original static HTML site to the current Vite + React SPA with a
prerendered build. docs/history/DEVELOPMENT_LOG.md has it version by version.
Where the tracker is
dream.scheller.ltd — a Forgejo instance, and naming it matters. The convention is portable; the reporting is not. Every figure on this project's card at privacyllc.dev is read from this Forgejo repository.
Credentials are in ~/.openclaw/docker-registry.env:
set -a; . ~/.openclaw/docker-registry.env; set +a
python3 scripts/forgejo-issue.py list
Despite its name that token is not registry-scoped — it works across the whole API, with push and pull. Never print it into a log or a chat.
Two traps that cost an hour each otherwise. Cloudflare fronts the instance and
1010-blocks clients that do not look like a browser or curl — Python's urllib
among them — so every request needs User-Agent: curl/8.5.0;
scripts/forgejo-issue.py already sends it and anything new must too. And
/issues returns pull requests too unless type=issues is passed.
Labels are exactly P0, P1, P2, release-blocker. They are queried by
name. A fifth label, P3, exists on 21 closed issues from before adoption and is
frozen — nothing new gets it, because nothing counts it.
Backend Goals
Initial API endpoints:
GET /api/health
POST /api/leads
POST /api/support
Initial SQLite tables:
leadssupport_requests
Contact and support forms should submit through Express, save to SQLite, and show user feedback with Sonner.
Agent Plan
The overhaul is handled through the agent pipeline below:
- Scarlett — design system, Tailwind/shadcn layout direction, responsive polish, accessibility review
- Neo — Vite/React implementation, Express API, SQLite/database work, build-system changes
- Private Hudson — security review for API routes, form handling, validation, data exposure, dependency risks, and backend hardening
- Scarlett — UI polish pass after implementation changes
- Bishop — build/runtime verification, route checks, documentation verification, version consistency
- Ripley — final local checks, commit, tag, and push to
dev
Agents do not touch git. Ripley owns all commits, tags, and pushes.
This pipeline says who does which part. docs/WORK_CYCLE.md says what must
be true before a piece of work counts as finished — closing the issue with its
evidence, closing the milestone if the batch landed, updating the documents the
change triggered in the same commit, and recording the next action. They are
different questions and both apply.
.learnings/ holds each agent's accumulated notes and error logs. It is
gitignored and local to this machine.
Batch Pipeline Rule
Work is dispatched as task batches. A batch runs through the required agents, then Ripley pushes that completed batch once.
Example Docker batch:
Neo → Private Hudson → Bishop → Ripley
The whole batch is one push, not one push per agent.
A batch is a milestone in the tracker. Closing the last issue under it does not close the milestone, and a complete-but-open milestone reads as a batch still in progress — closing it is what marks the batch shipped, and it moves a figure on the project card the same day.
Version numbers no longer encode the phase. Until 2026-08-18 the rule was that the minor version was the phase number — Phase 5 releases are
0.5.x— with Bishop responsible for keepingpackage.jsonin agreement with two root-level documents — PROJECT.md and HISTORY.md, named here without backticks because both were retired on 2026-08-18 and a backticked path is a claim that a file exists. It drifted twice; the second timepackage.jsonsaid0.8.3for two and a half months while commits said batch 0.9.3. The tracker holds the batch now, and docs/history/HISTORY.md has the full reasoning.
Design Direction
Based on the redesign review (see docs/design/REDESIGN_REVIEW.md), the site should feel:
- Modern, clean, stable — not experimental, not hacker aesthetic
- Business-first — B2B UCaaS/IT partner, not a dev portfolio
- Trust-forward — 8x8 partnership, certifications, uptime SLAs front and center
- Human but competent — less corporate fluff, more concrete outcomes
Color palette evolution (not rip-and-replace):
- Keep navy dark base, add teal/cyan accents for depth and hierarchy
- Improve contrast and spacing
- Mobile-first — SMB decision-makers browse on phones
Reference brands: RingCentral, Cloudflare, Dialpad — modern but enterprise-trustworthy.
See docs/design/REDESIGN_REVIEW.md for the full redesign assessment.
Docker Deployment
The application can be containerized using Docker for consistent deployment across environments.
Prerequisites
- Docker (v20+)
- Docker Compose (v2+)
Quick Start
Using Docker Compose (Recommended)
# Build and start the container
npm run docker:compose:up
# View logs
npm run docker:compose:logs
# Stop the container
npm run docker:compose:down
Manual Docker Build
# Build the image
npm run docker:build
# Run the container
npm run docker:run
Environment Variables
Set the following in the .env file (not included in image by default):
NODE_ENV=production
SERVER_PORT=3001
Data Persistence
SQLite database is persisted in the ./db directory. Data will survive container restarts.
Note on data persistence:
The application uses Docker named volumes (queuenorth-db and queuenorth-logs) to persist data. Docker manages the ownership and permissions of these volumes automatically, so no manual setup is required.
If you prefer to use host bind mounts instead, ensure your host ./db and ./logs directories are owned by UID 1001:
mkdir -p ./db ./logs
sudo chown -R 1001:1001 ./db ./logs
If you encounter "unable to open database file" errors, verify the host directory is writable by the container's UID (1001) or use named volumes as shown above.
Health Check
The container includes a health check at /api/health. A healthy container returns:
{"status":"ok","timestamp":"2026-05-12T..."}
Ports
- Backend API:
3001(host) →3001(container)
Build Optimization
The .dockerignore excludes:
node_modules(reinstalled in container)dist(built in container)db/(mounted as volume).git, logs, private docs
This ensures minimal image size and reproducible builds.
Run Locally
npm install
git config core.hooksPath .githooks # per clone — see below
npm run dev # Vite on 5173, Express on 3001
npm run build is the real gate: client bundle, SSR bundle, then prerender.
docs/TOOLS.md has every script and which ones can stop you.
The git hooks
Four hooks live in .githooks/ because .git/hooks is not versioned. The
core.hooksPath line above is per clone, so every checkout runs it once; an
uninstalled hook fails silently.
| Hook | What it does here |
|---|---|
pre-commit |
scans the staged diff for credentials, then runs npm run build if source is staged |
commit-msg |
refuses a message with no conventional type (feat, fix, ui, docs, test, refactor, security, perf, chore) |
post-commit |
pushes to origin |
pre-push |
refuses a push that leaves uncommitted or staged edits behind |
post-commit pushes. That is deliberate — work that exists on one laptop is
one disk away from gone — but it has a consequence: whatever documentation was
not in that commit is now behind the code by one push. That is the mechanical
reason documentation edits ride in the same commit as the change that caused
them. SKIP_GUARDS=1 and SKIP_PUSH=1 are the escape hatches, both loud.
Project Docs
README.md is the landing page. Detailed procedures belong in docs/, and open
work belongs in the tracker.
docs/DOC_TRUST_MAP.md is the entry point — read it
before trusting anything else in docs/.
| Doc | Purpose |
|---|---|
| docs/DOC_TRUST_MAP.md | Which document owns which answer, and which source wins when records disagree |
| docs/WORK_CYCLE.md | What happens at the end of a piece of work, and what privacyllc.dev will and will not update on its own |
| docs/TOOLS.md | Where the scripts are, which ones can stop you, and this project's npm commands |
| docs/OPERATIONS.md | What is deployed and where, what watches it, and what to run when it is down |
| docs/planning/PROJECT_PLAN.md | Scope, audience, and what this project deliberately is not |
| docs/planning/REQUIREMENTS.md | Engineering standards. Not changeable without _null's approval |
| docs/architecture/README.md | Module boundaries, the database schema, every API response shape |
| docs/architecture/GUARDS.md | How to write a check that can actually fail |
| docs/architecture/zoho-setup.md | The CRM integration, end to end |
| docs/design/OVERHAUL_PLAN.md | The visual system: tokens, type scale, spacing, layout blueprints |
| docs/design/REDESIGN_REVIEW.md | Brand positioning and the messaging standard |
| docs/security/SECURITY.md | Threat model, secrets, third parties, what is out of scope |
| docs/security/SECURITY_CHECKLIST.md | The list to work through before a release |
| docs/qa/ClaudeQAPlan.md | What a QA round consists of |
| docs/qa/ClaudeReport.md | The QA verdict — quoted verbatim on the project card |
| docs/qa/ClaudeQACoverage.md | What each pass actually reached, and the standing gaps |
| docs/history/DEVELOPMENT_LOG.md | Dated, append-only: what happened and when |
| docs/history/HISTORY.md | The narrative: decisions, and what was tried and dropped |
| docs/history/BATCH_LEDGER.md | Archived. What the batches were before the tracker held them |
Agent Notes
- Product truth comes from the code and the tracker before prose.
- Do not keep a work list in this README, or in any markdown file. That is what the tracker is for, and this project has already paid for the lesson.
- Finish with docs/WORK_CYCLE.md, every time: close the issues you finished with the evidence that proves it, close the milestone if the batch landed, update the documents the change triggered in the same commit, then record the next action and any blockers before you stop.
- Nothing on privacyllc.dev writes itself except the tracker counts and the pushed docs. The summary and next action change only when they are sent; the milestone and blocker tables there change only when a human edits them.
- Do not claim a feature is built unless you can cite the route, file, or screenshot that proves it. There is no test suite to cite.