# KC Systems — Rebuild Todo

> Stack: Next.js + MySQL | Payments: Stripe | Mail: Mailgun
> Logo: https://kcs.inleadsit.com/wp-content/uploads/2026/05/KC-System_dark-e1779440763671.png

---

## PHASE 1 — PLAN ✅

- [x] Define site architecture & page routes
- [x] Define database schema (users, subscriptions, products, journals, scholarships, jobs, tours)
- [x] Define API integrations (Jobs API: Adzuna, Scholarships: manual + CSV)
- [x] Define subscription tiers & pricing logic (Free / Registered / Journal RM49/mo / Job Seeker RM49/mo — Shop & Tours are free with signup)
- [x] Define user roles (Guest, Registered User, Journal Subscriber, Job Seeker, Admin)
- [x] Define mail flows (welcome, receipt, job apply, journal published, password reset, etc.)
- [x] Finalize project folder structure (Next.js App Router)
- [x] Set up .env config plan (DB, Stripe, Mailgun, Adzuna API keys)

> All details documented in `plan.md`

---

## PHASE 2 — DESIGN ✅

- [x] Design system: color palette, typography, spacing (modern minimal)
- [x] Design: Home page
- [x] Design: About page
- [x] Design: Shop (catalog + product detail + cart + checkout)
- [x] Design: Journals (listing + post view + write post)
- [x] Design: Scholarships (listing + detail)
- [x] Design: Jobs (listing + job detail + apply flow)
- [x] Design: Tours & Travel (listing + package detail + admin management)
- [x] Design: Login / Register pages
- [x] Design: Subscriber Dashboard
- [x] Design: Admin Dashboard (overview + products, journals, scholarships, jobs, subscriptions, settings)
- [x] Design: Shared components (navbar, footer, cards, modals, forms)
- [x] Mobile responsiveness review on all designs

---

## PHASE 3 — DEVELOPMENT

---

### 3.1 — Project Setup & Infrastructure
- [ ] Init Next.js project (App Router, TypeScript) — confirm folder structure
- [ ] Configure MySQL connection via Prisma (schema, client, migrations)
- [ ] Set up environment variables (.env.local — DB, Stripe, Mailgun, Adzuna, NextAuth secret)
- [ ] Set up NextAuth.js (credentials provider + session strategy)
- [ ] Set up Stripe SDK (server + client)
- [ ] Set up Mailgun SDK (transactional mail helper)
- [ ] Set up global middleware (auth guard, role-based route protection)
- [ ] Set up error boundary + global 404 / 500 pages

---

### 3.2 — Auth & User System
- [ ] DB migration: `users` table (roles: guest / registered / journal_subscriber / job_seeker / admin)
- [ ] Register: form → hash password (bcrypt) → save user → send welcome email (Mailgun)
- [ ] Login: credentials → NextAuth session → JWT/cookie
- [ ] Logout + session expiry handling
- [ ] Email verification flow (token → verify → activate account)
- [ ] Password reset flow (request → email link → reset)
- [ ] Role-based access control middleware (check role + active subscription per route)
- [ ] User profile page (view + edit basic info, change password)
- [ ] User dashboard: show active subscriptions, quick links to subscribed modules

---

### 3.3 — Subscription & Package Management System (Stripe)

> **Revised Architecture (June 2026)**
>
> **Two subscription plans — both $49 USD/month recurring via Stripe.**
> Users can hold one or both simultaneously. Access is checked via active subscription module, not user role.
>
> | Plan | Module slug | Access unlocks | Currency |
> |---|---|---|---|
> | **Academician** | `academician` | Journals (read full + write), Scholarships (full detail + apply) | USD + NGN |
> | **Job Seeker** | `job_seeker` | Apply for jobs, job seeker profile, resume builder | USD + NGN |
>
> **Free with registration only (no subscription):**
> Shop (browse + buy), Tours (enquire + book), Visa (enquiry form), public listing pages (jobs/journals/scholarships titles visible to all)
>
> **Currencies supported:** USD & Nigerian Naira (NGN) — user selects at checkout, Stripe handles both
>
> **Access control:** Proxy middleware reads `modules[]` from JWT — fast, no DB hit per request.
> JWT updated on login and on subscription webhook event.

