Advanced Clinical Odontogram Implementation Plan
Advanced Clinical Odontogram Implementation Plan
Section titled “Advanced Clinical Odontogram Implementation Plan”For Claude: REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
Goal: Implement the “top of the art” Odontogram feature with a strict clinical token namespace, 3-tone tooth depth, and UI additions (Patient Meta Bar, Legend Row) with 100% test coverage driven by TDD.
Architecture: We will first establish the --dental-* token namespace in the global CSS. Next, we will update ToothSVG with the 3-tone body fills and missing-tooth ‘X’ rendering. Finally, we will update Odontogram to receive patient metadata props, render the Meta Bar and Legend Row, and integrate the getToothName helper strictly in ToothPanel.
Tech Stack: React, TypeScript, CSS Variables, SVG, Jest/React Testing Library.
Task 1: Establish Clinical Namespace Tokens
Section titled “Task 1: Establish Clinical Namespace Tokens”Files:
- Modify:
frontend/src/index.css(or main global CSS file) - Test:
frontend/src/components/dental/__tests__/dentalTokens.test.ts(or similar utility test to ensure CSS load if possible, though CSS might be hard to unit test directly. We will test CSS variable application in component tests).
Since CSS files aren’t easily unit tested in isolation in a typical setup, we will skip the RED/GREEN for pure CSS variable declarations and test their application in Task 2.
Step 1: Write the CSS variables into frontend/src/index.css inside :root with documentation that it is the Clinical Namespace.
/* Clinical instrument tokens — NOT brand tokens */:root { --dental-condition-caries: #E24B4A; --dental-condition-fracture: #F97316; --dental-condition-missing: #A5A39E; --dental-condition-to-extract: #A5A39E; --dental-procedure-completed: #1A8A42; --dental-procedure-in-progress: #C07A10; --dental-procedure-planned: #2B6FED;
--dental-tooth-body-base: #F0EDE6; --dental-tooth-body-mid: #EAE7DF; --dental-tooth-body-deep: #E5E2DA; --dental-background: #F7F5F0;}Step 2: Commit
git add frontend/src/index.cssgit commit -m "feat: add clinical token namespace for odontogram"Task 2: 3-Tone Tooth Depth and Missing Tooth “X” in ToothSVG
Section titled “Task 2: 3-Tone Tooth Depth and Missing Tooth “X” in ToothSVG”Files:
- Modify:
frontend/src/components/dental/ToothSVG.tsx - Test:
frontend/src/components/dental/__tests__/ToothSVG.test.tsx(Create if missing)
Step 1: Write the failing test
import React from 'react';import { render } from '@testing-library/react';import { ToothSVG } from '../ToothSVG';
describe('ToothSVG', () => { it('renders 3-tone fill tokens for healthy teeth', () => { const { container } = render(<ToothSVG fdi={16} />); const paths = container.querySelectorAll('path');
// We expect the base rect to have --dental-tooth-body-base const rect = container.querySelector('rect'); expect(rect).toHaveAttribute('fill', 'var(--dental-tooth-body-base)');
// Oclusal path should have --dental-tooth-body-deep // Other paths should have --dental-tooth-body-mid // We will verify the specific fills in the DOM. });
it('renders large X for missing teeth', () => { const { container } = render(<ToothSVG fdi={16} status="missing" />); // Should have an SVG line or path representing the 'X' mark const xMark = container.querySelector('.missing-x-mark'); expect(xMark).toBeInTheDocument(); });});Step 2: Run test to verify it fails
Run: npm test frontend/src/components/dental/__tests__/ToothSVG.test.tsx
Expected: FAIL (paths are transparent, missing tooth lacks X mark).
Step 3: Write minimal implementation
- Update
ToothSVG.tsxbase<rect>to usevar(--dental-tooth-body-base). - Update
getStatusColoror the path rendering logic inToothSVG.tsxto returnvar(--dental-tooth-body-deep)for theOandIzones when healthy, andvar(--dental-tooth-body-mid)for others when healthy. - Add an SVG
<g className="missing-x-mark">containing two intersecting lines across the bounding box whenstatus === 'missing'.
Step 4: Run test to verify it passes
Run: npm test frontend/src/components/dental/__tests__/ToothSVG.test.tsx
Expected: PASS
Step 5: Commit
git add frontend/src/components/dental/ToothSVG.tsx frontend/src/components/dental/__tests__/ToothSVG.test.tsxgit commit -m "feat: implement 3-tone tooth depth and missing tooth X mark"Task 3: Patient Meta Bar & Legend Row in Odontogram
Section titled “Task 3: Patient Meta Bar & Legend Row in Odontogram”Files:
- Modify:
frontend/src/components/dental/Odontogram.tsx - Test:
frontend/src/components/dental/__tests__/Odontogram.test.tsx
Step 1: Write the failing test
import React from 'react';import { render, screen } from '@testing-library/react';import { Odontogram } from '../Odontogram';
describe('Odontogram Layout', () => { it('renders Patient Meta Bar when props are provided', () => { render(<Odontogram patientId="123" patientName="Juan Perez" patientAge={35} lastVisit="12/05/2026" />); expect(screen.getByText('Juan Perez')).toBeInTheDocument(); expect(screen.getByText(/35 años/)).toBeInTheDocument(); expect(screen.getByText(/Última visita: 12\/05\/2026/)).toBeInTheDocument(); });
it('renders the Clinical Legend Row', () => { render(<Odontogram patientId="123" />); // Check for legend labels expect(screen.getByText(/Caries/i)).toBeInTheDocument(); expect(screen.getByText(/Completado/i)).toBeInTheDocument(); expect(screen.getByText(/En Progreso/i)).toBeInTheDocument(); expect(screen.getByText(/Planificado/i)).toBeInTheDocument(); });});Step 2: Run test to verify it fails
Run: npm test frontend/src/components/dental/__tests__/Odontogram.test.tsx
Expected: FAIL (Patient Meta Bar and Legend elements do not exist).
Step 3: Write minimal implementation
- Expand
OdontogramPropsinOdontogram.tsxto includepatientName?: stringandlastVisit?: string. - Above the
dentitionModetoggles, add a div rendering the Patient Meta Bar. - Opposite the
dentitionModetoggles (top right), add the Legend Row rendering 4 distinct spans with colored dot indicators.
Step 4: Run test to verify it passes
Run: npm test frontend/src/components/dental/__tests__/Odontogram.test.tsx
Expected: PASS
Step 5: Commit
git add frontend/src/components/dental/Odontogram.tsx frontend/src/components/dental/__tests__/Odontogram.test.tsxgit commit -m "feat: add patient meta bar and legend row to odontogram"Task 4: ToothPanel Full Tooth Name Standardization
Section titled “Task 4: ToothPanel Full Tooth Name Standardization”Files:
- Modify:
frontend/src/components/dental/ToothPanel.tsx - Test:
frontend/src/components/dental/__tests__/ToothPanel.test.tsx
Step 1: Write the failing test
import React from 'react';import { render, screen } from '@testing-library/react';import { ToothPanel } from '../ToothPanel';import * as toothUtils from '../toothUtils';
describe('ToothPanel', () => { it('displays the full clinical tooth name in the header using getToothName', () => { // Spy on getToothName to ensure it's called const spy = jest.spyOn(toothUtils, 'getToothName');
render( <ToothPanel patientId="123" isOpen={true} onClose={() => {}} selectedTooth={{ fdi: 16 }} catalog={[]} onSave={() => {}} /> );
expect(spy).toHaveBeenCalledWith(16); expect(screen.getByText('16 - Primer Molar Superior Derecho')).toBeInTheDocument(); });});Step 2: Run test to verify it fails
Run: npm test frontend/src/components/dental/__tests__/ToothPanel.test.tsx
Expected: Depending on current implementation, may fail if the string format does not match exactly or if getToothName is missing/mocked incorrectly.
Step 3: Write minimal implementation
- Ensure the header in
ToothPanel.tsxis exactly{selectedTooth.fdi} - {getToothName(selectedTooth.fdi)}. - If it’s already perfectly implemented, the test will pass immediately, which violates TDD. If so, we acknowledge the test proves existing behavior is correct. (As noted in the spec, this is partially already in place but we are writing the test to verify and lock it down).
Step 4: Run test to verify it passes
Run: npm test frontend/src/components/dental/__tests__/ToothPanel.test.tsx
Expected: PASS
Step 5: Commit
git add frontend/src/components/dental/ToothPanel.tsx frontend/src/components/dental/__tests__/ToothPanel.test.tsxgit commit -m "test: ensure full clinical tooth name renders in ToothPanel header"