# Portfolio Access Gateway - System Architecture Plan

## 1. Goal

Build a **central access-control backend** for your portfolio that:

- shows a login screen,
- authenticates a user with `id` + `password`,
- checks which project/demo the user is allowed to access,
- returns the allowed service(s),
- redirects the user to the correct live demo.

> **Recommendation:** keep your current portfolio repo static, and create **one separate backend repo** for the access gateway instead of one backend per project.  
> Keep each live demo in its own repo/deployment.

This is the best balance of **cheap + reliable + easy to maintain**.

---

## 2. Recommended Architecture (Most Reliable Practical Architecture for 2024)

### ✅ Best fit for your use case

- **Frontend Portfolio:** static website
- **Access Gateway Backend:** Go API on AWS EC2
- **Database:** PostgreSQL
- **Reverse Proxy / TLS:** Nginx or Caddy
- **Auth:** JWT + bcrypt password hashing
- **Deployment:** GitHub Actions -> EC2
- **Observability:** CloudWatch logs or simple structured file logs

### Why this is the right architecture

- **Cheap:** static frontend + small EC2 instance is low cost
- **Reliable:** backend is independent from frontend and live demos
- **Scalable:** you can later add load balancer + second EC2 without redesigning everything
- **Secure:** credentials and permissions stay in one place
- **Simple:** one auth/access service for all demos is easier than many tiny backends

---

## 3. High-Level System Design

```mermaid
flowchart LR
    A[Visitor opens portfolio site] --> B[Static Frontend\nNetlify / Vercel / S3+CloudFront]
    B --> C[Login Form]
    C --> D[Go Access Gateway API\nEC2 + Nginx]
    D --> E[(PostgreSQL)]
    E --> D
    D --> F[Allowed services response\nJSON or redirect token]
    F --> G[Project Live Demo A]
    F --> H[Project Live Demo B]
    F --> I[Project Live Demo C]
```

---

## 4. Recommended Repo Structure

### Current repo
- `PersonalWebSite` -> your public static portfolio site

### New backend repo
Create a new repo like:

```text
portfolio-access-gateway/
```

This backend repo should manage:
- login
- user permission lookup
- service access response
- secure redirect logic
- audit logging if needed later

### Separate project repos
Each demo can stay in its own repo and have its own deployment URL, for example:

- `project-a-demo`
- `project-b-demo`
- `project-c-demo`

---

## 5. Architecture Recommendation by Stage

### Stage A - Cheap MVP
Use this first if budget matters most.

- Static frontend: **Netlify / Vercel / GitHub Pages**
- Backend: **1 EC2 instance** running Go app
- Reverse proxy: **Nginx**
- DB: **PostgreSQL** on **RDS** if possible
- Domain: `api.yourdomain.com`
- SSL: Let's Encrypt or AWS ACM if behind load balancer

### Stage B - Recommended Reliable Production
Use this when real users depend on it.

- Static frontend behind CDN
- **2 EC2 app instances** in different AZs
- **Application Load Balancer**
- **RDS PostgreSQL Multi-AZ**
- Secrets in **AWS Systems Manager Parameter Store** or **Secrets Manager**
- Logging and alerts in **CloudWatch**

### Stage C - Higher Reliability / Growth
Only needed if traffic grows.

- Auto Scaling Group for Go API
- Redis for short-lived sessions/cache
- Blue/green deploys
- WAF + rate limiting + monitoring dashboards

---

## 6. Recommended Tech Stack

### Backend
- **Language:** Go
- **Router:** `chi` or standard `net/http`
- **DB driver:** `pgx`
- **Migrations:** `golang-migrate`
- **Auth:** `bcrypt` + JWT (`github.com/golang-jwt/jwt/v5`)
- **Logging:** Go `slog` or `zap`

### Database
- **PostgreSQL**

### Frontend Integration
Your static site calls the API using `fetch()`:

```js
const response = await fetch('https://api.yourdomain.com/api/v1/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ loginId, password })
});
```

---

## 7. Core Backend Responsibilities

The Go backend should expose endpoints like:

### Public endpoints
- `POST /api/v1/login`
- `POST /api/v1/logout`
- `GET /api/v1/health`

### Protected endpoints
- `GET /api/v1/me`
- `GET /api/v1/services`
- `POST /api/v1/services/:id/access`

### Login flow
1. User submits `id` and `password`
2. Backend validates credentials
3. Backend checks `user_service_access`
4. Backend returns:
   - user info,
   - allowed services,
   - target demo URL or access token
5. Frontend opens the allowed demo

---

## 8. PostgreSQL Data Model

Recommended tables:

### `users`
- `id` UUID PK
- `login_id` VARCHAR UNIQUE NOT NULL
- `password_hash` TEXT NOT NULL
- `display_name` VARCHAR
- `is_active` BOOLEAN DEFAULT true
- `created_at` TIMESTAMP
- `updated_at` TIMESTAMP

### `services`
- `id` UUID PK
- `service_key` VARCHAR UNIQUE NOT NULL
- `service_name` VARCHAR NOT NULL
- `demo_url` TEXT NOT NULL
- `is_active` BOOLEAN DEFAULT true
- `created_at` TIMESTAMP

### `user_service_access`
- `user_id` UUID FK -> users.id
- `service_id` UUID FK -> services.id
- `granted_at` TIMESTAMP
- primary key `(user_id, service_id)`

