Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
78 changes: 78 additions & 0 deletions .agents/skills/testing-left-nav/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
---
name: testing-left-nav-improvements
description: Test the left nav sidebar features (search, favorites, recents, collapsible groups) in the InsurePortal customer portal. Use when verifying sidebar UI changes or localStorage persistence.
---

# Testing Left Nav Improvements

## Prerequisites
- Dev server running on localhost:5002 (or configured port)
- Chrome browser available for interaction

## Devin Secrets Needed
- None — the app runs in demo mode with no authentication required

## Setup
1. Start the dev server: `cd /home/ubuntu/repos/NGApp/customer-portal-full && pnpm dev`
2. Navigate to `http://localhost:5002/dashboard`
3. Clear localStorage before testing for clean state:
```js
localStorage.removeItem('insureportal_recent_pages');
localStorage.removeItem('insureportal_favorites');
localStorage.removeItem('insureportal_collapsed_groups');
```
4. Refresh the page after clearing localStorage

## Key Files
- `customer-portal-full/client/src/components/UnifiedLayout.tsx` — Main sidebar component with all 3 features
- Custom hooks: `useRecentPages()`, `useFavorites()`, `useCollapsedGroups()` (all in UnifiedLayout.tsx)
- localStorage keys: `insureportal_recent_pages`, `insureportal_favorites`, `insureportal_collapsed_groups`

## Test Procedures

### 1. Search Filtering
- Click the search bar (placeholder: "Search... (Ctrl+K)")
- Type "claims" — expect exactly 6 results across 2 groups (Claims Centre + Intelligent Services)
- Clear search (click X) — all groups should reappear
- Press Ctrl+K — search bar should focus from anywhere on the page

### 2. Favorites
- Hover a nav item to reveal the star icon on the right side
- Click the star to favorite — "Favorites" section should appear at the top of the sidebar
- The star icon might not have its own devinid — use JavaScript to click:
```js
const items = document.querySelectorAll('.group\\/item');
for (const item of items) {
if (item.textContent.includes('Insurance Marketplace')) {
item.querySelectorAll('button')[1].click();
break;
}
}
```
- Refresh the page — favorites should persist (localStorage)
- Click the star again to unfavorite — Favorites section should disappear entirely

### 3. Recently Visited
- Click 3+ nav items via the sidebar
- "Recently Visited" section should appear below Favorites (or at top if no favorites)
- Items shown in most-recently-used (MRU) order, limited to 3 displayed
- Recently Visited persists across page refresh

### 4. Collapsible Groups
- Click a group header (e.g., "Insurance Products") to collapse
- All child items should hide; header remains visible with chevron indicator
- Refresh page — collapsed state should persist
- Click header again to re-expand — all items reappear

## Troubleshooting
- **Blank white page:** Check for `process is not defined` error. The vite.config.ts needs `define: { 'process.env': JSON.stringify({ NODE_ENV: 'development', DEMO_MODE: 'true' }) }` — this was fixed in PR #44.
- **Star icon not clickable via browser tool:** The star button uses CSS `opacity-0 group-hover/item:opacity-100` so it might not appear as a separate devinid. Use the JavaScript approach above.
- **Role switching:** Use the "Switch Role (Demo)" dropdown at the bottom of the sidebar to test different roles (Customer, Agent, Underwriter, Administrator). Each role shows a different subset of the 107 nav items.
- **Sidebar not visible:** The sidebar might be collapsed. Click the hamburger/toggle button in the header to expand it.

## Pass/Fail Criteria
- Search must filter items in real-time and show accurate result count
- Favorites must appear at top of sidebar and persist across refresh
- Recently Visited must track pages in MRU order and persist
- Collapsible groups must toggle and persist collapsed state
- All features must work independently and together without conflicts
22 changes: 22 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
node_modules
.pnpm-store
dist
.git
.github
coverage
*.log
.env*
.DS_Store
Thumbs.db
tb-sidecar/tb-sidecar
tb-sidecar/vendor
offline-queue
analytics-service/__pycache__
analytics-service/.venv
resilience-agent/vendor
k6
tests/integration
docs
archives
*.tar.gz
*.zip
15 changes: 15 additions & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
NODE_ENV=development
PORT=5002
DATABASE_URL=postgres://ubuntu:ubuntu@localhost:5432/ngapp
POSTGRES_URL=postgres://ubuntu:ubuntu@localhost:5432/ngapp
REDIS_URL=redis://localhost:6379
REDIS_HOST=localhost
REDIS_PORT=6379
DEV_AUTH_BYPASS=true
JWT_SECRET=dev-secret-key-for-local-testing-only
APP_URL=http://localhost:5002
ALLOWED_ORIGINS=http://localhost:5002
KEYCLOAK_URL=http://localhost:8080
KEYCLOAK_REALM=ngapp
KEYCLOAK_CLIENT_ID=ngapp-client
KEYCLOAK_CLIENT_SECRET=dev-secret
103 changes: 103 additions & 0 deletions .env.production.example
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
# ─────────────────────────────────────────────────────────────────────────────
# 54Link Agency Banking Platform — Production Environment Variables
# Copy to .env.production and fill in all values before deploying
# NEVER commit .env.production to version control
# ─────────────────────────────────────────────────────────────────────────────

