# Job Info Test - Project Overview

## What is this?

**Job-Info-Test** is a modern, modular application testbed for exploring and validating:
- **Microsoft Graph API interactions** - token acquisition, caching, refresh, data queries
- **PocketBase integration** - OAuth2 flows, user management, data persistence
- **Industry-standard UI/UX patterns** - reactive components, state management, real-time updates
- **Developer experience (DX)** - clean APIs, TypeScript support, proper error handling, observability
- **Architecture best practices** - modular design, separation of concerns, testability

It uses a **Mode system** where different technology implementations can be built and tested in parallel without interfering with each other.

## Purpose

This is not just an auth test—it's a **reference implementation playground** for:
- Building **real, production-quality features** with Graph API (user data, calendar, files, etc.)
- Implementing **reactive, modern UI** with Svelte and industry best practices
- Creating **clean, maintainable code architecture** that teams can learn from
- Testing **complex workflows** combining Graph + PocketBase + custom logic
- Demonstrating **proper error handling, loading states, and data synchronization**
- Building **DX-first APIs** that are a pleasure to use and extend

## Development Standards

**These rules MUST be followed on every code change. Review before editing.**

### 1. Variable Naming — Strict Consistency
- Auth and token variable names are **NOT flexible** — they are fixed throughout the project
- Use **identical names** every time a value is referenced, passed, or used
- **Examples of correct consistency:**
  - Graph token: always `graphToken` (never `graph_token`, `token`, or `accessToken`)
  - PocketBase token: always `pbToken` (never `pocketbaseToken`, `pb_token`, or `userToken`)
  - User ID: always `userId` (never `user_id`, `uid`, or `id`)
  - Current user: always `currentUser` (never `user`, `loggedInUser`, or `authUser`)
- **Why:** Eliminates confusion about what value is being used and where it comes from
- **Enforcement:** If a variable name changes, it must change everywhere it's used in that mode

### 2. Mode Independence — Standalone Projects
- **Each mode is completely independent** — can run on any machine without parent directory
- **Copy modules in, never depend on them externally**
  - If `auth-module` is used in multiple modes, copy it into each mode's directory
  - Never import from `../auth-module` or `../../auth-module`
  - Each mode has its own complete copy of all dependencies
- **Modes must not reference each other**
  - No imports between Mode1 and Mode1Svelte
  - No shared backend code between modes
- **Benefit:** Can delete, move, or duplicate a mode without breaking anything else

### 3. Development Scope — Edit Only Your Mode
- **Only edit the mode you're actively working on** — all other modes untouched
- **You can reference other modes** for patterns/examples, but don't code in them
- **Exception:** Only modify another mode if explicitly agreed upon in writing
- **Corollary:** If shared logic needs updating (like auth-module), update it in your working mode, test it, then copy it to other modes if approved

### 4. Ports — 3005 & 3006 ONLY
- **Work exclusively with ports 3005 and 3006**
  - Port 3005: Active mode backend + frontend
  - Port 3006: ModeSwitch orchestrator
- **Do NOT check any other ports** — ignore them entirely
- **Ignore all other running services** — focus only on these two ports

### 5. Service Restart — Kill, Then Start
- **Always assume something is running** on the port before starting
- **Always kill first, then start:**
  ```bash
  pkill -f "bun.*server.ts" || true
  sleep 1
  PORT=3005 bun run backend/server.ts
  ```
- **This prevents port-binding conflicts** and ensures clean startup

### 6. Service Validation — One Check, Then Stop
- **Do ONE comprehensive health check after startup**
  - Verify backend is listening on correct port
  - Verify frontend is accessible
  - Verify all critical endpoints respond (auth endpoints, health checks)
  - Verify no error messages in logs
- **Then STOP checking** — if health is good, leave it running
- **Do NOT check 3, 4, or multiple times** — it wastes time and adds no value
- **If health check passes, service is ready** — move forward to next task

### 7. Git Commits & Sync — Developer Agreement Required
- **Never commit or sync without explicit developer approval**
- **Only prompt for commit/sync AFTER code verification**
  - Code must be working as intended
  - Tests passing (if applicable)
  - Health checks passing
  - Developer has confirmed the feature/fix is complete
- **Workflow:** Build → Test → Confirm Working → **Then ask about commit**
- **No automatic commits or premature prompts**

## Architecture

```
Job-Info-Test/
├── auth-module/              # Shared, reusable auth component (root copy)
├── Mode1/                    # Hono + vanilla JavaScript (LOCKED/READ-ONLY reference)
├── Mode1Svelte/              # Hono + SvelteKit (active development - modern DX/UX)
├── ModeSwitch/               # Orchestrator to manage mode switching
├── Mode6Test/                # Legacy testing environment
└── README.md                 # This file
```

## The Mode System

Each **Mode** is a completely independent project that:
- Has its own copy of `auth-module` (no cross-dependencies)
- Runs on the same ports (3005 backend, 3006 orchestrator)
- Can be swapped via ModeSwitch without affecting others
- Shares the same secret configuration (`/home/admin/secrets/.env`)

### Current Modes

#### **Mode1** (READ-ONLY Reference Implementation)
- **Frontend:** Vanilla HTML + JavaScript
- **Backend:** Hono (TypeScript)
- **Status:** Reference implementation, locked to prevent accidental changes
- **Port:** 3005

