# Clone repo
git clone <repo-url>
cd morning-command-center
# Install dependencies
npm install
# Create environment file
cp .env.example .env.local
# Start dev server
npm run dev
# Open http://localhost:3000Create .env.local in project root:
# Database
DATABASE_URL=postgresql://user:password@localhost:5432/morning_command_center_dev
# Jira
JIRA_CLIENT_ID=your-client-id-here
JIRA_CLIENT_SECRET=your-client-secret-here
JIRA_INSTANCE_URL=https://company.atlassian.net
# Outlook / Microsoft 365
OUTLOOK_CLIENT_ID=your-client-id-here
OUTLOOK_CLIENT_SECRET=your-client-secret-here
OUTLOOK_TENANT_ID=your-tenant-id-here
OUTLOOK_REDIRECT_URI=http://localhost:3000/api/auth/callback/outlook
# Session
SESSION_SECRET=random-string-at-least-32-chars
# Environment
NODE_ENV=development
LOG_LEVEL=debugWhere to get credentials:
-
Jira:
- Go to https://dev.atlassian.com/
- Create OAuth app → save Client ID & Secret
-
Outlook:
- Go to https://portal.azure.com/
- Azure AD → App registrations → New → save credentials
macOS/Linux:
# Install PostgreSQL (if not already installed)
brew install postgresql@15
# Start service
brew services start postgresql@15
# Create database
createdb morning_command_center_dev
# Verify connection
psql morning_command_center_dev
\q # exitWindows:
# Install PostgreSQL from https://www.postgresql.org/download/windows/
# Then open PostgreSQL prompt:
psql -U postgres
CREATE DATABASE morning_command_center_dev;
\q# Check Node.js version (need 18+)
node --version
# Install npm dependencies
npm install
# Install dev dependencies
npm install --save-dev @types/node typescript# Run migrations
npm run db:migrate
# Verify tables created
npm run db:statusmorning-command-center/
├── src/
│ ├── pages/ # Next.js pages or React routes
│ │ ├── index.tsx # Dashboard home
│ │ ├── overnight-summary.tsx
│ │ └── settings.tsx
│ ├── components/ # React components
│ │ ├── OvernightSummaryCard.tsx
│ │ ├── KPICard.tsx
│ │ ├── KPIGrid.tsx
│ │ └── ...
│ ├── api/ # Backend routes (Next.js) or Express routes
│ │ ├── overnight-summary.ts
│ │ ├── dashboard.ts
│ │ └── ...
│ ├── services/ # Business logic
│ │ ├── jira-service.ts
│ │ ├── outlook-service.ts
│ │ ├── aggregation-service.ts
│ │ └── ...
│ ├── types/ # TypeScript interfaces
│ │ ├── jira.ts
│ │ ├── outlook.ts
│ │ ├── dashboard.ts
│ │ └── ...
│ ├── hooks/ # Custom React hooks
│ │ ├── useOvernightSummary.ts
│ │ ├── useDashboard.ts
│ │ └── ...
│ ├── styles/ # CSS/Tailwind
│ │ ├── globals.css
│ │ └── theme.css
│ └── utils/ # Helper functions
│ ├── timezone.ts
│ ├── attention-score.ts
│ └── ...
├── docs/ # Documentation
│ ├── ARCHITECTURE.md
│ ├── INTEGRATIONS.md
│ └── ...
├── specs/ # Specifications
│ ├── FEATURES.md
│ ├── API.md
│ ├── DATA_MODEL.md
│ ├── UI_SPECS.md
│ └── ...
├── tests/ # Test files
│ ├── unit/
│ ├── integration/
│ └── ...
├── .env.local # Environment variables (not in git)
├── .env.example # Template for .env.local
├── package.json
├── tsconfig.json
├── tailwind.config.js
├── README.md
├── CLAUDE.md
├── PROJECT_PLAN.md
└── SETUP.md
# Start dev server (with hot reload)
npm run dev
# Open http://localhost:3000# Build optimized bundle
npm run build
# Start production server
npm start# Run all tests
npm test
# Run tests in watch mode
npm test -- --watch
# Run specific test file
npm test -- src/services/jira-service.test.ts
# Check test coverage
npm test -- --coverage# Run TypeScript type check
npm run type-check
# Run ESLint
npm run lint
# Fix linting issues
npm run lint -- --fix# Connect to database
psql morning_command_center_dev
# List tables
\dt
# View users table
SELECT * FROM users;
# View overnight summaries
SELECT id, user_id, generated_at FROM overnight_summaries;
# Exit
\q# Drop all tables
npm run db:reset
# Re-run migrations
npm run db:migrate# Get overnight summary
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/overnight-summary
# Get dashboard
curl -H "Authorization: Bearer $TOKEN" \
http://localhost:3000/api/executive-dashboardCreate requests.http:
@host = http://localhost:3000
@token = your-jwt-token-here
### Get Overnight Summary
GET {{host}}/api/overnight-summary
Authorization: Bearer {{token}}
### Get Dashboard
GET {{host}}/api/executive-dashboard
Authorization: Bearer {{token}}
### Get Jira Items
GET {{host}}/api/jira-items?days=1
Authorization: Bearer {{token}}
# Frontend debugging
# Press F12 in Chrome → go to Network/Console/Sources tabsAdd to .vscode/launch.json:
{
"version": "0.2.0",
"configurations": [
{
"type": "node",
"request": "launch",
"name": "Launch Backend",
"program": "${workspaceFolder}/src/server.ts",
"restart": true,
"runtimeArgs": ["--loader", "ts-node/esm"]
}
]
}# Set debug level
DEBUG=app:* npm run dev
# View logs
tail -f logs/app.log| Issue | Solution |
|---|---|
ECONNREFUSED when connecting to DB |
Verify PostgreSQL is running: psql -U postgres |
ENOENT .env.local |
Create .env.local with required variables |
| Port 3000 already in use | Kill process: lsof -ti :3000 | xargs kill -9 |
| Jira API 401 Unauthorized | Check token expiration, refresh in integration_tokens table |
| Slow API response (>5s) | Check external API response times (Jira/Outlook) |
| TypeScript errors | Run npm run type-check to see all errors |
| Tests failing | Clear test cache: npm test -- --clearCache |
// ✅ Good
interface OvernightSummary {
id: string;
userId: string;
metrics: SummaryMetrics;
}
function calculateAttentionScore(summary: OvernightSummary): number {
// Implementation
}
// ❌ Avoid
const summary: any = {...}; // Don't use 'any'
const AttentionScore = (s) => {...}; // Function names in camelCase// ✅ Good
interface OvernightSummaryCardProps {
summary: OvernightSummary;
onRefresh: () => void;
}
export const OvernightSummaryCard: React.FC<OvernightSummaryCardProps> = ({
summary,
onRefresh
}) => {
return <div>...</div>;
};
// ❌ Avoid
export default function OvernightSummaryCard(props) {...} // Use named exports/* ✅ Use Tailwind classes */
<div className="flex items-center justify-between bg-white dark:bg-neutral-900 rounded-lg shadow">
/* ❌ Avoid raw CSS when Tailwind provides utility */
<div style={{display: 'flex', backgroundColor: '#ffffff'}}># Create feature branch
git checkout -b feat/overnight-summary
# Make changes, test locally
# Commit with meaningful message
git commit -m "feat(overnight-summary): Calculate attention score"
# Push to remote
git push origin feat/overnight-summary
# Create PR on GitHub
# Get review, merge when approved
git checkout main
git pull origin main# Deploy to staging environment
npm run deploy:staging
# View logs
npm run logs:staging# Build & deploy to production
npm run deploy:production
# Monitor health
npm run monitor:production-
Enable Caching
// Cache API responses for 5 minutes const cache = new Map();
-
Code Splitting
// Lazy load non-critical components const OvernightSummary = lazy(() => import('./OvernightSummary'));
-
Database Indexing
CREATE INDEX idx_overnight_summaries_user_date ON overnight_summaries(user_id, generated_from_date DESC);
-
API Optimization
- Use pagination for large datasets
- Filter server-side, not client-side
- Batch requests when possible
- TypeScript: https://www.typescriptlang.org/docs/
- React: https://react.dev/
- Tailwind CSS: https://tailwindcss.com/docs
- Next.js: https://nextjs.org/docs (if using Next.js)
- PostgreSQL: https://www.postgresql.org/docs/
- Jira API: https://developer.atlassian.com/cloud/jira/
- Microsoft Graph: https://learn.microsoft.com/en-us/graph/
- Check documentation in
/docsfolder - Review specs in
/specsfolder - Look at examples in existing components
- Ask team in Slack/Discord
- Check GitHub Issues for known problems