# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

**Augint Billing Library** - A serverless billing service library for Stripe integration. This is a Python library designed to be used by AWS Lambda functions for implementing usage-based billing.

#### Test Quality Principles:
1. **Test Behavior, Not Implementation**: Verify what the system does, not how
2. **Use State Verification**: Check database changes, not method calls
3. **Test Real Business Logic**: Actual calculations, validations, transformations
4. **Maintain Test Independence**: Each test should be isolated and deterministic


### Stripe Integration
- Uses official Stripe Python SDK
- Event processing support (webhooks, EventBridge, queues)
- Handles customer creation, invoicing, and payment processing
- Supports both test and live modes

### AWS Services Used
- **DynamoDB**: Primary data storage (boto3)
- **EventBridge**: Event publishing for billing events

## Important Implementation Notes

2. **No Telemetry**: Sentry and telemetry code removed for simplicity
4. **Error Handling**: Use custom exceptions from `exceptions.py`
5. **Type Hints**: Full type hints required (mypy strict mode)

## Critical Context from Development Sessions

### Library vs API Layer Separation - STRICT BOUNDARIES ⚠️

#### THIS IS A LIBRARY - What It IS:
- **Pure Python library** published to PyPI for import by other projects
- **Business logic only** - billing calculations, Stripe operations, data models
- **Infrastructure-agnostic** - processes events regardless of delivery mechanism
- **Reusable components** - can be imported by Lambda, FastAPI, Django, Flask, etc.
- **CLI for testing and emergency use** - admin/debug tool, NOT the primary interface but must remain usable

#### What It IS NOT - NEVER ADD THESE:
- ❌ **NO Lambda handlers** - Those belong in augint-billing-api project
- ❌ **NO API Gateway configs** - Infrastructure layer responsibility  
- ❌ **NO HTTP routing/endpoints** - API wrapper project handles this
- ❌ **NO infrastructure creation** - Assumes DynamoDB, EventBridge exist
- ❌ **NO authentication/authorization** - API layer handles Cognito/JWT
- ❌ **NO request/response handling** - Library returns data, API formats responses
- ❌ **NO CloudFormation/SAM templates** - Only minimal test infrastructure
- ❌ **NO API rate limiting** - API Gateway responsibility
- ❌ **NO CORS handling** - API layer concern
- ❌ **NO webhook endpoints** - API creates the endpoint, library processes events

#### Testing Without Infrastructure:
- Use CLI commands for manual testing
- Use pytest with mocked AWS/Stripe services for unit tests
- Use DynamoDB for integration tests
- Never require deployed infrastructure to test the library

#### When You're Tempted to Add Infrastructure:
Ask yourself:
1. "Does this process business data?" → ✅ Library
2. "Does this handle HTTP/Lambda/API Gateway?" → ❌ API project
3. "Does this require AWS deployment?" → ❌ API project
4. "Can this be tested without AWS?" → ✅ Library
5. "Is this reusable across different frameworks?" → ✅ Library



### Infrastructure Testing
- **Minimal template.yaml** - Only what's needed for testing
- **Account isolation** - Environments isolated by AWS account, not by naming convention

### Anti-Patterns to Avoid

1. **DON'T add authentication/authorization** - API layer responsibility
2. **DON'T create infrastructure** - Assume it exists
3. **DON'T add API routes or Lambda handlers** - Library only
4. **DON'T mock internal components in tests** - Use real objects
5. **DON'T use float for money** - Always use Decimal
6. **DON'T catch and suppress exceptions** - Let them bubble up
7. **DON'T add logging to library** - API layer responsibility
8. **DON'T hardcode configuration** - Use environment variables

### Component Ownership Matrix

| Component | augint-billing-lib (THIS) | augint-billing-api | Notes |
|-----------|---------------------------|-------------------|-------|
| Business Logic | ✅ All billing calculations | ❌ | Pure functions, no I/O |
| Data Models | ✅ Pydantic models | ❌ | Shared type definitions |
| DynamoDB Operations | ✅ CRUD operations | ❌ | Via boto3 client |
| Stripe SDK Calls | ✅ Payment processing | ❌ | Official SDK usage |
| Lambda Handlers | ❌ NEVER | ✅ | Infrastructure layer |
| API Routes | ❌ NEVER | ✅ | REST/GraphQL endpoints |
| Authentication | ❌ NEVER | ✅ | Cognito/JWT validation |
| HTTP Request Parsing | ❌ NEVER | ✅ | Body/header extraction |
| Response Formatting | ❌ NEVER | ✅ | Status codes, CORS |
| Webhook Endpoints | ❌ NEVER | ✅ | HTTP POST handlers |
| Error HTTP Responses | ❌ NEVER | ✅ | 4xx/5xx responses |
| CloudWatch Logging | ❌ NEVER | ✅ | Request/response logs |
| API Gateway Config | ❌ NEVER | ✅ | Routes, stages, auth |
| Rate Limiting | ❌ NEVER | ✅ | API Gateway throttling |
| Request Validation | ⚠️ Data only | ✅ Full | Library validates data, API validates HTTP |
| Event Processing | ✅ Business logic | ⚠️ Routing only | Library processes, API routes |
| CLI Commands | ✅ Testing/admin | ❌ | Development tool only |
| Unit Tests | ✅ Comprehensive | ✅ Minimal | Library tests logic, API tests integration |

### Database Design Constraints

1. **Single Table Design**: All data in one DynamoDB table
2. **Lowercase Keys**: Always use lowercase `pk`, `sk`, `gsi1pk`, `gsi1sk`
3. **Uppercase Prefixes**: Entity prefixes like `CUSTOMER#`, `USAGE#`
4. **No JOINs**: Design access patterns to avoid cross-entity queries
5. **Eventual Consistency**: Design for eventual consistency where possible

### External Service Integration

#### Stripe Integration Rules
- Always use official SDK, never raw HTTP
- Process Stripe events from any source (webhook validation optional)
- Handle Stripe-specific exceptions
- Use test mode for all non-production environments
- Store Stripe IDs separately from internal IDs
