# SONUS — MASTER PROMPT ## Mission Build and finish **Sonu...
Prompt
# SONUS — MASTER PROMPT ## Mission Build and finish **Sonus**, a cross-platform educational body-sound training app for Android, iOS, and modern web browsers. Sonus teaches recognition of heart and lung sounds through a curated audio library, explanations, diagrams, quizzes, progress tracking, and a layered audio simulator. Use the existing repository as the source of truth. The repository path is: `C:\Users\K1\Desktop\Projects\Ideas\Ideas\Sonus` The detailed source specification is represented by the numbered prompts in `Prompts/1.md` through `Prompts/20.md`. Treat this master prompt as their consolidated implementation contract. Do not implement the numbered prompts as twenty disconnected mini-projects. Build one coherent product with one shared architecture, one shared data model, one shared audio pipeline, one shared persistence layer, and one shared cross-platform codebase. The app is educational only. It must not diagnose, recommend treatment, prescribe medication, replace professional judgment, or present itself as a medical device. Do not use real patient-identifiable data. Keep all user-facing text, code comments, README content, configuration comments, and developer documentation in English. --- ## Operating rules for the implementation agent 1. Inspect the repository, package manifest, Expo configuration, route tree, source tree, assets, tests, and existing instructions before editing. 2. Preserve working behavior. Extend the responsible existing module instead of creating parallel implementations. 3. If the repository is incomplete, create the missing foundation, but do not recreate or discard valid existing work. 4. Use the simplest architecture that satisfies the complete contract below. 5. Keep the single shared codebase for Android, iOS, and Web. Do not create separate unrelated native and web applications. 6. Use React Native primitives and platform-safe abstractions. Do not depend on direct DOM APIs in shared UI. 7. Keep business logic outside screens whenever practical. Keep pure data, selectors, quiz logic, progress calculations, validation, and persistence adapters independently testable. 8. Keep one canonical `SoundDefinition` model. Features reference sounds by `soundId`; they do not duplicate sound metadata. 9. Keep one canonical `AudioAssetSource` model. Library playback, quiz playback, preload logic, and simulator playback use the same asset-resolution helpers. 10. Keep one canonical storage abstraction. Preferences, progress, user simulator presets, and theme settings use it with versioning, validation, migration, and safe defaults. 11. Do not add speculative backend services, authentication, analytics, patient records, social features, billing, or remote dependencies. MVP content must work with bundled assets and local storage. 12. Do not invent real medical audio or claim that placeholder assets are clinically validated. Mark placeholders clearly and keep asset replacement straightforward. 13. Handle malformed data, missing assets, unavailable audio APIs, failed storage, invalid routes, empty quiz pools, and render errors without crashing the app. 14. Respect keyboard operation on Web, touch operation on mobile, screen readers, dynamic font scaling, sufficient contrast, and reduced-motion preferences. 15. Run the smallest sufficient proof after each meaningful stage. Before completion, run formatting/lint/type checks, unit tests, and a web smoke/build check when the repository supports them. Report commands and real results. 16. Update README documentation to match the actual implementation. Never document files, commands, routes, or features that do not exist. --- ## Product scope Sonus must provide these complete user journeys: 1. First launch shows onboarding when it has not been completed. 2. User enters the app and can browse the sound library. 3. User filters by heart, lung, or all sounds and searches by title or description. 4. User opens a sound detail view with educational explanation, timing/location notes, diagram content when available, and shared audio controls. 5. User plays, pauses, stops, loops, and adjusts volume for a sound. 6. User starts a quiz, chooses a mode and optional filters, listens to sounds, answers questions, receives feedback, and reviews the result. 7. Completed quizzes are recorded exactly once in local progress history. 8. User views progress summaries and can reset local quiz history after confirmation. 9. User opens the simulator, chooses a built-in or saved configuration, adjusts layers and heart rate, and controls playback. 10. User saves, loads, and deletes simulator configurations. 11. User changes theme mode, replays onboarding, reads About and educational/legal notices, and reaches all main features through clear navigation. 12. The app runs from one Expo project on Android, iOS, and Web, with graceful feature fallbacks where a platform lacks an equivalent audio capability. --- ## Required technology and project shape Use: - Expo, latest stable version compatible with the repository. - React Native. - TypeScript with `strict: true`. - Expo Router for navigation. - React Native Web for browser support. - `expo-av` or the repository's current supported Expo audio package for native and compatibility playback. If the installed Expo SDK has replaced or deprecated `expo-av`, use the supported replacement while preserving the same internal audio abstraction. - Web Audio API for layered Web simulator playback when available. - React Context and hooks for small global state domains; do not introduce Redux or another large state framework without a demonstrated need. - Existing project styling and dependencies when they fit. Avoid adding dependencies for functionality already provided by React Native, Expo, or the installed project. Maintain a structure similar to this, adapting only when the repository already has a better coherent structure: ```text app/ _layout.tsx index.tsx (tabs)/ _layout.tsx library.tsx quiz.tsx progress.tsx simulator.tsx settings.tsx sound/[soundId].tsx quiz-review.tsx onboarding.tsx about.tsx debug.tsx # optional, development-only access src/ components/ screens/ data/ audio/ core/ providers/ storage/ preferences/ progress/ simulatorUserPresets/ errors.ts logging.ts theme/ utils/ assets/ audio/heart/ audio/lung/ tests/ README.md ``` Routes may use another valid Expo Router arrangement, but all required destinations must remain discoverable and deep-link-safe. --- ## Architecture and ownership ### Canonical data ownership Create or preserve a single `SoundDefinition` type in `src/data/`. It must include at least: ```ts type SoundCategory = "heart" | "lung"; type DifficultyLevel = "beginner" | "intermediate" | "advanced"; type SoundTag = | "S1" | "S2" | "S3" | "S4" | "murmur" | "systolic" | "diastolic" | "wheezing" | "crackles" | "rhonchi" | "stridor" | "normal" | "abnormal"; type AudioAssetSource = | { type: "bundled"; asset: number } | { type: "remote"; uri: string }; ``` `SoundDefinition` must contain: - `id` - `title` - `category` - `tags` - `description` - `shortHint` - `audioAsset: AudioAssetSource` - optional `pcgDiagram` or diagram reference - optional `locationNotes` - optional `timingNotes` - `difficultyLevel` Use a meaningful placeholder dataset containing at least three heart sounds and three lung sounds: - normal S1/S2 - a systolic murmur such as mitral regurgitation - a diastolic murmur such as aortic regurgitation - normal vesicular breath sounds - wheezing - crackles Use realistic educational descriptions, but do not imply that placeholder audio is validated clinical evidence. Put all sound selectors in a pure module: - `getSoundById(id)` - `getSoundsByCategory(category)` - `searchSoundsByTag(tag)` - `searchSoundsByText(query)` Export canonical data types, mock data, and selectors through a stable barrel file. ### Shared providers and storage Create or preserve `AppProviders` in the root layout. Compose providers without circular dependencies: - preferences - progress - simulator user presets - theme, if not integrated into preferences - error/logging facilities only when needed Create a versioned storage abstraction over AsyncStorage or the installed Expo-compatible local storage solution, with a Web-compatible fallback. It must: - serialize and parse typed values safely - validate loaded data - use stable namespaced keys - recover to defaults when data is missing or corrupt - avoid writing partial state - support future migrations - expose clear errors without crashing the UI Store only educational preferences, quiz performance, theme choice, onboarding completion, and simulator presets. No patient data. ### Error and logging ownership Create one `AppError` model with categories such as `audio`, `data`, `storage`, `network`, `quiz`, `simulator`, and `unknown`. Map low-level failures into `AppError` before they cross module boundaries. Centralize logging and never log secrets, user health information, or raw sensitive payloads. Add a root error boundary with a clear English fallback, retry action, and safe navigation behavior. Feature errors must expose recovery actions such as retry, go back, skip invalid content, or return to a safe screen. --- ## Design system and layout Create or preserve one typed theme token system containing: - light and dark colors - high-contrast text colors - primary calm blue - secondary teal/green - restrained amber accent - backgrounds, surfaces, borders, danger, warning, success - spacing scale - typography sizes, line heights, and weights - radii and platform-safe elevation/shadows Create reusable components such as: - `Screen` - `Typography` variants: title, subtitle, body, caption - `PrimaryButton` - `Card` - shared input, toggle, slider, empty-state, loading-state, error-state, and audio-control components as justified by reuse Do not build ad-hoc typography and container systems inside each screen. Components must use theme tokens, handle safe areas, support optional scrolling, allow a readable maximum content width on Web, and work on narrow phones, tablets, and desktop browsers. Responsive behavior: - one-column content on small screens - two- or three-column library grid on larger screens when useful - side-by-side diagram/details layout on large screens, stacked layout on small screens - readable simulator and progress layouts at every supported width - no horizontal overflow - keyboard focus remains visible and logical Accessibility: - meaningful labels, roles, hints, and states on controls - touch targets large enough for mobile use - dynamic font scaling where supported - AA-level contrast where practical - no information communicated by color alone - semantic headings and readable long-form text - Tab, Shift+Tab, Enter, and Space operation on Web - reduced-motion fallback for animated visualizations All UI strings and comments are English only. --- ## Navigation and onboarding Use Expo Router. Main navigation must make Library, Quiz, Progress, Simulator, and Settings easy to reach. Detail, review, onboarding, About, and optional Debug routes may be stack routes. Onboarding must contain three or four concise English slides explaining: - training the clinical ear for heart and lung sounds - appropriate headphone use - using Library and Quiz together - educational-only limitations and the need for professional judgment Persist `hasCompletedOnboarding` through the shared preferences/storage system. Show onboarding at startup only when needed. Provide `Next`, `Back`, `Skip`, and final `Get started` actions. Settings must offer `View onboarding again` without corrupting navigation state. --- ## Audio pipeline ### Single-track playback All Library, Sound Detail, and Quiz playback must use one audio abstraction under `src/audio/`. No screen may call `Audio.Sound` or Web Audio directly. Provide a typed service with operations equivalent to: - `loadTrack(source)` - `play()` - `pause()` - `stop()` - `unload()` - `getStatus()` - optional `setVolume()` and loop control - disposal/cleanup Expose a React hook such as `useAudioPlayer` with loading, playing, paused, stopped, error, current source, and actions. Provide reusable `AudioPlayerControls` with accessible labels and visible loading/error/retry states. Use bundled local assets for the core MVP so the Library, Quiz, and simulator remain useful offline. Support remote URI sources only as an explicit optional path with network failure handling. Use shared asset-resolution helpers for bundled and remote sources. Set safe audio defaults from preferences: - volume range `0..1` - loop enabled/disabled - no unexpected autoplay except when the user preference explicitly enables it - stop and unload on unmount or source replacement - avoid overlapping stale tracks - prevent race conditions when rapid load/play/stop actions occur ### Library and detail Library must: - render all available sounds in a scrollable accessible list or responsive grid - show title, category, key tags, and difficulty - filter All/Heart/Lung - search title and description - display matching-result count - respect the preferred category filter - navigate by `soundId` Sound Detail must: - resolve canonical data by `soundId` - show title, category, tags, description, location notes, timing notes, difficulty, diagram content, and shared audio controls - handle missing IDs safely with a clear message and return action - honor `autoPlayOnDetail`, volume, and loop preferences - offer `Open in simulator` when a relevant simulator preset exists ### Diagrams Define a canonical `DiagramDefinition` linked by `soundId`, with: - `id` - `soundId` - `type: "phonocardiogram" | "lung"` - title - description - optional image asset - notes Create `DiagramCard` using shared theme/layout components. Render diagrams on Sound Detail. Keep the model ready for later SVG/canvas or synchronized waveform work, but do not add a complex diagram engine when static educational content is sufficient. Descriptive text must remain available to screen readers. --- ## Quiz system Define quiz questions that reference canonical sounds by `soundId`: - `id` - `soundId` - `questionText` - choices - correct choice index or stable correct answer - difficulty - optional explanation Create a UI-agnostic `useQuizEngine` or equivalent domain engine. It must own: - current question/index - finite question set - score - selected answers - answer history - correct/incorrect state - finished state - restart behavior - configuration