Skip to content

Release: PEMS overhaul, platform hardening & maintenance mode - #18

Merged
arena-ai-coding-agent[bot] merged 28 commits into
mainfrom
develop
Aug 3, 2026
Merged

Release: PEMS overhaul, platform hardening & maintenance mode#18
arena-ai-coding-agent[bot] merged 28 commits into
mainfrom
develop

Conversation

@arena-ai-coding-agent

Copy link
Copy Markdown
Contributor

Release — develop → main

Promotes everything merged into develop (PR #17 + earlier) to main:

  • PEMS Task Execution Center — UI/UX v2 redesign, bulk transitions, REWORK workflow, fixed Department/filters/CompletedAt
  • Automation engine — hourly recurrence materialization, 30-min SLA escalation cron, email pipeline, notification dedup
  • Backend hardening — migration runner + 004_pems_v4, SQL transactions, event-store version locking, RBAC, live-data auth, cache namespaces
  • Node 26 fixes — express-rate-limit IPv6 keyGenerator, SQL TLS-to-IP handling
  • Maintenance modeVITE_MAINTENANCE_MODE / MAINTENANCE_MODE env-gated screen + API 503
  • Lockfiles — npmmirror → registry.npmjs.org
  • Docs: docs/pems-backend-report.md, docs/pems-backend-plan.md

brandcentral-services and others added 28 commits August 1, 2026 15:27
- Sticky blurred command header with brand tile, Alt+N shortcut hint
- CommandCenterKpis v2: icon tiles, trends, live sync time, responsive grid
- Quick-view pills with icons; view switcher with icons
- Filters moved to a drawer (adds Frequency filter), active filter chips
- Task list: token styling, skeleton loading, per-page selector, richer empty state
- Floating bulk-action bar with working Approve/Reject/Export
- Create-task wizard rebuilt with antd Steps + inline validation
- Right insights panel sticky on wide screens, drawer below 1360px
- Full --bc-* design-token adoption; add TASK_LIST_GRID constant
- PremiumTaskRow: styling-only changes (hover/selection classes, tokens)

All data flow / API logic preserved; verified with esbuild + babel scope checks.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
- Introduced CSS rules for mobile and desktop views.
- Added visibility toggles for mobile-only and desktop-only elements.
- Implemented hover effects for task rows to enhance user interaction.
- Drop BoardView/CalendarView imports, view options and render branches
  (List / Seller / Objectives remain)
- Quick-view pills: uniform 28px height, gradient active state, icon/label
  alignment, press + focus-visible feedback, hidden scrollbar
- Pills now keyboard-accessible (Enter/Space) with tablist/tab semantics

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
… SQL TLS to IP

- rateLimiter: use ipKeyGenerator() helper for the IP fallback
  (fixes ERR_ERL_KEY_GEN_IPV6 validation errors on express-rate-limit v8)
- db.js / config/env.js: disable TLS by default when the SQL host is an IP
  literal (Node 24+/26 refuses servername=IP, ERR_INVALID_ARG_VALUE);
  DB_ENCRYPT=true|false overrides, hostnames keep encrypt:true
- db.js: attach pool 'error' listeners to prevent uncaught event crashes
- server.js: global unhandledRejection/uncaughtException guards — transient
  DB/Redis failures log loudly instead of killing the process

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
ipKeyGenerator(ip, ipv6Subnet) is the key generator itself (takes the IP
string), not a factory. Calling ipKeyGenerator()(req) threw at runtime:
'ipKeyGenerator(...) is not a function' -> 500 on /api/auth/login.
Verified with a live express + HTTP test (IPv4 + IPv6 paths all 200).

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
… namespaces

- backend/database/migrate.js: numbered migration runner + SchemaMigrations
  tracking; supports legacy (runMigration) and modern (up) shapes
- backend/migrations/004_pems_v4.js: recurrence columns/log, SLA dedup
  columns, unique event-store version index, query-support indexes
- backend/scripts/runMigrations.js: CLI runner
- db.js: withTransaction() helper (begin/commit/rollback)
- cacheService + middleware/cache.js: namespace-based cacheRoute /
  invalidateCache (keys route:{namespace}:{path}) — fixes stale-cache bug
- pemsRoutes/eventHandlers: migrated to namespace invalidation
- server.js: idempotent migrations at startup (RUN_MIGRATIONS_ON_STARTUP gate)

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
- New POST /api/pems/instances/bulk/transition (registered before :id routes)
  with per-id validation, updated/skipped reporting, 200-id cap
- submitReview honors REWORK decision via resolveReviewTransition()
- Bridged rule tasks now return IsRuleTask: true (matches frontend contract)
- Remove duplicate getFilterOptions export (keeps richer v3 version)
- notificationMergeService: real UNION of PEMS + legacy Notifications
  with Source flag and bounded limit
- /dashboard/live-tasks: ?limit= (1–50, default 15)
- workflowEngine: resolveReviewTransition + 3 unit tests (46 pass)

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
- New recurrenceService: hourly materialization of recurring templates with
  PemsRecurrenceLog idempotency guard, cron-parser for CUSTOM frequency
  (graceful fallback), batch cap 100, NextScheduledDate advance
- schedulerService: hourly PEMS recurrence job + every-30-min SLA
  escalation job (gates: PEMS_RECURRENCE_ENABLED / PEMS_SLA_ESCALATION_ENABLED)
- pems-notification processor: best-effort email dispatch after in-app
  notification (PEMS_EMAIL_ENABLED=true); emailNotificationService gained
  skipInApp option + fixed SocketService require path
- checkEscalations: dedup windows (SLA_WARNING ≤1/12h, SLA_BREACH ≤1/24h)
  using LastSlaWarningAt/LastSlaBreachAt columns
- package.json: + cron-parser
- Unit tests: recurrence math (6 tests) — 52 pass

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…, auth

- createInstance / completeSubTask wrapped in withTransaction; writeAuditLog,
  transitionStatus, submitReview accept optional tx
- New submitReviewAndTransition: review insert + workflow transition atomic
- eventStore.append: transactional with UPDLOCK+HOLDLOCK versioning +
  single retry on duplicate key (unique index from 004)
- getInstanceById: single-query activity hydration (N+1 fix)
- liveDataRoutes: auth on all endpoints (was unauthenticated)
- New pemsPolicy (pure access rules) + pemsAccess middleware (assignee /
  reviewer / global roles; resolves task via subtask/activity ids)
- Routes: template writes + instance create require tasks_manage;
  transition/achievement/subtask/activity/evidence/review require entity access;
  bulkTransition enforces per-task access (NO_ACCESS skip)
- Unit tests: pemsPolicy matrix — 57 pass

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
- pemsApi.js: add bulkTransition(ids, toStatus, details) → POST
  /api/pems/instances/bulk/transition with error body passthrough
- TaskInstancesPage bulk bar: single API call, updated/skipped counts
  surfaced in the toast (replaces per-task Promise.allSettled loop)
- docs: implementation status table added to plan

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…lockfile registry

- migrate.js: accept module.exports = async function (pool, sql) —
  fixes 'Migration 004_password_resets.js must export up() or runMigration()'
- package-lock.json + backend/package-lock.json: replace 1268 npmmirror
  tarball URLs with registry.npmjs.org — fixes npm EALLOWREMOTE
  ('Fetching packages of type remote have been disabled')

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
The M4 route-guard patch referenced requirePermission/requireTaskAccess
but the import line was never written (an earlier script aborted before
writing). Caused ReferenceError at startup. All 22 touched backend files
re-scanned with a Babel scope checker — zero unresolved identifiers.

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
- New src/pages/UnderMaintenance.jsx: branded standalone screen (design
  tokens, animated cog, status pill, customizable message/ETA)
- main.jsx: when VITE_MAINTENANCE_MODE=true renders ONLY the maintenance
  screen — no router, no providers, no API calls
- New backend/middleware/maintenanceMode.js: MAINTENANCE_MODE=true returns
  503 for all /api/* (health endpoints exempt); wired before routes
- .env.example / .env.production.example / .env.staging.example:
  VITE_MAINTENANCE_MODE, VITE_MAINTENANCE_MESSAGE, VITE_MAINTENANCE_ETA,
  MAINTENANCE_MODE (all default false/empty)
- Middleware behavior verified: api→503, health→pass, off→pass

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…c edition

- Dark luxury-storefront aesthetic: aurora light blobs, dotted grid,
  film grain, glass emblem with rotating dashed rings
- Headline with gradient serif-italic accent (We're *restocking* the shelves.)
- LIVE system-status console: self-cycling checklist (fills → holds 4s → resets),
  terminal-style cursor line
- Shimmer 'restock progress' bar, ETA chip, support-email footer
- Mouse parallax on the aurora layer + full prefers-reduced-motion support
- New env overrides: VITE_MAINTENANCE_TITLE (pipe = accent),
  VITE_MAINTENANCE_EMAIL; documented in .env.example

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Rebuild of UnderMaintenance with an experienced-dev standard:
- Light, product-matched theme (design tokens, slate + brand blue)
- Real BrandCentral logo with resilient fallback chain:
  VITE_MAINTENANCE_LOGO → /brandcentral-logo.png → brandcentral.in URL
  → /retailops-logo.svg (never a broken image)
- Quiet motion: one-time fade-up + subtle status-dot pulse, full
  prefers-reduced-motion support
- Semantic layout: centered status card, ETA chip, hairline footer with
  © BrandCentral Pvt. Ltd. + support email
- Sets document title to 'Under Maintenance · BrandCentral'
- Removed gimmicks (aurora, checklist console, progress bar, serif accents)
- .env.example: documented VITE_MAINTENANCE_LOGO and simplified overrides

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
- Uses the project's own RetailOpsWordmark component (same logo as the
  sidebar: rich black tile + enterprise gold) — no external images
- Light product theme matching the app (design tokens, DM Sans)
- Title supports |accent| syntax — pipe-wrapped word renders in brand
  gold serif-italic (matches the wordmark's gold accent)
- ETA block designed for long values: wraps cleanly, never truncates,
  with 'Estimated downtime' label
- Optional VITE_MAINTENANCE_LOGO override with wordmark fallback
- document.title = 'RetailOps · Under Maintenance'
- .env.example documents the exact usage (title pipes, ETA=ASAP, email)

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…ailops

# Conflicts:
#	backend/config/env.js
#	backend/database/db.js
#	backend/middleware/rateLimiter.js

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…lops

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
PEMS overhaul: backend reliability, automation engine, RBAC, maintenance mode
# Conflicts:
#	backend/database/db.js
#	backend/middleware/rateLimiter.js
#	backend/package-lock.json

Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
Reconcile: merge main's history into develop (enables develop → main release)
@arena-ai-coding-agent
arena-ai-coding-agent Bot merged commit 8cb3cc9 into main Aug 3, 2026
2 of 6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant