# latifahsan/la-portfolio architecture

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

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

## Overview

LA Portfolio is a portfolio CMS and public website: an administrator manages published content and site settings in the protected dashboard; the public site reads that content, accepts contact messages, and offers an AI chat grounded in published CMS material. The graph preserves the documented project, gallery, blog, media, inbox, analytics, audit, notifications, SEO, and recycle-bin capabilities. Relationships for unsampled routes and feature actions are limited to documented behavior; not every runtime call could be verified from the supplied excerpts.

Main entry points: [`src/lib/prisma.ts`](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/prisma.ts) (Portfolio Database), [`src/app/api/ai/chat/route.ts`](https://github.com/latifahsan/la-portfolio/blob/main/src/app/api/ai/chat/route.ts) (Chat API), [`src/app/(dashboard)/dashboard`](https://github.com/latifahsan/la-portfolio/tree/main/src/app/(dashboard)/dashboard) (Dashboard), [`src/components/public/contact-form.tsx`](https://github.com/latifahsan/la-portfolio/blob/main/src/components/public/contact-form.tsx) (Contact Form)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_public["Public Website"]
  node_public_pages["Public Pages"]
  node_contact_form["Contact Form<br/>[contact-form.tsx]"]
  node_chat_widget["Chat Widget<br/>[chat-widget.tsx]"]
end

subgraph group_admin["Admin CMS"]
  node_dashboard["Dashboard"]
  node_login["Admin Login<br/>[actions.ts]"]
  node_content_manager["Content Manager"]
  node_settings["Site Settings<br/>[actions.ts]"]
  node_media["Media Library<br/>[actions.ts]"]
  node_inbox["Inbox<br/>[actions.ts]"]
  node_recycle["Recycle Bin<br/>[actions.ts]"]
  node_analytics["Analytics<br/>[actions.ts]"]
end

subgraph group_content["Content Services"]
  node_public_content["Published Content"]
  node_contact_actions["Contact Actions<br/>[actions.ts]"]
  node_generic_actions["Generic CRUD<br/>[generic-actions.ts]"]
  node_content_modules["Content Modules"]
  node_projects_gallery_blog["Projects, Gallery, Blog"]
end

subgraph group_platform["Data And Integrations"]
  node_auth_service["Supabase Auth<br/>[server.ts]"]
  node_middleware["Route Protection<br/>[middleware.ts]"]
  node_storage["Supabase Storage<br/>[server.ts]"]
  node_audit["Audit Log<br/>[log.ts]"]
  node_notifications["Notifications<br/>[notify.ts]"]
  node_prisma[("Portfolio Database<br/>[prisma.ts]")]
end

subgraph group_assistant["AI Assistant"]
  node_chat_api["Chat API<br/>[route.ts]"]
  node_ai_context["Published Context<br/>[context-builder.ts]"]
  node_ai_prompt["Prompt Builder<br/>[prompt-builder.ts]"]
  node_ai_settings["AI Settings<br/>[settings.ts]"]
  node_rate_limit["Rate Limit<br/>[rate-limit.ts]"]
  node_gemini_client["Gemini Client<br/>[gemini-client.ts]"]
end

node_visitor(("Visitor"))
node_gemini{{"Google Gemini"}}
node_contact_sender(("Contact Sender"))

node_visitor -->|"visits"| node_public_pages
node_public_pages -->|"reads published"| node_public_content
node_public_content -->|"queries"| node_prisma
node_visitor -->|"submits"| node_contact_form
node_contact_form -->|"calls"| node_contact_actions
node_contact_actions -->|"stores message"| node_prisma
node_contact_sender -->|"submits"| node_contact_form
node_visitor -->|"signs in"| node_login
node_login -->|"authenticates"| node_auth_service
node_middleware -->|"checks session"| node_auth_service
node_middleware -->|"protects routes"| node_dashboard
node_dashboard -->|"renders CMS"| node_content_manager
node_content_manager -->|"invokes CRUD"| node_generic_actions
node_generic_actions -->|"reads and writes"| node_prisma
node_content_modules -->|"binds actions"| node_generic_actions
node_projects_gallery_blog -->|"manages content"| node_prisma
node_settings -->|"reads and writes"| node_prisma
node_media -->|"uploads files"| node_storage
node_media -->|"records media"| node_prisma
node_inbox -->|"manages messages"| node_prisma
node_recycle -->|"restores records"| node_prisma
node_analytics -->|"aggregates views"| node_prisma
node_dashboard -.->|"records activity"| node_audit
node_dashboard -.->|"dispatches alerts"| node_notifications
node_visitor -->|"asks"| node_chat_widget
node_chat_widget -->|"sends chat"| node_chat_api
node_chat_api -->|"checks quota"| node_rate_limit
node_chat_api -->|"loads settings"| node_ai_settings
node_ai_settings -->|"reads settings"| node_prisma
node_chat_api -->|"loads context"| node_ai_context
node_ai_context -->|"queries published"| node_prisma
node_chat_api -->|"builds instructions"| node_ai_prompt
node_chat_api -->|"requests client"| node_gemini_client
node_gemini_client -->|"calls model"| node_gemini
node_chat_api -->|"streams reply"| node_chat_widget

click node_public_pages "https://github.com/latifahsan/la-portfolio/tree/main/src/app/(public)"
click node_public_content "https://github.com/latifahsan/la-portfolio/tree/main/src/lib/public-content"
click node_contact_form "https://github.com/latifahsan/la-portfolio/blob/main/src/components/public/contact-form.tsx"
click node_contact_actions "https://github.com/latifahsan/la-portfolio/blob/main/src/features/contact/actions.ts"
click node_dashboard "https://github.com/latifahsan/la-portfolio/tree/main/src/app/(dashboard)/dashboard"
click node_login "https://github.com/latifahsan/la-portfolio/blob/main/src/features/auth/actions.ts"
click node_auth_service "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/supabase/server.ts"
click node_middleware "https://github.com/latifahsan/la-portfolio/blob/main/src/middleware.ts"
click node_content_manager "https://github.com/latifahsan/la-portfolio/blob/main/src/features/content-crud/content-manager.tsx"
click node_generic_actions "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/content/generic-actions.ts"
click node_content_modules "https://github.com/latifahsan/la-portfolio/tree/main/src/features"
click node_projects_gallery_blog "https://github.com/latifahsan/la-portfolio/tree/main/src/features"
click node_settings "https://github.com/latifahsan/la-portfolio/blob/main/src/features/settings/actions.ts"
click node_media "https://github.com/latifahsan/la-portfolio/blob/main/src/features/media/actions.ts"
click node_storage "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/supabase/server.ts"
click node_inbox "https://github.com/latifahsan/la-portfolio/blob/main/src/features/inbox/actions.ts"
click node_recycle "https://github.com/latifahsan/la-portfolio/blob/main/src/features/recycle-bin/actions.ts"
click node_analytics "https://github.com/latifahsan/la-portfolio/blob/main/src/features/analytics/actions.ts"
click node_audit "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/audit/log.ts"
click node_notifications "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/notifications/notify.ts"
click node_prisma "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/prisma.ts"
click node_chat_widget "https://github.com/latifahsan/la-portfolio/blob/main/src/components/ai-chat/chat-widget.tsx"
click node_chat_api "https://github.com/latifahsan/la-portfolio/blob/main/src/app/api/ai/chat/route.ts"
click node_ai_context "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/context-builder.ts"
click node_ai_prompt "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/prompt-builder.ts"
click node_ai_settings "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/settings.ts"
click node_rate_limit "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/rate-limit.ts"
click node_gemini_client "https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/gemini-client.ts"

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_public_pages,node_contact_form,node_chat_widget toneBlue
class node_dashboard,node_login,node_content_manager,node_settings,node_media,node_inbox,node_recycle,node_analytics toneAmber
class node_public_content,node_contact_actions,node_generic_actions,node_content_modules,node_projects_gallery_blog toneMint
class node_auth_service,node_middleware,node_storage,node_audit,node_notifications,node_prisma toneRose
class node_chat_api,node_ai_context,node_ai_prompt,node_ai_settings,node_rate_limit,node_gemini_client,node_visitor,node_gemini,node_contact_sender toneIndigo
```

## Components

### Public Website

- [Public Pages](https://github.com/latifahsan/la-portfolio/tree/main/src/app/(public)): `src/app/(public)`
- [Contact Form](https://github.com/latifahsan/la-portfolio/blob/main/src/components/public/contact-form.tsx): `src/components/public/contact-form.tsx`
- [Chat Widget](https://github.com/latifahsan/la-portfolio/blob/main/src/components/ai-chat/chat-widget.tsx): `src/components/ai-chat/chat-widget.tsx`

### Admin CMS

- [Dashboard](https://github.com/latifahsan/la-portfolio/tree/main/src/app/(dashboard)/dashboard): `src/app/(dashboard)/dashboard`
- [Admin Login](https://github.com/latifahsan/la-portfolio/blob/main/src/features/auth/actions.ts): `src/features/auth/actions.ts`
- [Content Manager](https://github.com/latifahsan/la-portfolio/blob/main/src/features/content-crud/content-manager.tsx): `src/features/content-crud/content-manager.tsx`
- [Site Settings](https://github.com/latifahsan/la-portfolio/blob/main/src/features/settings/actions.ts): `src/features/settings/actions.ts`
- [Media Library](https://github.com/latifahsan/la-portfolio/blob/main/src/features/media/actions.ts): `src/features/media/actions.ts`
- [Inbox](https://github.com/latifahsan/la-portfolio/blob/main/src/features/inbox/actions.ts): `src/features/inbox/actions.ts`
- [Recycle Bin](https://github.com/latifahsan/la-portfolio/blob/main/src/features/recycle-bin/actions.ts): `src/features/recycle-bin/actions.ts`
- [Analytics](https://github.com/latifahsan/la-portfolio/blob/main/src/features/analytics/actions.ts): `src/features/analytics/actions.ts`

### Content Services

- [Published Content](https://github.com/latifahsan/la-portfolio/tree/main/src/lib/public-content): `src/lib/public-content`
- [Contact Actions](https://github.com/latifahsan/la-portfolio/blob/main/src/features/contact/actions.ts): `src/features/contact/actions.ts`
- [Generic CRUD](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/content/generic-actions.ts): `src/lib/content/generic-actions.ts`
- [Content Modules](https://github.com/latifahsan/la-portfolio/tree/main/src/features): `src/features`
- [Projects, Gallery, Blog](https://github.com/latifahsan/la-portfolio/tree/main/src/features): `src/features`

### Data And Integrations

- [Supabase Auth](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/supabase/server.ts): `src/lib/supabase/server.ts`
- [Route Protection](https://github.com/latifahsan/la-portfolio/blob/main/src/middleware.ts): `src/middleware.ts`
- [Supabase Storage](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/supabase/server.ts): `src/lib/supabase/server.ts`
- [Audit Log](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/audit/log.ts): `src/lib/audit/log.ts`
- [Notifications](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/notifications/notify.ts): `src/lib/notifications/notify.ts`
- [Portfolio Database](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/prisma.ts): `src/lib/prisma.ts`

### AI Assistant

- [Chat API](https://github.com/latifahsan/la-portfolio/blob/main/src/app/api/ai/chat/route.ts): `src/app/api/ai/chat/route.ts`
- [Published Context](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/context-builder.ts): `src/lib/ai/context-builder.ts`
- [Prompt Builder](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/prompt-builder.ts): `src/lib/ai/prompt-builder.ts`
- [AI Settings](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/settings.ts): `src/lib/ai/settings.ts`
- [Rate Limit](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/rate-limit.ts): `src/lib/ai/rate-limit.ts`
- [Gemini Client](https://github.com/latifahsan/la-portfolio/blob/main/src/lib/ai/gemini-client.ts): `src/lib/ai/gemini-client.ts`

### Other components

- **Visitor**
- **Google Gemini**
- **Contact Sender**

## Connections

- Visitor → Public Pages: visits
- Public Pages → Published Content: reads published
- Published Content → Portfolio Database: queries
- Visitor → Contact Form: submits
- Contact Form → Contact Actions: calls
- Contact Actions → Portfolio Database: stores message
- Contact Sender → Contact Form: submits
- Visitor → Admin Login: signs in
- Admin Login → Supabase Auth: authenticates
- Route Protection → Supabase Auth: checks session
- Route Protection → Dashboard: protects routes
- Dashboard → Content Manager: renders CMS
- Content Manager → Generic CRUD: invokes CRUD
- Generic CRUD → Portfolio Database: reads and writes
- Content Modules → Generic CRUD: binds actions
- Projects, Gallery, Blog → Portfolio Database: manages content
- Site Settings → Portfolio Database: reads and writes
- Media Library → Supabase Storage: uploads files
- Media Library → Portfolio Database: records media
- Inbox → Portfolio Database: manages messages
- Recycle Bin → Portfolio Database: restores records
- Analytics → Portfolio Database: aggregates views
- Dashboard → Audit Log: records activity
- Dashboard → Notifications: dispatches alerts
- Visitor → Chat Widget: asks
- Chat Widget → Chat API: sends chat
- Chat API → Rate Limit: checks quota
- Chat API → AI Settings: loads settings
- AI Settings → Portfolio Database: reads settings
- Chat API → Published Context: loads context
- Published Context → Portfolio Database: queries published
- Chat API → Prompt Builder: builds instructions
- Chat API → Gemini Client: requests client
- Gemini Client → Google Gemini: calls model
- Chat API → Chat Widget: streams reply
