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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .claude/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"enabledPlugins": {
"mongodb@claude-plugins-official": true
}
}
59 changes: 27 additions & 32 deletions .github/workflows/main.yaml
Original file line number Diff line number Diff line change
@@ -1,58 +1,53 @@
# This is a basic workflow to help you get started with Actions

name: CI

# Controls when the workflow will run
on:
# Triggers the workflow on push or pull request events but only for the main branch
push:
branches: [ $default-branch ]
branches: [ main ]
pull_request:
branches: [ $default-branch ]

# Allows you to run this workflow manually from the Actions tab
branches: [ main ]
workflow_dispatch:

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
# This workflow contains a single job called "build"

build:
# The type of runner that the job will run on
runs-on: ubuntu-latest
environment: Testing
strategy:
matrix:
node-version: [14.x , 16.x]
max-parallel: 1

# Steps represent a sequence of tasks that will be executed as part of the job
node-version: [20.x, 22.x]
max-parallel: 1

steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
with:
ref: 'main-test'
- uses: actions/checkout@v4

- name: Install server npm packages
uses: bahmutov/npm-install@v1
- name: Use Node.js ${{ matrix.node-version }}
uses: actions/setup-node@v4
with:
working-directory: mern/server
node-version: ${{ matrix.node-version }}
cache: 'npm'
cache-dependency-path: |
mern/server/package-lock.json
mern/client/package-lock.json

- name: Install server npm packages
run: npm ci
working-directory: mern/server

- name: Install client npm packages
uses: bahmutov/npm-install@v1
with:
working-directory: mern/client
run: npm ci
working-directory: mern/client

- name: Start server in the background
env:
env:
ATLAS_URI: ${{ secrets.ATLAS_URI }}
run: (cd mern/server && echo "ATLAS_URI=$ATLAS_URI" > config.env && npm start &)

- name: Start React app in the background
run: (cd mern/client && npm start &)
run: |
echo "ATLAS_URI=$ATLAS_URI" > config.env
npm start &
working-directory: mern/server
Comment thread
sis0k0 marked this conversation as resolved.

- name: Install Cypress and run tests
uses: cypress-io/github-action@v2
uses: cypress-io/github-action@v6
with:
working-directory: mern/client
start: npm run dev
wait-on: 'http://localhost:5173'

80 changes: 80 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# AGENTS.md — AI Agent Guide

This file is the source of truth for AI agents working in this repository.

## Project Overview

Full-stack MERN CRUD app for managing employee records. React (Vite) frontend communicates with an Express REST API; MongoDB Atlas stores data in the `employees` database, `records` collection.

## Project Structure

```
mern-stack-example/
├── EDD.md # MongoDB data model — read before touching schema or routes
├── mern/
│ ├── client/ # React 18 + Vite + Tailwind CSS frontend
│ │ ├── src/
│ │ │ ├── App.jsx # Root component and routes
│ │ │ ├── components/
│ │ │ │ ├── Navbar.jsx
│ │ │ │ ├── Record.jsx # Create / edit form
│ │ │ │ └── RecordList.jsx # Main list view
│ │ ├── vite.config.js
│ │ └── package.json
│ └── server/ # Node.js + Express REST API
│ ├── db/
│ │ └── connection.js # MongoDB Atlas connection (appName set here)
│ ├── routes/
│ │ └── record.js # GET / POST / PATCH / DELETE /record
│ ├── seed.js # Database seed script
│ ├── server.js # Express app entry point
│ └── package.json
└── .github/workflows/main.yaml # CI: install, start, Cypress e2e
```

## Build and Test Commands

```bash
# Install and start the API server
cd mern/server
npm install
npm start # requires mern/server/config.env (see Environment Variables)

# Install and start the React dev server
cd mern/client
npm install
npm run dev # serves on http://localhost:5173

# Seed the database
cd mern/server
node seed.js # requires ATLAS_URI in config.env

# Run Cypress e2e tests (client must be running)
cd mern/client
npx cypress run
```