### Optional: `access_audit_logs`
- `id` UUID PK
- `user_id`
- `service_id`
- `ip_address`
- `user_agent`
- `created_at`

This design is flexible and keeps permissions centralized.

---

## 9. Security Recommendations

### Authentication
- Never store plain passwords
- Hash passwords with **bcrypt**
- Use **JWT** with short expiry
- Store secret keys in env vars / AWS secrets

### Authorization
- Do not let frontend decide access
- Backend must verify the user's permission before returning or redirecting to a demo

### API protection
- Enable **CORS** only for your frontend domain
- Add **rate limiting** on login endpoint
- Validate all input
- Use HTTPS only

### Better redirect pattern
Instead of exposing everything directly, you can:
- return only allowed services,
- or return a **signed access token** when user clicks a specific project,
- then the target demo validates that token if needed.

---

## 10. AWS Deployment Recommendation

## Cheap and good starting point

- **EC2:** `t4g.small` or `t3.small`
- **OS:** Ubuntu LTS
- **Go app:** run with `systemd`
- **Reverse proxy:** Nginx
- **DB:** **RDS PostgreSQL** preferred

### Why RDS is better than self-hosting Postgres on EC2
- automated backups
- easier recovery
- patching support
- better reliability

If budget is extremely tight, you *can* host Postgres on EC2, but it is less reliable and more work.

---

## 11. Domain Layout Suggestion

```text
www.yourdomain.com           -> static portfolio
api.yourdomain.com           -> Go access gateway
project-a.yourdomain.com     -> live demo A
project-b.yourdomain.com     -> live demo B
```

This is clean, professional, and easy to manage.

---

## 12. Recommended Implementation Plan

### Phase 1 - Foundation
- create backend repo `portfolio-access-gateway`
- initialize Go module
- connect PostgreSQL
- add migrations
- add health endpoint

### Phase 2 - Authentication
- create `users` table
- hash passwords with bcrypt
- add login endpoint
- issue JWT

### Phase 3 - Authorization
- create `services` and `user_service_access`
- return allowed service list after login
- add secure redirect/access endpoint

### Phase 4 - Production Readiness
- add Nginx
- add HTTPS
- add GitHub Actions deploy
- add logs / alerts
- add rate limiting

---

## 13. Final Recommendation

### Best architecture for you right now

**Do this:**
1. keep `PersonalWebSite` as a **static frontend repo**
2. create **one Go backend repo** called `portfolio-access-gateway`
3. keep each project/demo in its **own repo and deployment**
4. use **PostgreSQL** to control which user can access which demo
5. deploy the backend on **EC2**, preferably with **RDS PostgreSQL**

> For your current goal, **one central auth/access backend** is better than creating a separate backend for every project.

---

## 14. Prompt for "Jumpstart your project with Copilot"

Copy and paste this into GitHub Copilot:

```text
Create a production-minded Go backend project called "portfolio-access-gateway".

Goal:
This backend will act as a secure access gateway for my portfolio website. A user logs in with `login_id` and `password`, the backend authenticates them using PostgreSQL, checks which projects/services they are allowed to access, and returns the allowed service list and/or redirect URL for the selected live demo.

Tech requirements:
- Language: Go 1.22+
- Database: PostgreSQL
- HTTP API: REST
- Router: chi (preferred) or net/http
- DB driver: pgx
- Migrations: golang-migrate
- Auth: bcrypt password hashing + JWT
- Config: environment variables
- Deployment target: AWS EC2 behind Nginx

Project requirements:
1. Create a clean folder structure:
   - `cmd/api/main.go`
   - `internal/config/`
   - `internal/http/handlers/`
   - `internal/http/middleware/`
   - `internal/auth/`
   - `internal/store/`
   - `internal/models/`
   - `migrations/`
   - `Dockerfile`
   - `Makefile`
   - `README.md`

2. Implement these endpoints:
   - `GET /api/v1/health`
   - `POST /api/v1/login`
   - `GET /api/v1/me`
   - `GET /api/v1/services`
   - `POST /api/v1/services/{id}/access`

3. PostgreSQL schema must include:
   - `users`
   - `services`
   - `user_service_access`
   - optional `access_audit_logs`

4. `POST /api/v1/login` should:
   - accept `login_id` and `password`
   - validate user from PostgreSQL
   - compare password with bcrypt hash
   - return JWT on success
   - return user's allowed services

5. Add middleware for:
   - JWT auth
   - request logging
   - CORS for my frontend domain
   - recovery from panics

6. Security rules:
   - never store plain passwords
   - validate inputs
   - use short JWT expiry
   - read secrets from env vars
   - structure code to be production-ready and easy to maintain

7. Include:
   - SQL migration files
   - sample seed data
   - example `.env.example`
   - `curl` examples
   - basic unit tests for auth and login handler

8. Deployment notes:
   - show how to run locally
   - show how to deploy on EC2 with Nginx and systemd
   - show how to set env vars safely

Please generate a minimal but complete starter project with idiomatic Go code and concise comments.
```

---

## 15. Suggested Backend Repo Name

Recommended names:
- `portfolio-access-gateway`
- `portfolio-auth-gateway`
- `project-demo-access-api`

My recommendation: **`portfolio-access-gateway`**
