# liljaydi/full-stack-open architecture

> Architecture diagram of the GitHub repository liljaydi/full-stack-open, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-11-14). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/liljaydi/full-stack-open
- Repository: https://github.com/liljaydi/full-stack-open

## Overview

This repository is a collection of Full Stack Open course exercises, not one integrated application. Its projects span small React feedback, anecdote, and curriculum demos; country lookup with weather; a phonebook frontend and API; and a blog-list frontend and backend. The graph keeps these as separate product branches. The country API calls and blog backend routing are evidenced; the phonebook frontend-to-backend and blog frontend-to-backend links are shown as unverified because the excerpts do not establish their endpoint wiring.

Main entry points: [`part2/phonebook/src/App.jsx`](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/App.jsx) (Phonebook App), [`part5/bloglist-frontend/src/App.jsx`](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/App.jsx) (Bloglist App), [`part2/countries/src/App.jsx`](https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/App.jsx) (Country Search), [`part4/bloglist-backend/app.js`](https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/app.js) (Blog API Server)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_part1["Part 1 React Demos"]
  node_anecdotes["Anecdotes<br/>[App.jsx]"]
  node_unicafe["Feedback Statistics<br/>[App.jsx]"]
  node_course1["Course Summary<br/>[App.jsx]"]
end

subgraph group_part2["Part 2 React Apps"]
  node_countries["Country Search<br/>[App.jsx]"]
  node_countrylist["Country List<br/>[CountriesList.jsx]"]
  node_countrydetail["Country Detail<br/>[Country.jsx]"]
  node_course2["Curriculum Viewer<br/>[App.jsx]"]
  node_courseview["Course View<br/>[Course.jsx]"]
  node_courseheader["Course Header<br/>[Header.jsx]"]
  node_coursecontent["Course Content<br/>[Content.jsx]"]
end

subgraph group_phonebook["Phonebook Stack"]
  node_phoneapp["Phonebook App<br/>[App.jsx]"]
  node_personservice["Person API Client<br/>[persons.js]"]
  node_filter["Contact Filter<br/>[Filter.jsx]"]
  node_personform["Contact Form<br/>[PersonForm.jsx]"]
  node_persons["Contact List<br/>[Persons.jsx]"]
  node_notifications["Phonebook Notices<br/>[Notification.jsx]"]
  node_errors["Phonebook Errors"]
  node_phoneapi["Phonebook API<br/>[index.js]"]
  node_personmodel[("Person Model<br/>[person.js]")]
end

subgraph group_blogfront["Bloglist Frontend"]
  node_blogapp["Bloglist App<br/>[App.jsx]"]
  node_blogclient["Blog API Client<br/>[blogs.js]"]
  node_loginclient["Login Client<br/>[login.js]"]
  node_blogview["Blog View<br/>[Blog.jsx]"]
  node_blogform["Blog Form<br/>[BlogForm.jsx]"]
  node_blogtoggle["Form Toggle<br/>[Togglable.jsx]"]
  node_blognotice["Blog Notices<br/>[Notification.jsx]"]
end

subgraph group_blogback["Bloglist Backend"]
  node_blogserver["Blog API Server<br/>[app.js]"]
  node_blogroutes["Blog Routes<br/>[blogs.js]"]
  node_loginroutes["Login Routes<br/>[login.js]"]
  node_userroutes["User Routes<br/>[users.js]"]
  node_blogmodel[("Blog Model<br/>[blog.js]")]
end

node_user(("User"))
node_restcountries["REST Countries API"]
node_weather["OpenWeather API"]

node_user -->|"votes"| node_anecdotes
node_user -->|"rates"| node_unicafe
node_user -->|"searches"| node_countries
node_countries -->|"renders"| node_countrylist
node_countries -->|"renders"| node_countrydetail
node_countries -->|"requests data"| node_restcountries
node_countries -->|"requests weather"| node_weather
node_course2 -->|"renders"| node_courseview
node_courseview -->|"renders"| node_courseheader
node_courseview -->|"renders"| node_coursecontent
node_user -->|"manages contacts"| node_phoneapp
node_phoneapp -->|"calls"| node_personservice
node_phoneapp -->|"renders"| node_filter
node_phoneapp -->|"renders"| node_personform
node_phoneapp -->|"renders"| node_persons
node_phoneapp -->|"renders"| node_notifications
node_phoneapp -->|"renders"| node_errors
node_personservice -.->|"calls API"| node_phoneapi
node_phoneapi -->|"queries"| node_personmodel
node_user -->|"uses"| node_blogapp
node_blogapp -->|"calls"| node_blogclient
node_blogapp -->|"logs in"| node_loginclient
node_blogapp -->|"renders"| node_blogview
node_blogapp -->|"renders"| node_blogform
node_blogapp -->|"renders"| node_blogtoggle
node_blogapp -->|"renders"| node_blognotice
node_blogclient -.->|"calls API"| node_blogserver
node_loginclient -.->|"authenticates"| node_blogserver
node_blogserver -->|"mounts route"| node_blogroutes
node_blogserver -->|"mounts route"| node_loginroutes
node_blogserver -->|"mounts route"| node_userroutes
node_blogroutes -->|"queries"| node_blogmodel

