# gravedd/portfolio architecture

> Architecture diagram of the GitHub repository gravedd/portfolio, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-08-05). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/gravedd/portfolio
- Repository: https://github.com/gravedd/portfolio

## Overview

#### Purpose and Runtime
A PHP/MySQL personal business-card site with an MVC-style server-rendered architecture. It exposes public portfolio/content pages plus an administrator workflow for creating and editing articles. The web-server front controller is `index.php`; Apache access rules are represented by `.htaccess` files at the root and within protected directories.

#### Request Routing
`index.php` initializes request handling and delegates route resolution to `components/Router.php`. Route definitions live in `config/routes.php`, mapping URL patterns to controller actions. This is the principal control boundary between HTTP requests and application code.

#### Controllers
Controllers orchestrate page-level use cases:
- Public site pages: `controllers/SiteController.php`
- Article listing/detail/preview operations: `controllers/ArticlesController.php`
- Authentication and admin management actions: `controllers/AdminController.php`

Controllers select models, obtain data, and render PHP view templates rather than returning an API response.

#### Models and Persistence
The application persists content and admin data in MySQL. Database access is centralized in `components/db.php`; the schema/data baseline is `portfolio.sql`. Domain-facing model layers are:
- Site content: `models/sitemodel.php`
- Articles: `models/article.php`
- Admin/session-oriented behavior: `models/admin.php`, `models/adminbase.php`

The model/database boundary isolates SQL and persistence concerns from controllers.

#### Public Rendering Flow
A public request follows `index.php` → `components/Router.php` → site or article controller → relevant model → view. Top-level page templates include `views/index.php`, `views/AllArticles.php`, and `views/article.php`; reusable page composition is handled through includes such as `views/includes/header.php`, `views/includes/footer.php`, and article-content fragments.

Static presentation assets are served from `views/css`, `views/js`, `views/img`, and `views/fonts`.

#### Article Authoring and Preview
Article management has separate render states for creation, editing, and preview:
- `views/addarticle.php`
- `views/articleedit.php`
- `views/articlepreview.php`
- `views/newarticlepreview.php`

`controllers/ArticlesController.php` and `controllers/AdminController.php` form the workflow boundary for public article display versus privileged authoring actions, backed by `models/article.php`.

#### Administration and Uploaded Assets
Admin entry and dashboard rendering are represented by `views/adminlogin.php` and `views/admin.php`, with form/panel fragments in `views/includes/adminloginform.php` and `views/includes/adminpanel.php`. Admin authentication/authorization is expected to gate write operations before model updates.

User-managed files are stored under `uploads/`, notably `uploads/images`; this filesystem boundary is separate from database-backed article and admin records. The repository currently also contains document/design assets directly under `uploads/`.

