A Graph-Powered Career Planning Platform and Skill Dependency Engine Built for WEXA AI's CognoDB Take-Home Assignment.
- 🚀 Live Web Application: https://skill-path-sumeet17.vercel.app
- 🎥 Video Demo Walkthrough: Watch on Google Drive
- 💻 GitHub Repository: https://github.com/Sumeet2005/SkillPath
- 🔌 Production Backend API: https://skillpath-as6n.onrender.com
- 🩺 API Health Check: https://skillpath-as6n.onrender.com/api/health
- Quick Snapshot
- Overview
- The Problem
- Why a Graph Database?
- Graph Data Model
- Dataset & Seeding
- System Architecture
- End-to-End Application Flow
- Main Application Features
- Product Walkthrough & Screenshots
- Important Cypher Queries
- Multi-Hop Graph Traversal
- Relationally Awkward Query
- Parameterized Cypher & Driver Security
- CognoDB Setup & Configuration
- Environment Variables & Security
- Error Handling & Resilience
- Getting Started & Local Development
- Project Directory Structure
- WEXA Requirement Coverage Checklist
- Submission Information
- License
| Category | Component / Metric | Details |
|---|---|---|
| Graph Database | CognoDB / Neo4j | Connected via official neo4j-driver (^6.2.0) over secure Bolt protocol (bolt+s://). |
| Query Engine | openCypher | 100% Parameterized Cypher queries ($targetJob, $currentSkills, $skill). Zero string concatenation. |
| Backend Stack | Node.js + Express.js | Clean 3-tier architecture (Route Controllers → Business Services → Parameterized Queries). |
| Frontend Stack | React 18 + Vite | SPA with custom CSS Grid/Flexbox design tokens and 12 reusable atomic UI primitives. |
| 3D Visualization | Three.js / WebGL | Code-split WebGL 3D network graph stage with camera orbit controls and Node Inspector. |
| Seed Dataset | 15 Jobs, 41 Skills, 28 Courses | 170+ relationship edges: 34 prerequisite edges, 98 requirement edges, 38 teaching edges. |
| Hosted Environments | Vercel + Render + CognoDB | Frontend SPA on Vercel, REST API on Render, Graph Storage on CognoDB Cloud. |
SkillPath is an AI career skill intelligence and roadmap platform that helps software developers navigate non-linear technical career paths.
Instead of treating software development skills as flat, static lists, SkillPath models technical careers, skills, prerequisites, and learning resources as a native Directed Graph Network. A user selects a target engineering role (e.g., Generative AI Engineer, Backend Developer, DevOps Engineer) and inputs their currently mastered technical skills.
SkillPath queries a live CognoDB / Neo4j Graph Database using parameterized Cypher traversals to:
- Calculate a real-time Career Readiness Match Percentage.
- Identify missing prerequisite skills through variable-length shortest-path traversals (
shortestPath()). - Generate a sequenced, step-by-step Prerequisite Learning Roadmap with total estimated study hours.
- Recommend curated educational courses mapped directly to missing target and prerequisite skills.
- Render an interactive 3D WebGL Knowledge Network visualizer.
Navigating software developer career growth is complicated by complex, interdependent skill dependencies. Beginners and experienced engineers alike face critical questions that static learning platforms fail to answer:
- Unseen Prerequisite Dependencies: "I want to become a Generative AI Engineer, but what foundational machine learning and mathematics skills do I need before learning RAG or Vector Databases?"
- Optimal Learning Order: "Which missing skill should I learn first to unlock the most downstream capabilities?"
- Prerequisite Isolation: "Does Backend Development require HTML/CSS, or are backend dependencies strictly isolated to server-side frameworks and databases?"
- Targeted Resource Mapping: "Which specific educational courses directly teach the exact missing prerequisite skills in my learning chain?"
In a traditional relational database (SQL), answering these questions requires recursive joins, recursive Common Table Expressions (CTEs), and pulling raw data into application memory for manual traversal. SkillPath solves this problem by leveraging native graph storage in CognoDB.
Graph databases earn their place when the primary value of an application lies in the relationships between data entities rather than isolated records.
In SkillPath, career intelligence is defined by three interconnected entities and their directed relationships:
(:Job) ───[:REQUIRES]────────► (:Skill)
(:Skill) ───[:PREREQUISITE_OF]──► (:Skill)
(:Course) ───[:TEACHES]─────────► (:Skill)
- Direct Requirement Lookup: Which technical skills are explicitly required for a target job role?
- Variable-Length Prerequisite Traversal: What multi-hop prerequisite chain connects a user's known skills to a missing target skill?
- Course Coverage Mapping: Which courses directly teach missing target or prerequisite skills?
Note
Graph databases are not inherently "faster for everything" than relational databases. However, for multi-hop relationship traversals and recursive dependency chains, graph storage provides a far more expressive, maintainable, and index-free adjacency traversal mechanism.
| Feature / Aspect | Relational Database (SQL) | Native Graph Database (CognoDB / Neo4j) |
|---|---|---|
| Prerequisite Representation | Foreign keys or join tables (skill_prerequisites) requiring recursive CTEs (WITH RECURSIVE). |
Native directed relationship (:Skill)-[:PREREQUISITE_OF]->(:Skill) with index-free adjacency. |
| Multi-Hop Traversal | Deeply nested self-joins; query complexity and execution time increase with path depth. | Expressed natively via variable-length Cypher pattern matching (-[:PREREQUISITE_OF*1..10]->). |
| Shortest Path Search | Requires pulling raw adjacency lists into Node.js application memory to execute Dijkstra's algorithm. | Executed natively inside graph database memory via built-in openCypher shortestPath() function. |
| Schema Flexibility | Adding new relationship types requires ALTER TABLE statements and migration scripts. |
Schema-flexible; adding new relationship types (e.g., :RECOMMENDS, :CERTIFIES) is non-breaking. |
The database schema models software engineering careers as a Directed Acyclic Graph (DAG):
graph TD
Job["(:Job {title: 'Generative AI Engineer'})"] -->|:REQUIRES| TargetSkill["(:Skill {name: 'LLM Fundamentals'})"]
BaseSkill["(:Skill {name: 'Python'})"] -->|:PREREQUISITE_OF| TargetSkill
Course["(:Course {name: 'LLM Engineering'})"] -->|:TEACHES| TargetSkill
| Node Label | Key Properties | Description |
|---|---|---|
:Job |
title (Unique Constraint), level, industry |
Software engineering career roles (e.g., Backend Developer, Generative AI Engineer). |
:Skill |
name (Unique Constraint), category, level |
Technical skills across 7 categories (e.g., Python, React, Docker, SQL). |
:Course |
name (Unique Constraint), provider, level, duration_hours |
Educational learning courses mapped to technical skills. |
:Certification |
name (Unique Constraint) |
Professional certification nodes. |
| Relationship Type | Direction | Description |
|---|---|---|
:REQUIRES |
(:Job)-[:REQUIRES]->(:Skill) |
Maps a career role to its required technical skills. |
:PREREQUISITE_OF |
(:Skill)-[:PREREQUISITE_OF]->(:Skill) |
Maps a foundational prerequisite skill to a downstream dependent skill. |
:TEACHES |
(:Course)-[:TEACHES]->(:Skill) |
Maps an educational course to the specific skill it teaches. |
The database is populated using idempotent MERGE Cypher statements defined in scripts/seed.cypher and executed by scripts/seed-db.js.
┌─────────────────────────────────────────────────────────────┐
│ SkillPath Database Counts │
├──────────────────────────────┬──────────────────────────────┤
│ Jobs (:Job) │ 15 Software Engineering Roles│
│ Skills (:Skill) │ 41 Technical Skills (7 Cats) │
│ Courses (:Course) │ 28 Mapped Learning Courses │
│ Prerequisite Edges │ 34 PREREQUISITE_OF Edges │
│ Requirement Edges │ 98 REQUIRES Edges │
│ Teaching Edges │ 38 TEACHES Edges │
└──────────────────────────────┴──────────────────────────────┘
- 15 Software Engineering Roles: Generative AI Engineer, Backend Developer, Frontend Developer, Full Stack Developer, DevOps Engineer, Data Analyst, Machine Learning Engineer, Cloud Architect, RAG Engineer, Cybersecurity Engineer, Database Administrator, Mobile Developer, QA Automation Engineer, Security Engineer, Data Engineer.
- 41 Technical Skills: Grouped into 7 categories (Programming, Web Development, Data, AI/ML, Developer Tools, DevOps, Security).
- 28 Mapped Courses: Complete with duration, provider (Coursera, Udemy, edX), and difficulty level.
SkillPath implements a clean 3-tier architecture separating presentation, REST API business logic, and native graph storage:
graph TB
subgraph Presentation Layer
FE["React 18 + Vite SPA"]
TG["Three.js 3D WebGL Graph Stage"]
end
subgraph Backend API Layer
EX["Express.js Server"]
RT["Routes /controllers"]
SV["Services Layer"]
QP["Parameterized Cypher Queries"]
end
subgraph Storage Layer
DRV["Official neo4j-driver ^6.2.0"]
CDB[("CognoDB / Neo4j Graph Database")]
end
FE -->|HTTP / REST API| EX
TG -->|Read State| FE
EX --> RT
RT --> SV
SV --> QP
QP -->|Bolt Protocol bolt+s://| DRV
DRV --> CDB
Browser
│
│ HTTPS / REST
▼
Render API
│
│ Parameterized Cypher
▼
CognoDB / Neo4j
The frontend does not connect directly to the graph database. Database credentials remain server-side in the backend environment.
sequenceDiagram
autonumber
actor User
participant FE as React Frontend
participant BE as Express Backend API
participant DB as CognoDB (Neo4j)
User->>FE: Select Target Career & Mastered Skills
FE->>FE: Calculate Client Readiness Match %
User->>FE: Click "Build My Learning Path"
FE->>BE: POST /api/path { targetJob, currentSkills }
BE->>BE: Sanitize & Validate Inputs
BE->>DB: session.run(FIND_LEARNING_PATH, { targetJob, currentSkills })
DB->>DB: Traverse REQUIRES & shortestPath(PREREQUISITE_OF*1..10)
DB-->>BE: Return Target Skills, Hops, Chains & Courses
BE->>BE: Calculate Readiness Score & Format JSON Payload
BE-->>FE: HTTP 200 OK { success: true, readinessScore, path: [...] }
FE->>User: Render Sequenced Learning Roadmap & 3D Knowledge Graph
| Feature | Description | Implementation Details |
|---|---|---|
| Career Planner | 3-step interactive career planning workspace | Allows job selection, category skill toggling, and live readiness match percentage calculation. |
| Learning Roadmap | Sequenced prerequisite timeline | Renders step-by-step prerequisite chains, hop counts, estimated duration hours, and course cards. |
| 3D Knowledge Graph | Interactive WebGL network graph stage | Three.js visualizer with emissive category colors, curved relationship edges, camera controls, and Node Inspector. |
| Career Explorer | Directory of software engineering roles | Searchable grid of 15 engineering roles with level filters, required skill chips, and planning CTA links. |
| Skill Explorer | Directory of technical skills | Searchable grid of 41 skills across 7 categories with mastered state toggling and roadmap generation. |
| Course Library | Mapped educational course directory | Displays 28 learning courses derived from (:Course)-[:TEACHES]->(:Skill) graph relationships. |
| Dashboard Command Center | System metrics & telemetry overview | Real-time CognoDB connection indicator, active job metrics, readiness gauge, and quick-start links. |
The repository includes an eight-screen product walkthrough under ScreenShots/.
1. Landing Page Overview — Expand
What it demonstrates: Product positioning, CognoDB connection status, primary navigation, and entry points into the SkillPath experience.
2. Dashboard Command Center — Expand
What it demonstrates: System overview, career readiness entry point, graph preview, and production database connection state.
3. Career Planner Workspace — Expand
What it demonstrates: Target-career selection and the user's mastered-skill configuration used to build the personalized path.
4. Learning Roadmap — Expand
What it demonstrates: Graph-derived prerequisite milestones, hop counts, skill gaps, estimated duration, and mapped learning courses.
5. Flagship 3D WebGL Knowledge Graph — Expand
What it demonstrates: Interactive Three.js/WebGL exploration of career, skill, prerequisite, and course relationships.
6. Career Explorer Directory — Expand
What it demonstrates: Searchable career-role directory with role metadata and required skill profiles.
7. Skill Explorer Directory — Expand
What it demonstrates: Searchable skill catalogue, category filtering, and mastered/unmastered state management.
8. Course Library Directory — Expand
What it demonstrates: Course resources mapped to technical skills through graph relationships.
Repository note: Keep the image filenames in
ScreenShots/synchronized with the paths above if the screenshots are renamed.
All Cypher queries reside in backend/src/queries/ and use 100% Parameterized Inputs.
1. Main Pathfinding & Prerequisite Query (FIND_LEARNING_PATH) — Click to Expand
MATCH (j:Job {title: $targetJob})-[:REQUIRES]->(target:Skill)
WHERE NOT target.name IN $currentSkills
OPTIONAL MATCH pKnown = shortestPath((start:Skill)-[:PREREQUISITE_OF*1..10]->(target))
WHERE start.name IN $currentSkills
OPTIONAL MATCH pRoot = shortestPath((root:Skill)-[:PREREQUISITE_OF*1..10]->(target))
WHERE NOT ()-[:PREREQUISITE_OF]->(root) AND NOT root.name IN $currentSkills
OPTIONAL MATCH (anyPrereq:Skill)-[:PREREQUISITE_OF]->(target)
WITH target,
anyPrereq IS NOT NULL AS hasPrereqs,
CASE
WHEN pKnown IS NOT NULL THEN pKnown
WHEN pRoot IS NOT NULL THEN pRoot
ELSE NULL
END AS path
WITH target, hasPrereqs, path
ORDER BY CASE WHEN path IS NOT NULL THEN length(path) ELSE 999 END ASC
WITH target, hasPrereqs, head(collect(path)) AS bestPath
OPTIONAL MATCH (course:Course)-[:TEACHES]->(target)
RETURN
target.name AS targetSkill,
hasPrereqs,
CASE
WHEN bestPath IS NOT NULL THEN [n IN nodes(bestPath) | n.name]
ELSE [target.name]
END AS learningChain,
CASE
WHEN bestPath IS NOT NULL THEN length(bestPath)
ELSE 0
END AS hops,
collect(DISTINCT {
name: course.name,
provider: course.provider,
durationHours: course.duration_hours,
level: course.level
}) AS courses
ORDER BY hops ASC, targetSkillLocated in: backend/src/queries/learningPath.js
2. Target Job Requirements Query (GET_ALL_JOBS) — Click to Expand
MATCH (j:Job)
OPTIONAL MATCH (j)-[:REQUIRES]->(s:Skill)
RETURN j.title AS title, j.industry AS industry, j.level AS level, collect(s.name) AS requiredSkills
ORDER BY j.title ASCLocated in: backend/src/queries/jobs.js
3. Skills & Prerequisites Query (GET_ALL_SKILLS) — Click to Expand
MATCH (s:Skill)
OPTIONAL MATCH (p:Skill)-[:PREREQUISITE_OF]->(s)
RETURN s.name AS name, s.category AS category, s.level AS level, collect(p.name) AS prerequisites
ORDER BY s.category ASC, s.name ASCLocated in: backend/src/queries/skills.js
4. Course Recommendation Query (GET_COURSES_BY_SKILL) — Click to Expand
MATCH (c:Course)-[:TEACHES]->(s:Skill {name: $skill})
RETURN c.name AS name, c.provider AS provider, c.duration_hours AS durationHours, c.level AS level
ORDER BY c.name ASCLocated in: backend/src/queries/recommendations.js
WEXA Requirement Satisfied: Demonstrates at least one multi-hop graph traversal (2+ hops).
SkillPath evaluates prerequisite skill chains across multiple hops using variable-length relationship traversals:
OPTIONAL MATCH pKnown = shortestPath((start:Skill)-[:PREREQUISITE_OF*1..10]->(target))
WHERE start.name IN $currentSkillsTarget Job: Generative AI Engineer | User Known Skills: ["Python"]
(Python) ──[:PREREQUISITE_OF]──► (Machine Learning) ──[:PREREQUISITE_OF]──► (Deep Learning) ──[:PREREQUISITE_OF]──► (LLM Fundamentals)
[Known] [Hop 1] [Hop 2] [Hop 3 / Target]
In this traversal, LLM Fundamentals is a required skill for Generative AI Engineer. The query traverses 3 relationship hops (*1..10) to establish that mastering LLM Fundamentals requires first completing Machine Learning and Deep Learning.
WEXA Requirement Satisfied: Demonstrates a query that would be complex and awkward in a relational SQL database.
The FIND_LEARNING_PATH Cypher query executes five distinct graph operations in a single database roundtrip:
- Filters required target job skills (
-[:REQUIRES]->). - Excludes skills already mastered by the user (
WHERE NOT target.name IN $currentSkills). - Executes a variable-length shortest path search (
shortestPath((start:Skill)-[:PREREQUISITE_OF*1..10]->(target))). - Fallbacks to root skill paths if no known skill connection exists.
- Aggregates mapped teaching courses (
(:Course)-[:TEACHES]->(:Skill)).
Achieving this in SQL requires:
- Multiple recursive Common Table Expressions (
WITH RECURSIVE prerequisite_chain AS (...)). - Joining
jobs,job_skills,skills,skill_prerequisites, andcoursestables. - Pulling intermediate graphs into application memory to calculate shortest paths.
Cypher expresses this relationship chain natively in 35 lines of readable code.
- Zero Cypher Injection: All queries pass inputs via parameter maps (
{ targetJob, currentSkills, skill }). User inputs are never string-concatenated into Cypher statements. - Official Neo4j Driver: Uses
neo4j-driver(^6.2.0) over the encrypted Bolt protocol (bolt+s://). - Session Safety: Every database query method creates a session inside a
tryblock and guarantees closure in afinallyblock (await session.close()).
Follow these steps to connect SkillPath to a CognoDB graph instance:
- Sign up at CognoDB Cloud Console.
- Create a free C0 Neo4j-compatible database cluster.
- Note your Bolt URI (
bolt+s://db-XXXXX.bravo.databases.cognodb.com), username (cognodb), and generated password.
Create backend/.env based on backend/.env.example:
NEO4J_URI=bolt+s://db-XXXXX.bravo.databases.cognodb.com
NEO4J_USER=cognodb
NEO4J_PASSWORD=your_secure_password_here
PORT=5000cd backend
npm run test:dbOutput: SUCCESS: Connected to CognoDB / Neo4j Graph Database!
cd backend
node ../scripts/seed-db.jsPopulates 15 jobs, 41 skills, 28 courses, and 170+ relationship edges using idempotent MERGE statements.
| Variable Name | Description | Secret? | Example |
|---|---|---|---|
COGNODB_URI / NEO4J_URI |
CognoDB Bolt Connection String | No | bolt+s://db-XXXXX.bravo.databases.cognodb.com |
COGNODB_USER / NEO4J_USER |
Database Username | No | cognodb |
COGNODB_PASSWORD / NEO4J_PASSWORD |
Database Password | YES | your_secure_password_here |
FRONTEND_URL |
Production Frontend CORS Origin | No | https://skill-path-sumeet17.vercel.app |
PORT |
Local Listener Port | No | 5000 |
- Credentials are loaded strictly via
process.env. .envfiles are listed in.gitignoreand never committed.- Sample environment schemas are provided in
.env.example.
SkillPath implements centralized error handling to ensure application stability:
- Centralized Error Middleware (
backend/src/middleware/errorHandler.js): Catches async controller errors and returns structured JSON responses{ success: false, message }with accurate HTTP status codes (400,404,500). Suppresses stack traces in production. - Not Found Handler (
backend/src/middleware/notFound.js): Intercepts unknown routes and returns a structured404 Not FoundJSON payload. - Database Health Check (
backend/src/db/health.js): Verifies database connectivity on startup without interrupting server initialization.
- Node.js (v18.0.0 or higher)
- npm (v9.0.0 or higher)
- Active CognoDB database instance
# 1. Clone the repository
git clone https://github.com/Sumeet2005/SkillPath.git
cd SkillPath
# 2. Install root, backend, and frontend dependencies
npm install
cd backend && npm install
cd ../frontend && npm install
# 3. Configure backend environment
cd ../backend
cp .env.example .env
# Edit backend/.env with your CognoDB credentials
# 4. Seed CognoDB database
node ../scripts/seed-db.js
# 5. Start Backend API Server (Terminal 1)
cd backend
npm run dev
# Running on http://localhost:5000
# 6. Start Frontend Application (Terminal 2)
cd frontend
npm run dev
# Running on http://localhost:5173# Run Backend Readiness Test Engine
cd backend
node test-engine.js
# Run Graph Integrity Audit Script
node audit-graph.js
# Run Frontend Linter
cd ../frontend
npm run lint
# Run Frontend Production Build
npm run buildSkillPath/
├── backend/
│ ├── src/
│ │ ├── app.js # Express application setup & middleware assembly
│ │ ├── server.js # Node HTTP server entry point listening on PORT
│ │ ├── config/
│ │ │ └── env.js # Environment variable loader & validator
│ │ ├── db/
│ │ │ ├── driver.js # Neo4j driver initialization & health helper
│ │ │ └── health.js # Standalone database health check script
│ │ ├── middleware/
│ │ │ ├── errorHandler.js # Centralized JSON error handling middleware
│ │ │ └── notFound.js # 404 route catch-all handler
│ │ ├── queries/ # Parameterized Cypher query files
│ │ │ ├── courses.js
│ │ │ ├── jobs.js
│ │ │ ├── learningPath.js
│ │ │ ├── path.js
│ │ │ ├── recommendations.js
│ │ │ └── skills.js
│ │ ├── routes/ # Express route controllers
│ │ │ ├── jobs.js
│ │ │ ├── path.js
│ │ │ ├── recommendations.js
│ │ │ └── skills.js
│ │ ├── services/ # Business logic layer
│ │ │ ├── jobService.js
│ │ │ ├── pathService.js
│ │ │ ├── recommendationService.js
│ │ │ └── skillService.js
│ │ └── utils/
│ │ └── asyncHandler.js # Async controller wrapper
│ ├── .env.example
│ ├── audit-graph.js # Graph integrity audit script
│ ├── package.json
│ └── test-engine.js # Readiness score & path audit engine
├── frontend/
│ ├── public/
│ │ ├── favicon.svg
│ │ └── icons.svg # SVG icon sprite bundle
│ ├── src/
│ │ ├── components/
│ │ │ ├── graph/
│ │ │ │ ├── Ambient3DCanvas.jsx # Three.js background canvas
│ │ │ │ ├── HeroGraph.jsx # Interactive dashboard hero graph
│ │ │ │ └── KnowledgeGraph3D.jsx # Flagship 3D WebGL graph visualizer
│ │ │ ├── layout/
│ │ │ │ └── Sidebar.jsx # Collapsible sidebar & mobile drawer
│ │ │ ├── ui/ # 12 Reusable Atomic UI Primitives
│ │ │ ├── CareerExplorer.jsx
│ │ │ ├── CareerPlanner.jsx
│ │ │ ├── CourseLibrary.jsx
│ │ │ ├── Dashboard.jsx
│ │ │ ├── Header.jsx
│ │ │ ├── KnowledgeGraph.jsx
│ │ │ ├── LandingPage.jsx
│ │ │ ├── LearningRoadmap.jsx
│ │ │ ├── ReadinessGauge.jsx
│ │ │ └── SkillExplorer.jsx
│ │ ├── hooks/
│ │ │ └── useSkillPath.js # Custom React API state hooks
│ │ ├── services/
│ │ │ └── api.js # Axios API client
│ │ ├── App.css # Custom CSS Grid & Flexbox tokens
│ │ ├── App.jsx # Main App layout & route switcher
│ │ └── main.jsx
│ ├── eslint.config.js
│ ├── index.html
│ ├── package.json
│ ├── vercel.json # Frontend Vercel SPA rewrite config
│ └── vite.config.js # Vite build config & proxy
├── scripts/
│ ├── seed-db.js # Node.js database seeding script
│ └── seed.cypher # Cypher schema constraints & dataset seed statements
├── ScreenShots/ # 8 Application screenshots
├── .env.example
├── .gitignore
├── backend-audit.md # Complete forensic backend audit report
├── design-system.md # UI design system tokens & specs
├── frontend-status.md # Deployment status report
├── package.json
└── README.md
- Submission Candidate: Sumeet Sonar
- Submission Subject:
CognoDB Assignment 2 – Sumeet Sonar - Hosted Application: https://skill-path-sumeet17.vercel.app
- Demo Video Walkthrough: https://drive.google.com/file/d/1w97sUcgtGycr5qrmHFFkK1Q7ehiUmED5/view?usp=sharing
- GitHub Repository: https://github.com/Sumeet2005/SkillPath
Before submission, verify these production links:
Expected health response:
{
"status": "ok",
"success": true,
"message": "SkillPath backend is running",
"database": "connected"
}Recommended local checks:
cd frontend
npm run lint
npm run build
cd ../backend
node test-engine.js
node audit-graph.jsThis project is licensed under the MIT License.