click node_anecdotes "https://github.com/liljaydi/full-stack-open/blob/main/part1/anecdotes/src/App.jsx"
click node_unicafe "https://github.com/liljaydi/full-stack-open/blob/main/part1/unicafe/src/App.jsx"
click node_course1 "https://github.com/liljaydi/full-stack-open/blob/main/part1/courseinfo/src/App.jsx"
click node_countries "https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/App.jsx"
click node_countrylist "https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/components/CountriesList.jsx"
click node_countrydetail "https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/components/Country.jsx"
click node_course2 "https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/App.jsx"
click node_courseview "https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/components/Course.jsx"
click node_courseheader "https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/components/Header.jsx"
click node_coursecontent "https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/components/Content.jsx"
click node_phoneapp "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/App.jsx"
click node_personservice "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/services/persons.js"
click node_filter "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/Filter.jsx"
click node_personform "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/PersonForm.jsx"
click node_persons "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/Persons.jsx"
click node_notifications "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/Notification.jsx"
click node_errors "https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/ErrorNotification.jsx"
click node_phoneapi "https://github.com/liljaydi/full-stack-open/blob/main/part3/phonebook-backend/index.js"
click node_personmodel "https://github.com/liljaydi/full-stack-open/blob/main/part3/phonebook-backend/models/person.js"
click node_blogapp "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/App.jsx"
click node_blogclient "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/services/blogs.js"
click node_loginclient "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/services/login.js"
click node_blogview "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/Blog.jsx"
click node_blogform "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/BlogForm.jsx"
click node_blogtoggle "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/Togglable.jsx"
click node_blognotice "https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/Notification.jsx"
click node_blogserver "https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/app.js"
click node_blogroutes "https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/controllers/blogs.js"
click node_loginroutes "https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/controllers/login.js"
click node_userroutes "https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/controllers/users.js"
click node_blogmodel "https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/models/blog.js"

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_anecdotes,node_unicafe,node_course1,node_user toneBlue
class node_countries,node_countrylist,node_countrydetail,node_course2,node_courseview,node_courseheader,node_coursecontent toneAmber
class node_phoneapp,node_personservice,node_filter,node_personform,node_persons,node_notifications,node_errors,node_phoneapi,node_personmodel,node_restcountries,node_weather toneMint
class node_blogapp,node_blogclient,node_loginclient,node_blogview,node_blogform,node_blogtoggle,node_blognotice toneRose
class node_blogserver,node_blogroutes,node_loginroutes,node_userroutes,node_blogmodel toneIndigo
```

## Components

### Part 1 React Demos

- [Anecdotes](https://github.com/liljaydi/full-stack-open/blob/main/part1/anecdotes/src/App.jsx): `part1/anecdotes/src/App.jsx`
- [Feedback Statistics](https://github.com/liljaydi/full-stack-open/blob/main/part1/unicafe/src/App.jsx): `part1/unicafe/src/App.jsx`
- [Course Summary](https://github.com/liljaydi/full-stack-open/blob/main/part1/courseinfo/src/App.jsx): `part1/courseinfo/src/App.jsx`

### Part 2 React Apps

- [Country Search](https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/App.jsx): `part2/countries/src/App.jsx`
- [Country List](https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/components/CountriesList.jsx): `part2/countries/src/components/CountriesList.jsx`
- [Country Detail](https://github.com/liljaydi/full-stack-open/blob/main/part2/countries/src/components/Country.jsx): `part2/countries/src/components/Country.jsx`
- [Curriculum Viewer](https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/App.jsx): `part2/courseinfo/src/App.jsx`
- [Course View](https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/components/Course.jsx): `part2/courseinfo/src/components/Course.jsx`
- [Course Header](https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/components/Header.jsx): `part2/courseinfo/src/components/Header.jsx`
- [Course Content](https://github.com/liljaydi/full-stack-open/blob/main/part2/courseinfo/src/components/Content.jsx): `part2/courseinfo/src/components/Content.jsx`

### Phonebook Stack

- [Phonebook App](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/App.jsx): `part2/phonebook/src/App.jsx`
- [Person API Client](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/services/persons.js): `part2/phonebook/src/services/persons.js`
- [Contact Filter](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/Filter.jsx): `part2/phonebook/src/components/Filter.jsx`
- [Contact Form](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/PersonForm.jsx): `part2/phonebook/src/components/PersonForm.jsx`
- [Contact List](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/Persons.jsx): `part2/phonebook/src/components/Persons.jsx`
- [Phonebook Notices](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/Notification.jsx): `part2/phonebook/src/components/Notification.jsx`
- [Phonebook Errors](https://github.com/liljaydi/full-stack-open/blob/main/part2/phonebook/src/components/ErrorNotification.jsx): `part2/phonebook/src/components/ErrorNotification.jsx`
- [Phonebook API](https://github.com/liljaydi/full-stack-open/blob/main/part3/phonebook-backend/index.js): `part3/phonebook-backend/index.js`
- [Person Model](https://github.com/liljaydi/full-stack-open/blob/main/part3/phonebook-backend/models/person.js): `part3/phonebook-backend/models/person.js`

### Bloglist Frontend

- [Bloglist App](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/App.jsx): `part5/bloglist-frontend/src/App.jsx`
- [Blog API Client](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/services/blogs.js): `part5/bloglist-frontend/src/services/blogs.js`
- [Login Client](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/services/login.js): `part5/bloglist-frontend/src/services/login.js`
- [Blog View](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/Blog.jsx): `part5/bloglist-frontend/src/components/Blog.jsx`
- [Blog Form](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/BlogForm.jsx): `part5/bloglist-frontend/src/components/BlogForm.jsx`
- [Form Toggle](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/Togglable.jsx): `part5/bloglist-frontend/src/components/Togglable.jsx`
- [Blog Notices](https://github.com/liljaydi/full-stack-open/blob/main/part5/bloglist-frontend/src/components/Notification.jsx): `part5/bloglist-frontend/src/components/Notification.jsx`

### Bloglist Backend

- [Blog API Server](https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/app.js): `part4/bloglist-backend/app.js`
- [Blog Routes](https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/controllers/blogs.js): `part4/bloglist-backend/controllers/blogs.js`
- [Login Routes](https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/controllers/login.js): `part4/bloglist-backend/controllers/login.js`
- [User Routes](https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/controllers/users.js): `part4/bloglist-backend/controllers/users.js`
- [Blog Model](https://github.com/liljaydi/full-stack-open/blob/main/part4/bloglist-backend/models/blog.js): `part4/bloglist-backend/models/blog.js`

### Other components

- **User**
- **REST Countries API**
- **OpenWeather API**

## Connections

- User → Anecdotes: votes (evidence: `part1/anecdotes/src/App.jsx`)
- User → Feedback Statistics: rates (evidence: `part1/unicafe/src/App.jsx`)
- User → Country Search: searches (evidence: `part2/countries/src/App.jsx`)
- Country Search → Country List: renders (evidence: `part2/countries/src/App.jsx`)
- Country Search → Country Detail: renders (evidence: `part2/countries/src/App.jsx`)
- Country Search → REST Countries API: requests data (evidence: `part2/countries/src/App.jsx`)
- Country Search → OpenWeather API: requests weather (evidence: `part2/countries/src/App.jsx`)
- Curriculum Viewer → Course View: renders (evidence: `part2/courseinfo/src/App.jsx`)
- Course View → Course Header: renders (evidence: `part2/courseinfo/src/components/Course.jsx`)
- Course View → Course Content: renders (evidence: `part2/courseinfo/src/components/Course.jsx`)
- User → Phonebook App: manages contacts (evidence: `part2/phonebook/src/App.jsx`)
- Phonebook App → Person API Client: calls (evidence: `part2/phonebook/src/App.jsx`)
- Phonebook App → Contact Filter: renders (evidence: `part2/phonebook/src/App.jsx`)
- Phonebook App → Contact Form: renders (evidence: `part2/phonebook/src/App.jsx`)
- Phonebook App → Contact List: renders (evidence: `part2/phonebook/src/App.jsx`)
- Phonebook App → Phonebook Notices: renders (evidence: `part2/phonebook/src/App.jsx`)
- Phonebook App → Phonebook Errors: renders (evidence: `part2/phonebook/src/App.jsx`)
- Person API Client → Phonebook API: calls API
- Phonebook API → Person Model: queries (evidence: `part3/phonebook-backend/index.js`)
- User → Bloglist App: uses (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Bloglist App → Blog API Client: calls (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Bloglist App → Login Client: logs in (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Bloglist App → Blog View: renders (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Bloglist App → Blog Form: renders (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Bloglist App → Form Toggle: renders (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Bloglist App → Blog Notices: renders (evidence: `part5/bloglist-frontend/src/App.jsx`)
- Blog API Client → Blog API Server: calls API
- Login Client → Blog API Server: authenticates
- Blog API Server → Blog Routes: mounts route (evidence: `part4/bloglist-backend/app.js`)
- Blog API Server → Login Routes: mounts route (evidence: `part4/bloglist-backend/app.js`)
- Blog API Server → User Routes: mounts route (evidence: `part4/bloglist-backend/app.js`)
- Blog Routes → Blog Model: queries (evidence: `part4/bloglist-backend/controllers/blogs.js`)
