Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 8 additions & 2 deletions .github/prompts/audit-quality.prompt.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,16 +166,22 @@ Act as a **Principal Code Reviewer, Security Auditor, and Refactoring Architect*

**Objective:** Ensure compliance with applicable data protection and privacy regulations.

Not all regulations apply to every codebase. Determine which regulations are in scope based on the system's data subjects, geography, data types, and regulated activities. Only perform compliance checks for regulations that apply, and explicitly state why any listed regulation is out of scope.

Check compliance with:

- **United States:** HIPAA (Health Insurance Portability and Accountability Act)
- Applies when the system handles protected health information (PHI) for a covered entity or business associate.
- **European Union & Ireland:** GDPR (General Data Protection Regulation)
- Applies when the system processes personal data, especially if it profiles users, tracks behavior, or makes decisions that affect individuals.
- **Canada (Federal):** PIPEDA (Personal Information Protection and Electronic Documents Act)
- Applies when the system processes personal information for commercial activities in the private sector.
- **Canada - Ontario (Provincial):** PHIPA (Personal Health Information Protection Act)
- Applies when the system handles personal health information for a health information custodian or their agent.
- **South Korea:** PIPA (Personal Information Protection Act)
- **Vietnam:** PDPL (Personal Data Protection Law)
- Applies when the system processes personal information, including identifiers, contact data, or behavioral data.

Verify:
For each applicable regulation, verify:

- Right to access, rectification, erasure, and data portability
- Breach notification procedures
Expand Down
311 changes: 46 additions & 265 deletions docs/architecture/app-directory.md
Original file line number Diff line number Diff line change
@@ -1,28 +1,23 @@
# App Directory (Next.js)

This document explains the Next.js App Router directory structure and implementation in the Alexander Sullivan's Portfolio project.

## Overview

The project uses Next.js 16+ with the App Router architecture located in [`src/app/`](../../src/app/). This modern routing system uses file-system based routing with server and client components.

## Directory Structure

```text
src/app/
├── layout.tsx # Root layout with metadata
├── page.tsx # Home page component
├── manifest.ts # PWA manifest configuration
├── robots.ts # SEO robots.txt generator
├── error.tsx # Error boundary
├── global-error.tsx # Global error boundary
├── loading.tsx # Loading UI
├── not-found.tsx # 404 page
├── favicon.ico # Site favicon
└── sw.js/ # Service worker route handler
```
The portfolio uses Next.js App Router, where file names in [src/app/](../../src/app/) define routes and special behaviors. This follows Next.js convention-based routing rather than explicit route configuration.

## App Router Conventions

**File-Based Routing:** Next.js maps file names to functionality:

- `layout.tsx` — Wraps all child routes with shared UI and metadata
- `page.tsx` — Defines the `/` route content
- `error.tsx` — Catches errors in route segments
- `global-error.tsx` — Catches errors in root layout
- `not-found.tsx` — Handles 404 pages
- `loading.tsx` — Displays while routes load
- `manifest.ts` — Generates PWA manifest `/manifest.webmanifest`
- `robots.ts` — Generates `/robots.txt` for SEO

**Server by Default:** Components in [src/app/](../../src/app/) are React Server Components unless marked with `'use client'`. This minimizes client JavaScript.

## Architecture Pattern
## Component Hierarchy

```mermaid
flowchart TD
Expand All @@ -36,276 +31,62 @@ flowchart TD
Page -->|Renders| Banner
Page -->|Renders| Projects[ProjectsGrid]
Page -->|Renders| Pubs[Publications]
Page -->|Initializes| Firebase
Page -->|Registers| SW[Service Worker]
```

## Root Layout

Location: [`src/app/layout.tsx`](../../src/app/layout.tsx)

The root layout defines metadata, global styles, and wraps all pages with the GeneralLayout component.

### Key Features

1. **Metadata Configuration:** SEO, OpenGraph, Twitter Cards, and PWA manifest
2. **Global Styles:** Imports global SCSS styles
3. **Analytics Integration:** Vercel Speed Insights
4. **Service Worker Registration:** Client component for PWA support
5. **Theme Configuration:** Viewport settings and theme color

### Metadata Structure

