Learn by Directing AI
Unit 1

The Clinic Network

Step 1: Set up the project

Open a terminal and navigate to your development directory:

cd ~/dev

Start Claude Code:

claude

Paste the setup prompt:

Create the folder ~/dev/web-dev/p6. Download the project materials from https://learnbydirectingai.dev/materials/webdev/p6/materials.zip and extract them into that folder. Read CLAUDE.md -- it's the project governance file. Open VS Code in the project directory. Install the Claude Code extension and the Live Server extension if they aren't already installed.

Once Claude finishes, your workspace is ready. The CLAUDE.md file gives Claude persistent context about the project -- the client, the tech stack, the seven tickets, and the verification targets. Every session starts by loading this file.

Step 2: Read the email chain

Open materials/first-contact.md.

This is a forwarded email chain. Carlos Reyes, the board chair of Fundacion Esperanza, approved a $4,000 USD budget for a digital records system. He forwarded the approval to Dr. Lucia Pena, the medical director, along with your contact information.

Lucia's original email to Carlos explains the problem. Three clinics -- Santiago, Jarabacoa, and Constanza -- in the mountains north of Santiago de los Caballeros. All paper records. When a patient sees Dr. Martinez at the Jarabacoa clinic on Monday and then walks into the Santiago clinic on Thursday, the nurse calls Jarabacoa and hopes someone finds the folder. Last month, a medication interaction was nearly missed because one doctor didn't know what another had prescribed.

She lists what she needs: records accessible from any clinic, different access levels for different staff, secure, and simple enough for staff who aren't comfortable with computers. She also mentions that the Jarabacoa clinic has unreliable internet.

Notice the two voices in this email chain. Carlos is brief and operational -- budget approved, patient data stays in-country, wants monthly reporting. Lucia is detailed and grounded in specific patients and specific failures. Both give you requirements. The gaps between what they tell you and what you need to know are yours to discover.

Step 3: Talk to Lucia

Open the chat with Lucia. The email chain gives you the broad problem, but not enough detail to plan the system.

You need to understand:

  • Who works at each clinic. How many doctors, nurses, admin staff? Do the same people work across multiple clinics?
  • What each role needs to see. Lucia says "different access levels" but doesn't specify which roles see which data. A doctor needs clinical notes. A nurse needs care plans and vitals. Admin needs scheduling and contact information. But does Lucia see it that way?
  • What "secure" means to her. She knows patient data is sensitive. But has she thought about login credentials, session management, or what happens if someone's password is stolen?

Ask about these gaps. Lucia will fill in details about staff roles, clinic operations, and what each role needs to access. She uses medical terminology naturally -- "patient intake," "contraindicated medications" -- and catches herself: "sorry, what I mean is we need to know what other drugs a patient takes before prescribing."

Pay attention to what she doesn't mention. She won't volunteer the connectivity problems at Jarabacoa unless you ask about infrastructure. She won't mention the undocumented patients unless you ask about registration workflows. These are real constraints that will affect your architecture.

Step 4: Understand authentication vs authorization

Before planning the system, two concepts need to be clear. They sound similar but solve different problems.

Authentication answers: who are you? A user provides credentials -- email and password, for example -- and the system confirms their identity. After authentication, the system knows this is Dr. Martinez, not some anonymous visitor.

Authorization answers: what are you allowed to do? Dr. Martinez is authenticated, but that doesn't mean he can see billing records or admin dashboards. Authorization checks whether his role permits the action he's trying to take.

These two concerns are the foundation of everything you'll build. A system with authentication but broken authorization -- OWASP's number one web application vulnerability -- lets any logged-in user access any other user's data by changing an ID in the URL. That's the difference between "someone is logged in" and "the right person is accessing the right data."

Role-based access control (RBAC) is the pattern for managing authorization at scale. Instead of assigning permissions to individual users, you assign them to roles (doctor, nurse, admin), and each user gets a role. The role determines what they can access. Lucia's clinic network has natural roles -- the staff categories she described map directly to access levels.

One more concept: the trust boundary. This is the line in your system where access control decisions are made. Code above the boundary can be trusted to represent an authenticated, authorised user. Code below cannot. In a web application, the trust boundary is the server. The browser is below the boundary -- it can be manipulated, inspected, and bypassed. The server is above it. All access control decisions happen on the server. Client-side checks are visual guidance -- hiding a button for the wrong role -- but they are not security. Anyone who can construct an HTTP request bypasses the client entirely.

Step 5: Plan the system with Claude

Open the PRD template at materials/templates/prd-template.md. This template has sections for the data model, the access control model (including a roles table and a permissions matrix), technical architecture, and constraints.

Start a planning session with Claude. Before generating anything, give Claude the context it needs: Lucia's requirements from the email chain and the chat, the three roles and what each should access, and one critical constraint -- all access control decisions are enforced server-side, not on the client.

That constraint matters. AI commonly generates role-based access in React components -- hiding the admin panel when user.role !== 'admin' -- without adding the same check on the API route. The button disappears, but the data is still served to anyone who knows the URL. Stating the server-side enforcement constraint before Claude starts planning shapes the entire architecture.

Direct Claude to fill the PRD template. The data model should cover patients, providers, appointments, and medical records. The access control model should specify three roles minimum -- doctor, nurse, admin -- with a permissions matrix showing what each role can read, write, or not access at all. The technical architecture should name the stack: Next.js with App Router, PostgreSQL, and a managed auth solution.

When the PRD is complete, read through the access control matrix. Each cell should be explicit -- not "full access" or "limited access," but specific: doctors read and write clinical notes, nurses read care plans and write vitals, admin reads scheduling and contact info. If any cell says "full access" without specifying what that includes, ask Claude to be specific.

The PRD should also state, in plain language, that authorization is enforced server-side. This isn't a technical implementation detail buried in a footnote -- it's the most important architectural decision in the document.

✓ Check

✓ Check: The PRD specifies at least three distinct roles (doctor, nurse, admin) with different data access permissions, and states that authorization is enforced server-side.