### Technique Selection Guide Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Provides guidance on when to use different prompt engineering techniques such as XML tags, Chain of Thought, and Few-Shot Examples, as well as when to keep prompts simple. ```markdown ### When to Use XML Tags - Complex multi-part instructions - Clear input/output boundaries needed - Structured data or examples - Section separation in long prompts ### When to Use Chain of Thought - Multi-step reasoning required - Need transparency in decision-making - Complex calculations or analysis - Debugging or validation tasks ### When to Use Few-Shot Examples - Format requirements are specific - Task is novel or uncommon - Consistent style needed across outputs - Edge cases must be demonstrated ### When to Keep It Simple - Task is straightforward and unambiguous - Model has strong baseline capability - Context window is limited - Speed/cost optimization needed ``` -------------------------------- ### Prompt Engineering Agent Examples Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Illustrates how the prompt-engineer agent can be used in different scenarios, such as creating system prompts for agents, writing one-shot task prompts, and refining existing prompt text. ```markdown Context: User needs a system prompt for a new agent. user: "Create an agent that reviews pull requests for security issues" assistant: "I'll use the prompt-engineer agent to craft an effective system prompt for your security review agent." Context: User has a one-shot task needing better instructions. user: "Help me write a prompt to extract key facts from legal documents" assistant: "Let me use the prompt-engineer agent to design precise extraction instructions." Context: User needs to refine existing prompt text. user: "This paragraph in my prompt isn't clear enough - can you improve it?" assistant: "I'll use the prompt-engineer agent to refine that section for clarity and impact." ``` -------------------------------- ### Quick Setup Script Source: https://github.com/schoblaska/dotclaude/blob/main/README.md Executes the setup script to symlink all configuration files to the ~/.claude/ directory. Use with caution. ```bash ./setup.sh ``` -------------------------------- ### Setup and Verification Commands Source: https://github.com/schoblaska/dotclaude/blob/main/CLAUDE.md This snippet provides the necessary bash commands to set up the dotclaude configuration by creating symbolic links and to verify that these links have been created correctly. ```bash ./setup.sh ls -la ~/.claude/ ``` -------------------------------- ### Optimization Strategies for Efficiency Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Techniques for enhancing prompt efficiency, such as front-loading critical instructions, removing redundancy, combining instructions, and using references. ```plaintext ### For Efficiency - Front-load critical instructions - Remove redundant phrases ruthlessly - Combine related instructions - Use references instead of repetition ``` -------------------------------- ### Prompt Architecture by Type Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Details the recommended structure for different types of prompts, including system prompts, CLAUDE.md files, commands, one-shot tasks, and iterative refinements. ```markdown ### System Prompts & Agents - Define identity and capabilities upfront - Establish decision frameworks, not rigid steps - Include heuristics for ambiguous situations - Specify tool usage patterns and priorities - Build in graceful degradation strategies ### CLAUDE.md Files - Document repository-specific conventions and patterns - Define reusable concepts with meaningful names - Include concrete examples with generic names (User, Item, Data) - Specify what to do AND what to avoid - Balance completeness with context efficiency - Structure as flat bulleted lists for quick reference ### Commands & CLI Instructions - Template with clear variable markers: `{user_input}`, `${ENV_VAR}` - Provide unambiguous success criteria - Include error handling and edge cases - Design for composability and piping - Consider zero-shot vs few-shot needs ### One-Shot Task Prompts - Lead with task definition and expected output format - Use CO-STAR when appropriate: Context, Objective, Style, Tone, Audience, Response - Include relevant examples only when format matters - Place critical instructions both early and late (primacy/recency) - Specify length, format, and quality constraints explicitly ### Iterative Refinements - Focus on the delta - what specifically needs to change - Preserve working elements while addressing gaps - Consider cascading effects of modifications - Maintain consistent voice and style ``` -------------------------------- ### Initiate PR Review Source: https://github.com/schoblaska/dotclaude/blob/main/commands/pr-review.md Command to start the PR review process by providing a pull request URL or number. ```bash /pr-review ``` -------------------------------- ### Markdown Prompting Best Practices Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Guidelines for structuring markdown prompts, including the use of headers, lists, code blocks, and emphasis for semantic hierarchy and clarity. ```markdown ### Markdown Prompts - Use headers for semantic hierarchy - Leverage lists for parallel instructions - Code blocks for literal content - Bold/italic for emphasis sparingly ``` -------------------------------- ### Cross-Model Compatibility Guidelines Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Strategies for ensuring compatibility across different language models, including avoiding model-specific quirks, noting Claude-specific optimizations, and planning for graceful degradation. ```plaintext ### Cross-Model Compatibility - Avoid model-specific quirks when possible - Note when using Claude-specific optimizations - Consider graceful degradation for other models ``` -------------------------------- ### LLM Prompt Writing Process Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md A step-by-step process for writing effective LLM prompts, covering research, objective identification, architecture selection, technique choice, drafting, refinement, and context consideration. ```plaintext ## Writing Process 1. **Research Domain When Appropriate**: Investigate industry practices, data sources, terminology, and professional workflows relevant to the task. 2. **Identify Core Objective**: What must the LLM accomplish? What constitutes success? 3. **Choose Architecture**: System prompt, command, one-shot, or hybrid? 4. **Select Techniques**: XML tags, CoT, few-shot, or minimal? 5. **Draft Concisely**: Every sentence must change behavior or clarify intent. 6. **Refine Ruthlessly**: Cut redundancy, sharpen language, verify each word's value. 7. **Consider Context**: How will this prompt interact with surrounding text, tools, or systems? ``` -------------------------------- ### Effective RSpec Test Descriptions Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Provides examples of well-written RSpec test descriptions that are specific, clear, and read like complete sentences. It contrasts good examples with common anti-patterns. ```ruby # Good it "returns the user's full name" do # test end it "raises an error when the email is invalid" do # test end # Bad it "should work" do # test end it "handles the thing" do # test end ``` -------------------------------- ### Shared Examples for Reusable Test Behavior Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Shows how to define and use `shared_examples` in RSpec to encapsulate common testing logic, promoting DRY principles while maintaining clarity. This example demonstrates testing a searchable model. ```ruby # Good - reusable and clear shared_examples "a searchable model" do it "finds records by name" do record = create(described_class.name.underscore, name: "Test") expect(described_class.search("Test")).to include(record) end end describe Product do it_behaves_like "a searchable model" end ``` -------------------------------- ### Optimization Strategies for Clarity Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Techniques to improve prompt clarity, such as using active voice, concrete nouns, parallel structure, and consistent terminology. ```plaintext ### For Clarity - Active voice and direct instructions - Concrete nouns over abstract concepts - Parallel structure for similar items - Consistent terminology throughout ``` -------------------------------- ### Optimization Strategies for Consistency Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Methods to ensure consistency in prompts, including defining key terms, establishing output formats, using constraints, and including validation criteria. ```plaintext ### For Consistency - Define key terms explicitly - Establish output formats upfront - Use constraints rather than suggestions - Include validation criteria ``` -------------------------------- ### Core Principle of Prompt Engineering Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md A reminder that prompt engineering is about deliberately shaping model behavior through precise language and structure, not just writing prose. ```plaintext Remember: You're engineering behavior, not writing prose. Every token should deliberately shape the model's response toward the intended outcome. ``` -------------------------------- ### FactoryBot User Creation with Callbacks Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Example of a FactoryBot factory for a User, including an `after(:create)` hook to set up associated data like posts and a profile. This demonstrates how to create complex test data structures. ```ruby factory :user do email { "user@example.com" } name { "Jane Doe" } after(:create) do |user| create_list(:post, 5, user: user) create(:profile, user: user) # Too much automatic setup end end ``` -------------------------------- ### Domain Cohesion vs. Layer Separation Examples Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rails.md Contrasts two approaches to structuring Rails applications: domain cohesion and strict layer separation. The 'Good' examples show logic grouped by domain concepts, with models enforcing business rules and controllers orchestrating requests. The 'Bad' examples highlight issues like controllers being coupled to view needs or helpers performing view logic. ```ruby # Good - each layer handles its own logic # View: Presentation decisions # <% if user_signed_in? && @article.editable_by?(current_user) %> # <%= link_to "Edit", edit_article_path(@article), # class: @article.published? ? "btn-warning" : "btn-primary" %> # <% end %> # Controller: Request orchestration def update @article = Article.find(params[:id]) authorize @article # authorization logic if @article.update(article_params) redirect_to @article else render :edit end end # Model: Business rules class Article < ApplicationRecord def editable_by?(user) user == author || user.admin? end def publish! return false unless valid? && draft? update!(published_at: Time.current, status: :published) end end ``` ```ruby # Bad - controller coupled to view needs class ArticlesController < ApplicationController def show @article = Article.find(params[:id]) @can_edit = user_signed_in? && (@article.author == current_user || current_user.admin?) @edit_button_class = @article.published? ? "btn-warning" : "btn-primary" @show_edit_button = @can_edit # Controller shouldn't know about UI end end ``` ```html # Bad - helper doing what view should do module ArticlesHelper def edit_button_for(article) return unless user_signed_in? && article.editable_by?(current_user) link_to "Edit", edit_article_path(article), class: article.published? ? "btn-warning" : "btn-primary" end end # Now view can't see its own logic: <%= edit_button_for(@article) %> ``` -------------------------------- ### LLM Prompt Quality Checklist Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md A checklist to evaluate the quality of LLM prompts, ensuring understandability, measurable success criteria, unique value per instruction, addressed edge cases, precise language, and reliability. ```plaintext ## Quality Checklist - Can a competent human understand the task from these instructions? - Are success criteria measurable and unambiguous? - Does each instruction add unique value? - Are edge cases addressed without overspecification? - Is the language precise and actionable? - Will this work reliably across multiple invocations? ``` -------------------------------- ### Template Language Considerations Source: https://github.com/schoblaska/dotclaude/blob/main/agents/prompt-engineer.md Best practices for using template languages like ERB and TSX, focusing on escaping special characters, variable injection safety, rendering context, and documentation of required variables. ```plaintext ### Template Languages (ERB, TSX, etc.) - Escape special characters properly - Design for variable injection safety - Consider rendering context and loops - Document required variables clearly ``` -------------------------------- ### Execute PR Feedback Command Source: https://github.com/schoblaska/dotclaude/blob/main/commands/pr-feedback.md This command initiates the process of fetching and addressing feedback for the current pull request. Claude automatically detects the associated PR and guides the user through the review process. ```bash /pr-feedback ``` -------------------------------- ### Clear vs. Unclear Failure Message Example Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Demonstrates how to write assertions with clear, informative failure messages versus generic ones. This improves debugging by making the cause of a test failure immediately obvious. ```ruby # Good - clear failure message expect(user.role).to eq("admin"), "Expected user to be promoted to admin after three years" # Bad - unclear what went wrong expect(result).to be_truthy ``` -------------------------------- ### Arrange-Act-Assert (AAA) Test Structure Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Demonstrates the Arrange-Act-Assert pattern for structuring RSpec tests. This pattern separates test setup, execution, and verification for improved readability and maintainability. ```ruby it "calculates the total with tax" do # Arrange order = Order.new(subtotal: 100) # Act total = order.total_with_tax # Assert expect(total).to eq(110) end ``` -------------------------------- ### Ruby Utility Class Refactoring Suggestion Source: https://github.com/schoblaska/dotclaude/blob/main/commands/pr-review.md Suggests refactoring a procedural utility class in Ruby to a more object-oriented approach using instance methods for better expressiveness and adherence to Ruby patterns. This includes examples of the current procedural style and the proposed object-oriented alternative. ```ruby ## Current Procedural Style (auth_utils.rb) class AuthUtils def self.check_token_expiry(token_string) # ... implementation ... end def self.validate_token(jwt_string) # ... implementation ... end end # Usage: # AuthUtils.check_token_expiry(token_string) ## Proposed Object-Oriented Style class TokenValidator def initialize(jwt_string) @jwt_string = jwt_string # ... other initializations ... end def expired? # ... implementation ... end def valid? # ... implementation ... end end # Usage: # token = TokenValidator.new(token_string) # token.expired? # token.valid? ``` -------------------------------- ### Factory Definition with Traits Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Shows a basic factory definition using FactoryBot (formerly thoughtbot/factory_girl) with a trait for creating variations of objects. This promotes DRY principles in test data setup. ```ruby # Good factory :user do email { "user@example.com" } name { "Jane Doe" } trait :admin do role { "admin" } end end ``` -------------------------------- ### Prototype Approaches in Ruby and TypeScript Source: https://github.com/schoblaska/dotclaude/blob/main/commands/workshop.md Demonstrates two distinct prototyping approaches, one using patterns from ruby.md and another from typescript.md. This highlights the flexibility in suggesting different implementation styles based on loaded patterns. ```ruby class UserService { async getUser(id) { /* pattern-compliant implementation */ } } ``` ```typescript const fetchUser = async (id) => { /* functional pattern approach */ } ``` -------------------------------- ### MCP Servers Configuration Source: https://github.com/schoblaska/dotclaude/blob/main/README.md Configures various MCP (Model Context Protocol) servers, including linear, brave-search, github, and serena. This block should be added to the top-level of `~/.claude.json` and includes details on server types, commands, arguments, environment variables, and API keys. ```json { "mcpServers": { "linear": { "type": "sse", "url": "https://mcp.linear.app/sse" }, "brave-search": { "command": "npx", "args": [ "-y", "@modelcontextprotocol/server-brave-search" ], "env": { "BRAVE_API_KEY": "YOUR_API_KEY_HERE" } }, "github": { "type": "stdio", "command": "docker", "args": [ "run", "-i", "--rm", "-e", "GITHUB_PERSONAL_ACCESS_TOKEN", "ghcr.io/github/github-mcp-server" ], "env": { "GITHUB_PERSONAL_ACCESS_TOKEN": "YOUR_GITHUB_PAT_HERE" } }, "serena": { "command": "uvx", "args": [ "--from", "git+https://github.com/oraios/serena", "serena", "start-mcp-server", "--context", "ide-assistant" ] } } } ``` -------------------------------- ### Project Documentation Template Source: https://github.com/schoblaska/dotclaude/blob/main/templates/feature_design.md A template for documenting project features, following a pyramid structure. It includes sections for the core approach, minimal working code, supporting context, and patterns discovered. It also outlines implementation steps with verification and rollback strategies, and design context including experiments and applied patterns. ```markdown # Feature: [FEATURE_NAME] ## The Approach [One sentence: what we're building and how] ## Core Implementation ```language // Minimal code showing the key idea and how it satisfies the product requirements ``` [MermaidJS diagrams (Optional, only if appropriate)] ## Implementation Steps ### Step 1: [Foundation] ```language // Key code ``` **Verify:** [How to test this works] ### Step 2: [Core Logic] ```language // Builds on step 1 ``` **Verify:** [Test for this step] **Rollback:** [If this fails] ### Step 3: [Integration] ```language // Connect the pieces ``` **Verify:** [End-to-end test] ## Design Context ### Experiments * **Tried:** [Approach A] → [Why it didn't work] * **Chose:** [Approach B] → [Why it fits] ### Patterns Applied * [Pattern from CLAUDE.md] → [How we used it] ``` -------------------------------- ### Concurrent Request Testing Source: https://github.com/schoblaska/dotclaude/blob/main/commands/pr-review.md Instructions for verifying concurrent request handling and throttling behavior by running a provided stress test script. ```bash # Run provided stress test script: tests/load/concurrent_auth.rb ``` -------------------------------- ### Expressive Objects vs. Procedural Code in Ruby Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/ruby.md Demonstrates the difference between designing objects with intuitive interfaces and using procedural utility methods. Expressive objects lead to code that reads like intent, while procedural code can become tangled and less maintainable. ```ruby class Temperature def to_fahrenheit @celsius * 9/5.0 + 32 end def freezing? @celsius <= 0 end end temp.freezing? # reads like a question # Bad - procedural utilities class TemperatureUtils def self.convert_c_to_f(celsius) celsius * 9/5.0 + 32 end def self.is_freezing(celsius) celsius <= 0 end end TemperatureUtils.is_freezing(temp_c) # procedural, not object-oriented ``` -------------------------------- ### Time-Independent vs. Time-Dependent Test Example Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Illustrates the difference between a good, time-independent test using `travel_to` and a bad, time-dependent test that might fail based on when it's executed. This highlights the importance of controlling time in tests. ```ruby # Good - time-independent it "marks the order as expired" do travel_to Time.current do order = create(:order, expires_at: 1.hour.ago) expect(order).to be_expired end end # Bad - will fail at certain times it "marks the order as expired" do order = create(:order, expires_at: Time.current - 1.hour) expect(order).to be_expired end ``` -------------------------------- ### RSpec Describe and Context Usage Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Illustrates the correct usage of `describe` and `context` blocks in RSpec for grouping tests and defining scenarios. It highlights the importance of avoiding deep nesting to maintain test readability. ```ruby # Good - flat and readable RSpec.describe Order do describe "#total" do it "returns the sum of line items" do # test end context "with a discount code" do # setup for discount code it "applies the discount to the total" do # test end end end end # Bad - deeply nested and hard to follow RSpec.describe Order do describe "#total" do context "with items" do context "with discount" do context "when discount is percentage" do context "when percentage is valid" do # Too deep! end end end end end end ``` -------------------------------- ### Manual Token Refresh Test Source: https://github.com/schoblaska/dotclaude/blob/main/commands/pr-review.md Instructions for manually testing token refresh functionality by configuring a short token expiry time, waiting for it to expire, and then attempting an API call. ```bash # Set TOKEN_EXPIRY=5 in config, wait 6 seconds, attempt API call ``` -------------------------------- ### PR Review Assistant Workflow Source: https://github.com/schoblaska/dotclaude/blob/main/commands/pr-review.md Describes the interactive workflow for preparing pull request reviews, including initial assessment, collaborative discussion, background integration, and final output. ```APIDOC PRReviewAssistant: Workflow: Initial Assessment: - Presents a brief summary of PR changes and initial impressions. - Provides a bullet list of discussion points discovered during analysis. - Each point becomes a focused discussion topic. Collaborative Discussion: - For each point, opens relevant files at specific lines in the editor. - Discusses implications and alternatives together. - Determines if an issue is a blocker, suggestion, or non-issue. - Updates notes based on user expertise and context. Background Integration: - Loads linked tickets (Linear, GitHub Issues) asynchronously. - Verifies requirements as data becomes available. - Adds new insights to discussion points dynamically. Final Output: - Writes feedback to `/tmp/pr_review_.md`. - Categories include: Strengths, Must Fix, Consider, Questions, Testing. Analysis Checks: - Requirements: Verifies implementation matches ticket acceptance criteria. - Patterns: Compares against `~/.claude/patterns/` conventions. - Test Coverage: Assesses automated tests for completeness and edge cases. - Code Quality: Identifies potential issues, improvements, or concerns. - Local Behavior: Suggests and helps perform manual testing scenarios. Example Session: User: /pr-review https://github.com/owner/repo/pull/123 Claude: [Checks out branch, starts fetching Linear ticket SCH-456 in background, analyzes code] This PR implements authentication middleware for the API with JWT token handling and session management. The implementation is clean and follows established patterns from our codebase. I've identified a few areas worth discussing around error handling and configuration. ``` -------------------------------- ### Project Permissions Configuration Source: https://github.com/schoblaska/dotclaude/blob/main/README.md Defines project-specific permissions for Claude Code, specifying allowed and denied operations. This JSON configuration should be placed in `.claude/settings.local.json` within the project directory. ```json { "permissions": { "allow": [ "Edit", "Read", "Write", "Bash(git add:*)", "Bash(git commit:*)", "Bash(npm:*)", "Bash(python:*)", "Bash(pytest:*)", "Bash(ruby:*)", "Bash(bin/rails:*)", "Bash(bin/rake:*)", "Bash(bundle exec:*)" ], "deny": [] } } ``` -------------------------------- ### Query Objects as Scopes for Reusable and Composable Queries Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rails.md Shows how to define reusable query logic using ActiveRecord scopes and how controllers can compose these scopes for dynamic data retrieval. This promotes DRY principles and separates query concerns. ```ruby class Post < ApplicationRecord scope :published, -> { where(status: 'published') } scope :featured, -> { where(featured: true) } scope :recent, -> { order(created_at: :desc) } scope :by_author, ->(author) { where(author: author) } end class HomepageController < ApplicationController def index @posts = Post.published.featured.recent.limit(5) @events = Event.upcoming.featured.limit(3) end end class PostsController < ApplicationController def index @posts = Post.published.recent @posts = @posts.by_author(params[:author]) if params[:author] end end # Bad - model knows about UI contexts class Post < ApplicationRecord def self.for_homepage published.featured.recent.limit(5) end def self.for_sidebar published.popular.limit(10) end end ``` -------------------------------- ### Migration Strategy Source: https://github.com/schoblaska/dotclaude/blob/main/templates/data_model_design.md Details the plan for modifying the existing data schema. This includes steps for applying changes and ensuring data consistency during migration. ```language // If modifying existing schema ``` -------------------------------- ### Cursor Keybinds Configuration Source: https://github.com/schoblaska/dotclaude/blob/main/README.md Defines custom keybindings for VS Code, specifically for terminal interactions and Claude Code specific commands. Includes sequences for sending text to the terminal and mapping key combinations to actions. ```json { "key": "shift+enter", "command": "workbench.action.terminal.sendSequence", "args": { "text": "\u001b\r" }, "when": "terminalFocus" }, { "key": "shift+enter", "command": "workbench.action.terminal.sendSequence", "args": { "text": "\u001b\r" }, "when": "terminalFocus" }, { "key": "cmd+i", "command": "-composer.startComposerPrompt" }, { "key": "cmd+i", "command": "claude-code.insertAtMentioned", "when": "editorTextFocus" }, { "key": "alt+cmd+k", "command": "-claude-code.insertAtMentioned", "when": "editorTextFocus" } ``` -------------------------------- ### Git Commit and PR Attribution Source: https://github.com/schoblaska/dotclaude/blob/main/global/CLAUDE.md Specifies the required format for Claude-generated Git commits and Pull Request descriptions to ensure clear identification and attribution of AI contributions. ```markdown Prefix commits: `[🤖 Claude] ` Sign PR descriptions: "Written by 🤖 " PR titles: no prefix or attribution Never comment as user on GitHub Stage PR descriptions in temp files using `gh pr create --body-file` and ask for user review and feedback before submission ``` -------------------------------- ### Domain Objects Beyond ActiveRecord (POROs) Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rails.md Demonstrates the creation and usage of Plain Old Ruby Objects (POROs) for encapsulating complex domain logic, calculations, and workflows, contrasting this with anemic ActiveRecord models or procedural service classes. ```ruby # Good - PORO for complex domain logic class PricingCalculator def initialize(order) @order = order @rules = load_pricing_rules end def subtotal @order.line_items.sum(&:total) end def discount @rules.map { |rule| rule.apply(@order) }.sum end def tax TaxCalculator.new(@order.shipping_address).calculate(taxable_amount) end def total subtotal - discount + tax + shipping end private def taxable_amount subtotal - discount end end # Usage - clean interface calculator = PricingCalculator.new(order) order.update!( subtotal: calculator.subtotal, discount: calculator.discount, tax: calculator.tax, total: calculator.total ) # Bad - shoving everything into ActiveRecord class Order < ApplicationRecord def calculate_total # 200 lines of pricing logic mixed with persistence end end # Also bad - procedural service class class PricingService def self.calculate(order) subtotal = 0 order.line_items.each do |item| subtotal += item.quantity * item.price end discount = 0 if order.coupon_code discount = CouponService.calculate_discount(order.coupon_code, subtotal) end tax = TaxService.calculate_tax(subtotal - discount, order.shipping_address) shipping = ShippingService.calculate_shipping(order) total = subtotal - discount + tax + shipping order.update!( subtotal: subtotal, discount: discount, tax: tax, total: total ) end end # Procedural, not object-oriented ``` -------------------------------- ### Class Documentation Structure Source: https://github.com/schoblaska/dotclaude/blob/main/templates/class_design.md Provides a template for documenting classes within the dotclaude project. It covers the class purpose, public API, core implementation details, collaborations (dependencies), and design notes. ```plaintext # Class: [CLASS_NAME] ## Purpose [One sentence: what this class does] ## Interface ```language // Public API ``` ## Core Implementation ```language // Key internals showing the approach ``` ## Collaborations * Uses: [What it depends on] * Used by: [What depends on it] ## Design Notes * [Key decision and why] ``` -------------------------------- ### Rich Domain Models vs. Anemic Models Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rails.md Demonstrates the difference between a rich domain model with encapsulated business logic and an anemic model that relies on separate service objects. Rich models improve maintainability and readability. ```ruby class Article < ApplicationRecord def publish! self.published_at = Time.current self.status = 'published' notify_subscribers save! end def archive! update!(archived: true, archived_at: Time.current) end private def notify_subscribers # Side effect handled by model subscribers.each { |s| ArticleMailer.published(s, self).deliver_later } end end article.publish! # Bad - anemic model with service class PublishArticleService def call(article) article.published_at = Time.current article.status = 'published' article.save! NotificationService.new.notify_about(article) end end ``` -------------------------------- ### Linear Ticket Branching Strategy Source: https://github.com/schoblaska/dotclaude/blob/main/global/CLAUDE.md Defines the convention for naming branches when working on Linear tickets to maintain clarity and traceability. ```markdown When working on a Linear ticket, always work in a dedicated branch (`joseph/SCH-123_api-auth`). ``` -------------------------------- ### Relationship Definitions Source: https://github.com/schoblaska/dotclaude/blob/main/templates/data_model_design.md Illustrates how different entities within the data model are connected. This is crucial for understanding data flow and integrity. ```language // How entities connect ``` -------------------------------- ### Immutable Chain Building in Ruby Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/ruby.md Illustrates how to build chains of operations by returning new instances from methods, adhering to the 'with' pattern for modified copies. This approach allows for chain forking without affecting original objects, promoting immutability. ```ruby # Good - returns new instance class Query def where(conditions) with(conditions: @conditions.merge(conditions)) end def limit(n) with(limit: n) end private def with(attrs) self.class.new(@base_attrs.merge(attrs)) end end base = Query.new(table: 'users') active = base.where(active: true) recent = active.where(created: '2024-01-01..') limited = recent.limit(10) # base remains unchanged # Bad - mutates self class Query def where(conditions) @conditions.merge!(conditions) self end end ``` -------------------------------- ### Instance Double with Spy-like Verification Source: https://github.com/schoblaska/dotclaude/blob/main/patterns/rspec.md Demonstrates the use of `instance_double` with `have_received` for spy-like verification in RSpec. This approach enhances test readability by placing verification after the action. ```ruby # Good - instance double with spy-like verification it "sends a notification email" do mailer = instance_double(Mailer, send_order_confirmation: nil) service = OrderService.new(mailer:) service.complete_order(order) expect(mailer).to have_received(:send_order_confirmation).with(order) end # Less ideal - traditional mock with expectations set upfront it "sends a notification email" do mailer = double("mailer") expect(mailer).to receive(:send_order_confirmation).with(order) service = OrderService.new(mailer:) service.complete_order(order) end ```