#### **Mode1Svelte** (Active Development)
- **Frontend:** SvelteKit (Svelte components, reactive)
- **Backend:** Hono (same as Mode1)
- **Status:** Being converted to full SvelteKit following industry best practices
- **Port:** 3005

## Key Components

### Auth Module (`/auth-module/`)
Reusable authentication component with:
- **Backend** (`backend.ts`):
  - `AuthConfigManager` - Loads and provides configuration
  - `GraphTokenManager` - Acquires Microsoft Graph tokens via MSAL
  - `PocketBaseValidator` - Validates user tokens
  - `BackendAuth` - Orchestrates backend auth flow

- **Frontend** (`frontend.ts`):
  - `PocketBaseAuth` - OAuth2 login/logout/state management
  - `initPocketBaseAuth()` - Initialize with callbacks

- **Types** (`types.ts`):
  - `FrontendConfig` - Configuration provided to frontend
  - `AuthState` - Frontend authentication state

### ModeSwitch Orchestrator (`/ModeSwitch/`)
- Listens on port 3006
- Manages active mode switching via `POST /switch/:mode`
- Returns mode status and health checks
- Starts/stops backend servers as needed

## How It Works

### Startup Flow
1. **ModeSwitch starts** on port 3006 (orchestrator)
2. **Active mode backend starts** on port 3005
3. **Frontend served** at `http://localhost:3005` (or `https://ji-test.ccllc.pro`)
4. **Frontend fetches config** from `/api/auth/config`
5. **Backend loads secrets** from `/home/admin/secrets/.env`

### Auth Flow
1. **Frontend OAuth Login:**
   - User clicks login button
   - Browser redirected to PocketBase OAuth provider
   - PocketBase returns user and token
   - Frontend stores token in `pbAuth.getAuthState()`

2. **Backend Graph Token:**
   - Frontend calls `/api/auth/graph/token`
   - Backend uses MSAL to acquire Microsoft Graph token
   - Token cached with 60-second expiration buffer
   - Frontend receives token with JWT payload details

3. **Token Comparison:**
   - Frontend sends PocketBase token to `/api/auth/compare-tokens`
   - Backend validates PB token and decodes Graph token JWT
   - Returns side-by-side comparison showing they're different systems

## Running the Project

### Via ModeSwitch (Recommended)
```bash
# Start ModeSwitch (listens on 3006)
cd /home/admin/Job-Info-Test/ModeSwitch
PORT=3006 bun run backend/orchestrator.ts

# In another terminal, switch to desired mode
curl -X POST http://localhost:3006/switch/Mode1Svelte

# Access frontend
open https://ji-test.ccllc.pro
# or
open http://localhost:3005
```

### Direct Mode Start
```bash
# Start Mode1Svelte directly
cd /home/admin/Job-Info-Test/Mode1Svelte
PORT=3005 bun run backend/server.ts

# Access frontend
open http://localhost:3005
```

## Configuration

**Secrets** (`/home/admin/secrets/.env`):
```
CLIENT_ID=<Azure app client ID>
TENANT_ID=<Azure tenant ID>
CLIENT_SECRET=<Azure app client secret>
PB_URL=<PocketBase server URL>
PB_DB=<PocketBase database name>
```

These are loaded:
- **Backend:** Automatically on server startup via `dotenv`
- **Frontend:** Via API endpoint `/api/auth/config` (no hardcoded URLs)

## Project Structure Details

### Mode1 (Reference - READ-ONLY)
```
Mode1/
├── auth-module/         # Self-contained copy
├── backend/
│   └── server.ts       # Hono + auth endpoints
├── frontend/
│   ├── index.html      # Test dashboard
│   └── dist/           # Built assets
└── package.json
```

### Mode1Svelte (In Development)
```
Mode1Svelte/
├── auth-module/         # Self-contained copy
├── backend/
│   └── server.ts       # Hono + auth endpoints
├── src/
│   ├── routes/         # SvelteKit pages (to be added)
│   ├── lib/            # Svelte components (to be added)
│   └── app.svelte      # Root component (to be added)
└── svelte.config.js    # SvelteKit config (to be added)
```

## Development Notes

- **Mode1 is locked** to preserve the reference implementation
- **Mode1Svelte** is the active development branch
- Both modes can run simultaneously on different orchestrator instances
- No code dependencies between modes—each is fully independent
- Auth-module changes should be made in root `/auth-module/`, then copied to each mode

## Testing

**Dashboard at** `https://ji-test.ccllc.pro`:
- ✅ Complete auth flow (PocketBase OAuth2)
- ✅ Microsoft Graph token acquisition, caching, refresh
- ✅ Real Graph API interactions (user profile, mail, calendar, files, etc.)
- ✅ PocketBase data queries and mutations
- ✅ Token comparison and validation
- ✅ Error states and loading indicators
- ✅ Timestamped logs and observability
- ✅ Real-time data synchronization patterns

## Next Steps

1. **Convert Mode1Svelte to full SvelteKit** with modern component architecture
2. **Build Graph API features** - implement real use cases beyond auth
3. **Create reactive Svelte components** - proper state management, stores, lifecycle
4. **Add TypeScript throughout** - strict types, better DX
5. **Implement data layers** - abstracting Graph API and PocketBase queries
6. **Build responsive UI** - mobile-first design, accessibility (a11y)
7. **Add observability** - logging, error tracking, performance monitoring
8. **Create component library** - reusable, well-documented Svelte components
9. **Write comprehensive tests** - unit, integration, E2E
10. **Document patterns** - make this a reference for modern full-stack Svelte apps
