| name | backend-dev |
| description | This skill should be used when developing backend services for Manjha using Encore.ts, implementing agents, writing E2E tests, or working with the message-driven architecture. It ensures adherence to TDD practices, type safety, proper logging, and Manjha's development principles. |
| license | MIT |
Backend Development Skill for Manjha
This skill provides guidance for developing backend services in the Manjha project using Encore.ts, LangGraph agents, and PostgreSQL.
When to Use This Skill
Use this skill when:
- Creating new Encore.ts services or agents
- Writing E2E tests for backend flows
- Implementing message classification or agent orchestration
- Working with the database schema
- Setting up logging or configuration
- Debugging backend issues
- Ensuring type safety across services
Core Principles
1. Spec-Driven Development
Every feature starts with a spec in /specs folder before any code is written.
2. Red-Green-Refactor TDD
Follow this cycle religiously:
- Red: Write E2E test that fails
- Green: Implement feature until test passes
- Refactor: Clean up while keeping tests green
3. Type Safety (Non-Negotiable)
- Zero tolerance for
any types
- Use explicit interfaces and types (see
contracts/api.types.ts and contracts/database.types.ts)
- Prefer enums over string unions
- Linter must enforce type safety
4. Centralized Logging
All logging goes through the common logging module at common/logging/logger.ts. Never use console.log.
Architecture Overview
Encore.ts Services
Manjha uses Encore.ts for all backend services. Each service follows this structure:
service-name/
├── encore.service.ts # Service definition & API endpoints
├── agent.ts # Agent logic (if applicable)
├── db.ts # Database operations (if applicable)
└── migrations/ # SQL migrations (if applicable)
Agent-as-Service Pattern
Backend services are modular agents:
message-classifier: Routes messages to appropriate agents
finance-agent: Handles financial queries
general-agent: Handles general queries
agent-orchestrator: Orchestrates multi-agent workflows using LangGraph
Service Communication
Services communicate through Encore's generated clients:
import { getAuthData } from "encore.dev/auth";
import * as classifier from "~encore/clients/message-classifier";
E2E Test Development
Test Structure
E2E tests live in backend/tests/e2e/ and follow this format:
import { describe, it, expect, beforeEach } from "vitest";
describe("Feature Name", () => {
beforeEach(async () => {
});
it("validates the happy path flow", async () => {
});
it("handles edge case: specific scenario", async () => {
});
});
Test Principles
- Test USER-FACING behavior, not implementation details
- Each test should validate complete flows, not petty unit tests
- Use descriptive names that explain the scenario
- Include PURPOSE comments explaining what invariants are being tested
- Tests should be independent and idempotent
Running Tests
cd backend
encore test
CRITICAL: Never use npm test directly. Always use encore test as it properly initializes the Encore runtime environment.
Creating New Services
Step 1: Define Service Structure
Create the service directory with encore.service.ts:
import { Service } from "encore.dev/service";
export default new Service("service-name");
Step 2: Define API Endpoints
import { api } from "encore.dev/api";
import { Header } from "encore.dev/api";
import type { APIResponse } from "../contracts/api.types";
interface RequestPayload {
}
interface ResponsePayload {
}
export const endpointName = api(
{ method: "POST", path: "/path", expose: true, auth: false },
async (payload: RequestPayload): Promise<APIResponse<ResponsePayload>> => {
}
);
Step 3: Add Database Operations (if needed)
Create migrations in migrations/ directory:
001_create_table.up.sql - Migration
001_create_table.down.sql - Rollback
Define database operations in db.ts using the patterns from chat-gateway/db.ts.
Step 4: Implement Agent Logic (if applicable)
For agent services, create agent.ts with clear separation of concerns.
Step 5: Add to Contracts
Update contracts/api.types.ts and contracts/database.types.ts with new types.
Working with Agents
LangGraph Integration
Agent orchestration uses LangGraph. See agent-orchestrator/graph.ts for patterns.
Agent State Management
Define strongly-typed state interfaces:
interface AgentState {
messages: Array<{ role: string; content: string }>;
context: Record<string, unknown>;
}
Message Classification
The message-classifier service routes messages to appropriate agents. When adding new message types:
- Update the classifier logic in
message-classifier/classifier.ts
- Add enum values (not string unions)
- Update tests to cover new message types
Configuration & Constants
All configuration lives in common/config/constants.ts:
- API keys (from environment variables)
- Model configurations
- Rate limits
- Timeouts
Reference the file in references/ for complete patterns.
Logging Best Practices
import { logger } from "../common/logging/logger";
logger.info("Processing request", { userId, requestId });
logger.error("Failed to process", { error, context });
logger.debug("Detailed state", { state });
Type Safety Checklist
Before committing:
Quality Gates
Every backend change must:
- ✓ Have a spec in
/specs
- ✓ Have E2E test(s) that pass
- ✓ Use proper logging via common module
- ✓ Have zero
any types (linter enforced)
- ✓ Follow file organization rules
Common Patterns
API Response Pattern
import type { APIResponse } from "../contracts/api.types";
return { success: true, data: result };
return { success: false, error: { code: "ERROR_CODE", message: "Description" } };
Error Handling Pattern
try {
logger.info("Operation succeeded", { context });
return { success: true, data };
} catch (error) {
logger.error("Operation failed", { error, context });
return {
success: false,
error: { code: "OPERATION_ERROR", message: error.message }
};
}
Database Query Pattern
See chat-gateway/db.ts for established patterns on:
- Transaction handling
- Connection pooling
- Query parameterization
- Error handling
References
See the references/ directory for:
- Complete Encore.ts patterns
- Database schema documentation
- Testing patterns and examples
- LangGraph agent patterns
Next Steps After Using This Skill
- Review the E2E test to ensure it covers the feature
- Verify type safety (run linter)
- Check logging is through common module
- Confirm spec exists and is up-to-date
- Update this skill with any new patterns discovered