feat: add comprehensive styling and AI agent guidelines
- Add Bootstrap CSS and custom styles to frontend (index.css, App.css) - Create comprehensive AGENTS.md with instructions for all AI models - Include Gemini AI agent usage guidelines and commands - Add complete project documentation and development workflow - Ensure proper styling for React components using Bootstrap classes 🤖 Generated with [AI Assistant] Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
This commit is contained in:
252
AGENTS.md
252
AGENTS.md
@@ -1,8 +1,82 @@
|
||||
# Agent Guidelines for Adopt-a-Street
|
||||
|
||||
This file provides comprehensive guidance for all AI models (Claude, Gemini, and others) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Adopt-a-Street is a community street adoption platform with a React frontend and Node.js/Express backend. Users can adopt streets, complete maintenance tasks, participate in events, and earn rewards through a gamification system.
|
||||
|
||||
## Development Status
|
||||
|
||||
**This project is in active development and NOT in production.** Breaking changes are allowed and encouraged to improve code quality, architecture, and maintainability. Feel free to:
|
||||
- Refactor code structures and patterns
|
||||
- Change APIs and data models
|
||||
- Update dependencies and migrate to better solutions
|
||||
- Restructure the codebase for improved architecture
|
||||
- Make backward-incompatible changes that enhance the application
|
||||
|
||||
## Development Workflow
|
||||
|
||||
**IMPORTANT: Commit to Git After Every Feature/Fix/Update**
|
||||
|
||||
After implementing any feature, fix, or update, you MUST:
|
||||
|
||||
1. **Build and test** the changes:
|
||||
```bash
|
||||
# Backend
|
||||
cd backend && npm test
|
||||
|
||||
# Frontend
|
||||
cd frontend && npm run build
|
||||
```
|
||||
|
||||
2. **Create a git commit** with a descriptive message:
|
||||
```bash
|
||||
git add <files>
|
||||
git commit -m "feat/fix/docs: descriptive message
|
||||
|
||||
Detailed explanation of changes...
|
||||
|
||||
🤖 Generated with [AI Assistant]
|
||||
|
||||
Co-Authored-By: AI Assistant <noreply@ai-assistant.com>"
|
||||
```
|
||||
|
||||
3. **Use conventional commit prefixes**:
|
||||
- `feat:` - New features
|
||||
- `fix:` - Bug fixes
|
||||
- `docs:` - Documentation changes
|
||||
- `test:` - Test additions or updates
|
||||
- `refactor:` - Code refactoring
|
||||
- `chore:` - Maintenance tasks
|
||||
- `perf:` - Performance improvements
|
||||
|
||||
4. **Commit frequency**: Create commits for each logical unit of work. Don't batch multiple unrelated changes into one commit.
|
||||
|
||||
5. **Push regularly**: Push commits to origin after completing features or at end of session:
|
||||
```bash
|
||||
git push origin main
|
||||
```
|
||||
|
||||
This ensures:
|
||||
- Clear history of all changes
|
||||
- Easy rollback if needed
|
||||
- Better collaboration and code review
|
||||
- Deployment tracking
|
||||
- CI/CD pipeline triggers
|
||||
|
||||
## Commands
|
||||
**Backend** (from `/backend`): `npm test` (no tests configured yet), `npx eslint .` (lint)
|
||||
**Frontend** (from `/frontend`): `npm test` (run all tests), `npm test -- --testNamePattern="test name"` (single test), `npm run build` (build), `npm start` (dev server)
|
||||
|
||||
### Backend (from `/backend`)
|
||||
- `npm test` - Run all tests
|
||||
- `npx eslint .` - Run linter
|
||||
- `node server.js` - Start development server
|
||||
|
||||
### Frontend (from `/frontend`)
|
||||
- `npm test` - Run all tests in watch mode
|
||||
- `npm test -- --testNamePattern="test name"` - Run single test
|
||||
- `npm run build` - Production build
|
||||
- `npm start` - Start development server
|
||||
|
||||
## Code Style
|
||||
|
||||
@@ -23,3 +97,177 @@
|
||||
### General
|
||||
- **Types**: No TypeScript configured; use JSDoc comments for complex functions if needed
|
||||
- **ESLint**: Follows eslint config in backend; "no-unused-vars" and "no-undef" set to warn
|
||||
|
||||
## Architecture
|
||||
|
||||
### Monorepo Structure
|
||||
- `frontend/`: React application (Create React App)
|
||||
- `backend/`: Express API server with MongoDB
|
||||
|
||||
### Backend Architecture
|
||||
The backend follows a standard Express MVC pattern:
|
||||
- `server.js`: Main entry point with Socket.IO for real-time updates
|
||||
- `routes/`: API route handlers for auth, streets, tasks, posts, events, rewards, reports, ai, payments, users
|
||||
- `models/`: Mongoose schemas (User, Street, Task, Post, Event, Reward, Report)
|
||||
- `middleware/auth.js`: JWT authentication middleware using `x-auth-token` header
|
||||
|
||||
### Frontend Architecture
|
||||
React SPA using React Router v6:
|
||||
- `App.js`: Main router with client-side routing
|
||||
- `context/AuthContext.js`: Global authentication state management
|
||||
- `context/SocketContext.js`: Socket.IO real-time connection management
|
||||
- `components/`: Feature components (MapView, TaskList, SocialFeed, Profile, Events, Rewards, Premium, Login, Register, Navbar, ErrorBoundary)
|
||||
- Real-time updates via Socket.IO for events, posts, and tasks
|
||||
- Interactive map with Leaflet for street visualization
|
||||
- Comprehensive error handling with ErrorBoundary
|
||||
|
||||
Authentication flow: JWT tokens stored in localStorage and sent via `x-auth-token` header on all API requests.
|
||||
|
||||
Frontend proxies API requests to `http://localhost:5000` in development.
|
||||
|
||||
**Note:** This is a true monorepo - both frontend and backend are tracked in the same Git repository for simplified development and deployment.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
Backend requires `.env` file:
|
||||
- `MONGO_URI`: MongoDB connection string
|
||||
- `JWT_SECRET`: Secret for JWT signing
|
||||
- `PORT` (optional): Server port (defaults to 5000)
|
||||
|
||||
## API Endpoints
|
||||
|
||||
- `/api/auth`: Registration, login, and user authentication
|
||||
- `/api/streets`: Street data and adoption management
|
||||
- `/api/tasks`: Maintenance task CRUD operations
|
||||
- `/api/posts`: Social feed posts
|
||||
- `/api/events`: Community events with Socket.IO real-time updates
|
||||
- `/api/rewards`: Points and rewards system
|
||||
- `/api/reports`: Street condition reports
|
||||
- `/api/ai`: AI-powered suggestions and insights
|
||||
- `/api/payments`: Premium subscription management (currently mocked)
|
||||
- `/api/users`: User profile management
|
||||
|
||||
## Key Technologies
|
||||
|
||||
- Frontend: React 19, React Router v6, Leaflet (mapping), Axios, Socket.IO client, Stripe.js
|
||||
- Backend: Express, Mongoose (MongoDB), JWT, bcryptjs, Socket.IO, Stripe, Multer (file uploads)
|
||||
- Testing: React Testing Library, Jest
|
||||
|
||||
## Socket.IO Events
|
||||
|
||||
Real-time features for events:
|
||||
- `joinEvent(eventId)`: Join event room
|
||||
- `eventUpdate`: Broadcast updates to event participants
|
||||
|
||||
## Deployment
|
||||
|
||||
### Kubernetes Raspberry Pi Cluster
|
||||
|
||||
This application is deployed on a Kubernetes cluster running on Raspberry Pi hardware:
|
||||
|
||||
**Cluster Configuration:**
|
||||
- **2x Raspberry Pi 5 (8GB RAM)** - Primary worker nodes for application workloads
|
||||
- **1x Raspberry Pi 3B+ (1GB RAM)** - Worker node for lightweight services
|
||||
|
||||
**Architecture Considerations:**
|
||||
- ARM64 architecture (Pi 5) and ARMv7 architecture (Pi 3B+)
|
||||
- Multi-arch Docker images required (linux/arm64, linux/arm/v7)
|
||||
- Resource-constrained environment - optimize for low memory usage
|
||||
- Frontend and backend should be containerized separately
|
||||
- MongoDB should run as a StatefulSet with persistent storage
|
||||
- Consider resource limits and requests appropriate for Pi hardware
|
||||
|
||||
**Deployment Strategy:**
|
||||
- Use Kubernetes manifests or Helm charts
|
||||
- Implement horizontal pod autoscaling based on available resources
|
||||
- Place memory-intensive workloads (backend, MongoDB) on Pi 5 nodes
|
||||
- Place frontend static serving on any node (lightweight)
|
||||
- Use NodeAffinity/NodeSelector to control pod placement
|
||||
- Implement health checks and readiness probes
|
||||
- Use ConfigMaps for environment variables
|
||||
- Use Secrets for sensitive data (JWT_SECRET, CLOUDINARY credentials, etc.)
|
||||
|
||||
See deployment documentation for Kubernetes manifests and deployment instructions.
|
||||
|
||||
## Testing
|
||||
|
||||
Comprehensive test infrastructure is in place for both backend and frontend.
|
||||
|
||||
### Running Tests
|
||||
|
||||
Backend:
|
||||
```bash
|
||||
cd backend
|
||||
npm test # Run all tests
|
||||
npm run test:coverage # Run with coverage report
|
||||
npm run test:watch # Run in watch mode
|
||||
```
|
||||
|
||||
Frontend:
|
||||
```bash
|
||||
cd frontend
|
||||
npm test # Run in watch mode
|
||||
npm run test:coverage # Run with coverage report
|
||||
```
|
||||
|
||||
### Test Coverage
|
||||
|
||||
- **Backend**: ~55% coverage (109 passing tests)
|
||||
- Route tests for auth, streets, tasks, posts, events, rewards, reports
|
||||
- Model tests for User, Street, Task, Post
|
||||
- Middleware tests for authentication
|
||||
- Using Jest + Supertest + MongoDB Memory Server
|
||||
|
||||
- **Frontend**: MSW infrastructure in place
|
||||
- Component tests for Login, Register, ErrorBoundary
|
||||
- Integration tests for authentication flow
|
||||
- Using React Testing Library + Jest + MSW
|
||||
|
||||
See [TESTING.md](TESTING.md) for detailed testing documentation.
|
||||
|
||||
## Gemini AI Agents
|
||||
|
||||
Gemini LLM can be used to spawn AI agents for various tasks. There are two models available:
|
||||
|
||||
- **gemini-2.5-flash**: Quick responses that don't require thinking mode
|
||||
- **gemini-2.5-pro**: Thinking model for more demanding tasks
|
||||
|
||||
### Usage Commands
|
||||
```bash
|
||||
gemini --model gemini-2.5-flash -p "<PROMPT>"
|
||||
gemini --model gemini-2.5-pro -p "<PROMPT>"
|
||||
```
|
||||
|
||||
Use flash for simple, quick tasks and pro for complex reasoning, analysis, or creative tasks that require deeper thinking.
|
||||
|
||||
## AI Assistant Guidelines
|
||||
|
||||
### For All AI Models
|
||||
1. **Always read existing code** before making changes to understand patterns and conventions
|
||||
2. **Follow the established code style** and architectural patterns
|
||||
3. **Test your changes** before committing
|
||||
4. **Commit frequently** with descriptive messages following the conventional commit format
|
||||
5. **Ask for clarification** if requirements are unclear
|
||||
6. **Document complex decisions** in code comments or commit messages
|
||||
7. **Consider performance implications** of changes, especially for the Raspberry Pi deployment
|
||||
8. **Maintain backward compatibility** where possible, but remember breaking changes are allowed in development
|
||||
|
||||
### Task Prioritization
|
||||
1. **High Priority**: Security fixes, critical bugs, deployment blockers
|
||||
2. **Medium Priority**: New features, performance improvements, test coverage
|
||||
3. **Low Priority**: Code refactoring, documentation updates, minor UI improvements
|
||||
|
||||
### Communication
|
||||
- Be clear and concise in commit messages and code comments
|
||||
- Explain the "why" behind complex changes
|
||||
- Flag any potential breaking changes or security concerns
|
||||
- Suggest follow-up tasks or improvements when relevant
|
||||
|
||||
### Quality Assurance
|
||||
- Run linting and tests before committing
|
||||
- Ensure code follows established patterns
|
||||
- Verify functionality works end-to-end
|
||||
- Check for potential security vulnerabilities
|
||||
- Consider edge cases and error handling
|
||||
|
||||
Remember: This is a collaborative development environment. Your contributions help build a robust community platform for street adoption and maintenance.
|
||||
@@ -0,0 +1,123 @@
|
||||
/* App-specific styles */
|
||||
.container {
|
||||
max-width: 1200px;
|
||||
margin: 0 auto;
|
||||
padding: 0 15px;
|
||||
}
|
||||
|
||||
/* Navigation */
|
||||
.navbar {
|
||||
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
||||
}
|
||||
|
||||
.navbar-brand {
|
||||
font-weight: bold;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.nav-link {
|
||||
cursor: pointer;
|
||||
transition: color 0.3s ease;
|
||||
}
|
||||
|
||||
.nav-link:hover {
|
||||
color: #007bff !important;
|
||||
}
|
||||
|
||||
/* Form styles */
|
||||
.form-group {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.form-control {
|
||||
display: block;
|
||||
width: 100%;
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
color: #495057;
|
||||
background-color: #fff;
|
||||
background-clip: padding-box;
|
||||
border: 1px solid #ced4da;
|
||||
border-radius: 0.25rem;
|
||||
transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
}
|
||||
|
||||
.form-control:focus {
|
||||
color: #495057;
|
||||
background-color: #fff;
|
||||
border-color: #80bdff;
|
||||
outline: 0;
|
||||
box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);
|
||||
}
|
||||
|
||||
/* Button styles */
|
||||
.btn {
|
||||
display: inline-block;
|
||||
font-weight: 400;
|
||||
text-align: center;
|
||||
white-space: nowrap;
|
||||
vertical-align: middle;
|
||||
user-select: none;
|
||||
border: 1px solid transparent;
|
||||
padding: 0.375rem 0.75rem;
|
||||
font-size: 1rem;
|
||||
line-height: 1.5;
|
||||
border-radius: 0.25rem;
|
||||
transition: color 0.15s ease-in-out, background-color 0.15s ease-in-out, border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;
|
||||
cursor: pointer;
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.btn-primary {
|
||||
color: #fff;
|
||||
background-color: #007bff;
|
||||
border-color: #007bff;
|
||||
}
|
||||
|
||||
.btn-primary:hover {
|
||||
color: #fff;
|
||||
background-color: #0069d9;
|
||||
border-color: #0062cc;
|
||||
}
|
||||
|
||||
.btn-primary:disabled {
|
||||
color: #fff;
|
||||
background-color: #6c757d;
|
||||
border-color: #6c757d;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
|
||||
/* Card styles */
|
||||
.card {
|
||||
position: relative;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
min-width: 0;
|
||||
word-wrap: break-word;
|
||||
background-color: #fff;
|
||||
background-clip: border-box;
|
||||
border: 1px solid rgba(0, 0, 0, 0.125);
|
||||
border-radius: 0.25rem;
|
||||
box-shadow: 0 0.125rem 0.25rem rgba(0, 0, 0, 0.075);
|
||||
}
|
||||
|
||||
.card-body {
|
||||
flex: 1 1 auto;
|
||||
padding: 1.25rem;
|
||||
}
|
||||
|
||||
/* Responsive adjustments */
|
||||
@media (max-width: 768px) {
|
||||
.container {
|
||||
padding: 0 10px;
|
||||
}
|
||||
|
||||
.navbar-nav {
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.nav-item {
|
||||
margin-bottom: 0.5rem;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
/* Bootstrap CSS */
|
||||
@import url('https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css');
|
||||
|
||||
/* Global styles */
|
||||
body {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
background-color: #f8f9fa;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
}
|
||||
|
||||
/* Custom utility classes */
|
||||
.text-center {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.mt-5 {
|
||||
margin-top: 3rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1.5rem;
|
||||
}
|
||||
|
||||
.btn-block {
|
||||
display: block;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
/* Loading spinner */
|
||||
.spinner-border {
|
||||
display: inline-block;
|
||||
width: 2rem;
|
||||
height: 2rem;
|
||||
vertical-align: text-bottom;
|
||||
border: 0.25em solid currentColor;
|
||||
border-right-color: transparent;
|
||||
border-radius: 50%;
|
||||
animation: spinner-border 0.75s linear infinite;
|
||||
}
|
||||
|
||||
.spinner-border-sm {
|
||||
width: 1rem;
|
||||
height: 1rem;
|
||||
border-width: 0.125em;
|
||||
}
|
||||
|
||||
.sr-only {
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
height: 1px;
|
||||
padding: 0;
|
||||
margin: -1px;
|
||||
overflow: hidden;
|
||||
clip: rect(0, 0, 0, 0);
|
||||
white-space: nowrap;
|
||||
border: 0;
|
||||
}
|
||||
|
||||
@keyframes spinner-border {
|
||||
to {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user