# ebuka-fullstack/fso-part2 architecture

> Architecture diagram of the GitHub repository ebuka-fullstack/fso-part2, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-06-17). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/ebuka-fullstack/fso-part2
- Repository: https://github.com/ebuka-fullstack/fso-part2

## Overview

1. **Repository shape**
   - This is a small monorepo with **three independent React/Vite applications** in sibling folders: `courseinfo`, `dataforcountries`, and `Phonebook`.
   - They do **not share code**; each app has its own `package.json`, Vite config, ESLint config, `index.html`, and `src/main.jsx` entrypoint.

2. **Common frontend architecture**
   - All three apps are **browser SPAs built with React**.
   - The standard flow is: `main.jsx` mounts `App.jsx`, and `App.jsx` composes feature components plus CSS.
   - The architecture is therefore mostly **client-side component composition and state management**, not server-side rendering.

3. **`courseinfo`: pure presentation and prop drilling**
   - `courseinfo` is a **static course information app** with a small, purely UI-oriented component tree.
   - `App.jsx` is the composition root and likely holds the course data, while `Header`, `Content`, `Course`, `Part`, and `Total` render sections of that data.
   - Data flows **top-down via props**; there is no visible persistence layer, API client, or cross-component shared store.

4. **`courseinfo` boundary**
   - The key boundary is between **data definition in `App.jsx`** and **display components** in `src/components`.
   - This app is a good example of a **presentational component hierarchy**: simple inputs, deterministic outputs, no external services.

5. **`dataforcountries`: single-page lookup app**
   - `dataforcountries` is structurally simpler in the file tree: it has `App.jsx` and styles, but no component or service subdirectories.
   - That suggests the app’s logic is concentrated in one place, with **centralized state and conditional rendering** in the main app component.
   - Architecturally, it is a **client-only information search/browse app** rather than a multi-layered system.

6. **`dataforcountries` likely data flow**
   - User interaction is expected to flow from an input in `App.jsx` into local state, then back out to a filtered result view.
   - Because there is no separate service module in the tree, any data-fetching or lookup logic is likely handled **directly in the app component**, not abstracted behind a dedicated data layer.

7. **`Phonebook`: stateful CRUD app**
   - `Phonebook` is the most layered app in the repo.
   - `App.jsx` orchestrates the overall feature flow, while `PersonForm`, `Filter`, `Persons`, and `Notification` split the UI into input, search, list, and feedback concerns.
   - This app has explicit user-driven state transitions: create/update/delete contacts, filter the list, and show messages.

8. **`Phonebook` service boundary**
   - `src/services/persons.js` is the main architectural boundary in the repo.
   - It isolates **person-related backend communication** from React components, so UI code does not talk to persistence directly.
   - This separation makes the app a classic **UI layer + service layer** setup.

9. **`Phonebook` persistence**
   - `db.json` is the local data store for the phonebook app, indicating a **mock or lightweight JSON-backed backend** used during development.
   - In an architecture diagram, this should be shown as the persistence/data source behind the `persons` service module, not as part of the React UI.

10. **Notifications and ephemeral UI state**
   - `Notification.jsx` represents a transient UI channel for success/error feedback.
   - It is separate from the person list and form state, so notifications should be drawn as **application state rendered by a dedicated display component** rather than as part of the data model.

11. **What is shared across the repo**
   - The shared architectural pattern across all three apps is **React component composition with local state**.
   - There is no evidence of a shared backend, shared design system, or shared application shell across the folders.

12. **Tooling and runtime**
   - The repository uses **Vite** for each app, which shapes the structure around `main.jsx`, `index.html`, and fast local development.
   - The presence of separate lockfiles and configs means each app is independently installable and runnable.
   - `eslint.config.js` in each folder indicates per-app linting, not a centralized workspace setup.

Main entry points: [`Phonebook/src/App.jsx`](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/App.jsx) (App), [`courseinfo/src/App.jsx`](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/App.jsx) (App), [`courseinfo/src/components/Course.jsx`](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Course.jsx) (Course), [`courseinfo/src/components/Content.jsx`](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Content.jsx) (Content)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_courseinfo["courseinfo"]
  node_courseinfo_main["main.jsx<br/>entrypoint<br/>[main.jsx]"]
  node_courseinfo_app["App<br/>composition root<br/>[App.jsx]"]
  node_courseinfo_header["Header<br/>presentational<br/>[Header.jsx]"]
  node_courseinfo_content["Content<br/>presentational<br/>[Content.jsx]"]
  node_courseinfo_course["Course<br/>presentational<br/>[Course.jsx]"]
  node_courseinfo_part["Part<br/>presentational<br/>[Part.jsx]"]
  node_courseinfo_total["Total<br/>presentational<br/>[Total.jsx]"]
end

subgraph group_dataforcountries["dataforcountries"]
  node_data_main["main.jsx<br/>entrypoint<br/>[main.jsx]"]
  node_data_app["App<br/>stateful view<br/>[App.jsx]"]
end

subgraph group_phonebook["Phonebook"]
  node_phonebook_main["main.jsx<br/>entrypoint<br/>[main.jsx]"]
  node_phonebook_app["App<br/>orchestrator<br/>[App.jsx]"]
  node_phonebook_form["PersonForm<br/>input form<br/>[PersonForm.jsx]"]
  node_phonebook_filter["Filter<br/>search input<br/>[Filter.jsx]"]
  node_phonebook_persons["Persons<br/>list view<br/>[Persons.jsx]"]
  node_phonebook_notification["Notification<br/>feedback<br/>[Notification.jsx]"]
  node_phonebook_service["persons.js<br/>service layer<br/>[persons.js]"]
  node_phonebook_db[("db.json<br/>json backend<br/>[db.json]")]