```typescript
export const metadata: Metadata = {
title: {
template: `%s | ${metadataValues.title}`,
default: metadataValues.title,
},
description: metadataValues.description,
applicationName: metadataValues.title,
referrer: 'origin',
keywords: seoKeywords, // From src/data/keywords.ts
category: 'technology',
authors: [{ name: metadataValues.name, url: metadataValues.url }],
creator: metadataValues.name,
publisher: metadataValues.name,
openGraph: {
/* OpenGraph config */
},
twitter: {
/* Twitter Card config */
},
manifest: '/manifest.webmanifest',
// ... additional metadata
};
```

### Viewport Configuration

```typescript
export const viewport: Viewport = {
themeColor: '#131518',
width: 'device-width',
initialScale: 1,
minimumScale: 1,
maximumScale: 5,
userScalable: true,
};
```

## Home Page

Location: [`src/app/page.tsx`](../../src/app/page.tsx)

The home page is a client component that initializes services and renders main sections.

### Initialization Flow

```mermaid
sequenceDiagram
participant Page
participant Firebase
participant Console
participant SW
participant User

Page->>Firebase: init()
Page->>Console: debounceConsoleLogLogo()
Page->>SW: navigator.serviceWorker.register('/sw.js')
SW-->>Page: Registration complete
Page->>User: Render Banner
Page->>User: Render ProjectsGrid
Page->>User: Render Publications
```

### Component Structure

```typescript
'use client';

export default function Home() {
useEffect(() => {
init(); // Initialize Firebase
debounceConsoleLogLogo(); // Log ASCII art to console

// Register service worker
if (typeof navigator !== 'undefined' && 'serviceWorker' in navigator) {
navigator.serviceWorker.register('/sw.js').catch(function (err) {
console.error('Service Worker registration failed: ', err);
});
}
}, []);

return (
<Box component='div' sx={/* styles */}>
<Banner aria-label='Landing banner' />
<ProjectsGrid aria-label='Grid showing projects worked on' />
<Publications aria-label='List of scientific publications' />
</Box>
);
}
```
The root layout renders GeneralLayout which provides navigation, footer, background, and cookie consent for all pages.

## Special Route Handlers
## Root Layout

### Manifest (`manifest.ts`)

Generates the PWA manifest dynamically:

```typescript
import type { MetadataRoute } from 'next';

export default function manifest(): MetadataRoute.Manifest {
return {
name: "Alexander Sullivan's Portfolio",
short_name: "Alexander Sullivan's Portfolio",
icons: [
{ src: '/icon/android-chrome-192x192.png', sizes: '192x192', type: 'image/png' },
// ... more icons
],
theme_color: '#131518',
background_color: '#131518',
display: 'standalone',
start_url: '/',
};
}
```
**Metadata Configuration:** The layout exports a metadata object with SEO tags, OpenGraph, Twitter Cards, and PWA manifest path. Keywords are imported from [src/data/keywords.ts](../../src/data/keywords.ts).

