Skip to content

Commit 8a5fa99

Browse files
testac974claude
andcommitted
Fix markdownlint errors in Part 1 chapters
Resolved linting issues across Architecture Principles and Digestible Interfaces chapters: - Added language specifiers to code blocks (MD040) - Added blank lines around lists and headings (MD032, MD022) - Removed extra consecutive blank lines (MD012) - Converted emphasized text to proper headings (MD036) - Fixed table formatting (MD060) All validation checks now pass. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
1 parent 223fa33 commit 8a5fa99

18 files changed

Lines changed: 121 additions & 41 deletions

book/part1-foundations/03-architecture-principles/02-the-digestibility-principle.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ Let's make this concrete with a real scenario I encountered at a previous compan
209209

210210
The payment processing system was spread across 12 files:
211211

212-
```
212+
```text
213213
payment/
214214
├── handlers.py (routing, 300 lines)
215215
├── validators.py (validation, 250 lines)
@@ -243,7 +243,7 @@ By file #5, the AI agent's context window is half full with payment code, leavin
243243

244244
We refactored to a single, self-contained module:
245245

246-
```
246+
```text
247247
payment/
248248
└── payment_processor.py (single file, 600 lines)
249249
├── PaymentConfig (configuration, 50 lines)
@@ -270,7 +270,7 @@ Now, an AI agent (or human) could:
270270
Let's be specific about the numbers:
271271

272272
| Component Type | Lines of Code | Tokens | Fits in AI Context? |
273-
|----------------|---------------|--------|---------------------|
273+
| --- | --- | --- | --- |
274274
| Single digestible module | 500-1,000 | 2,000-4,000 | ✓ Yes, with room to spare |
275275
| Medium component with deps | 2,000-3,000 | 8,000-12,000 | ✓ Yes, but tight |
276276
| Large scattered system | 5,000+ | 20,000+ | ✗ No, requires fragmentation |

book/part1-foundations/03-architecture-principles/03-component-decomposition.md

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ The answer is **component decomposition**: the art of dividing a system into ind
3030

3131
Let's start with a common scenario. You're building an e-commerce platform. The traditional approach might decompose it like this:
3232

33-
```
33+
```text
3434
ecommerce/
3535
├── backend/
3636
│ ├── services/
@@ -60,7 +60,7 @@ That's six different directories and potentially 10+ files. The AI must keep all
6060

6161
Now consider **vertical decomposition**—organizing by feature:
6262

63-
```
63+
```text
6464
ecommerce/
6565
├── cart/
6666
│ ├── cart_api.py (API endpoints)
@@ -162,7 +162,7 @@ graph TB
162162

163163
**Example structure**:
164164

165-
```
165+
```text
166166
features/
167167
├── user_auth/
168168
│ ├── auth_api.py # API endpoints
@@ -198,7 +198,7 @@ features/
198198

199199
**Example**: E-commerce bounded contexts
200200

201-
```
201+
```text
202202
contexts/
203203
├── catalog/ # Product discovery domain
204204
│ ├── products/
@@ -366,7 +366,7 @@ Let me show you a real refactoring I did on a project where AI agents were strug
366366

367367
### Before: Monolithic User Service
368368

369-
```
369+
```text
370370
user_management/
371371
└── user_service.py (1,200 lines, 15 methods)
372372
- User registration
@@ -383,7 +383,7 @@ user_management/
383383

384384
### After: Feature-Based Decomposition
385385

386-
```
386+
```text
387387
user_management/
388388
├── registration/
389389
│ ├── signup.py (150 lines)
@@ -412,7 +412,7 @@ Here are anti-patterns to avoid:
412412

413413
**Bad**:
414414

415-
```
415+
```text
416416
utils/
417417
├── string_utils.py
418418
├── date_utils.py
@@ -425,7 +425,7 @@ utils/
425425

426426
**Good**: Put utilities near where they're used:
427427

428-
```
428+
```text
429429
cart/
430430
├── cart_service.py
431431
├── cart_validators.py (validation specific to carts)
@@ -456,15 +456,15 @@ def process_cart(user: User, items: List[Item]) -> Order:
456456

457457
**Bad**:
458458