end

node_courseinfo_main -->|"mounts"| node_courseinfo_app
node_courseinfo_app -->|"renders"| node_courseinfo_header
node_courseinfo_app -->|"renders"| node_courseinfo_content
node_courseinfo_content -->|"contains"| node_courseinfo_course
node_courseinfo_course -->|"contains"| node_courseinfo_part
node_courseinfo_course -->|"contains"| node_courseinfo_total
node_data_main -->|"mounts"| node_data_app
node_phonebook_main -->|"mounts"| node_phonebook_app
node_phonebook_app -->|"renders"| node_phonebook_form
node_phonebook_app -->|"renders"| node_phonebook_filter
node_phonebook_app -->|"renders"| node_phonebook_persons
node_phonebook_app -->|"renders"| node_phonebook_notification
node_phonebook_app -->|"uses"| node_phonebook_service
node_phonebook_service -->|"persists to"| node_phonebook_db

click node_courseinfo_main "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/main.jsx"
click node_courseinfo_app "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/App.jsx"
click node_courseinfo_header "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Header.jsx"
click node_courseinfo_content "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Content.jsx"
click node_courseinfo_course "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Course.jsx"
click node_courseinfo_part "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Part.jsx"
click node_courseinfo_total "https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Total.jsx"
click node_data_main "https://github.com/ebuka-fullstack/fso-part2/blob/main/dataforcountries/src/main.jsx"
click node_data_app "https://github.com/ebuka-fullstack/fso-part2/blob/main/dataforcountries/src/App.jsx"
click node_phonebook_main "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/main.jsx"
click node_phonebook_app "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/App.jsx"
click node_phonebook_form "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/PersonForm.jsx"
click node_phonebook_filter "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/Filter.jsx"
click node_phonebook_persons "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/Persons.jsx"
click node_phonebook_notification "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/Notification.jsx"
click node_phonebook_service "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/services/persons.js"
click node_phonebook_db "https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/db.json"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_courseinfo_main,node_courseinfo_app,node_courseinfo_header,node_courseinfo_content,node_courseinfo_course,node_courseinfo_part,node_courseinfo_total toneBlue
class node_data_main,node_data_app toneAmber
class node_phonebook_main,node_phonebook_app,node_phonebook_form,node_phonebook_filter,node_phonebook_persons,node_phonebook_notification,node_phonebook_service,node_phonebook_db toneMint
```

## Components

### courseinfo

React/Vite course information SPA

- [main.jsx](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/main.jsx): entrypoint · Vite browser entry that mounts the app · `courseinfo/src/main.jsx`
- [App](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/App.jsx): composition root · Holds course data and assembles the page · `courseinfo/src/App.jsx`
- [Header](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Header.jsx): presentational · Renders the course header · `courseinfo/src/components/Header.jsx`
- [Content](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Content.jsx): presentational · Renders the course content section · `courseinfo/src/components/Content.jsx`
- [Course](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Course.jsx): presentational · Wraps course-level display · `courseinfo/src/components/Course.jsx`
- [Part](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Part.jsx): presentational · Renders one course part · `courseinfo/src/components/Part.jsx`
- [Total](https://github.com/ebuka-fullstack/fso-part2/blob/main/courseinfo/src/components/Total.jsx): presentational · Shows the summed course hours · `courseinfo/src/components/Total.jsx`

### dataforcountries

React/Vite country lookup SPA

- [main.jsx](https://github.com/ebuka-fullstack/fso-part2/blob/main/dataforcountries/src/main.jsx): entrypoint · Vite browser entry that mounts the app · `dataforcountries/src/main.jsx`
- [App](https://github.com/ebuka-fullstack/fso-part2/blob/main/dataforcountries/src/App.jsx): stateful view · Centralized lookup and conditional rendering · `dataforcountries/src/App.jsx`

### Phonebook

React/Vite contacts CRUD app

- [main.jsx](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/main.jsx): entrypoint · Vite browser entry that mounts the app · `Phonebook/src/main.jsx`
- [App](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/App.jsx): orchestrator · Coordinates form, filter, list, and notifications · `Phonebook/src/App.jsx`
- [PersonForm](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/PersonForm.jsx): input form · Creates and updates contacts · `Phonebook/src/components/PersonForm.jsx`
- [Filter](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/Filter.jsx): search input · Filters the contact list · `Phonebook/src/components/Filter.jsx`
- [Persons](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/Persons.jsx): list view · Displays the current contacts · `Phonebook/src/components/Persons.jsx`
- [Notification](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/components/Notification.jsx): feedback · Shows transient success and error messages · `Phonebook/src/components/Notification.jsx`
- [persons.js](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/src/services/persons.js): service layer · Backend communication for contacts · `Phonebook/src/services/persons.js`
- [db.json](https://github.com/ebuka-fullstack/fso-part2/blob/main/Phonebook/db.json): json backend · Local persistence for the phonebook data · `Phonebook/db.json`

## Connections

- main.jsx → App: mounts · Bootstraps the React app
- App → Header: renders · Composes the page header
- App → Content: renders · Composes the main content section
- Content → Course: contains · Groups course presentation
- Course → Part: contains · Renders individual parts
- Course → Total: contains · Renders the total summary
- main.jsx → App: mounts · Bootstraps the lookup app
- main.jsx → App: mounts · Bootstraps the contacts app
- App → PersonForm: renders · Handles create and update input
- App → Filter: renders · Handles list filtering
- App → Persons: renders · Displays contacts
- App → Notification: renders · Displays transient feedback
- App → persons.js: uses · Delegates contact persistence and backend calls
- persons.js → db.json: persists to · Backs the service with local JSON data