### Robots (`robots.ts`)
**Viewport Setup:** Defines theme color (#131518), responsive scaling, and device width settings for mobile browsers.

Generates robots.txt for SEO:
**GeneralLayout:** Wraps children with [GeneralLayout](../../src/layouts/GeneralLayout.tsx) which provides navigation, footer, stars background, and cookie consent.

```typescript
import type { MetadataRoute } from 'next';
**Global Styles:** Imports [globals.scss](../../src/styles/globals.scss) for application-wide CSS.

export default function robots(): MetadataRoute.Robots {
return {
rules: {
userAgent: '*',
allow: '/',
},
sitemap: 'https://alexjsully.me/sitemap.xml',
};
}
```
**Analytics:** Includes Vercel SpeedInsights for performance tracking.

## Error Handling
Implementation: [src/app/layout.tsx](../../src/app/layout.tsx)

### Error Boundary (`error.tsx`)

Catches errors in the app and displays a fallback UI:

```typescript
'use client';

export default function Error({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<div>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</div>
);
}
```
## Home Page

### Global Error Boundary (`global-error.tsx`)

Catches errors at the root level (even in layout):

```typescript
'use client';

export default function GlobalError({
error,
reset,
}: {
error: Error & { digest?: string };
reset: () => void;
}) {
return (
<html>
<body>
<h2>Something went wrong!</h2>
<button onClick={() => reset()}>Try again</button>
</body>
</html>
);
}
```
The home page ([src/app/page.tsx](../../src/app/page.tsx)) is a client component (`'use client'`) that initializes services on mount:

## Loading States
**Firebase Initialization:** Calls `init()` from [src/configs/firebase.ts](../../src/configs/firebase.ts) to start analytics and performance tracking.

Location: [`src/app/loading.tsx`](../../src/app/loading.tsx)
**Console Logo:** Debounced ASCII art logged to browser console via [ascii helper](../../src/helpers/ascii.ts).

Displays a loading UI while the page is being rendered:
**Service Worker Registration:** Registers `/sw.js` for PWA offline support. Registration runs once on page load.

```typescript
import { CircularProgress } from '@mui/material';
**Content Rendering:** Displays Banner, ProjectsGrid, and Publications components in vertical stack.

export default function Loading() {
return (
<div style={centeredContainerStyles}>
<CircularProgress />
</div>
);
}
```
Implementation: [src/app/page.tsx](../../src/app/page.tsx)

The container uses inline styles with flexbox centering: `display: 'flex'`, `justifyContent: 'center'`, and `padding: '2rem'`.
## Special Route Handlers

## 404 Not Found
**PWA Manifest** ([src/app/manifest.ts](../../src/app/manifest.ts)) — Generates `/manifest.webmanifest` with app name, icons, theme colors, and display mode. See [PWA Documentation](./pwa.md).

Location: [`src/app/not-found.tsx`](../../src/app/not-found.tsx)
**Robots.txt** ([src/app/robots.ts](../../src/app/robots.ts)) — Generates `/robots.txt` allowing all crawlers with sitemap URL for SEO.

Custom 404 page with navigation back to home:
## Error Handling

```typescript
export default function NotFound() {
const pathname = usePathname();
**Error Boundary** ([src/app/error.tsx](../../src/app/error.tsx)) — Catches errors in route segments and displays fallback UI with reset button.

return (
<Stack /* ... */>
<Typography>404</Typography>
<Typography>{pathname}?! What is that?!</Typography>
<Link href='/' aria-label='Go home'>
<Button>Go back home!</Button>
</Link>
</Stack>
);
}
```
**Global Error** ([src/app/global-error.tsx](../../src/app/global-error.tsx)) — Catches errors in root layout, including its own `<html>` and `<body>` tags since layout errors prevent normal rendering.

## Best Practices
Both error boundaries are client components that accept `error` and `reset` props.

1. **Server vs Client Components:** Use server components by default, mark client components with `'use client'`
2. **Metadata:** Define metadata in layout.tsx for SEO benefits
3. **Error Boundaries:** Implement error.tsx for graceful error handling
4. **Loading States:** Use loading.tsx for better UX during navigation
5. **TypeScript:** Use Next.js types like `MetadataRoute`, `Metadata`, and `Viewport`
6. **Accessibility:** Include proper ARIA labels on all components
## Loading & 404

## Testing
**Loading UI** ([src/app/loading.tsx](../../src/app/loading.tsx)) — Shows MUI CircularProgress spinner centered on screen while routes load.

Test files are located alongside their components:
**Not Found** ([src/app/not-found.tsx](../../src/app/not-found.tsx)) — Custom 404 page displaying pathname and navigation button back to home.

- `loading.test.tsx` - Tests loading component
- `not-found.test.tsx` - Tests 404 page
Implementation: [src/app/loading.tsx](../../src/app/loading.tsx), [src/app/not-found.tsx](../../src/app/not-found.tsx)

## Related Documentation

- [Architecture Overview](./index.md)
- [Layouts](./layouts.md)
- [Components](./components/index.md)
- [PWA Documentation](./pwa.md)
- [Next.js App Router Documentation](https://nextjs.org/docs/app)

---

💡 **Tip:** The App Router automatically handles routing based on the file structure. Any `page.tsx` file becomes a route, and `layout.tsx` files wrap their children routes.
- [Architecture Overview](./index.md) — System architecture
- [Layouts Documentation](./layouts.md) — GeneralLayout details
- [PWA Documentation](./pwa.md) — Service worker and manifest
Loading
Loading