···11+# AT Protocol Implementation Guide
22+33+This guide provides comprehensive information about implementing AT Protocol (atproto) in the Coves platform.
44+55+## Table of Contents
66+- [Core Concepts](#core-concepts)
77+- [Architecture Overview](#architecture-overview)
88+- [Lexicons](#lexicons)
99+- [XRPC](#xrpc)
1010+- [Data Storage](#data-storage)
1111+- [Identity & Authentication](#identity--authentication)
1212+- [Firehose & Sync](#firehose--sync)
1313+- [Go Implementation Patterns](#go-implementation-patterns)
1414+- [Best Practices](#best-practices)
1515+1616+## Core Concepts
1717+1818+### What is AT Protocol?
1919+AT Protocol is a federated social networking protocol that enables:
2020+- **Decentralized identity** - Users own their identity (DID) and can move between providers
2121+- **Data portability** - Users can export and migrate their full social graph and content
2222+- **Interoperability** - Different apps can interact with the same underlying data
2323+2424+### Key Components
2525+1. **DIDs (Decentralized Identifiers)** - Persistent user identifiers (e.g., `did:plc:xyz123`)
2626+2. **Handles** - Human-readable names that resolve to DIDs (e.g., `alice.bsky.social`)
2727+3. **Repositories** - User data stored as signed Merkle trees in CAR files
2828+4. **Lexicons** - Schema definitions for data types and API methods
2929+5. **XRPC** - The RPC protocol for client-server communication
3030+6. **Firehose** - Real-time event stream of repository changes
3131+3232+## Architecture Overview
3333+3434+### Two-Database Pattern
3535+AT Protocol requires two distinct data stores:
3636+3737+#### 1. Repository Database (Source of Truth)
3838+- **Purpose**: Stores user-generated content as immutable, signed records
3939+- **Storage**: CAR files containing Merkle trees + PostgreSQL metadata
4040+- **Access**: Through XRPC procedures that modify repositories
4141+- **Properties**:
4242+ - Append-only (soft deletes via tombstones)
4343+ - Cryptographically verifiable
4444+ - User-controlled and portable
4545+4646+#### 2. AppView Database (Query Layer)
4747+- **Purpose**: Denormalized, indexed data optimized for queries
4848+- **Storage**: PostgreSQL with application-specific schema
4949+- **Access**: Through XRPC queries (read-only)
5050+- **Properties**:
5151+ - Eventually consistent with repositories
5252+ - Can be rebuilt from repository data
5353+ - Application-specific aggregations
5454+5555+### Data Flow
5656+5757+```
5858+Write Path:
5959+Client → XRPC Procedure → Service → Write Repo → CAR Store
6060+ ↓
6161+ Firehose Event
6262+ ↓
6363+ AppView Indexer
6464+ ↓
6565+ AppView Database
6666+6767+Read Path:
6868+Client → XRPC Query → Service → Read Repo → AppView Database
6969+```
7070+7171+## Lexicons
7272+7373+### What are Lexicons?
7474+Lexicons are JSON schema files that define:
7575+- Data types (records stored in repositories)
7676+- API methods (queries and procedures)
7777+- Input/output schemas for API calls
7878+7979+### Lexicon Structure
8080+```json
8181+{
8282+ "lexicon": 1,
8383+ "id": "social.coves.community.profile",
8484+ "defs": {
8585+ "main": {
8686+ "type": "record",
8787+ "key": "self",
8888+ "record": {
8989+ "type": "object",
9090+ "required": ["name", "createdAt"],
9191+ "properties": {
9292+ "name": {"type": "string", "maxLength": 64},
9393+ "description": {"type": "string", "maxLength": 256},
9494+ "rules": {"type": "array", "items": {"type": "string"}},
9595+ "createdAt": {"type": "string", "format": "datetime"}
9696+ }
9797+ }
9898+ }
9999+ }
100100+}
101101+```
102102+103103+### Lexicon Types
104104+105105+#### 1. Record Types
106106+Define data structures stored in user repositories:
107107+```json
108108+{
109109+ "type": "record",
110110+ "key": "tid|rkey|literal",
111111+ "record": { /* schema */ }
112112+}
113113+```
114114+115115+#### 2. Query Types (Read-only)
116116+Define read operations that don't modify state:
117117+```json
118118+{
119119+ "type": "query",
120120+ "parameters": { /* input schema */ },
121121+ "output": { /* response schema */ }
122122+}
123123+```
124124+125125+#### 3. Procedure Types (Write)
126126+Define operations that modify repositories:
127127+```json
128128+{
129129+ "type": "procedure",
130130+ "input": { /* request body schema */ },
131131+ "output": { /* response schema */ }
132132+}
133133+```
134134+135135+### Naming Conventions
136136+- Use reverse-DNS format: `social.coves.community.profile`
137137+- Queries often start with `get`, `list`, or `search`
138138+- Procedures often start with `create`, `update`, or `delete`
139139+- Keep names descriptive but concise
140140+141141+## XRPC
142142+143143+### What is XRPC?
144144+XRPC (Cross-Protocol RPC) is AT Protocol's HTTP-based RPC system:
145145+- All methods live under `/xrpc/` path
146146+- Method names map directly to Lexicon IDs
147147+- Supports both JSON and binary data
148148+149149+### Request Format
150150+```
151151+# Query (GET)
152152+GET /xrpc/social.coves.community.getCommunity?id=123
153153+154154+# Procedure (POST)
155155+POST /xrpc/social.coves.community.createPost
156156+Content-Type: application/json
157157+Authorization: Bearer <token>
158158+159159+{"text": "Hello, Coves!"}
160160+```
161161+162162+### Authentication
163163+- Uses Bearer tokens in Authorization header
164164+- Tokens are JWTs signed by the user's signing key
165165+- Service auth for server-to-server calls
166166+167167+## Data Storage
168168+169169+### CAR Files
170170+Content Addressable archive files store repository data:
171171+- Contains IPLD blocks forming a Merkle tree
172172+- Each block identified by CID (Content IDentifier)
173173+- Enables cryptographic verification and efficient sync
174174+175175+### Record Keys (rkeys)
176176+- Unique identifiers for records within a collection
177177+- Can be TIDs (timestamp-based) or custom strings
178178+- Must match pattern: `[a-zA-Z0-9._~-]{1,512}`
179179+180180+### Repository Structure
181181+```
182182+Repository (did:plc:user123)
183183+├── social.coves.post
184184+│ ├── 3kkreaz3amd27 (TID)
185185+│ └── 3kkreaz3amd28 (TID)
186186+├── social.coves.community.member
187187+│ ├── community123
188188+│ └── community456
189189+└── app.bsky.actor.profile
190190+ └── self
191191+```
192192+193193+## Identity & Authentication
194194+195195+### DIDs (Decentralized Identifiers)
196196+- Permanent, unique identifiers for users
197197+- Two types supported:
198198+ - `did:plc:*` - Hosted by PLC Directory
199199+ - `did:web:*` - Self-hosted
200200+201201+### Handle Resolution
202202+Handles resolve to DIDs via:
203203+1. DNS TXT record: `_atproto.alice.com → did:plc:xyz`
204204+2. HTTPS well-known: `https://alice.com/.well-known/atproto-did`
205205+206206+### Authentication Flow
207207+1. Client creates session with identifier/password
208208+2. Server returns access/refresh tokens
209209+3. Client uses access token for API requests
210210+4. Refresh when access token expires
211211+212212+## Firehose & Sync
213213+214214+### Firehose Events
215215+Real-time stream of repository changes:
216216+- Commit events (creates, updates, deletes)
217217+- Identity events (handle changes)
218218+- Account events (status changes)
219219+220220+### Subscribing to Firehose
221221+Connect via WebSocket to `com.atproto.sync.subscribeRepos`:
222222+```
223223+wss://bsky.network/xrpc/com.atproto.sync.subscribeRepos
224224+```
225225+226226+### Processing Events
227227+- Events include full record data and operation type
228228+- Process events to update AppView database
229229+- Handle out-of-order events with sequence numbers
230230+231231+## Go Implementation Patterns
232232+233233+### Using Indigo Library
234234+Bluesky's official Go implementation provides:
235235+- Lexicon code generation
236236+- CAR file handling
237237+- XRPC client/server
238238+- Firehose subscription
239239+240240+### Code Generation
241241+Generate Go types from Lexicons:
242242+```bash
243243+go run github.com/bluesky-social/indigo/cmd/lexgen \
244244+ --package coves \
245245+ --prefix social.coves \
246246+ --outdir api/coves \
247247+ lexicons/social/coves/*.json
248248+```
249249+250250+### Repository Operations
251251+```go
252252+// Write to repository
253253+rkey := models.GenerateTID()
254254+err := repoStore.CreateRecord(ctx, userDID, "social.coves.post", rkey, &Post{
255255+ Text: "Hello",
256256+ CreatedAt: time.Now().Format(time.RFC3339),
257257+})
258258+259259+// Read from repository
260260+records, err := repoStore.ListRecords(ctx, userDID, "social.coves.post", limit, cursor)
261261+```
262262+263263+### XRPC Handler Pattern
264264+```go
265265+func (s *Server) HandleGetCommunity(ctx context.Context) error {
266266+ // 1. Parse and validate input
267267+ id := xrpc.QueryParam(ctx, "id")
268268+269269+ // 2. Call service layer
270270+ community, err := s.communityService.GetByID(ctx, id)
271271+ if err != nil {
272272+ return err
273273+ }
274274+275275+ // 3. Return response
276276+ return xrpc.WriteJSONResponse(ctx, community)
277277+}
278278+```
279279+280280+## Best Practices
281281+282282+### 1. Lexicon Design
283283+- Keep schemas focused and single-purpose
284284+- Use references (`$ref`) for shared types
285285+- Version carefully - Lexicons are contracts
286286+- Document thoroughly with descriptions
287287+288288+### 2. Data Modeling
289289+- Store minimal data in repositories
290290+- Denormalize extensively in AppView
291291+- Use record keys that are meaningful
292292+- Plan for data portability
293293+294294+### 3. Performance
295295+- Batch firehose processing
296296+- Use database transactions wisely
297297+- Index AppView tables appropriately
298298+- Cache frequently accessed data
299299+300300+### 4. Error Handling
301301+- Use standard XRPC error codes
302302+- Provide meaningful error messages
303303+- Handle network failures gracefully
304304+- Implement proper retry logic
305305+306306+### 5. Security
307307+- Validate all inputs against Lexicons
308308+- Verify signatures on repository data
309309+- Rate limit API endpoints
310310+- Sanitize user-generated content
311311+312312+### 6. Federation
313313+- Design for multi-instance deployment
314314+- Handle remote user identities
315315+- Respect instance-specific policies
316316+- Plan for cross-instance data sync
317317+318318+## Common Patterns
319319+320320+### Handling User Content
321321+- Always validate against Lexicon schemas
322322+- Store in user's repository via CAR files
323323+- Index in AppView for efficient queries
324324+- Emit firehose events for subscribers
325325+326326+## Resources
327327+328328+### Official Documentation
329329+- [ATProto Specifications](https://atproto.com/specs)
330330+- [Lexicon Documentation](https://atproto.com/specs/lexicon)
331331+- [XRPC Specification](https://atproto.com/specs/xrpc)
332332+333333+### Reference Implementations
334334+- [Indigo (Go)](https://github.com/bluesky-social/indigo)
335335+- [ATProto SDK (TypeScript)](https://github.com/bluesky-social/atproto)
336336+337337+### Tools
338338+- [Lexicon CLI](https://github.com/bluesky-social/atproto/tree/main/packages/lex-cli)
339339+- [goat CLI](https://github.com/bluesky-social/indigo/tree/main/cmd/goat)
+51-75
CLAUDE.md
···11Project:
22-You are a distinguished developer helping build Coves, a forum like atProto social media platform (think reddit).
22+You are a distinguished developer helping build Coves, a forum like atProto social media platform (think reddit / lemmy).
3344Human & LLM Readability Guidelines:
55- Clear Module Boundaries: Each feature is a self-contained module with explicit interfaces
···1919- DB: PostgreSQL
2020- atProto for federation & user identities
21212222-## atProto Guidelines
2323-- Attempt to utilize bsky built indigo packages before building atProto layer functions from scratch
2222+## atProto Guidelines
2323+2424+For comprehensive AT Protocol implementation details, see [ATPROTO_GUIDE.md](./ATPROTO_GUIDE.md).
2525+2626+Key principles:
2727+- Utilize Bluesky's Indigo packages before building custom atProto functionality
2828+- Everything is XRPC - no separate REST API layer needed
2929+- Follow the two-database pattern: Repository (CAR files) and AppView (PostgreSQL)
3030+- Design for federation and data portability from the start
24312532# Architecture Guidelines
26332734## Required Layered Architecture
2835Follow this strict separation of concerns:
2936```
3030-Handler (HTTP) → Service (Business Logic) → Repository (Data Access) → Database
3737+Handler (XRPC) → Service (Business Logic) → Repository (Data Access) → Database
3138```
3939+- Handlers: XRPC request/response only
4040+- Services: Business logic, uses both write/read repos
4141+- Write Repos: CAR store operations
4242+- Read Repos: AppView queries
4343+32443345## Directory Structure
3434-```
3535-internal/
3636-├── api/
3737-│ ├── handlers/ # HTTP request/response handling ONLY
3838-│ └── routes/ # Route definitions
3939-├── core/
4040-│ └── [domain]/ # Business logic, domain models, service interfaces
4141-│ ├── service.go # Business logic implementation
4242-│ ├── repository.go # Data access interface
4343-│ └── [domain].go # Domain models
4444-└── db/
4545- └── postgres/ # Database implementation details
4646- └── [domain]_repo.go # Repository implementations
4747-```
4646+4747+For a detailed project structure with file-level details and implementation status, see [PROJECT_STRUCTURE.md](./PROJECT_STRUCTURE.md).
4848+4949+The project follows a layered architecture with clear separation between:
5050+- **XRPC handlers** - atProto API layer
5151+ - Only handle XRPC concerns: parsing requests, formatting responses
5252+ - Delegate all business logic to services
5353+ - No direct database access
5454+- **Core business logic** - Domain services and models
5555+ - Contains all business logic
5656+ - Orchestrates between write and read repositories
5757+ - Manages transactions and complex operations
5858+- **Data repositories** - Split between CAR store writes and AppView reads
5959+ - **Write Repositories** (`internal/atproto/carstore/*_write_repo.go`)
6060+ - Modify CAR files (source of truth)
6161+- **Read Repositories** (`db/appview/*_read_repo.go`)
6262+ - Query denormalized PostgreSQL tables
6363+ - Optimized for performance
48644965## Strict Prohibitions
5066- **NEVER** put SQL queries in handlers
5167- **NEVER** import database packages in handlers
5268- **NEVER** pass *sql.DB directly to handlers
5353-- **NEVER** mix business logic with HTTP concerns
6969+- **NEVER** mix business logic with XRPC concerns
5470- **NEVER** bypass the service layer
55715656-## Required Patterns
5757-5858-### Handlers (HTTP Layer)
5959-- Only handle HTTP concerns: parsing requests, formatting responses
6060-- Delegate all business logic to services
6161-- No direct database access
6262-6363-Example:
6464-```go
6565-func (h *UserHandler) CreateUser(w http.ResponseWriter, r *http.Request) {
6666- var req CreateUserRequest
6767- json.NewDecoder(r.Body).Decode(&req)
6868-6969- user, err := h.userService.CreateUser(req) // Delegate to service
7070- // Handle response formatting only
7171-}
7272-```
7373-7474-### Services (Business Layer)
7575-- Contain all business logic and validation
7676-- Use repository interfaces, never concrete implementations
7777-- Handle transactions and complex operations
7878-7979-Example:
8080-```go
8181-type UserService struct {
8282- userRepo UserRepository // Interface, not concrete type
8383-}
8484-```
8585-8686-### Repositories (Data Layer)
8787-- Define interfaces in core/[domain]/
8888-- Implement in db/postgres/
8989-- Handle all SQL queries and database operations
9090-9191-Example:
9292-```go
9393-// Interface in core/users/repository.go
9494-type UserRepository interface {
9595- Create(user User) (*User, error)
9696- GetByID(id int) (*User, error)
9797-}
9898-9999-// Implementation in db/postgres/user_repo.go
100100-type PostgresUserRepo struct {
101101- db *sql.DB
102102-}
103103-```
104104-10572## Testing Requirements
10673- Services must be easily mockable (use interfaces)
10774- Integration tests should test the full stack
···119862. Generate test file with failing tests
120873. Generate implementation to pass tests
121884. Generate handler with tests
122122-5. Update routes in api/routes/
8989+5. Update routes in xrpc/routes/
1239012491### Refactoring Checklist
12592Before considering a feature complete:
···135102- Never modify existing migrations
136103- Always provide rollback migrations
137104138138-139139-140105## Dependency Injection
141106- Use constructor functions for all components
142107- Pass interfaces, not concrete types
···145110Example dependency wiring:
146111```go
147112// main.go
148148-userRepo := postgres.NewUserRepository(db)
149149-userService := users.NewUserService(userRepo)
150150-userHandler := handlers.NewUserHandler(userService)
113113+userWriteRepo := carstore.NewUserWriteRepository(carStore)
114114+userReadRepo := appview.NewUserReadRepository(db)
115115+userService := users.NewUserService(userWriteRepo, userReadRepo)
116116+userHandler := xrpc.NewUserHandler(userService)
151117```
152118153119## Error Handling
···157123- Never expose internal error details in API responses
158124159125### Context7 Usage Guidelines:
160160-- Always check Context7 for best practices before implementing external integrations
126126+- Always check Context7 for best practices before implementing external integrations and packages
161127- Use Context7 to understand proper error handling patterns for specific libraries
162128- Reference Context7 for testing patterns with external dependencies
163129- Consult Context7 for proper configuration patterns
130130+131131+## XRPC Implementation
132132+133133+For detailed XRPC patterns and Lexicon examples, see [ATPROTO_GUIDE.md](./ATPROTO_GUIDE.md#xrpc).
134134+135135+### Key Points
136136+- All client interactions go through XRPC endpoints
137137+- Handlers validate against Lexicon schemas automatically
138138+- Queries are read-only, procedures modify repositories
139139+- Every endpoint must have a corresponding Lexicon definition
+76
PROJECT_STRUCTURE.md
···11+# Coves Project Structure
22+33+This document provides an overview of the Coves project directory structure, following atProto architecture patterns.
44+55+**Legend:**
66+- † = Planned but not yet implemented
77+- 🔒 = Security-sensitive files
88+99+```
1010+Coves/
1111+├── CLAUDE.md # Project guidelines and architecture decisions
1212+├── ATPROTO_GUIDE.md # Comprehensive AT Protocol implementation guide
1313+├── PROJECT_STRUCTURE.md # This file - project structure overview
1414+├── LICENSE # Project license
1515+├── README.md # Project overview and setup instructions
1616+├── go.mod # Go module definition
1717+├── go.sum # Go module checksums
1818+│
1919+├── cmd/ # Application entrypoints
2020+├── internal/ # Private application code
2121+│ ├── xrpc/ † # XRPC handlers (atProto API layer)
2222+│ ├── api/ # Traditional HTTP endpoints (minimal)
2323+│ ├── core/ # Business logic and domain models
2424+│ ├── atproto/ # atProto-specific implementations
2525+│ └── config/ † # Configuration management
2626+│
2727+├── db/ # Database layer
2828+│ ├── appview/ † # AppView PostgreSQL queries
2929+│ ├── postgres/ # Legacy/non-atProto database operations
3030+│ ├── migrations/ # Database migrations
3131+│ ├── local_dev_db_compose/ # Local development database
3232+│ └── test_db_compose/ # Test database setup
3333+│
3434+├── pkg/ # Public packages (can be imported by external projects)
3535+├── data/ # Runtime data storage
3636+│ └── carstore/ 🔒 # CAR file storage directory
3737+│
3838+├── scripts/ # Development and deployment scripts
3939+├── tests/ # Integration and e2e tests
4040+├── docs/ † # Additional documentation
4141+├── local_dev_data/ # Local development data
4242+├── test_db_data/ # Test database seed data
4343+└── build/ † # Build artifacts
4444+```
4545+4646+## Implementation Status
4747+4848+### Completed ✓
4949+- Basic repository structure
5050+- User domain models
5151+- CAR store foundation
5252+- Lexicon schemas
5353+- Database migrations
5454+5555+### In Progress 🚧
5656+- Repository service implementation
5757+- User service
5858+- Basic authentication
5959+6060+### Planned 📋
6161+- XRPC handlers
6262+- AppView indexer
6363+- Firehose implementation
6464+- Community features
6565+- Moderation system
6666+- Feed algorithms
6767+6868+## Development Guidelines
6969+7070+For detailed implementation guidelines, see [CLAUDE.md](./CLAUDE.md) and [ATPROTO_GUIDE.md](./ATPROTO_GUIDE.md).
7171+7272+1. **Start with Lexicons**: Define data schemas first
7373+2. **Implement Core Domain**: Create models and interfaces
7474+3. **Build Services**: Implement business logic
7575+4. **Add Repositories**: Create data access layers
7676+5. **Wire XRPC**: Connect handlers last