459-
```
459+
```text
460460
orders → cart → inventory → orders (circular!)
461461
```
462462

463463
**Problem**: AI agents must load entire cycle into context.
464464

465465
**Good**: Establish dependency hierarchy:
466466

467-
```
467+
```text
468468
orders → cart → inventory (one direction, no cycles)
469469
```
470470

book/part1-foundations/03-architecture-principles/04-interface-boundaries.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ A specification is a machine-readable contract. There's no room for interpretati
266266

267267
**Human documentation**:
268268

269-
```
269+
```text
270270
The email field should be a valid email address.
271271
```
272272

@@ -578,7 +578,7 @@ When asking an AI agent to implement an interface:
578578

579579
**Good prompt**:
580580

581-
```
581+
```text
582582
Implement the UserService according to this OpenAPI specification:
583583
[paste spec]
584584

book/part1-foundations/03-architecture-principles/05-separation-of-concerns.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -401,7 +401,7 @@ An AI agent can now modify tax logic without touching configuration management.
401401

402402
**Structure**:
403403

404-
```
404+
```text
405405
project/
406406
├── src/
407407
│ ├── domain/ # Business logic

book/part1-foundations/03-architecture-principles/06-testability-for-ai-code.md

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,13 @@ In traditional development, you write code slowly and carefully, testing as you
3434
Consider this scenario: You prompt Claude Code to implement user authentication. Five minutes later, you have a complete implementation with password hashing, session management, JWT tokens, and email verification. It looks sophisticated. But does it work? Are there security vulnerabilities? Does it handle edge cases?
3535

3636
Without good tests, you're forced to:
37+
3738
- **Manually test every scenario** (slow and error-prone)
3839
- **Read and understand all the generated code** (defeats the velocity gains)
3940
- **Hope the AI got it right** (dangerous)
4041

4142
With a testable architecture, you can:
43+
4244
- **Run automated tests in seconds** and know if it works
4345
- **Trust the AI-generated code** if tests pass
4446
- **Iterate quickly** by regenerating implementations and re-running tests
@@ -72,6 +74,7 @@ class UserService:
7274
```
7375

7476
This code is **impossible to test** without:
77+
7578
- A real PostgreSQL database running
7679
- SendGrid credentials configured
7780
- Actually sending emails during tests
@@ -122,6 +125,7 @@ When you prompt an AI agent to implement a feature, you can specify: "Use depend
122125
### 2. Pure Functions: Predictable and Easy to Test
123126

124127
A **pure function** is one that:
128+
125129
- **Always returns the same output for the same inputs** (deterministic)
126130
- **Has no side effects** (doesn't modify external state, doesn't do I/O)
127131

@@ -149,6 +153,7 @@ def calculate_total_price(cart_id):
149153
```
150154

151155
This function is **painful to test**:
156+
152157
- Need to set up global cart store
153158
- Need a database with tax rates
154159
- Behavior changes based on time of day
@@ -222,11 +227,13 @@ graph TD
222227
*Figure 3.6: Component boundaries define test boundaries. Each component has focused unit tests, while integration tests verify components work together.*
223228

224229
When components have:
230+
225231
- **Clear interfaces**: Easy to mock for testing
226232
- **Single responsibility**: Tests focus on one thing
227233
- **Explicit dependencies**: Easy to inject test doubles
228234

229235
Then you can:
236+
230237
- **Test each component in isolation** (fast unit tests)
231238
- **Test integrations between components** (targeted integration tests)
232239
- **Know exactly what broke** when tests fail (precise test boundaries)
@@ -274,6 +281,7 @@ def test_user_creation_logic():
274281
```
275282

276283
With fast unit tests, you can run hundreds of tests in seconds. This enables:
284+
277285
- **Continuous testing** while developing with AI
278286
- **Immediate feedback** when something breaks
279287
- **Confidence to iterate rapidly** knowing tests will catch regressions
@@ -313,7 +321,7 @@ This loop accelerates over time. The more you optimize for testability, the fast
313321

314322
## Common Testability Mistakes
315323

316-
**Mistake 1: Testing implementation details instead of behavior**
324+
### Mistake 1: Testing implementation details instead of behavior
317325