#### Stripe Configuration — Live & Sandbox Mode
- [ ] `SiteSetting` key-value entries (stored in DB, editable by super admin):
  - `stripe_mode` = `"sandbox"` | `"live"`
  - `stripe_live_secret_key`, `stripe_live_publishable_key`, `stripe_live_webhook_secret`
  - `stripe_sandbox_secret_key`, `stripe_sandbox_publishable_key`, `stripe_sandbox_webhook_secret`
- [ ] System reads active mode from DB on every Stripe call (no server restart needed)
- [ ] **Sandbox banner**: when `stripe_mode = "sandbox"`, show a persistent yellow warning bar on ALL pages (public + admin)
- [ ] Admin: Stripe settings section in `/admin/settings` — input all 6 keys + Live/Sandbox toggle, save to DB
- [ ] On save: instantly switches mode — no `.env` changes needed

#### Stripe Setup (admin does this inside admin panel)
- [ ] Admin creates Stripe products manually in Stripe Dashboard (test + live)
- [ ] Admin copies price IDs into package edit form in `/admin/subscriptions/packages`
- [ ] Each package stores 4 price IDs: `stripePriceIdUsdLive`, `stripePriceIdNgnLive`, `stripePriceIdUsdSandbox`, `stripePriceIdNgnSandbox`
- [ ] Webhook endpoint: `https://kc.inleads-it.com.my/api/webhooks/stripe`
  - Events: `checkout.session.completed`, `invoice.paid`, `customer.subscription.deleted`, `customer.subscription.updated`

