Skip to content

Conversation

Copy link
Contributor

Copilot AI commented Jan 5, 2026

Implements comprehensive documentation for Data Layer Patterns (Repository, Active Record, Optimistic/Pessimistic Locking) with working Go examples, interactive quiz, hands-on refactoring exercise, and deliverables section as specified in Task 1.0.

Documentation (docs/11-application-development/11.2.2-data-layer-patterns.md)

  • Repository Pattern: Interface abstraction over data access, multiple implementations (SQLite/in-memory)
  • Active Record Pattern: Self-persisting domain objects with encapsulated data access
  • Optimistic Locking: Version-based conflict detection with retry logic
  • Pessimistic Locking: Transaction-based exclusive locks with deadlock prevention
  • Anti-patterns section showing direct data access problems
  • Decision matrices comparing patterns based on complexity, testability, concurrency needs
  • Multi-user scenarios demonstrating concurrent access patterns
  • Deliverables section: 7 critical thinking questions testing pattern understanding and application

Go Examples (examples/ch11/data-patterns/)

Five self-contained examples with comprehensive tests (all passing):

Repository Pattern (repository/):

type UserRepository interface {
    Create(user *User) error
    FindByID(id int) (*User, error)
    Update(user *User) error
}

// Swap implementations without touching business logic
var repo UserRepository
repo = NewSQLiteUserRepository(db)      // Production
repo = NewInMemoryUserRepository()      // Testing

Active Record Pattern (active-record/):

user := &User{Name: "Alice", Email: "alice@example.com"}
user.Save()                             // Object saves itself
user.Delete()                           // Object deletes itself
found, _ := FindUserByID(1)            // Class method

Optimistic Locking (concurrency/optimistic/):

type Product struct {
    ID       int
    Quantity int
    Version  int  // Conflict detection
}

// Update fails if version changed (concurrent modification)
UPDATE products SET quantity = ?, version = version + 1
WHERE id = ? AND version = ?

Pessimistic Locking (concurrency/pessimistic/):

// Exclusive lock prevents concurrent access
tx.Begin()
account := FindByIDForUpdate(tx, id)  // Lock acquired
account.Balance -= amount
Update(tx, account)
tx.Commit()                            // Lock released

Exercise Starter (repository-exercise-starter/):

// Anti-pattern example - SQL embedded in HTTP handlers
func handleUsers(w http.ResponseWriter, r *http.Request) {
    // SQL query directly in handler - no abstraction
    rows, err := db.Query("SELECT id, name, email FROM users")
    // Business logic mixed with data access...
}

Refactoring Exercise

Exercise Starter Project (examples/ch11/data-patterns/repository-exercise-starter/):

  • Working REST API demonstrating anti-patterns (Users and Orders management)
  • SQL queries embedded directly in HTTP handlers
  • No abstraction layer between business logic and data access
  • Duplicated query patterns across multiple handlers
  • Tightly coupled to SQLite database
  • Mix of business logic and data access throughout

Exercise Instructions (in documentation):

  • Uses leading questions to guide discovery instead of step-by-step solutions
  • Encourages critical thinking about separation of concerns
  • Students identify problems and design their own refactoring approach
  • No reference to the clean repository example as a solution

Deliverables

Added comprehensive deliverables section with 7 questions covering:

  • Pattern selection criteria (Repository vs Active Record)
  • Connection to SOLID principles
  • Concurrency strategy trade-offs (Optimistic vs Pessimistic Locking)
  • Anti-pattern analysis from exercise starter code
  • Multi-database support considerations
  • Testability improvements
  • Real-world application scenarios (e.g., high-traffic e-commerce)

Quiz (src/quizzes/chapter-11/11.2.2/)

12 questions covering pattern recognition, concurrency scenarios, and decision-making trade-offs using quizdown format.

Configuration Updates

  • Added page to docs/_sidebar.md
  • Updated .markdownlint.json to support <quizdown> elements and table styles
  • Front-matter auto-generated in docs/README.md
Original prompt

This section details on the original issue you should resolve