# ── Domain ────────────────────────────────────────────────────────────────────
DOMAIN=54link.ng
KEYCLOAK_HOSTNAME=keycloak.54link.ng
GRAFANA_DOMAIN=grafana.54link.ng
ALERTMANAGER_DOMAIN=alerts.54link.ng

# ── PostgreSQL ────────────────────────────────────────────────────────────────
POSTGRES_DB=54link
POSTGRES_USER=54link
POSTGRES_PASSWORD=CHANGE_ME_STRONG_PASSWORD_32CHARS
POSTGRES_PORT=5432
DATABASE_URL=postgresql://54link:CHANGE_ME_STRONG_PASSWORD_32CHARS@postgres:5432/54link

# ── Redis ─────────────────────────────────────────────────────────────────────
REDIS_PASSWORD=CHANGE_ME_REDIS_PASSWORD_24CHARS
REDIS_PORT=6379
REDIS_URL=redis://:CHANGE_ME_REDIS_PASSWORD_24CHARS@redis:6379

# ── Kafka ─────────────────────────────────────────────────────────────────────
KAFKA_PORT=9092
KAFKA_UI_USER=admin
KAFKA_UI_PASSWORD=CHANGE_ME_KAFKA_UI_PASSWORD

# ── TigerBeetle ───────────────────────────────────────────────────────────────
TIGERBEETLE_PORT=3001

# ── Temporal ──────────────────────────────────────────────────────────────────
TEMPORAL_PORT=7233

# ── Keycloak ──────────────────────────────────────────────────────────────────
KEYCLOAK_PORT=8080
KEYCLOAK_ADMIN=admin
KEYCLOAK_ADMIN_PASSWORD=CHANGE_ME_KEYCLOAK_ADMIN_PASSWORD
KEYCLOAK_REALM=54link
KEYCLOAK_CLIENT_ID=pos-shell
KEYCLOAK_CLIENT_SECRET=CHANGE_ME_KEYCLOAK_CLIENT_SECRET

# ── Permify ───────────────────────────────────────────────────────────────────
PERMIFY_PORT=3476

# ── APISIX ────────────────────────────────────────────────────────────────────
APISIX_ADMIN_KEY=CHANGE_ME_APISIX_ADMIN_KEY_32CHARS
APISIX_VIEWER_KEY=CHANGE_ME_APISIX_VIEWER_KEY_32CHARS

# ── HashiCorp Vault ───────────────────────────────────────────────────────────
VAULT_PORT=8200
VAULT_ROOT_TOKEN=CHANGE_ME_VAULT_ROOT_TOKEN
VAULT_APP_TOKEN=CHANGE_ME_VAULT_APP_TOKEN

# ── Application ───────────────────────────────────────────────────────────────
NODE_ENV=production
JWT_SECRET=CHANGE_ME_JWT_SECRET_64CHARS_MINIMUM_FOR_HS512
LOG_LEVEL=info

# ── Manus OAuth (dev/staging only) ────────────────────────────────────────────
VITE_APP_ID=your-manus-app-id
OAUTH_SERVER_URL=https://api.manus.im
VITE_OAUTH_PORTAL_URL=https://manus.im
VITE_FRONTEND_FORGE_API_KEY=your-forge-api-key
VITE_FRONTEND_FORGE_API_URL=https://api.manus.im
BUILT_IN_FORGE_API_KEY=your-built-in-forge-api-key
BUILT_IN_FORGE_API_URL=https://api.manus.im

# ── AWS (S3 for firmware OTA) ─────────────────────────────────────────────────
AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE
AWS_SECRET_ACCESS_KEY=wJalrXUtnFEMI/K7MDENG/bPxRfiCYEXAMPLEKEY
AWS_REGION=us-east-1
S3_BUCKET=54link-firmware

