Here is a followup from a post a few days ago.
I spent time the past few days configuring cursor rules for composer agent for a certain project, and it has so far been incredible to see. I’ve really focused on:
-
Getting cursor to add very verbose logging in its code whether it’s new, or existing code we are implementing/testing.
-
Getting it to work with my development environment and showing it how to run database commands, view the docker logs, test the HTTP endpoints, giving it a specific pat_ token to use.
My application hot reloads once I select “Apply changes”, and then cursor will generate a command to test our changes, and then if a failure, it will check the logs if it needs to or look at the response from our test, and decide what to do from there.
It’s saved me the context switching penalty when navigating and copying and pasting between Cursor, Postman, Postico, Docker and my terminal which has been is incredible for productivity.
I’ve made changes to my codebase also to make it work well with iterative process, such as when in development mode, have a specific header that gives the full path to the file that has the HTTP handler, and another header with the name of the handler function. Cursor can get this in its context when it performs the test and knows exactly straight away where to look for the related code.
Here are my rules:
# Development Context
- Project: [redacted]
- Stack: Go + Chi Router + sqlx + PostgreSQL
- Environment: Dockerized application on apple silicon.
- Hot Reload: Using Air for automatic container restarts
- POST is used instead of PUT for updates
# Docker Configuration
Main API Container: api-api-1
Database Container: api-postgres-1
Database Credentials:
- User: postgres
- Password: postgres
- Database: postgres
# Entity ID System
1. Internal Structure (Database):
- id (int) - Internal primary key, never exposed
- external_id (string) - Maps to "id" in all API responses
2. External API Interface:
- All "id" fields in API responses are actually the external_id from database
- Example:
Database: {id: 1, external_id: "usr_123"}
API Response: {id: "usr_123", name: "John"}
# Here are some guidelines for you to follow:
1. Database tables are singular, but the API endpoints are plural.
2. Follow existing code patterns and conventions.
3. Use sqlx for database operations.
4. Be overly verbose with logging in code you write.
5. Make use of tools for debugging if the issue in the code isn't obvious.
6. Once you've made a code change, you MUST remind me to apply the changes first before running commands.
7. Endpoint resources are snake_case.
8. When debugging, using commands to check database schema is very valuable.
# Endpoints
[redacted]
## Testing & Debugging
This first thing you must do is check the database schema for the tables we are working with.
This is very important to understand the data structure and relationships.
Be smart with the below commands. For example, to check if a resource was created, use the get resource by id endpoint, not the full list. Also for SQL, only get what is needed.
During debugging, if you run a command and see an unrelated error, we fix that first.
You have access to a VSCode terminal on macOS M1 (Apple Silicon). Commands MUST be non-interactive and complete without user input.
Example commands:
1. View container logs:
docker logs --tail 50 api-api-1
2. Run postgres commands (you must use the below format for non-interactive commands):
docker exec -i api-postgres-1 psql -U postgres -d postgres -P pager=off -c "command"
Example: docker exec -i api-postgres-1 psql -U postgres -d postgres -P pager=off -c "\dt"
When getting full table data, limit to 5 rows.
3. Test API endpoints. You dont need to repeat the full response back to me, just the important parts:
curl -i -H "Authorization: pat_cursor" http://localhost:3000/v1/resource_type
Endpoints following this format:
GET http://localhost:3000/v1/resource_type (for getting a list of resources)
GET http://localhost:3000/v1/resource_type/:id (for getting a single resource by id)
POST http://localhost:3000/v1/resource_type (for creating a new resource)
POST http://localhost:3000/v1/resource_type/:id (for partial updates)
DELETE http://localhost:3000/v1/resource_type/:id (for deleting a resource)
When testing, use the below headers to help with debugging. X-Handler-File is the path relative to the project root:
X-Handler-Function: <function_name>
X-Handler-File: <file_name>
4. File system operations such as listing files, searching in files, finding files, etc.
Ask for documentation if needed.
Watching this iteration process of code implementation (whether it be new features, or fixes, enhancements), testing, log checking, fixing, testing, is amazing to watch. If it goes off track, I just have to cancel, go back to a checkpoint or start a new session, give it the correct direction and watch it go again.