The difference between someone with no experience “vibe coding” something, and a software developer using an LLM to rapidly deploy an actually production ready piece of software often comes down to the high level decisions around how that software is built: the architecture. As someone who has built many WordPress plugins in the past, I have a good understanding how they should work, and what best practices go into their build, so I’m able to make good decisions up front which set Claude off on the right path.

If you don’t know these answers, stop what you are doing and go take the time to educate yourself on at least the basics and best practices. It will help prevent the nightmare scenario in the future of your software breaking important things, leaking important data, or being turned into a spam trap or hack site.

After the requirements brief, Claude didn’t start generating a plan. Instead, it organized what it didn’t yet know into six categories, each with specific questions. This is the architecture dance—the back-and-forth that transforms a brief into a buildable design.

The Gap Analysis

Claude’s response to the brief grouped open questions into logical clusters:

Core Data Architecture: How should Courses relate to Lessons? Three patterns were possible—taxonomy-based (Lessons tagged with Course terms), parent-child (Lessons as children of Course posts), or meta-based (Course stores ordered array of Lesson IDs). Each had tradeoffs. And where do Quizzes fit—standalone post type, or embedded in Lessons?

Completion Logic: What triggers a Lesson as complete? Quiz submission, manual “Mark Complete” button, or both? What’s the pass threshold for quizzes, and can students retake them?

User Model: New role or capability modifications to existing roles? Where does the profile page live—custom template, shortcode, or dedicated page? What’s the enrollment flow?

File Attachments: Download links or inline rendering? What file types need support?

Technical Stack: This was flagged for deeper discussion—build tooling, block development approach, data layer patterns.

Block Inventory: What blocks are needed for each phase?

Technique

When Claude organizes questions into categories before asking them, it’s modeling good requirements gathering. The categories themselves reveal how the system will be structured.

The Pattern Presentation

The Course↔Lesson relationship question showed how architecture options should be presented. Claude laid out three patterns:

Pattern 1: Taxonomy-based
Lessons are a CPT, Courses are a custom taxonomy. Pros: Simple queries, familiar WordPress pattern. Cons: No inherent ordering, taxonomy UI less intuitive for “containers.”

Pattern 2: Parent-child (hierarchical CPT)
Single CPT with Lessons as children of Courses. Pros: Built-in hierarchy, single query for course contents. Cons: Shared templates, less flexibility for Course-specific fields.

Pattern 3: Meta-based relationship
Both are CPTs, Course stores _lesson_ids array. Pros: Full flexibility, explicit ordering, independent templates. Cons: Manual relationship management, slightly more complex queries.

This presentation style—options with explicit pros and cons—does something important. It lets the person with domain expertise make an informed choice rather than accepting a recommendation blindly.

Boundary

Claude can propose architecture patterns and articulate tradeoffs, but it needs domain expertise to validate which tradeoffs matter for a specific project. Present options, don’t just recommend.

My response addressed each category:

1. I think pattern 3 is also the best approach for a strong balance of flexibility and ease of use. Quizzes should probably be able to be assigned at the lesson (chapter quiz) and course (final exam) levels.
2. Lessons should have a hybrid approach. Not every lesson needs to have a quiz, but if it DOES have a quiz, passing it is a prerequisite to moving forward. Pass threshold is 80%, with unlimited retakes. We want the student to learn, not to block them. 
3. Let's implement a new student role so we can assign custom capabilities as needed. This will be single admin for now, but let's keep "instructor" role in the soft requirements list for later. The profile should be a dedicated front end page, and the "student" role which is assigned on user-based  front-end account creation should explicitly redirect any back end profile functionality to the front end profile page. The WP Admin bar should also be fully hidden from this user type. Self assigning of courses is clicking Enroll on course page and immediately enrolled, with a message confirming the enrollment was completed, and a button to begin learning in the course leading to the first lesson. Prerequisite checks may come later with a full curriculum structure, but for now will remain on the "soft requirements" future feature list. Users may unenroll themselves. 
4. File attachments should be downloaded for using locally with Claude. There should also be a "Claude Prompt" block which renders as styled <pre> tag content and features a copy icon that lets users copy to clipboard. Any code block should use syntax highlighting.
5. I think the technical stack question requires a greater conversation than just this simple question set. Let's tag this as a point to come back to once we've answered the others.
6. Claude Prompt block (required). Interactive Claude instance block (future feature, not required now).

Notice point 5: deferring the technical stack question rather than rushing through it. Complex topics deserve focused attention. Trying to resolve everything in a single pass leads to shallow decisions.

Technique

Defer complex topics rather than rushing them. “Let’s tag this as a point to come back to” keeps the current conversation focused while ensuring nothing is forgotten.

The Refinement Questions

Claude confirmed each decision, then identified five remaining gaps—edge cases and UI details that needed resolution:

1. Quiz cardinality: Can a Lesson have multiple quizzes, or strictly one-to-one?
2. Quiz visibility: Same page as lesson content, or separate?
3. “Begin Learning” destination: First lesson, or course overview?
4. Unenrollment behavior: Preserve progress data, or reset?
5. Claude Prompt block styling: Any specific design direction?

On the fifth point, Claude proposed a “Try this prompt” label—a small design suggestion that emerged from the conversation rather than the original brief.

1. Quizzes: one to one for both.
2. Content and quiz are on the same lesson page as you assume.
3. Begin learning links to course overview.
4. User unenrolling keeps progress (default approach to stored user metadata)
5. I like the "Try this prompt" label idea. Let's integrate that.
Insight

Refinement questions are normal, not failure. They’re how high-level requirements become implementable specifications. A session that jumps straight from brief to code is skipping necessary work.

The Technical Stack

With functional requirements resolved, we returned to the deferred technical stack question. Claude presented four decision areas:

Build Tooling: @wordpress/scripts (recommended) vs. custom webpack vs. no build step. The recommendation came with rationale: standardized config, built-in React/JSX support, handles both blocks and frontend assets.

Block Development: Hybrid approach—React for editor experience, PHP render callbacks for dynamic frontend content. Pure JavaScript blocks can’t access current user context at render time.

Data Interactions: REST API throughout vs. admin-ajax vs. direct PHP. REST was recommended for consistency, modern patterns, and better separation of concerns.

Custom Tables: User meta for most progress data, but a custom table for quiz attempts. Why? Quiz attempts need relational queries (scores by quiz, attempts over time, aggregate statistics) that become expensive with meta queries at scale.

I agree completely with each of your recommendations for the reasons outlined.

This answer is short because the decisions were well-reasoned. When recommendations come with clear rationale, agreement can be brief. The technical stack section in the final plan documented not just the choices but why—important for future sessions that might question those decisions.

What the Dance Produced

The architecture conversation took three exchanges after the initial brief. By the end:

Data model defined (CPTs for Course, Lesson, Quiz; meta-based relationships; custom table for attempts). User model specified (new Student role, frontend profile, enrollment flow). Completion logic detailed (hybrid approach, 80% pass threshold, unlimited retakes). Technical stack locked (@wordpress/scripts, hybrid blocks, REST API, one custom table). Block inventory phased (Claude Prompt in PoC, Interactive Claude deferred).

Claude generated the comprehensive project plan immediately after—500+ lines covering everything from database schemas to sprint sequences. That generation was possible because the architecture dance had resolved the ambiguities.

The next post covers the final piece: how the project framework was structured to support development sessions while integrating documentation capture.