# ZUCE Group Webapp — Project Spec

**Staging:** app.zucegroup.com (shared cPanel, Node.js via "Setup Node.js App" / LiteSpeed's Node hosting (lsnode.js))
**Database:** MySQL

## 0. About ZUCE Group (read this before writing any public-facing copy)

ZUCE Group (legal name: Zubre Creative Enterprises (ZUCE) Group Limited) is an integrated
**events, PR, media and communications company** headquartered in Nairobi, Kenya, operating
across East Africa. It is **not** a generic corporate-services or SaaS company — every public
page, hero statement, and case study should read like an events/experiential/communications
agency, not a B2B software vendor.

- **Tagline:** "Build. Brand. Beyond borders."
- **Founded:** 2016, originally as Zubre Creative Enterprises (a Nairobi branding/comms agency),
  formally became ZUCE Group as capabilities expanded.
- **Stats to use consistently across the site:** Founded 2016 - 100+ clients served - 4 divisions
  - 6+ countries.
- **Four divisions:**
  1. **ZUCE Events & Experiences** (core) — conferences, exhibitions & trade shows, corporate
     dinners & galas, stakeholder forums, virtual/hybrid events, event documentation.
  2. **ZUCE Creative, PR & Media Relations** (core) — brand strategy, corporate communications,
     PR & media relations, OOH advertising, event communications, content development, campaign
     design.
  3. **ZUCE Digital** (support) — event registration & ticketing, event websites, corporate
     websites & CMSs, mobile event apps, live streaming/virtual platforms, data & analytics.
     (This is the division that would commission a webapp like the one we're building.)
  4. **ZUCE Media Production** (support) — event videography, corporate photography,
     testimonial/interview production, post-production editing, live broadcast, content
     repurposing.
- **Vision:** to be a trusted platform for the organisation of events, exhibitions, and
  collaborative experiences that connect people, institutions, and markets across Africa.
- **Mission:** to design and deliver structured events, supported by precise communications,
  capable digital platforms, and professional media production.
- **Core values:** Clarity, Reliability, Collaboration, Practical Creativity.
- **Sectors served:** Financial Services & Fintech, Trade & Commerce, Government & Public Sector,
  Technology, NGOs & Civil Society, Education, Health, Real Estate & Construction, Hospitality &
  Tourism.
- **Regional reach:** Kenya (primary hub, full delivery), Rwanda (secondary hub, full delivery),
  Tanzania & Uganda (active delivery partners), Ethiopia (regional events), broader Africa
  (select partnerships).
- **Existing site for reference:** zucegroup.com (WordPress). This project replaces/extends it
  on the app.zucegroup.com subdomain.
- **Source documents:** `ZUCE GROUP - Corporate Profile 2026.pdf` (uploaded to this project) has
  the full division breakdown, process (Brief & Scoping -> Proposal & Plan -> Approvals &
  Contracting -> Production -> Delivery & Execution -> Reporting & Close), and sector examples —
  refer back to it for any public copy rather than inventing generic agency language.

### Brand assets

- **Logo files:** `D:\MegaColloSync\Zubre\ZuceGroup\Zuce Logo` (source), copied into
  `public/images/logo/` in this repo (black, full-color, and white-on-blue SVG variants).
- **Primary color:** `#10789f` (steel/teal blue)
- **Accent color:** `#5fcbed` (sky blue)
- Wordmark: "ZUCE" (bold condensed, with accent over the C) + "GROUP" (light weight, tracked out) beneath.

## 1. What we're building

A single web application with two faces:

- **Public site** — marketing pages reflecting ZUCE Group's actual identity as an events/PR/media/
  digital company (see section 0), not a generic corporate-services pitch.
- **Authenticated backend** — a suite of *internal* systems ZUCE Group's own team uses day to day,
  behind login:
  - CMS (pages & blog) — **build first**
  - HR Management
  - Finance & Accounting
  - CRM / Project Management
  - (room for more modules later)

## 2. Stack

- **Runtime:** Node.js + Express — chosen for cPanel LiteSpeed's Node hosting (lsnode.js) compatibility (single long-running Node process, no Docker/containers needed).
- **Database:** MySQL — native to virtually all cPanel hosts, accessed via Sequelize (ORM) for migrations/models across modules.
- **Views:** Server-rendered (EJS) for the public site and authenticated dashboard. Avoids a separate SPA build pipeline, which is friction-prone on shared hosting. Can revisit a React/SPA layer for specific modules later if needed.
- **Auth:** Session-based (express-session, MySQL session store) — simpler to operate on shared hosting than OAuth/JWT infra, and sufficient for an internal-tools use case. Passwords hashed with `bcryptjs` (pure JS, no native compilation) rather than `bcrypt`, since shared cPanel hosts don't reliably offer build tools for native Node modules.
- **Styling:** Tailwind CSS (compiled at build time, static output committed — no runtime build step needed on the server).

## 3. Why this stack for this host

Shared cPanel via LiteSpeed's Node hosting (lsnode.js) runs your app as one persistent Node process that cPanel restarts on deploy. That means:
- No background workers/queues without extra setup — keep things synchronous or use simple cron (cPanel supports cron jobs) for scheduled tasks.
- No custom ports/sockets — LiteSpeed's Node hosting (lsnode.js) handles the HTTP entry point.
- Environment variables set via cPanel's Node app UI, mirrored locally in `.env`.

## 4. High-level folder structure

```
zucegroup/
  app.js                 # LiteSpeed's Node hosting (lsnode.js) entry point
  package.json
  .env.example
  config/
    database.js          # Sequelize connection
    session.js
  src/
    modules/
      public-site/        # marketing pages, service offerings
      auth/                # login, session, user model
      cms/                 # pages & blog (Phase 1)
      hr/                  # Phase 2+
      finance/             # Phase 2+
      crm/                 # Phase 2+
    shared/
      middleware/
      views/layouts/
      utils/
  public/                 # compiled CSS/JS, static assets
  docs/
    PROJECT_SPEC.md        # this file
```

Each module owns its own routes, models, views, and controllers so modules can be built and reviewed independently without entangling the others.

## 5. Build phasing

1. **Foundation** — Express app skeleton, MySQL connection, session-based auth, base layout/nav, deployable "hello world" on app.zucegroup.com via LiteSpeed's Node hosting (lsnode.js).
2. **Public site** — service offering pages driven by the CMS (so content is editable from day one, not hardcoded).
3. **CMS module** — page builder + blog (create/edit/publish), admin UI for logged-in users.
4. **CRM / Project Management, HR, Finance & Accounting** — sequenced after CMS ships; order to be revisited once CMS is live.

## 6. Core data model (initial draft, will expand per module)

- `users` — id, name, email, password_hash, role, timestamps
- `sessions` — session store table (managed by session middleware)
- `pages` — id, slug, title, body, status (draft/published), author_id, timestamps
- `posts` (blog) — id, slug, title, body, excerpt, status, published_at, author_id, timestamps
- `roles` / `permissions` — simple role-based access (e.g. admin, editor, HR, finance, sales) so later modules can gate access without redesigning auth

## 7. Deployment notes (cPanel)

- **Server app root:** `/home/wemqjdto/app.zucegroup.com`
- App root set to the repo root; LiteSpeed's Node hosting (lsnode.js) points at `app.js`.
- Node version pinned via cPanel's Node selector to match `package.json` engines field.
- `.env` values (DB credentials, session secret) entered through cPanel's Node app environment variables UI — never committed.
- MySQL database + user created via cPanel's MySQL Databases tool; credentials wired into `.env`.

## 8. Deployment gotchas (learned the hard way — read before touching app.js or deployment)

- **Don't call `app.listen()` unconditionally.** LiteSpeed's Node hosting requires the entry file as a module and calls `.listen()` itself. Our own explicit call caused a recurring `"http.Server.listen() was called more than once"` crash loop, which in turn prevented the session-store table from ever finishing its auto-creation. Fix: `app.listen()` is now wrapped in `if (require.main === module)`, so it only runs for local dev (`node app.js`), never when LiteSpeed requires the file.
- **`app.set('trust proxy', 1)` is required.** LiteSpeed terminates HTTPS and forwards to Node over plain HTTP. Without trusting the proxy, Express thinks every request is insecure, and `express-session` silently drops `Set-Cookie` for secure cookies — no error, just an endless bounce back to `/login`. This is set near the top of `app.js`.
- **Use `DB_HOST=127.0.0.1`, not `localhost`.** Node/mysql2 resolves `localhost` to `::1` (IPv6) first, which this host's MySQL doesn't listen on, giving `ECONNREFUSED ::1:3306`.
- **Activating the Node virtualenv:** the server's `nodevenv` path is `/home/wemqjdto/nodevenv/app.zucegroup.com/18/bin/activate` (version folder confirmed as `18` on this host — check with `ls /home/wemqjdto/nodevenv/app.zucegroup.com/` if it ever changes). `npm`/`node` aren't on PATH outside this venv.
- **cPanel's own "Run NPM Install" button** (in Setup Node.js App) is more reliable than activating the venv by hand in a terminal — it's what actually got a clean install working when manual shell activation had path issues.
- **Terminal paste gotchas:** multi-line heredocs (`cat > file << 'EOF' ...`) can get flattened into one line by some terminal pastes, leaving the shell stuck waiting for a literal `EOF` line. Type `EOF` + Enter to escape, then use `nano file` instead for anything pasted — far less fragile.
- **Shell access must be explicitly enabled** by the host (Truehost) on top of SFTP access — the two are separate toggles. SSH connecting successfully but immediately closing with "Shell access is not enabled on your account" means only SFTP is on; contact host support.

## 9. Open questions to revisit

- Role/permission granularity once HR and Finance modules are scoped (those likely need stricter access control than CMS).
- Whether any module needs a richer frontend (React) beyond server-rendered EJS — defer until a concrete UI need arises.
