Content Management System for CHIRP Radio built with Payload CMS.
- Articles - Blog posts and news articles with rich text, images, YouTube embeds
- Events - Event management with venue info, tickets, performers
- DJs - DJ profiles with bio, show info, contact details
- Media - Image upload and management with automatic resizing
- Node.js 18+
- MongoDB (local or cloud)
-
Install dependencies:
npm install
-
Set up MongoDB:
Option A: Local MongoDB
# Install MongoDB (macOS) brew tap mongodb/brew brew install mongodb-community brew services start mongodb-communityOption B: MongoDB Atlas (Cloud)
- Create free account at https://www.mongodb.com/cloud/atlas
- Create a cluster
- Get connection string
- Update
.envwith your connection string
-
Configure environment variables:
# Edit .env file DATABASE_URI=mongodb://localhost/chirp-cms # or your Atlas connection string PAYLOAD_SECRET=your-secret-key-here-change-in-production PORT=3000
-
Start development server:
npm run dev
-
Access admin panel:
- Open http://localhost:3000/admin
- Create your first admin user
-
Import existing data (optional):
npm run seed
This will import articles, events, and DJ profiles from the JSON files.
GET /api/articles- List all articlesGET /api/articles/:id- Get single articleGET /api/articles?where[featured][equals]=true- Get featured articles
GET /api/events- List all eventsGET /api/events/:id- Get single eventGET /api/events?where[date][greater_than_equal]=2025-01-01- Get upcoming events
GET /api/djs- List all DJsGET /api/djs/:id- Get single DJ profile
GET /api/media- List all mediaGET /api/media/:id- Get single media item
All API responses match the frontend's expected JSON structure:
Article Example:
{
"id": "article-001",
"title": "Chicago Underground Music Scene",
"slug": "chicago-underground-music-scene",
"author": {
"name": "Sarah Martinez",
"id": "user-002",
"profileImage": "https://..."
},
"featuredImage": "https://...",
"excerpt": "...",
"content": "...",
"category": "Music Scene",
"tags": ["chicago", "indie"],
"publishedDate": "2024-12-01T10:00:00Z",
"featured": true,
"readTime": 8
}npm run buildnpm run serve- Copy project to server
- Install dependencies:
npm install - Build:
npm run build - Set up environment variables
- Run with PM2:
pm2 start dist/server.js --name chirp-cms
chirp-data/
├── src/
│ ├── collections/ # Content type definitions
│ │ ├── Articles.ts
│ │ ├── Events.ts
│ │ ├── DJs.ts
│ │ └── Media.ts
│ ├── seed/ # Data import scripts
│ │ └── import-data.ts
│ ├── payload.config.ts # Payload configuration
│ └── server.ts # Express server
├── media/ # Uploaded images (git ignored)
├── .env # Environment variables
└── package.json
npm run dev- Start development servernpm run typecheck- Run TypeScript type checkingnpm run lint- Check for linting issuesnpm run lint:fix- Auto-fix linting issuesnpm run format- Format all files with Prettiernpm run format:check- Check code formatting
npm run build- Build for productionnpm run start- Run production server
npm run seed- Import data from JSON filesnpm run generate:types- Generate TypeScript types from Payload schema
Git hooks are automatically set up via Husky when you run npm install.
Before each commit, the following checks run automatically:
- ESLint - Checks code quality and auto-fixes issues
- Prettier - Formats code consistently
This ensures consistent code quality and formatting across the team.
- Admin panel runs at
/admin - REST API runs at
/api - GraphQL API runs at
/api/graphql - Images are stored in
media/directory - External image URLs are supported via
featuredImageUrlfields