Files
adopt-a-street/AGENTS.md
William Valentin bb9c8ec1c3 feat: Migrate from Socket.IO to Server-Sent Events (SSE)
- Replace Socket.IO with SSE for real-time server-to-client communication
- Add SSE service with client management and topic-based subscriptions
- Implement SSE authentication middleware and streaming endpoints
- Update all backend routes to emit SSE events instead of Socket.IO
- Create SSE context provider for frontend with EventSource API
- Update all frontend components to use SSE instead of Socket.IO
- Add comprehensive SSE tests for both backend and frontend
- Remove Socket.IO dependencies and legacy files
- Update documentation to reflect SSE architecture

Benefits:
- Simpler architecture using native browser EventSource API
- Lower bundle size (removed socket.io-client dependency)
- Better compatibility with reverse proxies and load balancers
- Reduced resource usage for Raspberry Pi deployment
- Standard HTTP-based real-time communication

🤖 Generated with [AI Assistant]

Co-Authored-By: AI Assistant <noreply@ai-assistant.com>
2025-12-05 22:49:22 -08:00

277 lines
11 KiB
Markdown

# 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 && bun test
# Frontend
cd frontend && bun 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`)
- `bun test` - Run all tests
- `bunx eslint .` - Run linter
- `node server.js` - Start development server
### Frontend (from `/frontend`)
- `bun test` - Run all tests in watch mode
- `bun test -- --testNamePattern="test name"` - Run single test
- `bun run build` - Production build
- `bun start` - Start development server
## Code Style
### Backend (Node.js/Express)
- **Imports**: Use `require()` for CommonJS modules; group by: built-in → third-party → local (models, middleware, routes)
- **Formatting**: 2-space indent, trailing commas in objects/arrays, double quotes for strings
- **Naming**: camelCase for variables/functions, PascalCase for models/schemas, lowercase for routes
- **Error Handling**: Use try-catch in async routes; log errors with `console.error(err.message)`; return generic "Server error" (500) or specific error messages (400)
- **Responses**: Return JSON with `res.json()` for success, `res.status(code).json({ msg: "..." })` or `res.status(code).send("...")` for errors
### Frontend (React)
- **Imports**: ES6 `import`; group by: React → third-party → local components → context → styles
- **Components**: Functional components with hooks; export default at end
- **Naming**: PascalCase for components, camelCase for functions/variables
- **State**: Use `useState` for local state, Context API for global state (AuthContext pattern)
- **Error Handling**: Handle errors in async operations, display user-friendly messages
### 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 CouchDB
### Backend Architecture
The backend follows a standard Express MVC pattern:
- `server.js`: Main entry point with SSE (Server-Sent Events) for real-time updates
- `routes/`: API route handlers for auth, streets, tasks, posts, events, rewards, reports, ai, payments, users
- `models/`: CouchDB document models (User, Street, Task, Post, Event, Reward, Report)
- `services/couchdbService.js`: CouchDB connection and document management service
- `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/SSEContext.js`: SSE (Server-Sent Events) real-time connection management
- `components/`: Feature components (MapView, TaskList, SocialFeed, Profile, Events, Rewards, Premium, Login, Register, Navbar, ErrorBoundary)
- Real-time updates via SSE (Server-Sent Events) 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:
- `COUCHDB_URL`: CouchDB connection URL (e.g., http://localhost:5984)
- `COUCHDB_DB_NAME`: CouchDB database name (e.g., adopt-a-street)
- `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 SSE 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, Stripe.js
- Backend: Express, CouchDB (NoSQL database), Nano (CouchDB client), JWT, bcryptjs, Stripe, Multer (file uploads)
- Testing: React Testing Library, Jest
## SSE Real-time Events
Real-time features using Server-Sent Events:
- **Topics**: Clients subscribe to topics via `/api/sse/subscribe`
- **Event Types**: `eventUpdate`, `taskUpdate`, `newPost`, `postUpdate`, `newComment`, `streetUpdate`, `achievementUnlocked`
- **Connection**: `/api/sse/stream` with JWT authentication
- **Heartbeat**: 30-second keepalive messages
## 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
- CouchDB 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, CouchDB) 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, CouchDB 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
bun test # Run all tests
bun run test:coverage # Run with coverage report
bun run test:watch # Run in watch mode
```
Frontend:
```bash
cd frontend
bun test # Run in watch mode
bun 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 + CouchDB testing utilities
- **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.