318326
Don't test *how* the code works internally. Test *what* it does from the outside.
319327

@@ -340,11 +348,11 @@ def test_password_hashing_is_secure():
340348
assert not service.verify_password("wrong", hashed)
341349
```
342350

343-
**Mistake 2: Skipping tests because "AI code is usually correct"**
351+
### Mistake 2: Skipping tests because "AI code is usually correct"
344352

345353
AI code is usually *plausible*, not necessarily correct. It can have subtle bugs, security issues, or misunderstand requirements. Tests catch these.
346354

347-
**Mistake 3: Over-mocking to the point of meaningless tests**
355+
### Mistake 3: Over-mocking to the point of meaningless tests
348356

349357
```python
350358
# Bad: Mocks so much that test is meaningless

book/part1-foundations/03-architecture-principles/07-practical-application.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,19 +32,22 @@ Let's walk through a complete example: **designing a task management API** that
3232
Imagine we're building a REST API for a task management system with these key requirements:
3333

3434
**Core Features**:
35+
3536
- Users can create projects and add tasks
3637
- Tasks have assignees, due dates, status, and comments
3738
- Teams can collaborate on shared projects
3839
- Real-time notifications when tasks are updated
3940
- Search and filtering across tasks
4041

4142
**Non-Functional Requirements**:
43+
4244
- Must handle 1,000 concurrent users
4345
- API response time < 200ms (p95)
4446
- Easy for frontend developers to integrate
4547
- Testable in isolation without external services
4648

4749
**Constraints**:
50+
4851
- 6-week timeline to MVP
4952
- Small team (1-2 developers + AI agents)
5053
- Standard tech stack (Node.js, PostgreSQL, REST)
@@ -94,7 +97,7 @@ graph TD
9497

9598
**Working with Claude Code**:
9699

97-
```
100+
```text
98101
Prompt: "Design the Task Service for our task management API.
99102
Requirements:
100103
- Manage CRUD operations for tasks
@@ -172,7 +175,7 @@ paths:
172175
173176
**Working with Claude Code**:
174177
175-
```
178+
```text
176179
Prompt: "Implement the POST /tasks endpoint according to the
177180
OpenAPI spec. Use dependency injection for ProjectService and
178181
UserService. Include input validation and error handling."
@@ -187,14 +190,15 @@ Claude generates code that exactly matches the specification.
187190
**Applying the principles**:
188191
189192
We'll use a **layered architecture** that separates:
193+
190194
- **API layer**: HTTP handling, request validation
191195
- **Business logic layer**: Task rules and workflows
192196
- **Data access layer**: Database queries
193197
- **Infrastructure layer**: External service clients
194198
195199
**Task Service Structure**:
196200
197-
```
201+
```text
198202
task-service/
199203
├── src/
200204
│ ├── api/
@@ -216,10 +220,10 @@ task-service/
216220

217221
**Why this separation?**
218222

219-
1. **Testability**: Business logic in `domain/` is pure—easy to test
220-
2. **Clarity**: Each file has one job
221-
3. **AI-friendly**: Clear file naming tells Claude what goes where
222-
4. **Maintainability**: Changes localized to single layer
223+
- **Testability**: Business logic in `domain/` is pure—easy to test
224+
- **Clarity**: Each file has one job
225+
- **AI-friendly**: Clear file naming tells Claude what goes where
226+
- **Maintainability**: Changes localized to single layer
223227

224228
**Example - Pure Business Logic**:
225229

@@ -373,7 +377,7 @@ Here's our final architecture applying all five principles:
373377

374378
**Working with Claude Code on This Architecture**:
375379

376-
```
380+
```text
377381
Session 1 - Design Phase:
378382
Prompt: "Review this architecture diagram and OpenAPI specs.
379383
Identify any missing error cases or edge conditions."

book/part1-foundations/03-architecture-principles/08-common-pitfalls.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ This test works regardless of hashing algorithm. Switch to argon2? Tests still p
364364

365365
**What it looks like**:
366366

367-
```
367+
```text
368368
Your 6-week MVP split into 15 microservices:
369369
- User Service
370370
- Auth Service

0 commit comments

Comments
 (0)