Skip to content
Draft
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
11 changes: 11 additions & 0 deletions .claude/settings.local.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"permissions": {
"allow": [
"Bash(npm install:*)",
"Bash(pre-commit install:*)",
"Bash(gh run list:*)",
"Bash(gh run view:*)",
"Bash(npm run build:*)"
]
}
}
66 changes: 45 additions & 21 deletions .devcontainer/devcontainer.json
Original file line number Diff line number Diff line change
@@ -1,30 +1,54 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/typescript-node
{
"name": "Node.js & TypeScript",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",
"name": "Node.js & TypeScript",
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
"image": "mcr.microsoft.com/devcontainers/typescript-node:1-20-bullseye",

// Features to add to the dev container. More info: https://containers.dev/features.
// "features": {},
"mounts": [
"source=/run/host-services/ssh-auth.sock,target=/ssh-agent,type=bind"
],

// Use 'forwardPorts' to make a list of ports inside the container available locally.
// "forwardPorts": [],
"containerEnv": {
"SSH_AUTH_SOCK": "/ssh-agent"
},

// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "npm install -g @angular/cli",
// Features to add to the dev container. More info: https://containers.dev/features.
"features": {
"ghcr.io/devcontainers-extra/features/apt-packages:1": {
"packages": "zstd"
},
"ghcr.io/devcontainers-extra/features/angular-cli:2": {},
"ghcr.io/devcontainers-community/npm-features/prettier:1": {},
"ghcr.io/devcontainers-extra/features/pre-commit:2": {},
"ghcr.io/devcontainers/features/azure-cli:1": {},
"ghcr.io/devcontainers/features/docker-in-docker:2": {},
"ghcr.io/devcontainers/features/github-cli:1": {},
"ghcr.io/prulloac/devcontainer-features/ollama:1": {
"pull": "llama3.1"
}
},

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"angular.ng-template",
"ms-azuretools.vscode-docker",
"motivesoft.vscode-uuid-generator"
]
}
},
// Use 'forwardPorts' to make a list of ports inside the container available locally.
"forwardPorts": [11434],

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
// Use 'postCreateCommand' to run commands after the container is created.
"postCreateCommand": "cd solthoth && npm install",
"postStartCommand": ".devcontainer/post-start.sh",

// Configure tool-specific properties.
"customizations": {
"vscode": {
"extensions": [
"tal7aouy.icons",
"angular.ng-template",
"ms-azuretools.vscode-docker",
"motivesoft.vscode-uuid-generator",
"anthropic.claude-code"
]
}
}

// Uncomment to connect as root instead. More info: https://aka.ms/dev-containers-non-root.
// "remoteUser": "root"
}
14 changes: 14 additions & 0 deletions .devcontainer/post-start.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -euo pipefail

export OLLAMA_HOST="${OLLAMA_HOST:-0.0.0.0:11434}"

# If already running, don't start another copy
if pgrep -x ollama >/dev/null 2>&1; then
echo "ollama already running"
exit 0
fi

# Start in background with logs
nohup ollama serve > /tmp/ollama.log 2>&1 &
echo "ollama started (logs: /tmp/ollama.log)"
67 changes: 43 additions & 24 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,51 @@ name: Build and Test
run-name: ${{ github.actor }} is building ProfileSite
on: [push, pull_request]
jobs:
commitlint:
runs-on: ubuntu-latest
env:
working-directory: ./solthoth
defaults:
run:
working-directory: ${{ env.working-directory }}
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install commitlint dependencies
run: npm ci
- name: Validate PR commits with commitlint
if: github.event_name == 'pull_request'
run: npx commitlint --from ${{ github.event.pull_request.base.sha }} --to ${{ github.event.pull_request.head.sha }} --verbose
- name: Validate current commit (push)
if: github.event_name == 'push'
run: npx commitlint --from HEAD~1 --to HEAD --verbose

prettier:
runs-on: ubuntu-latest
env:
working-directory: ./solthoth
defaults:
run:
working-directory: ${{ env.working-directory }}
steps:
- uses: actions/checkout@v4
- name: Setup Node
uses: actions/setup-node@v4
with:
node-version: 20
- name: Install dependencies
run: npm ci
- name: Check code formatting with Prettier
run: npm run format:check

build:
runs-on: ubuntu-latest
needs: [commitlint, prettier]
env:
working-directory: ./solthoth
defaults:
Expand All @@ -18,27 +61,3 @@ jobs:
- run: npm ci
# - run: npm run test:headless
- run: npm run build
- name: Upload browser files
uses: actions/upload-artifact@v4
with:
name: browser_profile_ftp
path: ${{ github.workspace }}/solthoth/dist/solthoth/browser/
if-no-files-found: error
deploy:
runs-on: ubuntu-latest
needs: build
if: github.ref == 'refs/heads/main'
steps:
- name: Download browser files
uses: actions/download-artifact@v4
with:
name: browser_profile_ftp
# https://github.com/marketplace/actions/ftp-deploy
- name: FTP Deploy
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
with:
server: ${{ env.FTP_SERVER }}
username: ${{ env.FTP_USERNAME }}
password: ${{ secrets.FTP_PASSWORD }}
protocol: ftps

5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# Custom Files
.DS_Store
PR_TITLE.txt
PR.md

# Created by https://www.toptal.com/developers/gitignore/api/visualstudiocode,angular
# Edit at https://www.toptal.com/developers/gitignore?templates=visualstudiocode,angular