#### Currency
- [ ] Each Stripe plan has two Prices: USD ($49) and NGN (₦ — follows Stripe's live rate, admin sets the NGN price value in Stripe and pastes the price ID)
- [ ] `/subscribe` page has USD / NGN toggle — user picks currency → checkout uses matching price ID
- [ ] No hardcoded exchange rate — admin controls NGN price by updating it in Stripe + pasting price ID in admin panel

#### DB Schema Changes
- [ ] `subscription_packages`: remove `stripePriceId`, add:
  - `stripePriceIdUsdLive`, `stripePriceIdNgnLive`
  - `stripePriceIdUsdSandbox`, `stripePriceIdNgnSandbox`
- [ ] Seed two packages: **Academician** (module=`academician`) + **Job Seeker** (module=`job_seeker`) — price IDs blank until admin fills via admin panel
- [ ] `subscriptions`: add `currency` column (`usd` | `ngn`) to track which currency was used

#### JWT Enhancement (Auth)
- [ ] Add `modules: string[]` to JWT payload (e.g. `["academician"]` or `["academician","job_seeker"]`)
- [ ] Populate `modules` from active subscriptions (status=`active`) on login
- [ ] Extend `types/next-auth.d.ts` to include `modules` on session + JWT
- [ ] Proxy reads `token.modules` to guard routes — no DB call per request

#### Route Access Map (Proxy rules)
- `/journal/[slug]`, `/journal/new` → require `modules.includes("academician")`
- `/scholarships/[id]` → require `modules.includes("academician")`
- `/jobs/[id]/apply` → require `modules.includes("job_seeker")`
- `/dashboard/**` → any authenticated user
- `/shop/**`, `/tours/**`, `/visa/**`, `/jobs`, `/scholarships`, `/journal` (listing) → any registered user
- `/admin/**` → `role === "admin"` only
- Public listing pages (jobs, journals, scholarships titles) → no auth required

#### Subscribe Page & Checkout Flow
- [ ] Public `/subscribe` page: two plan cards (Academician + Job Seeker) with USD/NGN toggle
- [ ] User must be logged in to subscribe (redirect to login if not)
- [ ] Already-subscribed badge shown on active plan card
- [ ] "Subscribe" button → `POST /api/checkout` with `{ packageId, currency }` → create Stripe Checkout Session → redirect
- [ ] Stripe success URL: `/dashboard?subscribed=1`
- [ ] Stripe cancel URL: `/subscribe`

#### Stripe Webhook Handler (`/api/webhooks/stripe`)
- [ ] `checkout.session.completed` → upsert `subscriptions` row, set status=`active`
- [ ] `invoice.paid` → extend `currentPeriodEnd`
- [ ] `customer.subscription.deleted` → set status=`cancelled`
- [ ] `customer.subscription.updated` → sync status + period dates

#### Cancel & Manage
- [ ] Dashboard: "Manage" button → `GET /api/portal` → Stripe Customer Portal → redirect
- [ ] Stripe Customer Portal handles cancel, payment update, invoice history
- [ ] On cancel: webhook → DB updated, module removed from JWT on next login

#### Admin: Subscription Management
- [ ] Admin `/admin/subscriptions`: tabs — **Subscribers** list (user, plan, currency, status, renewal, Stripe link) + **Packages** list (edit plans)
- [ ] Admin: Package CRUD — create/edit/delete package (name, module, price USD, price NGN, all 4 Stripe price IDs, features list, active toggle)
- [ ] Admin: Subscriber detail — view user, plan, status; manual cancel button
- [ ] Admin: export subscribers to CSV

---

### 3.4 — E-Commerce (Shop) ✅ SHOP STOREFRONT COMPLETE

> Design is complete. All frontend pages must render data from DB/API — no hardcoded content.
> **Database seeded with 12 products, 5 categories, 3 shop slides, 4 featured products**

#### Product Management (Admin)
- [x] DB migrations: `products`, `product_variations`, `product_images`, `product_categories`, `shop_slides` tables
- [x] DB seed: 12 sample products with images (Electronics, Books, Fashion, Home & Living, Accessories)
- [x] DB seed: 5 product categories
- [x] DB seed: 3 homepage shop slides with images
- [x] Featured products functionality (4 products flagged as featured)
- [ ] Admin: create / edit / delete product (name, slug, description, price, stock, category, status)
- [ ] Admin: manage product variations (size, colour, SKU, stock per variant, price override)
- [ ] Admin: product image upload (multiple images, reorder, set primary image)
- [ ] Admin: set featured products (flag → feeds homepage featured section)
- [ ] Admin: manage homepage shop slider (add/remove/reorder slides, each with image, title, CTA link)
- [ ] Admin: product categories CRUD (name, slug, parent category for nested)
- [ ] Admin: product preview (view as it appears on storefront)

#### Storefront (design preserved — data from DB) ✅
- [x] Shop catalog page: list products with filters (category, price range, search) — fully functional at `/shop`
- [x] Category filter navigation (5 categories: All, Electronics, Books, Fashion, Home & Living, Accessories)
- [x] Search functionality for products
- [x] Featured products section (displays 4 featured products in special grid)
- [x] Product cards with image, name, category, price, featured badge
- [x] Empty state handling ("No products found")
- [x] Homepage shop slider component (ShopSlider.tsx) — renders 3 active slides from DB
- [ ] Product detail page: gallery (from `product_images`), variations selector (from `product_variations`), add to cart
- [ ] Featured products on home page (pull `is_featured = true` from DB)

#### Cart & Checkout
- [ ] Cart: add / remove / update quantity (localStorage + server sync for logged-in users)
- [ ] Cart page: summary, totals, proceed to checkout
- [ ] Checkout page: shipping details form + Stripe Payment Intent
- [ ] Order confirmation page + confirmation email (Mailgun)
- [ ] DB migrations: `orders`, `order_items` tables
- [ ] Guest checkout support (email stored on order)

#### Buyer CRM (Admin)
- [ ] Admin: orders list (filter by status, date, customer)
- [ ] Admin: order detail view (items, buyer info, shipping address, payment status)
- [ ] Admin: update order status (pending → paid → shipped → completed)
- [ ] Admin: buyer list (registered customers who have placed orders)
- [ ] Admin: buyer profile view (contact info, order history, total spend)
- [ ] Admin: issue refund via Stripe from order detail

---

### 3.5 — Journals

> Design is complete. All frontend pages must render data from DB — no hardcoded content.
> **Academician plan ($49 USD/mo)** required to read full content and write posts. Listing titles are public.

#### Journal Features
- [ ] DB migration: `journals`, `journal_categories` tables
- [ ] Journal listing page: published posts, pagination, search, category filter — **public can see listing titles, content locked behind subscription**
- [ ] Journal post view page: full content, author, published date — **Journal Subscriber only**
- [ ] Write journal post: rich text editor (TipTap or similar), draft / publish — **Journal Subscriber only**
- [ ] Edit / delete own journal post
- [ ] Auto-generate slug from title
- [ ] Journal categories (admin managed, feeds filter on listing page)

#### Journal CRM (Admin)
- [ ] Admin: all journals list (filter by status: draft / published / flagged)
- [ ] Admin: moderate journal (approve, flag, unpublish, delete)
- [ ] Admin: journal user list (all subscribers who have posted)
- [ ] Admin: subscriber CRM — view subscriber profile, subscription status, journal activity
- [ ] Admin: send notification email to subscriber (Mailgun)
- [ ] Notify author via email when post is published / flagged (Mailgun)

---

### 3.6 — Scholarships

#### Scholarships Features
- [ ] DB migration: `scholarships` table
- [ ] Scholarships listing page: list all active scholarships, filter by country / deadline / amount
- [ ] Scholarship detail page: full info + external apply link
- [ ] API integration: connect to scholarship data source (manual CSV import or external API)
- [ ] CSV import tool for bulk scholarship upload (admin)

#### Scholarships Admin
- [ ] Admin: create / edit / delete scholarship (manual entry)
- [ ] Admin: bulk import scholarships via CSV
- [ ] Admin: toggle active / inactive per scholarship
- [ ] Admin: API sync scheduler (cron or manual trigger to pull latest scholarships)

---

### 3.7 — Jobs Portal

> Design is complete. All frontend pages must render data from DB/API — no hardcoded content.
> **Job Seeker plan ($49 USD/mo)** required to apply. Listing and job detail are public.

#### Job Loading & Display (Public)
- [ ] DB migrations: `jobs`, `job_seekers`, `job_applications` tables
- [ ] Adzuna API integration: fetch jobs, store in DB, auto-refresh (cron / scheduled)
- [ ] Jobs listing page: search, filter by type / location / salary — **public**
- [ ] Job detail page: full description, company info, apply button — **public view, apply requires Job Seeker plan**
- [ ] Featured jobs: admin can flag jobs as featured (shown prominently on listing + home)

#### Job Seeker Client Portal (Subscription-based)
- [ ] Sign-up flow: register (free) → subscribe to Job Seeker plan (RM49/mo) → Stripe checkout → portal unlocked
- [ ] Job seeker profile: full name, phone, skills, experience, education
- [ ] Resume builder: fill structured form → generates resume stored in DB + downloadable PDF
- [ ] Resume file upload (alternate path — upload PDF directly)
- [ ] Apply for job: cover letter + attach resume → save application to DB
- [ ] My applications page: list of applied jobs with status (submitted / viewed / shortlisted / rejected)
- [ ] Application status update email when admin changes status (Mailgun)

#### Jobs Super Admin
- [ ] Admin: jobs list (all synced jobs, filter by source / type / location / featured)
- [ ] Admin: manual job creation / edit / delete
- [ ] Admin: trigger API sync manually (refresh jobs from Adzuna)
- [ ] Admin: set / unset featured job
- [ ] Admin: applications list (all applications across all jobs)
- [ ] Admin: application detail (seeker info, resume view/download, cover letter, job info)
- [ ] Admin: update application status (submitted → viewed → shortlisted → rejected)
- [ ] Admin: job seeker CRM — list all job seekers, view profile, resume, applications history
- [ ] Admin: subscription management for job seekers (status, renewal, cancel)
- [ ] Admin: export job seekers / applications to CSV

---

### 3.8 — Tours & Travels

> Design is complete. All frontend pages must render data from DB — no hardcoded content.
> No subscription required — free registered account can book / enquire.

#### Tour Packages (Admin Managed)
- [ ] DB migrations: `tour_packages`, `tour_categories`, `tour_images`, `tour_bookings` tables
- [ ] Admin: create / edit / delete tour package (title, slug, description, destination, duration, price per pax, min/max pax, inclusions, exclusions, itinerary)
- [ ] Admin: tour image upload (multiple images, reorder, set primary)
- [ ] Admin: set featured packages (flag → feeds homepage featured section + tours listing top)
- [ ] Admin: manage homepage tour slider (add/remove/reorder banner slides with image, title, subtitle, CTA link)
- [ ] Admin: tour categories CRUD (adventure, family, luxury, honeymoon, etc.)
- [ ] Admin: package preview (view as it appears on storefront)
- [ ] Admin: enable / disable package (active/inactive)

#### Tours Storefront (design preserved — data from DB)
- [ ] Tours listing page: all active packages, filter by destination / category / duration / price range
- [ ] Tour package detail page: image gallery, itinerary, pricing, inclusions/exclusions, book now CTA — data from DB
- [ ] Featured tours on home page (pull `is_featured = true` from DB)
- [ ] Homepage tours slider (pull active slides from DB)
- [ ] Tour booking / enquiry form (name, email, phone, date, pax, message) → save to DB + notify admin via email (Mailgun)

#### Tours CRM (Admin)
- [ ] Admin: bookings / enquiries list (filter by package, date, status)
- [ ] Admin: booking detail (customer info, package, date, pax, notes)
- [ ] Admin: update booking status (enquiry → confirmed → completed / cancelled)
- [ ] Admin: tour customer CRM — list all tour enquirers / bookers
- [ ] Admin: customer profile view (contact, bookings history)
- [ ] Admin: send confirmation / follow-up email to customer (Mailgun)
- [ ] Admin: export bookings to CSV

---

### 3.9 — Admin Dashboard (Global)
- [ ] Admin overview: KPI cards — total orders, revenue, active journal subscribers, active job seekers, tour bookings, total registered users
- [ ] Admin: recent activity feed (latest orders, applications, journal posts, tour enquiries)
- [ ] Admin: manage all users (list, search, view profile, change role, suspend / reactivate account)
- [ ] Admin: global subscription CRM (all subscribers across all plans — plan, status, renewal date, Stripe link)

#### Package Management (Super Admin Only)
- [ ] Admin: list all subscription packages (name, module, price, billing period, active status)
- [ ] Admin: create new subscription package (name, module, description, price, billing period, feature list, Stripe price ID)
- [ ] Admin: edit existing package (updates reflected on subscribe page immediately)
- [ ] Admin: enable / disable package (hides from public subscribe page)
- [ ] Admin: delete package (only if no active subscribers)
- [ ] Admin: annual billing toggle per package + discount %
- [ ] Package changes auto-sync to Stripe on save

#### Site Settings (Super Admin Only)
- [ ] Admin: general settings (site name, tagline, logo upload, contact email, phone, address)
- [ ] Admin: social links (Facebook, Instagram, LinkedIn, Twitter/X)
- [ ] Admin: API keys / integration config (Stripe publishable + secret, Mailgun domain + key, Adzuna app ID + key, **OpenAI API key**)
- [ ] Admin: **WhatsApp floating button** — editable phone number (default: +60188721718), enable/disable toggle
- [ ] Admin: homepage sliders overview (quick links to shop slider, tours slider management)
- [ ] Admin: manage admin accounts (add / remove / edit admin users)

---

### 3.10 — WhatsApp Floating Widget ✅

- [x] Floating WhatsApp button component (bottom-right, fixed position) — visible on all public pages
- [x] Button opens `https://wa.me/{number}` in new tab
- [x] Component reads number from `NEXT_PUBLIC_WHATSAPP_NUMBER` env var — default: +60188721718
- [x] Hide button on admin panel pages (PublicShell guard)
- [ ] DB: store WhatsApp number + enable/disable flag in `site_settings` table (Phase 3.9 — pending DB setup)
- [ ] Admin: WhatsApp settings in Site Settings page (editable number, enable/disable toggle)

---

### 3.11 — AI Chat System (OpenAI) ✅

> ⚠️ Store OpenAI API key in `.env.local` only. Never hardcode. Set `OPENAI_API_KEY` before running.

#### Database (pending DB setup in Phase 3.1)
- [ ] DB migration: `chat_faqs` table (id, question, answer, category, source, is_active, created_at)
- [ ] DB migration: `chat_sessions` table (id, session_token, visitor_name, visitor_email, started_at)
- [ ] DB migration: `chat_messages` table (id, session_id, role ENUM('user','assistant'), content, created_at)
- [ ] DB migration: `chat_leads` table — migrate from JSON file to DB

#### FAQ / Knowledge Base (Admin — pending DB)
- [ ] Admin: FAQ management — list, create, edit, delete FAQ entries (question + answer + category)
- [ ] Admin: bulk FAQ import via CSV
- [ ] Admin: "Crawl & Learn" tool — scrape own pages → auto-generate FAQs via OpenAI → review before publish
- [ ] Active FAQs injected as system context into every chat session

#### Chat Widget (Frontend) ✅
- [x] Floating chat bubble (bottom-right, above WhatsApp button) — all public pages
- [x] Chat panel opens as slide-up with header, messages area, input
- [x] Opening greeting from AI (streaming response)
- [x] After 2nd user message: lead capture form slides in (name + email)
- [x] Name + email saved to `/data/chat-leads.json` via `POST /api/chat/lead`
- [x] AI chat uses OpenAI GPT API (`gpt-4o-mini` default) with KC Systems system prompt
- [x] Streaming responses (typewriter effect via ReadableStream)
- [x] Chat history persisted in sessionStorage
- [x] Hidden on admin panel pages

#### Chat API ✅
- [x] `POST /api/chat` — stream message via OpenAI with system prompt
- [x] `POST /api/chat/lead` — save visitor name + email
- [x] `GET /api/chat/lead` — list all leads (for admin)
- [x] `PATCH /api/chat/lead` — mark lead as contacted

#### Chat CRM (Admin) ✅
- [x] Admin: `/admin/chat` — Chat Leads list (name, email, date, contacted status)
- [x] Admin: mailto link per lead
- [ ] Admin: mark as contacted UI (requires client-side action handler — next iteration)
- [ ] Admin: export chat leads to CSV

#### Admin Settings (pending DB)
- [ ] Admin: OpenAI API key field in Site Settings (currently via `.env.local`)
- [ ] Admin: chat widget enable/disable toggle
- [ ] Admin: AI persona name + greeting message editable
- [ ] Admin: model selector (gpt-4o / gpt-4o-mini / gpt-3.5-turbo)

---

### 3.13 — Visa Assistance

> Design is complete (visa page live). Enquiry-based — no subscription required. Free registered or guest users can submit enquiries.

#### Visa Features (Public)
- [ ] DB migration: `visa_enquiries` table (id, name, email, phone, visa_type, destination, message, status ENUM('new','in_progress','resolved'), created_at)
- [ ] Visa enquiry form: submit → save to DB + send confirmation email to user + notify admin (Mailgun)
- [ ] Visa types display: data-driven (from DB or config) — student, work, tourist, business, dependent, PR, transit, religious
- [ ] Homepage / public visa page: fully data-driven (no hardcoded content for slides, stats, visa types)

#### Visa Slider (Admin Managed)
- [ ] DB migration: `visa_slides` table (id, image_url, title, subtitle, cta_text, cta_link, sort_order, is_active)
- [ ] Admin: manage visa slider (add/remove/reorder slides with image, title, CTA)
- [ ] Frontend: visa slider pulls active slides from DB

#### Visa CRM (Admin)
- [ ] Admin: `/admin/visa` — visa enquiries list (filter by status, visa type, date)
- [ ] Admin: enquiry detail view (name, email, phone, visa type, destination, message, submitted date)
- [ ] Admin: update enquiry status (new → in_progress → resolved)
- [ ] Admin: reply via email (Mailgun) directly from detail view
- [ ] Admin: export enquiries to CSV

---

### 3.12 — Final & Launch
- [ ] SEO metadata on all public pages (title, description, OG tags)
- [ ] Sitemap generation (`/sitemap.xml`)
- [ ] robots.txt
- [ ] Image optimisation (Next.js `<Image>`, WebP, lazy load)
- [ ] Performance audit (Lighthouse — target 90+ on all pages)
- [ ] Security audit: input validation, CSRF protection, rate limiting on auth + API routes, SQL injection guard (Prisma), XSS protection
- [ ] Error monitoring setup (Sentry or similar)
- [ ] Deploy to production server (PM2 / Docker / Vercel)
- [ ] Configure production environment variables
- [ ] DNS / domain verification (kc.inleads-it.com.my)
- [ ] SSL certificate check
- [ ] Smoke test all flows end-to-end (register → subscribe → buy → apply → book → admin)

---

## CURRENT STATUS

> ✅ Phase 1 — COMPLETE
> ✅ Phase 2 — COMPLETE (all pages built, mobile responsive, build passes with 0 errors) — June 1, 2026
> 🔨 Phase 3 — Development — IN PROGRESS
> ✅ 3.10 WhatsApp Floating Widget — DONE
> ✅ 3.11 AI Chat System — DONE (core complete; DB migration + admin settings pending Phase 3.1)
> 📋 3.13 Visa Assistance — ADDED (design live, development pending Phase 3.1 DB setup)