## Environment Variables

Create `mern/server/config.env` (not committed):

| Variable | Description | Example |
|-------------|------------------------------------------|---------|
| `ATLAS_URI` | MongoDB Atlas connection string | `mongodb+srv://user:[email protected]/` |
| `PORT` | Port for the Express server | `5050` |

## MongoDB Skills

Use the official MongoDB agent skills from https://github.com/mongodb/agent-skills
whenever the task is MongoDB-specific and a matching skill exists.

## When To Use EDD.md

Use [EDD.md](./EDD.md) as the source of truth for the MongoDB data model in this repository.

Consult [EDD.md](./EDD.md) before making changes that touch:

- MongoDB collections, document structure, or field names
- Express routes that read or write database records
- Validation, form fields, API payloads, or UI that depend on persisted data
- Schema documentation, Mermaid diagrams, or entity modeling discussions
49 changes: 49 additions & 0 deletions EDD.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# EDD — Entity Document Diagram

Data model for the **MERN Stack Employee Records App**.

- **Database**: `employees`
- **Driver**: MongoDB Node.js Driver 6

---

## Entities

### Record [collection: records] [indexes: {_id:1}]

```
_id: ObjectId
name: string # employee full name
position: string # job title / role
level: string # seniority level, e.g. "junior", "mid", "senior"
```
Comment thread
sis0k0 marked this conversation as resolved.

---

## Relationships

```
records — standalone collection, no references to other collections
```

---

## Mermaid Diagram

```mermaid
erDiagram
RECORDS {
ObjectId _id PK
string name
string position
string level
}
```

---

## Notes