<issue_title>Task 1.0: Data Layer Patterns Documentation and Examples (11.2.2)</issue_title>
<issue_description># GitHub Issue: Task 1.0 - Data Layer Patterns Documentation and Examples (11.2.2)

🎯 Task Overview

Task ID: 1.0
Parent Spec: docs/specs/01-spec-design-patterns-section/01-spec-design-patterns-section.md
Status: Ready for Implementation
Estimated Time: 2-3 hours

This task implements comprehensive documentation for Data Layer Patterns (11.2.2), including Repository, Active Record, and Concurrency patterns (Optimistic/Pessimistic Locking) with working Go examples and an interactive quiz.


📋 Specification Context

Project Overview

This specification defines the remaining Design Patterns subsections for Chapter 11 (Application Development) of the DevOps Bootcamp. Building on the completed SOLID Principles foundation (11.2.1), this spec focuses on architectural patterns (data layer and business logic) and classical Gang of Four patterns that students will encounter in production applications.

User Story

US-1: Understanding Data Layer Patterns
As a bootcamp apprentice learning production development, I want to understand Repository and Active Record patterns so that I can structure data access logic in enterprise applications.

US-2: Managing Concurrent Data Access
As a developer building multi-user applications, I want to understand Optimistic and Pessimistic Locking patterns so that I can handle concurrent data modifications safely.

Functional Requirements

ID Requirement
U2-FR1 The system shall explain Repository Pattern with implementation examples showing interface abstraction over data access operations
U2-FR2 The system shall explain Active Record Pattern with examples showing domain objects that encapsulate data access methods
U2-FR3 The system shall provide decision guidance contrasting Repository vs Active Record based on domain complexity, testability requirements, and team preferences
U2-FR4 The system shall demonstrate Optimistic Locking pattern with self-contained SQLite database examples showing version-based conflict detection
U2-FR5 The system shall demonstrate Pessimistic Locking pattern with self-contained SQLite database examples showing exclusive access control
U2-FR6 The system shall include multi-user scenario examples demonstrating when each concurrency pattern is appropriate
U2-FR7 The system shall include anti-patterns showing pain points of direct data access mixed with business logic
U2-FR8 The system shall provide a self-directed refactoring exercise for students to convert direct data access to Repository pattern
U2-FR9 The system shall include an interactive quiz testing pattern recognition and decision-making for data layer patterns

✅ Acceptance Criteria (Proof Artifacts)

The following artifacts must exist and be verified for task completion:

  • Documentation: docs/11-application-development/11.2.2-data-layer-patterns.md exists with complete content including front-matter, pattern explanations, decision guidance, and exercises
  • Repository Pattern: examples/ch11/data-patterns/repository/ contains working Go implementation with README, tests, and clear interface abstraction
  • Active Record Pattern: examples/ch11/data-patterns/active-record/ contains working Go implementation with README demonstrating domain objects with encapsulated data access
  • Optimistic Locking: examples/ch11/data-patterns/concurrency/optimistic/ contains SQLite-based demonstration with README showing version-based conflict detection
  • Pessimistic Locking: examples/ch11/data-patterns/concurrency/pessimistic/ contains SQLite-based demonstration with README showing exclusive access control
  • Quiz: src/quizzes/chapter-11/11.2.2/data-layer-patterns-quiz.js exists with pattern recognition questions following quizdown format
  • CLI Verification: go test ./... passes in all example directories
  • Integration Verification: Quiz renders correctly in Docsify when served with npm start

📝 Sub-tasks

Documentation Tasks

  • 1.1 Create documentation file docs/11-application-development/11.2.2-data-layer-patterns.md with front-matter (category: Application Development, technologies: Go/SQLite/Design Patterns, estReadingMinutes: 45, exercise definition)
  • 1.2 Write Repository Pattern section explaining interface abstraction over data access, benefits (testability, flexibility), and when to use it
  • 1.3 Write Active Record Pattern section explaining domain objects with encapsulated data access methods and when to use it
  • 1.4 Write pattern comparison section with decision guidance based on domain complexity, testability requirements, and team preferences
  • 1.5 Write Optimisti...

