919 lines
42 KiB
Markdown
919 lines
42 KiB
Markdown
|
|
# Development log — Queue North Website
|
|||
|
|
|
|||
|
|
```
|
|||
|
|
Status: Current
|
|||
|
|
Owner: _null
|
|||
|
|
Last reviewed: 2026-08-18
|
|||
|
|
Governs: the dated record of what happened
|
|||
|
|
Review trigger: Nothing. This file is appended to, never revised.
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## How to use this
|
|||
|
|
|
|||
|
|
Newest first. **One entry per work session**, written before you stop — that is
|
|||
|
|
step 6 of `docs/WORK_CYCLE.md`, and the two lines it insists on are `Next
|
|||
|
|
action` and `Blockers`.
|
|||
|
|
|
|||
|
|
Those two are not decoration. The next session starts by reading the top of this
|
|||
|
|
file, and a session that ended without saying what came next hands the one after
|
|||
|
|
it a re-derivation instead of a starting point — which is where drift enters.
|
|||
|
|
Neither line competes with anything: the live next action is the field on the
|
|||
|
|
project at privacyllc.dev and the live blockers are issues in the tracker, while
|
|||
|
|
these say what both were **at this date**. A record of then never disagrees with
|
|||
|
|
a record of now.
|
|||
|
|
|
|||
|
|
**Append-only by convention.** Correcting an old entry rewrites the record of
|
|||
|
|
what was known at the time, which is the one thing this file is for. If an entry
|
|||
|
|
turns out to be wrong, add a later entry saying so; do not edit the first.
|
|||
|
|
|
|||
|
|
Note the Review trigger above says "nothing", deliberately. A dated log cannot
|
|||
|
|
rot the way a description of current state can — the entries were true when
|
|||
|
|
written and stay true. It is exempt from review for the same reason a receipt is.
|
|||
|
|
|
|||
|
|
## Where the entries below came from
|
|||
|
|
|
|||
|
|
Everything from `v0.7.1` down predates this repository adopting the template, and
|
|||
|
|
arrived from two root-level files that were merged here on 2026-08-18 — the
|
|||
|
|
gitignored `HISTORY.md` (a version-by-version changelog) and the gitignored
|
|||
|
|
`DEVELOPMENT_LOG.md` (an agent-activity log). Both are reproduced **verbatim**.
|
|||
|
|
|
|||
|
|
They are kept as two blocks rather than interleaved by date, deliberately. The
|
|||
|
|
changelog carries three duplicated version headings — two `v0.5.2`, two `v0.5.3`
|
|||
|
|
and two `v0.5.4`, written by different agents on the same day — so merging the
|
|||
|
|
two streams into one date order would have required choosing an order the record
|
|||
|
|
does not actually support. Two labelled blocks say what is known; one merged
|
|||
|
|
sequence would have implied more.
|
|||
|
|
|
|||
|
|
## Entries
|
|||
|
|
|
|||
|
|
### 2026-08-18 — Adopted the project template
|
|||
|
|
|
|||
|
|
Placeholder — replaced at the end of this session with the real entry, which
|
|||
|
|
carries Next action and Blockers.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## From `HISTORY.md` — the version changelog, verbatim
|
|||
|
|
|
|||
|
|
> Migrated 2026-08-18. Newest first, as written. Not edited.
|
|||
|
|
|
|||
|
|
## v0.7.1 — Low-Priority Fixes (6 issues, batches 10.0–10.2) — 2026-05-18
|
|||
|
|
|
|||
|
|
### Batch 10.0: Backend Cleanup (Neo)
|
|||
|
|
- **#128:** Removed React Query dependency (~45KB bundle savings) — replaced with simple async fetch
|
|||
|
|
- **#127:** Added HTTP→HTTPS redirect middleware for production (x-forwarded-proto)
|
|||
|
|
- **#129:** Added CSP connectSrc comment documenting Zoho server-to-server calls
|
|||
|
|
|
|||
|
|
### Batch 10.1: Image Optimization & UX (Scarlett)
|
|||
|
|
- **#97:** Converted 5 large PNGs to WebP (95-96% size reduction each, total ~11MB → ~511KB)
|
|||
|
|
- **#130:** Added loading spinner animation to Contact and Support form submit buttons
|
|||
|
|
|
|||
|
|
### Batch 10.2: Accessibility (Scarlett + Ripley)
|
|||
|
|
- **#101:** Added aria-labels to interactive elements across Header, Footer, MobileNav, Home, Contact, Support
|
|||
|
|
- Fixed JSX template literal syntax bug where aria-label and className both used `${}` on same element
|
|||
|
|
- Fixed Footer.jsx template literal aria-labels that would render as literal text
|
|||
|
|
- Fixed Home.jsx duplicated aria-label text fragment
|
|||
|
|
|
|||
|
|
## v0.7.0 — Audit Bug Fixes (44 issues, batches 9.0–9.9) — 2026-05-18
|
|||
|
|
|
|||
|
|
### Batch 9.0: Backend Security (Neo)
|
|||
|
|
- **#120:** Added UNIQUE constraint on leads.email + migration script
|
|||
|
|
- **#121:** Fixed Docker healthcheck — process.exit(1) on DB failure instead of always returning 200
|
|||
|
|
- **#123:** Removed world-writable chmodSync on SQLite DB file
|
|||
|
|
|
|||
|
|
### Batch 9.1: UI Fixes (Scarlett)
|
|||
|
|
- **#104:** Header CTA visibility — changed from invisible navy-on-navy to cyan-on-navy
|
|||
|
|
- **#89:** Added ScrollToTop component for route navigation
|
|||
|
|
- **#88:** Created 404 NotFound page with catch-all route
|
|||
|
|
|
|||
|
|
### Batch 9.2: UI Fixes (Scarlett)
|
|||
|
|
- **#91:** 8x8 white logo visibility on Trust Bar — added `brightness-0 invert` CSS filter
|
|||
|
|
- **#94:** Industries page now uses dynamic icons instead of hardcoded building SVG
|
|||
|
|
- **#125:** Added Building2 fallback for missing industry icons
|
|||
|
|
- **#92:** Industry cards use homeDesc with fallback text
|
|||
|
|
- **#93:** Removed redundant shortDesc from Home page service cards
|
|||
|
|
|
|||
|
|
### Batch 9.3: Navigation Fixes (Scarlett)
|
|||
|
|
- **#109:** Desktop nav now has hover dropdown menus for Services and Industries
|
|||
|
|
- **#102:** Replaced all `<Button onClick={navigate}>` with `<Link>` elements in Home.jsx
|
|||
|
|
- **#105:** Contact page CTA scrolls to form instead of linking to itself
|
|||
|
|
|
|||
|
|
### Batch 9.4: UI Fixes (Scarlett)
|
|||
|
|
- **#112:** Support CTA uses `bg-white text-primary-navy` instead of undefined `bg-secondary-bg`
|
|||
|
|
- **#106:** Support page phone/email are now clickable links
|
|||
|
|
- **#90:** Footer tel: links now include `+1` country code
|
|||
|
|
|
|||
|
|
### Batch 9.5: Backend Security (Neo)
|
|||
|
|
- **#119:** Honeypot spam protection on Contact and Support forms
|
|||
|
|
- **#126:** 409 Conflict shows friendly toast instead of error
|
|||
|
|
|
|||
|
|
### Batch 9.6: Build & Security (Neo)
|
|||
|
|
- **#122:** Disabled production sourcemaps
|
|||
|
|
- **#124:** CORS default changed from `*` to `https://queuenorth.com`
|
|||
|
|
- **#131:** CSP allows WebSocket for Vite HMR in development
|
|||
|
|
|
|||
|
|
### Batch 9.7: Assets & Meta (Scarlett)
|
|||
|
|
- **#99:** Added favicon, apple-touch-icon, site.webmanifest
|
|||
|
|
- **#117:** og:image now uses PNG (1200x630) instead of unsupported SVG
|
|||
|
|
- **#118:** Logo optimized from 348KB SVG to 44KB PNG (87% reduction)
|
|||
|
|
|
|||
|
|
### Batch 9.8: Icons & Copy (Scarlett)
|
|||
|
|
- **#98:** Cisco uses ShieldCheck icon, Veteran uses Award icon (no more text placeholders)
|
|||
|
|
- **#100:** Removed invalid Category/slug display from ServiceDetail sidebar
|
|||
|
|
- **#103:** Removed JointLogoWhite placeholder section, replaced with clean Trust Bar
|
|||
|
|
- **#107:** Footer address changed from marketing copy to "Orlando, FL"
|
|||
|
|
|
|||
|
|
### Batch 9.9: Cleanup (Neo)
|
|||
|
|
- **#95:** Removed 23 unused asset files (24MB freed)
|
|||
|
|
- **#113:** MobileNav verified clean (no dead code found)
|
|||
|
|
- **#114:** Removed duplicate CardDescription.jsx (properly used from Card.jsx)
|
|||
|
|
- **#115:** Removed unused Dialog.jsx component
|
|||
|
|
- **#116:** Removed unused zustand dependency
|
|||
|
|
|
|||
|
|
## v0.6.6 — Phase 7: Zoho CRM Integration Complete — 2026-05-17
|
|||
|
|
|
|||
|
|
### Zoho Integration (all batches 7.0–7.4)
|
|||
|
|
- **#74 (Batch 7.0):** Fixed OAuth token endpoint — accounts domain vs API domain, removed unnecessary redirect_uri, added retry logic on token refresh failure
|
|||
|
|
- **#75 (Batch 7.1):** Fixed lead payload mapping — split name into First_Name/Last_Name, added Lead_Source: Website, mapped Service_Interest to Description, added trigger: ["workflow"]
|
|||
|
|
- **#76 (Batch 7.2):** Added Zoho Cases forwarding — forwardSupportToZoho() for support requests, ZOHO_CASES_ENABLED toggle, fire-and-forget pattern, priority/name/company mapping
|
|||
|
|
- **#77 (Batch 7.3):** Changed to upsert API — duplicate leads update instead of fail, duplicate_check_fields: ["Email"]
|
|||
|
|
- **#78 (Batch 7.4):** Created docs/zoho-setup.md — step-by-step setup guide for non-technical admins, datacenter variants, troubleshooting
|
|||
|
|
- **#73:** Parent Zoho CRM Integration issue closed
|
|||
|
|
|
|||
|
|
## v0.6.5 — Batch 0.6.5: Code Review Bug Fixes (10 issues) — 2026-05-17
|
|||
|
|
|
|||
|
|
### Fixed
|
|||
|
|
- **#63 (P0):** Home.jsx — `industry.href` undefined, navigating to `/industries/undefined`. Fixed to use `/industries/${industry.id}`
|
|||
|
|
- **#50 (P1):** Server — `sanitized` scope error in catch block. Moved `let sanitized` before `try` so it's accessible in both `try` and `catch`
|
|||
|
|
- **#58 (P1):** Footer.jsx — All internal links converted from `<a href>` to `<Link to>` for client-side navigation
|
|||
|
|
- **#61 (P1):** Textarea.jsx — className template literal used regular quotes instead of backticks, so `${className}` was never interpolated
|
|||
|
|
- **#59 (P2):** About.jsx — CTA button converted from `<a href>` to `<Link to>`
|
|||
|
|
- **#60 (P2):** Support.jsx — Contact Us button converted from `<a href>` to `<Link to>`
|
|||
|
|
- **#62 (P2):** Badge.jsx — `text-foreground` (undefined) changed to `text-text`
|
|||
|
|
- **#64 (P2):** Support.jsx — `hover:bg-navy-darker` (undefined) changed to `hover:bg-primary-navy-dark`
|
|||
|
|
- **#65 (P2):** Server — timeoutMiddleware moved before catch-all routes so it actually applies
|
|||
|
|
- **#66 (P3):** Contact.jsx — Self-referencing `<a href="/contact">` converted to `<Link to="/contact">`
|
|||
|
|
|
|||
|
|
### Open
|
|||
|
|
- **#67 (P3):** Asset filenames with spaces (low priority, cosmetic)
|
|||
|
|
|
|||
|
|
## v0.6.2 — Phase 6 Complete: All Owner Feedback Issues Closed — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- **Issue #45:** Nav active-state styling — already implemented (useLocation + isActive helper, desktop + mobile)
|
|||
|
|
- **Issue #46:** Service card icons — already implemented (lucide-react icons from services.js data)
|
|||
|
|
- **Issue #47:** Cisco partnership signals — already implemented (Home hero, trust signals, Why Queue North, footer)
|
|||
|
|
|
|||
|
|
### Note
|
|||
|
|
These three issues were resolved in earlier Phase 5/6 batches. Verified in code and closed.
|
|||
|
|
|
|||
|
|
## v0.6.1 — Batch 0.6.1: Security Hardening, Retry Logic, Debouncing — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- **Batch 0.6.1:**
|
|||
|
|
- **Issue #12 (P2):** Removed `'unsafe-inline'` from CSP styleSrc since built SPA has all styles in CSS files (no inline styles)
|
|||
|
|
- **Issue #15 (P2):** Added exponential backoff retry logic with 3 max retries (1s, 2s, 4s) to `src/lib/api.js` for 5xx errors and network failures
|
|||
|
|
- **Issue #17 (P3):** Added `useDebounce` hook with 300ms delay to debounce validation errors in Contact.jsx and Support.jsx
|
|||
|
|
- **Issue #18 (P3):** Closed — React Query already handles GET caching with `staleTime: 5 minutes`
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `server/index.js` — Removed `'unsafe-inline'` from CSP styleSrc
|
|||
|
|
- `src/lib/api.js` — Added `retryFetch` helper with exponential backoff for get/post methods
|
|||
|
|
- `src/hooks/useDebounce.js` — Created debounce hook
|
|||
|
|
- `src/pages/Contact.jsx` — Integrated debounce for validation errors
|
|||
|
|
- `src/pages/Support.jsx` — Integrated debounce for validation errors
|
|||
|
|
- `package.json` — Version bumped to 0.6.1
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- ✅ `npm run build` passes
|
|||
|
|
- ✅ Docker image builds successfully
|
|||
|
|
- ✅ Container starts on port 3001 and responds to health check
|
|||
|
|
- ✅ Contact and Support forms debounce validation errors
|
|||
|
|
- ✅ API retry logic configured (3 retries, exponential backoff)
|
|||
|
|
- ✅ CSP correctly configured for static SPA (no inline styles)
|
|||
|
|
|
|||
|
|
### Forgejo Issues
|
|||
|
|
- Issue #12 closed (CSP fix applied)
|
|||
|
|
- Issue #15 closed (retry logic implemented)
|
|||
|
|
- Issue #17 closed (debouncing added)
|
|||
|
|
- Issue #18 closed (React Query handles GET caching)
|
|||
|
|
|
|||
|
|
**Note for Ripley:** Forgejo issue closing via API requires `FORGEJO_REGISTRY_TOKEN` environment variable. Token must be provided manually or via CI/CD secrets before closing issues via the Forgejo API.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.9 — Phase 6 Batches 0.6.5–0.6.7: Industry Icons, 8x8 Page Merge, Image Verification — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- **Batch 0.6.5 (Industry Icons Bigger, Issue #41):**
|
|||
|
|
- Industry icons enlarged with improved color and contrast
|
|||
|
|
- Icons more visually prominent on all screen sizes
|
|||
|
|
|
|||
|
|
- **Batch 0.6.6 (8x8 Page Merge, Issue #32):**
|
|||
|
|
- Removed standalone /8x8 page and route
|
|||
|
|
- Merged 8x8 partnership content into UCaaS and CCaaS service entries
|
|||
|
|
- Removed 8x8 nav links from Header and Footer
|
|||
|
|
- Deleted src/pages/8x8.jsx
|
|||
|
|
|
|||
|
|
- **Batch 0.6.7 (Verify Image Issues, Issues #30, #31):**
|
|||
|
|
- Confirmed services and industries pages render icons correctly (lucide-react)
|
|||
|
|
- No broken image references — Phase 5 redesign resolved both issues
|
|||
|
|
- Docker build + runtime test passed
|
|||
|
|
|
|||
|
|
### Forgejo Issues Closed
|
|||
|
|
- #30 (service images broken) — resolved by icon redesign
|
|||
|
|
- #31 (industry images broken) — resolved by icon redesign
|
|||
|
|
- #32 (8x8 page merge) — merged into service pages
|
|||
|
|
- #33–#41 — all owner feedback issues resolved
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Industry icon sizing (batch 0.6.5)
|
|||
|
|
- `src/data/services.js` — Expanded UCaaS/CCaaS with 8x8 content (batch 0.6.6)
|
|||
|
|
- `src/router.jsx` — Removed /8x8 route
|
|||
|
|
- `src/components/layout/Header.jsx` — Removed 8x8 nav link
|
|||
|
|
- `src/components/layout/Footer.jsx` — Removed 8x8 nav link
|
|||
|
|
- `src/pages/8x8.jsx` — Deleted
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.7 — Phase 5 Batch 9: Hero Left-Alignment + About Section Fixes (Issues #33, #34, #36, #37) — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- **Batch 0.6.3 (Hero Left-Alignment, Issue #33):**
|
|||
|
|
- Hero text left-aligned on all screen sizes (was center-aligned on desktop)
|
|||
|
|
- Hero image changed from `hidden lg:block` to always visible, `md:order-2` for tablet+ layout
|
|||
|
|
- Grid changed from `lg:grid-cols-2` to `md:grid-cols-2` for earlier responsive breakpoint
|
|||
|
|
- Spacing refactored from margin utils to gap utils
|
|||
|
|
- **Batch 0.6.4 (About Section Fixes, Issues #34, #36, #37):**
|
|||
|
|
- Removed "Founded in 2000" → updated to "Founded by military veterans"
|
|||
|
|
- Added "We continue the mission" veteran framing paragraph
|
|||
|
|
- Replaced "Cybersecurity for Communications" with "Vendor-Neutral Consulting" in expertise list
|
|||
|
|
- Updated About page image sizing to `max-h-96 h-auto object-cover`
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Hero section layout changes, image visibility fix
|
|||
|
|
- `src/pages/About.jsx` — Story text update, image sizing fix, expertise list update
|
|||
|
|
- `package.json` — Version bumped to 0.5.7
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- ✅ `npm run build` passes clean
|
|||
|
|
- ✅ Docker image builds successfully
|
|||
|
|
- ✅ Container starts on port 3001 and responds to health check
|
|||
|
|
- ✅ Home page loads at http://localhost:3001 — hero text left-aligned, image visible
|
|||
|
|
- ✅ About page loads at http://localhost:3001/about — veteran framing present, image sized correctly
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Cisco Partnership Signals — 2026-05-17
|
|||
|
|
|
|||
|
|
### Added
|
|||
|
|
- Cisco Certified Partner trust card in Trust Signals section (8x8 and Cisco dual partnership)
|
|||
|
|
- Cisco platform mentions in Services section descriptions
|
|||
|
|
- Cisco partner badge in Footer bottom section
|
|||
|
|
- Cisco partner visual indicator (white "C" badge) in Trust Bar section
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Cisco trust card, trust bar Cisco badge, vendor neutrality section
|
|||
|
|
- `src/data/services.js` — Cisco platform mentions in unified-communications and contact-center services
|
|||
|
|
- `src/components/layout/Footer.jsx` — Cisco in footer bottom section
|
|||
|
|
- `package.json` — Version bumped to 0.5.6
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- ✅ `npm run build` passes clean
|
|||
|
|
- ✅ Docker image builds successfully
|
|||
|
|
- ✅ Container starts on port 3001 and responds to health check
|
|||
|
|
- ✅ Home page loads at http://localhost:3001 — Cisco appears in trust signals
|
|||
|
|
- ✅ Services page loads at http://localhost:3001/services
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## Zoho P0/P1 Audit Fixes — 2026-05-17
|
|||
|
|
|
|||
|
|
### Fixed
|
|||
|
|
- P0 #2: Added null check for Zoho credentials before forwarding (early return)
|
|||
|
|
- P0 #3: Added response.ok check for Zoho API responses (log + return on failure)
|
|||
|
|
- P0 #4: Confirmed Docker uses USER nodejs (no su-exec needed)
|
|||
|
|
- P1 #5: Added 10-second timeout on Zoho fetch using AbortController
|
|||
|
|
- P1 #6: UNIQUE constraint on email already handled by db.js migration
|
|||
|
|
- P1 #10: Schema normalizes empty strings to null; Zoho payload uses `|| null`
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `server/index.js` — Zoho forwarding logic (credential checks, response validation, timeout, payload normalization)
|
|||
|
|
|
|||
|
|
### Build
|
|||
|
|
- ✅ `npm run build` passes
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.5 — Phase 5 Batch 8: Service Card Icons (Issue #35) — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Services page updated with lucide-react icons matching Home page pattern
|
|||
|
|
- 7 distinct icons: MessageCircle, Users, LifeBuoy, GraduationCap, LinkIcon, Wifi, Network
|
|||
|
|
- Icon-switching logic in Services.jsx maps each service icon name to correct component
|
|||
|
|
- No hardcoded lightning bolt — each service displays its own distinct icon
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Services.jsx` — replaced hardcoded lightning bolt SVG with lucide-react imports and icon-switching logic
|
|||
|
|
- `package.json` — version bumped to 0.5.5
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- ✅ `npm run build` passes clean
|
|||
|
|
- ✅ Docker image builds successfully
|
|||
|
|
- ✅ Container starts on port 3001 and responds to health check
|
|||
|
|
- ✅ Services page loads at http://localhost:3001/services
|
|||
|
|
- ✅ Each of the 7 service cards displays a distinct icon per services.js data
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.4 — Phase 5 Batch 7: Nav Active-State Styling — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Header.jsx and MobileNav.jsx now use `useLocation` hook from React Router 7
|
|||
|
|
- Active nav links display white text (`text-white`) with `font-semibold` styling
|
|||
|
|
- `isActive()` helper function compares `location.pathname` to link href
|
|||
|
|
- Both desktop and mobile navigation use consistent active-state styling
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/components/layout/Header.jsx` — Added `useLocation` import and `isActive()` function, updated desktop nav and mobile nav link styling
|
|||
|
|
- `src/components/layout/MobileNav.jsx` — Added `useLocation` import and `isActive()` function, updated all nav links with active-state styling
|
|||
|
|
- `package.json` — Version bumped to 0.5.4
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- ✅ `npm run build` passes clean
|
|||
|
|
- ✅ Docker image builds successfully
|
|||
|
|
- ✅ Container starts on port 3001 and responds to health check
|
|||
|
|
- ✅ Home page loads at http://localhost:3001
|
|||
|
|
- ✅ Both Header.jsx and MobileNav.jsx import `useLocation` from `react-router-dom`
|
|||
|
|
- ✅ `isActive()` function correctly compares `location.pathname` to link href
|
|||
|
|
- ✅ Active links display white text with font-semibold styling
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.3 — Phase 5 Batch 6: Footer + Contact Improvements — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Footer cleanup: email (`info@queuenorth.com`), phone (`(906) 482-6616`), and CTA (`Request Consultation`) all present
|
|||
|
|
- Contact page hero: prominent phone/email display + CTA button
|
|||
|
|
- Home page CTA links added to Trust Signals, Services, Why Queue North sections
|
|||
|
|
- Minor updates to Support page
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/components/layout/Footer.jsx` — Footer cleanup
|
|||
|
|
- `src/pages/Home.jsx` — CTA links in sections
|
|||
|
|
- `src/pages/Contact.jsx` — Hero CTA
|
|||
|
|
- `src/pages/Support.jsx` — Minor updates
|
|||
|
|
- `package.json` — Version bumped to 0.5.3
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes
|
|||
|
|
- Docker image builds and container starts on port 3001
|
|||
|
|
- Footer renders with email, phone, and CTA
|
|||
|
|
- Contact page hero displays phone/email and Request Consultation button
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.2 — Phase 5 Batch 5: Why Queue North Section Refinement — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Replaced generic "Architecture/Deployment/Lifecycle" pillars with 4 concrete differentiators
|
|||
|
|
- Added lucide-react icons: Headphones, UserCheck, Activity, ShieldCheck
|
|||
|
|
- Changed grid from 3-col to 4-col responsive layout (1 col mobile, 2 col tablet, 4 col desktop)
|
|||
|
|
- Removed unused CardDescription import
|
|||
|
|
- Updated Why Queue North section subtitle to "Four concrete differentiators that set us apart"
|
|||
|
|
- Clean card layout with centered icon containers and consistent styling
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Why Queue North section complete redesign
|
|||
|
|
- `package.json` — Version bumped to 0.5.2
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes
|
|||
|
|
- Docker image builds and container starts
|
|||
|
|
- Home page loads on http://localhost:3001
|
|||
|
|
- Responsive layout verified (1/2/4 columns as specified)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.1 — Phase 5 Batch 1: Hamburger Menu Fix + DialogTitle A11y — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Fixed SheetContent missing positional CSS classes (panel was zero-size)
|
|||
|
|
- Installed and configured tailwindcss-animate
|
|||
|
|
- Added visually hidden SheetTitle for accessibility (Radix DialogTitle requirement)
|
|||
|
|
- Forgejo issues #22, #23 closed
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.4 — Phase 5 Batch 4: Services Rewrite — Business Outcomes — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Section title changed: "Our Services" → "What We Handle"
|
|||
|
|
- Subtitle changed to outcome-focused: "From phones to firewalls, we keep your business running"
|
|||
|
|
- Added `homeDesc` field to all 7 services in `src/data/services.js` with business-outcome language
|
|||
|
|
- Service cards now show: icon + name + homeDesc (outcome) + shortDesc (supporting) + CTA
|
|||
|
|
- lucide-react icons per service: MessageCircle, Users, LifeBuoy, GraduationCap, LinkIcon, Wifi, Network
|
|||
|
|
- B2B professional card layout with icon containers (primary-navy/10 bg)
|
|||
|
|
- Service detail pages (ServiceDetail.jsx) unchanged
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Services section rewrite
|
|||
|
|
- `src/data/services.js` — Added homeDesc field to each service
|
|||
|
|
- `FUTURE.md` — Marked batch 0.5.4 complete
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.3 — Phase 5 Batch 3: Trust Signals Section — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Added dedicated Trust Signals section immediately after hero section
|
|||
|
|
- 8x8 Certified Partner badge: prominent white card with logo, certification number, and descriptive text
|
|||
|
|
- Veteran Owned badge: VCERT verified with certification #, values-based messaging
|
|||
|
|
- "25+ Years Experience": metric card with 25+ using Georgia font (font-numeric class)
|
|||
|
|
- Metrics grid: 4 key stats displayed (99.99% uptime, <15m response, 24/7 support, 100% satisfaction)
|
|||
|
|
- Clean card layout: white cards on section-alt background with hover effects
|
|||
|
|
- Mobile-first: three-column grid on desktop, stacked on mobile
|
|||
|
|
- Business outcomes focus: reliability, experience, support承诺, not technical jargon
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Added Trust Signals section after hero
|
|||
|
|
- `FUTURE.md` — Marked batch 0.5.3 complete
|
|||
|
|
|
|||
|
|
### Notes for Next Agent
|
|||
|
|
- The trust signals are now front and center after the hero, before services
|
|||
|
|
- Georgia font (`font-numeric`) consistently used for all metrics
|
|||
|
|
- All metrics use realistic placeholder values that can be replaced with real stats when available
|
|||
|
|
- The white card design provides contrast against the section-alt background
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.5.2 — Phase 5 Batch 2: Hero Section Rewrite — 2026-05-17
|
|||
|
|
|
|||
|
|
### Completed
|
|||
|
|
- Hero headline replaced: "Modern Communications Infrastructure Without the Vendor Noise" → "Reliable Business Communications — Without the Runaround"
|
|||
|
|
- Subtext updated to emphasize trust, reliability, and business outcomes
|
|||
|
|
- 8x8 Certified Partner badge made prominent (featured card with logo, not small pill)
|
|||
|
|
- Trust signals immediately visible on mobile without scrolling
|
|||
|
|
- CTAs updated: "Schedule Consultation" (primary, /contact), "View Services" (secondary, /services)
|
|||
|
|
- Color palette evolved: navy base with teal-900 gradient accent
|
|||
|
|
- Mobile-first design verified — trust signals visible above fold on phone viewports
|
|||
|
|
|
|||
|
|
### Files Modified
|
|||
|
|
- `src/pages/Home.jsx` — Hero section rewrite
|
|||
|
|
- `.learnings/scarlett/LEARNINGS.md` — Added hero rewrite entry
|
|||
|
|
- `FUTURE.md` — Marked batch 0.5.2 complete
|
|||
|
|
|
|||
|
|
### Notes for Next Agent
|
|||
|
|
- The 8x8 badge is now prominently featured — keep this prominence in future sections
|
|||
|
|
- Georgia font (`font-numeric`) used for "25+ Years Experience" — consistent with design rule
|
|||
|
|
- Consider similar trust signal presentation in the Trust Bar section
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.4.8 — Phase 4 Batch 8: Error Handling Hardening + Dep Audit — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Global error handlers: uncaughtException + unhandledRejection → log + exit(1)
|
|||
|
|
- 404 catch-all for `/api/*` routes returns `{ error: 'Not found' }`
|
|||
|
|
- Health check enhanced: DB connectivity check, returns `{ status: 'ok', db: 'ok' }` or 503
|
|||
|
|
- Request timeout: 30-second middleware, 504 response
|
|||
|
|
- Consistent error format: 400/404/429/500/503/504 all follow `{ error, fields? }` pattern
|
|||
|
|
- `npm audit`: 0 vulnerabilities
|
|||
|
|
- `npm outdated`: major updates noted (Express 5, Vite 8, etc.) but not upgraded
|
|||
|
|
|
|||
|
|
## v0.4.7 — Phase 4 Batch 7: Rate Limiting + Security Headers + CORS — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- express-rate-limit: 5 req/min per IP on /api/leads and /api/support, configurable via RATE_LIMIT_PER_MINUTE
|
|||
|
|
- helmet: CSP (scripts 'self', styles 'self' inline, fonts 'self' + Google Fonts), HSTS, X-Content-Type-Options, X-Frame-Options DENY
|
|||
|
|
- cors: configurable via CORS_ORIGIN env var, credentials enabled, API routes only
|
|||
|
|
- Trust proxy enabled for correct client IP behind Docker/reverse proxy
|
|||
|
|
- Rate limit returns 429 with JSON error + retryAfter
|
|||
|
|
- All security headers confirmed via curl
|
|||
|
|
- Docker config updated: all new env vars in Dockerfile and docker-compose.yml
|
|||
|
|
|
|||
|
|
## v0.4.6 — Phase 4 Batch 6: Zoho Forwarding Layer — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Zoho CRM forwarding via REST API v8 (POST /crm/v8/Leads)
|
|||
|
|
- OAuth2 token management: refresh token → access token, in-memory cache with auto-refresh
|
|||
|
|
- Fire-and-forget: Zoho forwarding is async, never blocks form response
|
|||
|
|
- Configurable via 6 env vars: ZOHO_ENABLED, ZOHO_API_DOMAIN, ZOHO_CLIENT_ID, ZOHO_CLIENT_SECRET, ZOHO_REFRESH_TOKEN, ZOHO_REDIRECT_URI
|
|||
|
|
- Best-effort design: Zoho failures logged but never propagate to client
|
|||
|
|
- ZOHO_ENABLED=false: no Zoho activity, form submits normally
|
|||
|
|
- ZOHO_ENABLED=true with invalid creds: form still succeeds, Zoho errors logged to console
|
|||
|
|
|
|||
|
|
## v0.4.5 — Phase 4 Batch 5: Server-Side Validation + Input Sanitization — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Zod schemas updated with `.trim()` and `.max()` on all fields
|
|||
|
|
- Input sanitization: strip HTML/script tags, truncate to max lengths
|
|||
|
|
- Request body size limit: 1MB (returns 413)
|
|||
|
|
- Validation errors formatted as `{ error, fields }` — no stack traces
|
|||
|
|
- All curl tests pass: valid data, empty fields, invalid email, XSS, max length, short issue
|
|||
|
|
- XSS test confirmed: `<script>` and `<b>` tags stripped from stored data
|
|||
|
|
|
|||
|
|
## v0.4.4 — Phase 4 Batch 4: Client-Side Validation + Sonner Feedback — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Contact form: required field validation (company, name, email, message)
|
|||
|
|
- Support form: required field validation (name, company, email, issue)
|
|||
|
|
- Email format validation with regex on both forms
|
|||
|
|
- Issue minimum length validation (10 chars) on Support form
|
|||
|
|
- Inline error messages below each invalid field (red text, small)
|
|||
|
|
- Sonner toast for validation errors on submit attempt
|
|||
|
|
- Error clearing as user corrects fields (onChange)
|
|||
|
|
- Red ring/border on Input/Textarea when field has validation error
|
|||
|
|
- Form inputs disabled during submission (mutation.isPending)
|
|||
|
|
- Form opacity reduced to 70% during submission
|
|||
|
|
- Build passes clean
|
|||
|
|
|
|||
|
|
## v0.4.1 — Phase 4 Batch 1: Contact Form Wired to Express — 2026-05-12
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Contact form submits all fields to `/api/leads` via TanStack Query mutation
|
|||
|
|
- Success/error response handling with Sonner toasts
|
|||
|
|
- Confirmation shown on success, form resets
|
|||
|
|
- Error state shown on failure
|
|||
|
|
- Backend Zod validation + SQLite storage working
|
|||
|
|
- Already implemented in Phase 1/2, verified end-to-end
|
|||
|
|
|
|||
|
|
## v0.2.13-fix — Phase 2 Fix: Legacy CSS Consolidation — 2026-05-13
|
|||
|
|
|
|||
|
|
### Fixed
|
|||
|
|
- Removed duplicate `src/index.css` (was not imported anywhere)
|
|||
|
|
- Created clean `src/index.css` as single Tailwind entry point
|
|||
|
|
- Moved `maxWidth.container: 1280px` into `tailwind.config.js` theme extensions
|
|||
|
|
- Updated `src/App.jsx` import from `./App.css` to `./index.css`
|
|||
|
|
- Deleted redundant `src/App.css`
|
|||
|
|
- All `bg-section-alt` usages verified still working
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes
|
|||
|
|
- All 14 Phase 2 batches now fully verified
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.4.3 — Phase 4 Batch 3: SQLite Persistence Verification — 2026-05-13
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Database file (`db/queuenorth.db`) created on first run if missing
|
|||
|
|
- `leads` and `support_requests` tables have correct schema (all columns match server/index.js)
|
|||
|
|
- Data persists across server restarts
|
|||
|
|
- Docker volume test: stop container, restart, confirm data present
|
|||
|
|
- Health check endpoint responds correctly
|
|||
|
|
- `docker-test.sh` persistence suite passes all checks
|
|||
|
|
|
|||
|
|
## v0.4.2 — Phase 4 Batch 2: Support Form Wired to Express — 2026-05-12
|
|||
|
|
|
|||
|
|
### Verified Complete
|
|||
|
|
- Support form submits all fields to `/api/support` via TanStack Query mutation
|
|||
|
|
- Success/error response handling with Sonner toasts
|
|||
|
|
- Confirmation shown on success, form resets
|
|||
|
|
- Error state shown on failure
|
|||
|
|
- Backend Zod validation + SQLite storage working
|
|||
|
|
- Already implemented in Phase 1/2, verified end-to-end
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.2.2 — Docker Image Size Fix — 2026-05-12
|
|||
|
|
|
|||
|
|
### Fixed
|
|||
|
|
- Removed duplicate `node_modules` copy in Dockerfile runner stage (was copying full dev+prod modules as a permanent layer)
|
|||
|
|
- Reduced image size from 331MB to 215MB (35% reduction)
|
|||
|
|
- `npm ci --omit=dev` now runs cleanly without pre-existing dev modules
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- Docker build succeeds
|
|||
|
|
- Container starts and health check passes
|
|||
|
|
- Frontend serves correctly
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
# Queue-North-Website — Changelog
|
|||
|
|
|
|||
|
|
## v0.3.4 — Phase 3 Visual Overhaul Complete — 2026-05-12
|
|||
|
|
|
|||
|
|
### Completed Batches
|
|||
|
|
- **Batch 1 (v0.3.1):** Tailwind theme tokens, spacing scale, container width, Inter font
|
|||
|
|
- **Batch 2 (v0.3.2):** Home page redesign — hero, trust bar, services grid, why QN pillars, industries preview, final CTA
|
|||
|
|
- **Batch 3 (v0.3.3):** Header/footer/mobilenav polish, navy-light color token, fixed Button.jsx TS generics build bug
|
|||
|
|
- **Batch 4 (v0.3.4):** Inner pages layout system — consistent hero/card/CTA pattern across About, Services, ServiceDetail, Industries, IndustryDetail, 8x8
|
|||
|
|
- **Batch 5:** Contact/Support forms verified compliant, no changes needed
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- All batches build successfully
|
|||
|
|
- Contact and Support pages already compliant with OVERHAUL_PLAN.md
|
|||
|
|
- No `asChild` usage on Button (unsupported, replaced with styled anchors)
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.3.2 — Phase 3 Batch 2: Home Page Redesign — 2026-05-12
|
|||
|
|
|
|||
|
|
### Changed
|
|||
|
|
- Updated Home.jsx to import `industries` data from data file
|
|||
|
|
- Replaced hardcoded industry data with dynamic rendering from `industries.js`
|
|||
|
|
- Updated Services and Industries cards to use Button component for "Learn more" links
|
|||
|
|
- Added MapPin icon from lucide-react for industry cards
|
|||
|
|
- Added useNavigate hook for programmatic navigation
|
|||
|
|
- Ensured consistent use of shadcn/ui Button component across the home page
|
|||
|
|
- Updated version to `0.3.2` for Phase 3 Batch 2
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes
|
|||
|
|
- All routes respond correctly
|
|||
|
|
- Button components render with correct styling
|
|||
|
|
- Responsive layout works on mobile and desktop
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.3.1 — Phase 3 Batch 1: Theme + Tailwind Config + Typography — 2026-05-12
|
|||
|
|
|
|||
|
|
### Changed
|
|||
|
|
- Enhanced Tailwind spacing scale with utility values (24-48rem)
|
|||
|
|
- Updated container max-width to 1280px per design spec
|
|||
|
|
- Confirmed color palette, Inter font, Georgia numeric font already in place
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.1.1 — Phase 1 Agent-Pass Checkpoint — 2026-05-12
|
|||
|
|
|
|||
|
|
### Changed
|
|||
|
|
- Corrected Phase 1 version to reflect completed agent-pass checkpoint semantics.
|
|||
|
|
- Documented that every completed agent pass/checkpoint within a phase increments the patch version.
|
|||
|
|
- Confirmed Phase 1 verified output is pushed to `dev` at `0.1.1`.
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes.
|
|||
|
|
- Backend health endpoint responds successfully at `/api/health`.
|
|||
|
|
|
|||
|
|
## v0.2.1 — Dockerization — 2026-05-12
|
|||
|
|
|
|||
|
|
### Added
|
|||
|
|
- Docker build for production deployment
|
|||
|
|
- docker-compose.yml for local development with SQLite persistence
|
|||
|
|
- npm scripts: `docker:build`, `docker:run`, `docker:compose:up/down/logs`
|
|||
|
|
- Health check in Dockerfile and docker-compose
|
|||
|
|
- Non-root `nodejs` user for security
|
|||
|
|
- Layer caching optimization (copy package.json first, install, then copy source)
|
|||
|
|
- `.dockerignore` to exclude node_modules, dist, db, logs, git, private docs
|
|||
|
|
|
|||
|
|
### Changed
|
|||
|
|
- Updated package.json to `0.2.1` for Docker batch
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- Docker build succeeds with `npm run docker:build`
|
|||
|
|
- Container starts and health check passes
|
|||
|
|
- SQLite database persists in `./db` volume
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.2.0 — Phase 2 Layout Complete — 2026-05-12
|
|||
|
|
|
|||
|
|
### Added
|
|||
|
|
- All route pages implemented (Home, About, Services, ServiceDetail, Industries, IndustryDetail, 8x8, Contact, Support).
|
|||
|
|
- Data files for services and industries moved to `/src/data/`.
|
|||
|
|
- Layout components (Header, Footer, MobileNav) built and integrated.
|
|||
|
|
- Legacy `styles.css` removed (replaced by Tailwind configuration).
|
|||
|
|
- Contact and support forms wired to Express backend via TanStack Query.
|
|||
|
|
- All pages render meaningful content matching original business information.
|
|||
|
|
- Version bumped to `0.2.0` for Phase 2 baseline.
|
|||
|
|
|
|||
|
|
### Changed
|
|||
|
|
- Replaced hash-based routing with React Router 7.
|
|||
|
|
- Standardized layout patterns across all pages (page hero, main content, sidebar, CTA band).
|
|||
|
|
- Updated package.json, PROJECT.md, OVERHAUL_PLAN.md, HISTORY.md to reflect Phase 2 status.
|
|||
|
|
- Overhaul plan updated to note Phase 2 scope and goals.
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes.
|
|||
|
|
- All routes respond correctly.
|
|||
|
|
- Contact form submits via `/api/leads`.
|
|||
|
|
- Support form submits via `/api/support`.
|
|||
|
|
- No references to legacy `styles.css` remain in source code.
|
|||
|
|
|
|||
|
|
## v0.1.0 — Phase 1 Foundation — 2026-05-12
|
|||
|
|
|
|||
|
|
### Added
|
|||
|
|
- Rebuilt project foundation on Vite + React SPA with React Router.
|
|||
|
|
- Added Tailwind CSS with Queue North light-first business palette.
|
|||
|
|
- Added shadcn/ui-style local primitives for buttons, cards, inputs, textarea, select, badge, sheet, and dialog usage.
|
|||
|
|
- Added Sonner toast support and TanStack Query provider/API helper.
|
|||
|
|
- Added Express backend with `/api/health`, `/api/leads`, and `/api/support`.
|
|||
|
|
- Added better-sqlite3 storage for `leads` and `support_requests`.
|
|||
|
|
- Added all planned frontend routes for home, about, services, service details, industries, industry details, 8x8, contact, and support.
|
|||
|
|
- Added Phase 1 documentation, build summary, script reference, and phase-based versioning rules.
|
|||
|
|
|
|||
|
|
### Changed
|
|||
|
|
- Replaced the static HTML/CSS/JS entry with the Vite React entry.
|
|||
|
|
- Updated README to point to `OVERHAUL_PLAN.md` as the design source of truth.
|
|||
|
|
- Standardized versioning so Phase 1 uses `0.1.x`, Phase 2 uses `0.2.x`, and later phases follow the same pattern.
|
|||
|
|
- Added Bishop verification rules and the requirement that Ripley pushes to `dev` after each verified phase.
|
|||
|
|
|
|||
|
|
### Verified
|
|||
|
|
- `npm run build` passes.
|
|||
|
|
- Backend health endpoint responds successfully at `/api/health`.
|
|||
|
|
- Required routes are configured.
|
|||
|
|
- Contact and support API paths exist and write through SQLite.
|
|||
|
|
|
|||
|
|
## v0.0.1 — Project Initialization — 2026-05-11
|
|||
|
|
|
|||
|
|
### Added
|
|||
|
|
- Project initialized with PROJECT.md, STRUCTURE.md, FUTURE.md, HISTORY.md, DEVELOPMENT_LOG.md.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## From `DEVELOPMENT_LOG.md` — the agent-activity log, verbatim
|
|||
|
|
|
|||
|
|
> Migrated 2026-08-18. Newest first, as written. Not edited. Its entries
|
|||
|
|
> overlap the changelog above in date but not in content: that file recorded
|
|||
|
|
> what shipped, this one recorded what each agent did and verified.
|
|||
|
|
|
|||
|
|
|
|||
|
|
## v0.6.0 — Navigation Active State Styling (Issue #38) — 2026-05-17
|
|||
|
|
|
|||
|
|
**Scarlett** — Nav Active-State Styling Implementation
|
|||
|
|
|
|||
|
|
**Status**: Already implemented in Header.jsx (no changes required)
|
|||
|
|
|
|||
|
|
**Implementation Details**:
|
|||
|
|
- `useLocation` from `react-router-dom` v7.1.3 is properly imported
|
|||
|
|
- `isActive(href)` helper compares `location.pathname === href`
|
|||
|
|
- Desktop nav: Active links show `text-white underline underline-offset-4`, inactive use `text-white/70 hover:text-white`
|
|||
|
|
- Mobile Sheet nav: Active links use `text-white font-semibold`, inactive use `text-white/70 hover:text-white`
|
|||
|
|
- Sub-links (Services/Industries) use brand color `text-navy-light` (#68A3B8) for visual hierarchy
|
|||
|
|
|
|||
|
|
**Routes supported**: `/`, `/services`, `/industries`, `/about`, `/contact`, `/support` and sub-routes
|
|||
|
|
|
|||
|
|
**Notes**: Implementation was complete prior to this batch. All navigation links correctly indicate current page with clear visual feedback for both desktop and mobile views. No issues found.
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.4.8 — Error Handling Hardening + Dep Audit Batch — 2026-05-13
|
|||
|
|
|
|||
|
|
**Neo** — Server-side error handling hardening
|
|||
|
|
- Added global error handlers:
|
|||
|
|
- `process.on('uncaughtException')`: logs error and exits with code 1
|
|||
|
|
- `process.on('unhandledRejection')`: logs error and exits with code 1
|
|||
|
|
- Both use `log.error()` for consistent timestamped logging
|
|||
|
|
- Added 404 catch-all middleware for API routes:
|
|||
|
|
- Returns `{ error: 'Not found' }` for unmatched `/api/*` routes
|
|||
|
|
- Non-API routes fall through to SPA (express.static)
|
|||
|
|
- Logs warnings for API 404s
|
|||
|
|
- Enhanced health check (`/api/health`):
|
|||
|
|
- Now verifies DB connection with `db.prepare('SELECT 1').get()`
|
|||
|
|
- Returns `{ status: 'ok', db: 'ok' }` on success
|
|||
|
|
- Returns 503 with `{ error: 'Service unavailable', db: 'error' }` on DB failure
|
|||
|
|
- Added 30-second request timeout middleware:
|
|||
|
|
- Returns 504 with `{ error: 'Request timeout' }` for slow requests
|
|||
|
|
- Logs timeout events with `log.warn()`
|
|||
|
|
- Verified consistent error response format:
|
|||
|
|
- 400: `{ error: string, fields: object }` (validation errors)
|
|||
|
|
- 404: `{ error: 'Not found' }`
|
|||
|
|
- 429: `{ error: 'Too Many Requests', message: string, retryAfter: number }`
|
|||
|
|
- 500: `{ error: string }` (no stack traces leaked)
|
|||
|
|
- 503: `{ error: 'Service unavailable', db: 'error' }`
|
|||
|
|
- 504: `{ error: 'Request timeout' }`
|
|||
|
|
- Dependency audit: `npm audit` → 0 vulnerabilities
|
|||
|
|
- Dependency review: `npm outdated` → Major updates noted (Express 5, Vite 8, Tailwind 4, etc.) but not upgraded per batch instructions
|
|||
|
|
- All client-side code preserved (no changes to React components)
|
|||
|
|
|
|||
|
|
**Verification**
|
|||
|
|
- Server starts successfully with all new middleware logged
|
|||
|
|
- Build passes: `npm run build`
|
|||
|
|
- Health endpoint returns DB status correctly
|
|||
|
|
- API 404s return consistent JSON response
|
|||
|
|
- Timeout middleware active (30s limit)
|
|||
|
|
|
|||
|
|
## v0.4.4 — Client-Side Validation + Sonner Feedback Batch — 2026-05-13
|
|||
|
|
|
|||
|
|
**Scarlett** — Client-side form validation implementation
|
|||
|
|
- Added client-side validation to Contact.jsx:
|
|||
|
|
- Required field validation: company, name, email, message
|
|||
|
|
- Email format validation with regex
|
|||
|
|
- Inline error messages below each invalid field (red text, small)
|
|||
|
|
- Sonner toast for validation errors on submit attempt
|
|||
|
|
- Error clearing as user types (on change)
|
|||
|
|
- Red ring/border on Input/Textarea when field has validation error
|
|||
|
|
|
|||
|
|
- Added client-side validation to Support.jsx:
|
|||
|
|
- Required field validation: name, company, email, issue
|
|||
|
|
- Email format validation with regex
|
|||
|
|
- Issue minimum length validation (10 chars — matches server-side Zod rule)
|
|||
|
|
- Inline error messages below each invalid field
|
|||
|
|
- Sonner toast for validation errors on submit attempt
|
|||
|
|
- Error clearing as user types (on change)
|
|||
|
|
- Red ring/border on Input/Textarea when field has validation error
|
|||
|
|
|
|||
|
|
- Added loading state UI:
|
|||
|
|
- Form inputs disabled during submission (`mutation.isPending`)
|
|||
|
|
- Form opacity reduced to 70% during submission
|
|||
|
|
- Submit button already shows "Submitting..." text
|
|||
|
|
|
|||
|
|
**Verification**
|
|||
|
|
- `npm run build` passes without errors
|
|||
|
|
- Both forms show validation errors when submitting empty form
|
|||
|
|
- Invalid email addresses trigger email field error
|
|||
|
|
- Valid submissions trigger success toast
|
|||
|
|
- Server errors trigger error toast
|
|||
|
|
- Error fields clear when user corrects them
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.4.6 — Security Hardening Batch (Rate Limiting, Helmet, CORS) — 2026-05-13
|
|||
|
|
|
|||
|
|
**Private_Hudson** — Security hardening and environment variable configuration
|
|||
|
|
- Installed security packages: `express-rate-limit`, `helmet`, `cors`
|
|||
|
|
- Added rate limiting to `/api` endpoints:
|
|||
|
|
- 5 requests per minute (configurable via `RATE_LIMIT_PER_MINUTE`)
|
|||
|
|
- IPv6-safe key generator
|
|||
|
|
- Standard rate limit headers (`X-RateLimit-Remaining`, `X-RateLimit-Reset`)
|
|||
|
|
- 429 response with retry-after information
|
|||
|
|
- Added Helmet security headers:
|
|||
|
|
- Content Security Policy (CSP) configured with strict default-src, script-src, style-src
|
|||
|
|
- HSTS enabled with 1-year max-age and includeSubDomains
|
|||
|
|
- Frameguard set to DENY
|
|||
|
|
- X-Content-Type-Options nosniff
|
|||
|
|
- X-Frame-Options DENY
|
|||
|
|
- X-XSS-Protection enabled
|
|||
|
|
- Referrer-Policy set to same-origin
|
|||
|
|
- Hide Powered-By header
|
|||
|
|
- Added CORS configuration:
|
|||
|
|
- Configurable via `CORS_ORIGIN` env var (default: `*` for development)
|
|||
|
|
- Credentials enabled for authenticated requests
|
|||
|
|
- Exposed rate limit headers
|
|||
|
|
- Updated server startup logging to show security config status
|
|||
|
|
- Request body size limit (`1mb`) already in place
|
|||
|
|
|
|||
|
|
**Docker Configuration Updates**
|
|||
|
|
- Added new environment variables to `docker-compose.yml`:
|
|||
|
|
- `RATE_LIMIT_PER_MINUTE=5`
|
|||
|
|
- `CORS_ORIGIN=https://queuenorth.com` (prod-safe default)
|
|||
|
|
- `LOG_LEVEL=info`
|
|||
|
|
- `ZOHO_ENABLED=false` (explicit off for non-CRM deployments)
|
|||
|
|
- `ZOHO_API_DOMAIN`, `ZOHO_CLIENT_ID`, `ZOHO_CLIENT_SECRET`, `ZOHO_REFRESH_TOKEN`, `ZOHO_REDIRECT_URI`
|
|||
|
|
- Added environment defaults to `Dockerfile`:
|
|||
|
|
- All new env vars with reasonable defaults
|
|||
|
|
- `CORS_ORIGIN=\*` (development default)
|
|||
|
|
- `LOG_LEVEL=info`
|
|||
|
|
- `ZOHO_ENABLED=false`
|
|||
|
|
- `docker-entrypoint.sh` verified — no changes required (env vars passed through automatically)
|
|||
|
|
|
|||
|
|
**Verification**
|
|||
|
|
- `npm run build` passes without errors
|
|||
|
|
- Server starts with security headers logged:
|
|||
|
|
- `[Security] Helmet enabled with CSP configured`
|
|||
|
|
- `[CORS] Enabled with origin: https://queuenorth.com`
|
|||
|
|
- `Rate limiting: 5 requests per 60 seconds`
|
|||
|
|
- Rate limiting headers present on API responses
|
|||
|
|
- All security headers confirmed via `curl -I http://localhost:3001/api/health`
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.4.5 — Server-Side Validation + Input Sanitization Batch — 2026-05-13
|
|||
|
|
|
|||
|
|
**Neo** — Server-side validation hardening and input sanitization
|
|||
|
|
- Added request body size limit: `express.json({ limit: '1mb' })` — returns 413 for oversized payloads
|
|||
|
|
- Added input sanitization after Zod validation (prevents XSS, trims whitespace, enforces max lengths at DB level):
|
|||
|
|
- `sanitizeString()` helper: trims whitespace, removes HTML/script tags, truncates to max length
|
|||
|
|
- `sanitizePayload()` applies sanitization to validated data before DB insert
|
|||
|
|
- Updated Zod schemas with comprehensive validation:
|
|||
|
|
- All string fields: `.trim()` applied
|
|||
|
|
- All string fields: `.max()` limits applied per RFC standards:
|
|||
|
|
- `company`: 200 chars
|
|||
|
|
- `name`: 100 chars
|
|||
|
|
- `email`: 254 chars (RFC 5321)
|
|||
|
|
- Updated error responses to match v0.4.6 error format standards:
|
|||
|
|
- 400: `{ error: 'Validation failed', fields: object }`
|
|||
|
|
- 500: `{ error: 'Failed to submit lead/support' }`
|
|||
|
|
|
|||
|
|
**Verification**
|
|||
|
|
- `npm run build` passes without errors
|
|||
|
|
- Zod validation correctly rejects invalid inputs
|
|||
|
|
- Input sanitization trims whitespace and removes HTML tags
|
|||
|
|
- Max length limits enforced at DB level
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.4.0 — Phase 4 Baseline — 2026-05-13
|
|||
|
|
|
|||
|
|
**Ripley** — Phase 4 initialization
|
|||
|
|
- Updated `package.json` version to `0.4.0`
|
|||
|
|
- Updated `PROJECT.md` to indicate Phase 4 active
|
|||
|
|
- Updated `HISTORY.md` with v0.4.0 release notes
|
|||
|
|
- Updated `FUTURE.md` with Phase 4 roadmap
|
|||
|
|
- Updated `OVERHAUL_PLAN.md` with Phase 4 task breakdown
|
|||
|
|
|
|||
|
|
**Phase 4 Scope**
|
|||
|
|
- v0.4.1-0.4.7: Incremental hardening batches (security, validation, error handling)
|
|||
|
|
- v0.4.8: Final hardening batch (global error handlers, health check, dependency audit)
|
|||
|
|
- Target: Production-ready, audited server with comprehensive error handling
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## v0.0.1 — 2026-05-11
|
|||
|
|
|
|||
|
|
**Ripley** — Project initialized
|
|||
|
|
- Created project directory at `/home/kaspa/.openclaw/Projects/Queue-North-Website/`.
|
|||
|
|
- Set up initial PROJECT.md, STRUCTURE.md, FUTURE.md, HISTORY.md, DEVELOPMENT_LOG.md.
|