Expand Down
14 changes: 14 additions & 0 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
repos:
- repo: https://github.com/pre-commit/mirrors-prettier
rev: v3.1.0
hooks:
- id: prettier
types_or: [javascript, jsx, ts, tsx, json, yaml, markdown, css, scss]
exclude: "package-lock.json"

- repo: https://github.com/alessandrojcm/commitlint-pre-commit-hook
rev: v9.11.0
hooks:
- id: commitlint
stages: [commit-msg]
additional_dependencies: ["@commitlint/config-conventional"]
95 changes: 95 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## Project Overview

ProfileSite is an Angular 17 application showcasing professional work experience through a job listing interface. The application uses standalone components (no NgModules), Angular Material for UI, and supports server-side rendering via Express.

## Development Commands

All commands should be run from the `solthoth/` directory:

```bash
cd solthoth
```

- **Install dependencies**: `npm install`
- **Development server**: `npm start` (serves on `http://0.0.0.0:4200`)
- **Build for production**: `npm run build`
- **Build with watch mode**: `npm run watch`
- **Run tests**: `npm test` (Karma/Jasmine)
- **SSR production server**: `npm run serve:ssr:solthoth` (serves built SSR app on port 4000)

Note: Tests are currently commented out in CI (see `.github/workflows/ci.yaml:19`).

## Architecture

### Application Structure

The application follows Angular 17's standalone component pattern with dependency injection via the `inject()` function rather than constructor injection.

**Core Components:**
- `AppComponent` - Root component with Material toolbar and router outlet
- `HomeComponent` - Main listing page displaying all jobs
- `JobComponent` - Reusable card component for individual job entries
- `JobDetailsComponent` - Detail view for a specific job (route: `/details/:id`)

**Routing:**
- `/` - HomeComponent (job listing)
- `/details/:id` - JobDetailsComponent (job detail view)

Routes defined in [app.routes.ts](solthoth/src/app/app.routes.ts).

### Data Model

Job data is currently **hardcoded** in [JobService](solthoth/src/app/job.service.ts:9-166) as an in-memory array. The `Job` interface includes:
- `id`: UUID string
- `title`, `companyName`, `companyLink`
- `dateRange`, `internalRange`: String dates (not Date objects)
- `achivements`: Array of accomplishment strings
- `details`: Optional additional details array

### Styling System

Global design tokens are defined in [styles.css](solthoth/src/styles.css:5-39) using CSS custom properties:
- Layout: `--layout-max-width: 960px`
- Spacing scale: `--spacing-{2xs,xs,sm,md,lg,xl,2xl,3xl,4xl}`
- Color system: Primary blue (`#2563eb`), secondary indigo (`#6366f1`)
- Typography: Inter font family via `--font-display`

Components use these tokens for consistent spacing and theming. The app uses Angular Material's indigo-pink prebuilt theme.

### Server-Side Rendering

SSR is configured via [server.ts](solthoth/server.ts) using Angular's CommonEngine with Express. The server:
- Serves static files from `dist/solthoth/browser/`
- Renders Angular routes server-side
- Runs on port 4000 (configurable via `PORT` env var)
- Includes placeholder for REST API endpoints at line 21

### TypeScript Configuration

Strict mode enabled in [tsconfig.json](solthoth/tsconfig.json:7-11) with:
- `strict: true`
- `noImplicitReturns: true`
- `noFallthroughCasesInSwitch: true`
- Angular strict templates enabled

Target: ES2022 with ES2022 modules.

## CI/CD

GitHub Actions workflow (`.github/workflows/ci.yaml`) runs on push/PR:
1. Build job: `npm ci` → `npm run build` → upload browser artifacts
2. Deploy job (main branch only): Downloads artifacts → FTP deploy to production

The default branch for PRs is `master` (not `main`), but deployment triggers on `main`.

## Development Environment

DevContainer configuration available at `.devcontainer/devcontainer.json` with:
- Node.js 20 TypeScript image
- Angular CLI pre-installed
- Azure CLI, Prettier, pre-commit hooks
- Post-create command runs `npm install` in solthoth/
27 changes: 27 additions & 0 deletions commitlint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
module.exports = {
extends: ["@commitlint/config-conventional"],
rules: {
"type-enum": [
2,
"always",
[
"feat", // New feature
"fix", // Bug fix
"docs", // Documentation changes
"style", // Code style changes (formatting, semicolons, etc.)
"refactor", // Code refactoring
"perf", // Performance improvements
"test", // Adding or updating tests
"build", // Build system or dependency changes
"ci", // CI configuration changes
"chore", // Other changes that don't modify src or test files
"revert", // Revert a previous commit
],
],
"type-case": [2, "always", "lower-case"],
"type-empty": [2, "never"],
"subject-empty": [2, "never"],
"subject-full-stop": [2, "never", "."],
"header-max-length": [2, "always", 100],
},
};
19 changes: 19 additions & 0 deletions scripts/pr-create-draft.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#!/usr/bin/env bash
set -euo pipefail

BASE_BRANCH="${BASE_BRANCH:-main}"

if [[ ! -f PR_TITLE.txt || ! -f PR.md ]]; then
echo "Missing PR_TITLE.txt or PR.md. Run scripts/pr-draft-ai.sh first."
exit 1
fi

title="$(cat PR_TITLE.txt)"
head_branch="$(git rev-parse --abbrev-ref HEAD)"

gh pr create \
--base "$BASE_BRANCH" \
--head "$head_branch" \
--title "$title" \
--body-file PR.md \
--draft
Loading