Delegate independent tasks to specialized agents working concurrently with isolated context.
Tzurot v3 Architecture
tzurot-architecture
Microservices architecture for Tzurot v3 - Service boundaries, responsibilities, dependency rules, and anti-patterns from v2. Use when deciding where code belongs or designing new features.
SKILL.md
Full skill instructions
Tzurot v3 Architecture
Use this skill when: Adding new features, deciding where code belongs, designing system interactions, or refactoring service boundaries.
Quick Reference
Discord User
↓
bot-client (Discord.js)
↓ HTTP
api-gateway (Express + BullMQ)
↓ Redis Queue
ai-worker (AI + pgvector)
↓
OpenRouter/Gemini API
Core Principles
- Simple, clean classes - No DDD over-engineering (learned from v2)
- Clear service boundaries - Each service has single responsibility
- No circular dependencies - Services can't import from each other
- Shared code in common-types - Cross-service types, utils, services
- Constructor injection - Simple dependency passing, no DI containers
Three Microservices
| Service | Responsibility | Does | Does NOT |
|---|---|---|---|
| bot-client | Discord interface | Events, webhooks, commands, formatting | Business logic, AI calls, direct DB |
| api-gateway | HTTP API + queue | Endpoints, validation, job creation | AI processing, Discord interaction |
| ai-worker | AI + memory | Jobs, memory, AI calls, embeddings | HTTP endpoints, Discord interaction |
Where to Put New Code
| Type | Location |
|---|---|
| Webhook/message formatting | bot-client/ |
| Slash commands | bot-client/commands/ |
| HTTP endpoints | api-gateway/routes/ |
| Job creation | api-gateway/queue.ts |
| AI provider clients | ai-worker/providers/ |
| Memory/embeddings | ai-worker/services/ |
| Shared types/constants | common-types/ |
| Discord type guards | common-types/types/ |
Autocomplete Utilities (CRITICAL)
ALWAYS check for existing utilities before writing autocomplete handlers.
Available in bot-client/src/utils/autocomplete/:
| Utility | Purpose | Option Names |
|---|---|---|
handlePersonalityAutocomplete | Personality selection | personality, character |
handlePersonaAutocomplete | Profile/persona selection | profile, persona |
// ✅ GOOD - Delegate to shared utility
import { handlePersonalityAutocomplete } from '../../utils/autocomplete/personalityAutocomplete.js';
await handlePersonalityAutocomplete(interaction, {
optionName: 'personality',
showVisibility: true,
ownedOnly: false,
});
// ❌ BAD - Duplicating 50+ lines of autocomplete logic
Error Message Patterns
| Layer | Pattern | Example |
|---|---|---|
| api-gateway | Clean JSON, NO emojis | { "error": "NOT_FOUND", "message": "Persona not found" } |
| bot-client | ADD emojis for users | '❌ Profile not found.' |
// ✅ Gateway - clean for programmatic use
sendError(res, ErrorResponses.notFound('Persona'));
// ✅ Bot - emoji for users
await interaction.editReply({ content: '❌ Profile not found.' });
Anti-Patterns from v2 (DON'T DO)
| Pattern | Why Not | v3 Alternative |
|---|---|---|
Generic IRepository<T> | Too abstract | Concrete service methods |
| DI containers | Over-engineered | Direct instantiation |
Controller→UseCase→Service→Repository→ORM | Too many layers | Route→Service→Prisma |
| Complex event bus | Unnecessary | Redis pub/sub for cache only |
| Value objects everywhere | Overhead | Simple validation functions |
// ❌ v2 - Container hell
container.bind('PersonalityService').to(PersonalityService);
const service = container.get('PersonalityService');
// ✅ v3 - Simple
const service = new PersonalityService(prisma);
Dependency Injection
// ✅ GOOD - Simple constructor injection
class MyService {
constructor(
private prisma: PrismaClient,
private redis: Redis
) {}
}
const service = new MyService(prisma, redis);
When to Extract a Service
Extract when:
- Shared across multiple microservices → common-types
- Complex business logic
- Stateful operations
- Easier testability needed
Keep inline when:
- Used in one place only
- Stateless utility function
- Very simple logic
Database Access
Direct Prisma in services - No repository pattern
// ✅ Direct Prisma
async getPersonality(id: string) {
return this.prisma.personality.findUnique({ where: { id } });
}
// ❌ Generic repository
interface PersonalityRepository {
findById(id: string): Promise<Personality>;
}
Configuration
- Environment variables: Secrets (tokens, DB URLs)
- common-types constants: Application config (timeouts, limits)
import { TIMEOUTS, RETRY_CONFIG } from '@tzurot/common-types';
const timeout = TIMEOUTS.LLM_INVOCATION;
Related Skills
- tzurot-async-flow - BullMQ job patterns
- tzurot-db-vector - Database patterns
- tzurot-types - Type definitions
- tzurot-gemini-collab - Major design decisions
References
- Full architecture:
CLAUDE.md#architecture - Project structure:
CLAUDE.md#project-structure - Architecture decisions:
docs/architecture/ARCHITECTURE_DECISIONS.md
More Other skills
brand-guidelines
Applies Anthropic's official brand colors and typography to any sort of artifact that may benefit from having Anthropic's look-and-feel. Use it when brand colors or style guidelines, visual formatting, or company design standards apply.
theme-factory
Toolkit for styling artifacts with a theme. These artifacts can be slides, docs, reportings, HTML landing pages, etc. There are 10 pre-set themes with colors/fonts that you can apply to any artifact that has been creating, or can generate a new theme on-the-fly.
internal-comms
A set of resources to help me write all kinds of internal communications, using the formats that my company likes to use. Claude should use this skill whenever asked to write some sort of internal communications (status reports, leadership updates, 3P updates, company newsletters, FAQs, incident reports, project updates, etc.).
Fundamental design principles for writing maintainable, testable Python code.
responsive-design
Modern responsive layouts using container queries, fluid typography, CSS Grid, and mobile-first strategies.
Generate Playwright tests from scenarios using interactive browser exploration and validation.
Automated website exploration and test case generation using Playwright.
Modern React state management with Redux Toolkit, Zustand, Jotai, and React Query for every state category.
gdpr-data-handling
GDPR-compliant data handling with consent management, data subject rights, and privacy controls.
Python error handling patterns including input validation, exception hierarchies, and partial failure handling. Use when implementing validation logic, designing exception strategies, handling batch processing failures, or building robust APIs.
refactor-plan
Detailed multi-file refactor planning with safety checks and rollback guidance.