💬 We'd love your input! Share your thoughts on Copilot coding agent in our 2 minute survey.

Copilot AI changed the title [WIP] Add documentation for data layer patterns and examples Add Data Layer Patterns documentation and Go examples (11.2.2) Jan 5, 2026
Copilot AI requested a review from jburns24 January 5, 2026 19:29
@jburns24
Copy link
Collaborator

jburns24 commented Jan 7, 2026

@copilot

Create a starter project for Exercise 1 in the Data Layer Patterns documentation that demonstrates the anti-pattern of direct data access scattered throughout the codebase. This will serve as the "before" state that participants need to refactor.

Requirements

  1. Create Starter Project: Build a simple Go application in examples/ch11/data-patterns/repository-exercise-starter/ that demonstrates poor data access patterns:
    - SQL queries embedded directly in HTTP handlers
    - No abstraction layer between business logic and data access
    - Duplicated queries across multiple handlers
    - Tightly coupled to SQLite (hard to test or switch databases)
    - Mix of business logic and data access in the same functions
  2. Application Scope: Keep it simple but realistic:
    - 2-3 entities (e.g., Users and Orders)
    - 4-6 HTTP endpoints (CRUD operations)
    - SQLite database
    - Demonstrate multiple anti-patterns clearly
  3. Update Exercise Instructions: Modify the exercise in docs/11-application-development/11.2.2-data-layer-patterns.md to:
    - Point to the new starter project
    - Keep refactoring instructions vague and general
    - Include leading questions/hints that prompt critical thinking
    - DO NOT provide step-by-step solutions
    - DO NOT reference the clean repository example as a solution
    - Let participants figure out their own approach
  4. The existing examples/ch11/data-patterns/repository/ should NOT be mentioned as a solution or reference in the exercise instructions.

Key Principles

  • Vague Instructions: Give general guidance, not specific steps
  • Critical Thinking: Use questions to guide thinking rather than providing answers
  • No Solution: Participants should struggle and discover patterns themselves
  • Realistic Problems: The starter code should feel like real legacy code they might encounter

Todo List

  • Create directory structure at examples/ch11/data-patterns/repository-exercise-starter/
  • Write a simple Go application with 2-3 entities demonstrating anti-patterns
  • Add HTTP handlers with SQL queries directly embedded (no abstraction)
  • Include duplicated query logic across multiple handlers
  • Mix business logic with data access in handlers
  • Create a README.md with basic setup instructions only (no solution hints)
  • Add go.mod and necessary dependencies
  • Ensure the application runs and has working (but poorly designed) functionality
  • Update exercise instructions in docs/11-application-development/11.2.2-data-layer-patterns.md
  • Replace specific refactoring steps with vague general guidance
  • Add 3-5 leading questions to prompt critical thinking
  • Remove reference to examples/ch11/data-patterns/repository/ from exercise instructions
  • Test that starter project runs successfully (go run .)
  • Verify exercise instructions are appropriately vague

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot

Create a starter project for Exercise 1 in the Data Layer Patterns documentation that demonstrates the anti-pattern of direct data access scattered throughout the codebase. This will se...

Created the exercise starter project in commit c17623e.

Starter Project (examples/ch11/data-patterns/repository-exercise-starter/):

  • Working REST API with Users and Orders endpoints
  • SQL queries embedded directly in HTTP handlers (no abstraction)
  • Duplicated query patterns across 5 different handlers
  • Business logic mixed with data access throughout
  • Global database connection shared everywhere
  • Tightly coupled to SQLite

Updated Exercise Instructions:

  • Replaced step-by-step instructions with 5 leading questions
  • Questions guide students to discover problems themselves
  • No reference to the clean repository example
  • Focuses on exploring trade-offs rather than following a recipe
  • Encourages multiple approaches and experimentation

The starter code demonstrates realistic legacy code patterns that students will need to identify and refactor on their own.