Main entry points: [`components/Router.php`](https://github.com/gravedd/portfolio/blob/main/components/Router.php) (Router), [`controllers/AdminController.php`](https://github.com/gravedd/portfolio/blob/main/controllers/AdminController.php) (Admin controller), [`controllers/ArticlesController.php`](https://github.com/gravedd/portfolio/blob/main/controllers/ArticlesController.php) (Articles controller), [`views/index.php`](https://github.com/gravedd/portfolio/blob/main/views/index.php) (Public views)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_runtime["Web runtime"]
  node_apache{{"Apache rules<br/>web server<br/>[.htaccess]"}}
  node_front_controller["Front controller<br/>PHP entry point<br/>[index.php]"]
end

subgraph group_application["Application"]
  node_router["Router<br/>request routing<br/>[Router.php]"]
  node_routes["Route definitions<br/>route map<br/>[routes.php]"]
  node_site_controller["Site controller<br/>public controller<br/>[SiteController.php]"]
  node_articles_controller["Articles controller<br/>content controller"]
  node_admin_controller["Admin controller<br/>privileged controller"]
  node_site_model["Site model<br/>content model<br/>[sitemodel.php]"]
  node_article_model["Article model<br/>[article.php]"]
  node_admin_models["Admin models<br/>admin/session models<br/>[admin.php]"]
end

subgraph group_rendering["Rendering"]
  node_public_views["Public views<br/>PHP templates<br/>[index.php]"]
  node_authoring_views["Authoring views<br/>PHP templates<br/>[addarticle.php]"]
  node_admin_views["Admin views<br/>PHP templates<br/>[adminlogin.php]"]
  node_shared_layout["Shared layout<br/>template includes<br/>[header.php]"]
  node_static_assets["Static assets<br/>presentation assets"]
end

subgraph group_storage["Storage"]
  node_database_access["Database access<br/>SQL gateway<br/>[db.php]"]
  node_mysql[("MySQL<br/>database<br/>[portfolio.sql]")]
  node_uploads["Uploaded assets<br/>filesystem storage"]
end

node_apache -->|"forwards requests"| node_front_controller
node_front_controller -->|"delegates"| node_router
node_router -->|"resolves against"| node_routes
node_router -->|"public pages"| node_site_controller
node_router -->|"article routes"| node_articles_controller
node_router -->|"admin routes"| node_admin_controller
node_site_controller -->|"loads content"| node_site_model
node_articles_controller -->|"reads articles"| node_article_model
node_admin_controller -->|"auth/session"| node_admin_models
node_admin_controller -->|"writes articles"| node_article_model
node_site_model -->|"queries"| node_database_access
node_article_model -->|"queries"| node_database_access
node_admin_models -->|"queries"| node_database_access
node_database_access -->|"persists"| node_mysql
node_site_controller -->|"renders"| node_public_views
node_articles_controller -->|"renders"| node_public_views
node_articles_controller -->|"renders previews"| node_authoring_views
node_admin_controller -->|"renders editing"| node_authoring_views
node_admin_controller -->|"renders"| node_admin_views
node_public_views -->|"includes"| node_shared_layout
node_admin_views -->|"includes"| node_shared_layout
node_public_views -.->|"uses"| node_static_assets
node_authoring_views -->|"manages assets"| node_uploads

click node_apache "https://github.com/gravedd/portfolio/blob/main/.htaccess"
click node_front_controller "https://github.com/gravedd/portfolio/blob/main/index.php"
click node_router "https://github.com/gravedd/portfolio/blob/main/components/Router.php"
click node_routes "https://github.com/gravedd/portfolio/blob/main/config/routes.php"
click node_site_controller "https://github.com/gravedd/portfolio/blob/main/controllers/SiteController.php"
click node_articles_controller "https://github.com/gravedd/portfolio/blob/main/controllers/ArticlesController.php"
click node_admin_controller "https://github.com/gravedd/portfolio/blob/main/controllers/AdminController.php"
click node_site_model "https://github.com/gravedd/portfolio/blob/main/models/sitemodel.php"
click node_article_model "https://github.com/gravedd/portfolio/blob/main/models/article.php"
click node_admin_models "https://github.com/gravedd/portfolio/blob/main/models/admin.php"
click node_database_access "https://github.com/gravedd/portfolio/blob/main/components/db.php"
click node_mysql "https://github.com/gravedd/portfolio/blob/main/portfolio.sql"
click node_public_views "https://github.com/gravedd/portfolio/blob/main/views/index.php"
click node_authoring_views "https://github.com/gravedd/portfolio/blob/main/views/addarticle.php"
click node_admin_views "https://github.com/gravedd/portfolio/blob/main/views/adminlogin.php"
click node_shared_layout "https://github.com/gravedd/portfolio/blob/main/views/includes/header.php"
click node_static_assets "https://github.com/gravedd/portfolio/tree/main/views/css"

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_apache,node_front_controller toneBlue
class node_router,node_routes,node_site_controller,node_articles_controller,node_admin_controller,node_site_model,node_article_model,node_admin_models toneAmber
class node_public_views,node_authoring_views,node_admin_views,node_shared_layout,node_static_assets toneMint
class node_database_access,node_mysql,node_uploads toneRose
```

## Components

### Web runtime

- [Apache rules](https://github.com/gravedd/portfolio/blob/main/.htaccess): web server · Root and protected-directory access rules. · `.htaccess`
- [Front controller](https://github.com/gravedd/portfolio/blob/main/index.php): PHP entry point · `index.php`

### Application

- [Router](https://github.com/gravedd/portfolio/blob/main/components/Router.php): request routing · `components/Router.php`
- [Route definitions](https://github.com/gravedd/portfolio/blob/main/config/routes.php): route map · `config/routes.php`
- [Site controller](https://github.com/gravedd/portfolio/blob/main/controllers/SiteController.php): public controller · `controllers/SiteController.php`
- [Articles controller](https://github.com/gravedd/portfolio/blob/main/controllers/ArticlesController.php): content controller · Handles public article display and preview states. · `controllers/ArticlesController.php`
- [Admin controller](https://github.com/gravedd/portfolio/blob/main/controllers/AdminController.php): privileged controller · Gates administration and write actions. · `controllers/AdminController.php`
- [Site model](https://github.com/gravedd/portfolio/blob/main/models/sitemodel.php): content model · `models/sitemodel.php`
- [Article model](https://github.com/gravedd/portfolio/blob/main/models/article.php): article model · `models/article.php`
- [Admin models](https://github.com/gravedd/portfolio/blob/main/models/admin.php): admin/session models · `models/admin.php`

### Rendering

- [Public views](https://github.com/gravedd/portfolio/blob/main/views/index.php): PHP templates · Home and article listing/detail templates. · `views/index.php`
- [Authoring views](https://github.com/gravedd/portfolio/blob/main/views/addarticle.php): PHP templates · Create, edit, and preview article states. · `views/addarticle.php`
- [Admin views](https://github.com/gravedd/portfolio/blob/main/views/adminlogin.php): PHP templates · Login, dashboard, and admin form fragments. · `views/adminlogin.php`
- [Shared layout](https://github.com/gravedd/portfolio/blob/main/views/includes/header.php): template includes · `views/includes/header.php`
- [Static assets](https://github.com/gravedd/portfolio/tree/main/views/css): presentation assets · `views/css`

### Storage

- [Database access](https://github.com/gravedd/portfolio/blob/main/components/db.php): SQL gateway · `components/db.php`
- [MySQL](https://github.com/gravedd/portfolio/blob/main/portfolio.sql): database · Schema and baseline data are in portfolio.sql. · `portfolio.sql`
- **Uploaded assets**: filesystem storage · User-managed images, documents, and design assets.

## Connections

- Apache rules → Front controller: forwards requests
- Front controller → Router: delegates
- Router → Route definitions: resolves against
- Router → Site controller: public pages
- Router → Articles controller: article routes
- Router → Admin controller: admin routes
- Site controller → Site model: loads content
- Articles controller → Article model: reads articles
- Admin controller → Admin models: auth/session
- Admin controller → Article model: writes articles
- Site model → Database access: queries
- Article model → Database access: queries
- Admin models → Database access: queries
- Database access → MySQL: persists
- Site controller → Public views: renders
- Articles controller → Public views: renders
- Articles controller → Authoring views: renders previews
- Admin controller → Authoring views: renders editing
- Admin controller → Admin views: renders
- Public views → Shared layout: includes
- Admin views → Shared layout: includes
- Public views → Static assets: uses
- Authoring views → Uploaded assets: manages assets