- No validation schema is enforced at the database level; validation is handled in the Express routes (`mern/server/routes/record.js`).
- `level` is a free-form string. Typical values used in the seed data: `junior`, `mid`, `senior`.
- All fields are required by convention in the application code.
Comment thread
sis0k0 marked this conversation as resolved.
Outdated
81 changes: 73 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,29 +1,94 @@
# mern-stack-example
Mern Stack code for the [Mern Tutorial](https://www.mongodb.com/languages/mern-stack-tutorial)
# MERN Stack Employee Records App with MongoDB Atlas

A full-stack CRUD application built with MongoDB, Express, React, and Node.js (MERN). Demonstrates how to manage employee records — create, read, update, and delete — using MongoDB Atlas as the database and a REST API backend.

Companion code for the [MERN Stack Tutorial](https://www.mongodb.com/languages/mern-stack-tutorial?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel).

[![CI](https://github.com/mongodb-developer/mern-stack-example/actions/workflows/main.yaml/badge.svg)](https://github.com/mongodb-developer/mern-stack-example/actions/workflows/main.yaml)

## How To Run
Create the file `mern/server/config.env` with your Atlas URI and the server port:
## Features

- List all employee records stored in MongoDB Atlas
- Create a new employee record (name, position, level)
- Edit an existing record in place
- Delete a record
- React frontend (Vite + Tailwind CSS) communicating with an Express REST API

## Architecture Overview

```
┌─────────────────────┐ REST (JSON) ┌──────────────────────────┐
│ React (Vite) │ ─────────────────────► │ Express API │
│ mern/client │ ◄───────────────────── │ mern/server │
│ :5173 │ │ :5050 │
└─────────────────────┘ └───────────┬──────────────┘
│ MongoDB Node.js driver
┌──────────────────────────┐
│ MongoDB Atlas │
│ database: employees │
│ collection: records │
└──────────────────────────┘
```
ATLAS_URI=mongodb+srv://<username>:<password>@sandbox.jadwj.mongodb.net/

- **Frontend**: React 18, Vite, Tailwind CSS, React Router
- **Backend**: Node.js, Express 4, MongoDB Node.js Driver 6
- **Database**: MongoDB Atlas — `employees` database, `records` collection

## Quick Start

### Prerequisites

- Node.js 18+
- A free [MongoDB Atlas](https://www.mongodb.com/atlas?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel) cluster
Comment thread
sis0k0 marked this conversation as resolved.

### 1. Configure the server

Create `mern/server/config.env`:

```
ATLAS_URI=mongodb+srv://<username>:<password>@<cluster>.mongodb.net/
PORT=5050
```

Start server:
### 2. Seed the database (optional)

```bash
cd mern/server
node seed.js
```
Comment on lines +54 to 59

### 3. Start the API server

```bash
cd mern/server
npm install
npm start
```

Start Web server
```
### 4. Start the React app

```bash
cd mern/client
npm install
npm run dev
```

Open [http://localhost:5173](http://localhost:5173).

## MongoDB Features Demonstrated

| Feature | Where |
|---|---|
| [MongoDB Node.js Driver](https://www.mongodb.com/docs/drivers/node/current/?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel) | `mern/server/db/connection.js` |
| [CRUD operations](https://www.mongodb.com/docs/manual/crud/?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel) | `mern/server/routes/record.js` |
| [MongoDB Atlas](https://www.mongodb.com/atlas?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel) | Atlas URI in `config.env` |
| [Server API version](https://www.mongodb.com/docs/manual/reference/stable-api/?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel) | `ServerApiVersion.v1` in connection |

## Additional Resources

- [MERN Stack Tutorial](https://www.mongodb.com/languages/mern-stack-tutorial?utm_campaign=devrel&utm_medium=github&utm_content=mern.stack.example&utm_term=learning.fuel) — step-by-step walkthrough of this codebase

## Disclaimer

Use at your own risk; not a supported MongoDB product
56 changes: 56 additions & 0 deletions mern/server/seed.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/**
* seed.js — Populate the employees.records collection with sample data.
*
* Usage:
* node seed.js
*
* Requires config.env in the same directory with ATLAS_URI set.
*/

import { MongoClient, ServerApiVersion } from "mongodb";
import * as fs from "node:fs";

// Load config.env manually (same pattern as the app)
if (fs.existsSync(new URL("./config.env", import.meta.url))) {
const env = fs.readFileSync(new URL("./config.env", import.meta.url), "utf8");
for (const line of env.split("\n")) {
const [key, ...rest] = line.split("=");
if (key && rest.length) process.env[key.trim()] = rest.join("=").trim();
}
Comment thread
sis0k0 marked this conversation as resolved.
Comment thread
sis0k0 marked this conversation as resolved.
}

const URI = process.env.ATLAS_URI;
if (!URI) {
console.error("ATLAS_URI is not set. Create mern/server/config.env first.");
process.exit(1);
}

const client = new MongoClient(URI, {
serverApi: { version: ServerApiVersion.v1, strict: true, deprecationErrors: true },
appName: "devrel-github-javascript-mern",
});

const records = [
{ name: "Alice Johnson", position: "Software Engineer", level: "senior" },
{ name: "Bob Martinez", position: "Product Manager", level: "mid" },
{ name: "Carol Lee", position: "UX Designer", level: "junior" },
{ name: "David Kim", position: "DevOps Engineer", level: "mid" },
{ name: "Eva Nguyen", position: "Data Scientist", level: "senior" },
{ name: "Frank Chen", position: "Frontend Developer", level: "junior" },
{ name: "Grace Patel", position: "Backend Developer", level: "mid" },
{ name: "Henry Okafor", position: "QA Engineer", level: "junior" },
{ name: "Iris Müller", position: "Engineering Manager", level: "senior" },
{ name: "James Tanaka", position: "Security Engineer", level: "mid" },
Comment thread
sis0k0 marked this conversation as resolved.
Outdated
];

try {
await client.connect();
const collection = client.db("employees").collection("records");

// Remove existing records to avoid duplicates on re-runs
await collection.deleteMany({});
const result = await collection.insertMany(records);
Comment thread
sis0k0 marked this conversation as resolved.
console.log(`Inserted ${result.insertedCount} records into employees.records`);
} finally {
await client.close();
}
Loading