@jburns24
Copy link
Collaborator

jburns24 commented Jan 7, 2026

@copilot We need to add a "Deliverable" section to docs/11-application-development/11.2.2-data-layer-patterns.md

Look at the following sections for examples of what good deliverables look like

  • docs/9-kubernetes-container-orchestration/9.7.2-helm.md
  • docs/4-virtual-machines-containers/4.5.3-tilt.md

This is an example of bad deliverables

  • docs/4-virtual-machines-containers/4.5.1-docker-compose.md

Copy link
Contributor Author

Copilot AI commented Jan 7, 2026

@copilot We need to add a "Deliverable" section to docs/11-application-development/11.2.2-data-layer-patterns.md

Look at the following sections for examples of what good deliverables look like
...

Added Deliverables section in commit ff38f5b.

The section includes 7 questions that:

  • Test pattern selection criteria (Repository vs Active Record)
  • Connect to SOLID principles from 11.2.1
  • Explore concurrency strategy trade-offs (Optimistic vs Pessimistic Locking)
  • Apply concepts to real-world scenarios (e.g., e-commerce inventory)
  • Evaluate testability improvements from abstraction
  • Consider multi-database support decisions

Questions encourage critical thinking about architectural decisions rather than just recalling facts.

@jburns24 jburns24 marked this pull request as ready for review January 14, 2026 00:40
Copilot AI and others added 10 commits January 13, 2026 16:40
…Record, Optimistic/Pessimistic Locking)

Co-authored-by: jburns24 <19497855+jburns24@users.noreply.github.com>
… examples

Co-authored-by: jburns24 <19497855+jburns24@users.noreply.github.com>
- Create starter project with anti-patterns (direct SQL in handlers, no abstraction)
- Demonstrate tightly coupled code with duplicated queries
- Mix business logic with data access throughout handlers
- Update exercise instructions to use leading questions instead of step-by-step solution
- Remove specific implementation steps to encourage critical thinking

Co-authored-by: jburns24 <19497855+jburns24@users.noreply.github.com>
- Add 7 deliverable questions testing pattern understanding and application
- Questions focus on decision-making, trade-offs, and practical scenarios
- Cover Repository vs Active Record comparison, SOLID principles connection
- Address concurrency patterns and their real-world application
- Include questions about testability improvements and multi-database support

Co-authored-by: jburns24 <19497855+jburns24@users.noreply.github.com>
…Separating interface from implementation creating an easier to understand repository. Also practicing practice of least surprise and changes repository implementations from mutating the input object
Fix race condition where concurrent goroutines received different database
connections, each seeing isolated :memory: databases. This caused "no such
table" errors during concurrent operations.

Changes:
- Use file::memory:?cache=shared for true shared in-memory databases
- Enable WAL mode for better concurrent write performance
- Set connection pool to 10 for realistic concurrent access
- Enhance optimistic locking retry logic to handle database locks (5 retries, exponential backoff)
- Fix pessimistic locking to actually acquire row locks via dummy UPDATE
- Add educational comments explaining SQLite's table-level write lock limitations

Results:
- Optimistic locking: 10/10 operations succeed with retry handling
- Pessimistic locking: 1-2 operations succeed (expected due to SQLite limitations)
- Both examples now demonstrate true concurrent behavior without table errors
- Add inline exercises for Repository and Active Record patterns
- Add new exercise for AI-assisted refactoring with Spec-Driven Development
- Emphasize using proper vocabulary when working with AI agents
- Update front-matter metadata with all new exercises including AI collaboration
- Fix markdown linting error (multiple blank lines)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@jburns24 jburns24 force-pushed the copilot/document-data-layer-patterns branch from e96be74 to 80065c8 Compare January 14, 2026 00:40
@jburns24 jburns24 merged commit b68f73a into master Jan 14, 2026
2 checks passed
@jburns24 jburns24 deleted the copilot/document-data-layer-patterns branch January 14, 2026 00:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Task 1.0: Data Layer Patterns Documentation and Examples (11.2.2)

2 participants