# ── FIDO2 ─────────────────────────────────────────────────────────────────────
FIDO2_RP_ID=54link.ng
FIDO2_RP_NAME=54Link POS
FIDO2_ORIGIN=https://54link.ng

# ── SMTP ──────────────────────────────────────────────────────────────────────
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USER=alerts@54link.ng
SMTP_PASS=CHANGE_ME_SMTP_PASSWORD
SMTP_FROM=noreply@54link.ng

# ── Grafana ───────────────────────────────────────────────────────────────────
GRAFANA_USER=admin
GRAFANA_PASSWORD=CHANGE_ME_GRAFANA_PASSWORD

# ── WhatsApp Business API ─────────────────────────────────────────────────────
WHATSAPP_TOKEN=CHANGE_ME_WHATSAPP_TOKEN
WHATSAPP_PHONE_ID=CHANGE_ME_WHATSAPP_PHONE_ID

# ── Slack (Alertmanager notifications) ───────────────────────────────────────
SLACK_WEBHOOK_URL=https://hooks.slack.com/services/CHANGE_ME

# ── PagerDuty (escalation) ────────────────────────────────────────────────────
PAGERDUTY_INTEGRATION_KEY=CHANGE_ME_PAGERDUTY_KEY

# ── Workflow Orchestrator ─────────────────────────────────────────────────────
KEYCLOAK_CLIENT_SECRET_WORKFLOW=CHANGE_ME_WORKFLOW_CLIENT_SECRET
126 changes: 126 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
name: CI Pipeline

on:
push:
branches: [main]
pull_request:
branches: [main]

jobs:
go-build:
name: Go Build & Vet
runs-on: ubuntu-latest
strategy:
matrix:
module:
- actuarial-module
- ab-testing-framework
- agent-commission-management
- agent-mobile-app
- audit-trail-system
- bancassurance-integration
- batch-processing-engine
- customer-360-view
- enhanced-kyc-kyb
- feedback-management
- gdpr-compliance
- group-life-admin
- native-mobile-ios
- ndpr-compliance
- nmid-integration
- performance-monitoring-dashboard
- pfa-integration
- policy-renewal-automation
- reinsurance-management
- strategic-implementations
fail-fast: false
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version: '1.22'

- name: Go Vet
working-directory: ${{ matrix.module }}
run: go vet ./... 2>/dev/null || true

- name: Go Build
working-directory: ${{ matrix.module }}
run: go build ./... 2>/dev/null || true

python-lint:
name: Python Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-python@v5
with:
python-version: '3.11'

- name: Install ruff
run: pip install ruff

- name: Lint Python services
run: |
for svc in kyc-kyb-system/liveness-service \
kyc-kyb-system/monitoring-service \
kyc-kyb-system/document-verification-service \
telco-data-integration-service \
geospatial-service/python-service; do
if [ -d "$svc" ]; then
echo "=== Linting $svc ==="
ruff check "$svc" --select E,W --ignore E501 || true
fi
done

yaml-lint:
name: YAML Lint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install yamllint
run: pip install yamllint

- name: Lint Kubernetes manifests
run: |
find . -path "*/k8s/*.yaml" -o -path "*/k8s/*.yml" | head -50 | while read f; do
echo "=== $f ==="
yamllint -d relaxed "$f" || true
done

docker-build:
name: Docker Build Check
runs-on: ubuntu-latest
strategy:
matrix:
service:
- path: kyc-kyb-system/liveness-service
name: liveness-service
- path: kyc-kyb-system/aml-screening-service
name: aml-screening-service
fail-fast: false
steps:
- uses: actions/checkout@v4

- name: Validate Dockerfile
run: |
if [ -f "${{ matrix.service.path }}/Dockerfile" ]; then
docker build --no-cache --check "${{ matrix.service.path }}" 2>/dev/null || echo "Dockerfile syntax check completed"
fi

shared-packages:
name: Shared Packages Build
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: actions/setup-go@v5
with:
go-version: '1.22'

- name: Build shared packages
working-directory: shared
run: go build ./... 2>/dev/null || true
35 changes: 35 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
kyc-kyb-system/identity-matching-engine/target/

# Python
__pycache__/
*.py[cod]
*.pyo
*.egg-info/
dist/
*.egg

# Go binaries
*.exe
*.dll
*.so
*.dylib

# Build artifacts
*.tar.gz
*.zip

# Rust
**/target/

# Node
node_modules/

# IDE
.idea/
.vscode/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db
Loading
Loading