docs: initialize project documentation, AI guidelines, and logging standards

This commit is contained in:
2026-08-15 00:31:20 -07:00
parent 150e3dfbd5
commit 3d0156a7d8
5 changed files with 230 additions and 0 deletions
+32
View File
@@ -0,0 +1,32 @@
# AI Development Guidelines for Hireme
These guidelines provide context to AI assistants working on the `hireme` repository. Adhere to these principles to maintain the project's architecture and design philosophy.
## 1. Single Binary & Zero Dependencies
- **Goal:** The application must compile into a single Go binary.
- **Rule:** Do NOT introduce external dependencies that require separate build steps, node_modules, or static asset folders unless explicitly authorized.
- **Rule:** Use Go 1.22+ standard library features wherever possible (e.g., `net/http` `ServeMux`).
## 2. UI Philosophy (HTMX + Tailwind)
- **Rule:** Do NOT introduce React, Vue, or any heavy JS frameworks.
- **Rule:** All dynamic interactions must be handled via HTMX (`hx-get`, `hx-post`, `hx-target`). Endpoints should return HTML fragments, not JSON, for UI updates.
- **Rule:** CSS is handled via Tailwind CSS utility classes. Maintain the dark mode aesthetic using `bg-slate-*`, `text-slate-*`, and vibrant accents (`indigo`, `emerald`, `rose`).
- **Rule:** UI templates are stored as constant strings in Go files (`internal/ui/template_*.go`) and registered in `templates.go`. Do not create external `.html` files.
## 3. Database Integrity
- **Rule:** Use `go-sqlite3` and ensure `PRAGMA journal_mode=WAL;` is maintained. The application heavily relies on WAL mode to allow concurrent reads (from the UI) and writes (from background workers).
- **Rule:** Avoid long-running transactions that could lock the database.
## 4. Structured Logging
- **Rule:** Use `zap` structured logging exclusively. Do NOT use the standard library `log.Printf`.
- **Rule:** Use the `w` methods (`Infow`, `Debugw`, `Errorw`) to pass key-value pairs.
- **Correct:** `logger.Log.Infow("User created", "component", "API", "user_id", id)`
- **Incorrect:** `logger.Log.Infof("[API] User created: %d", id)`
## 5. Background Workers
- **Rule:** Long-running tasks (Crawling, LLM Analysis) must be executed asynchronously via the `internal/worker` pool. Do not block HTTP request handlers. Enqueue tasks in the SQLite `tasks` table instead.
+51
View File
@@ -0,0 +1,51 @@
---
name: Structured Logging with Zap
description: How to correctly use the zap structured logging library in this repository instead of standard log or string formatting.
---
# Structured Logging with Zap
When adding logs to the `hireme` repository, **always** use the global `logger.Log` (which is a `zap.SugaredLogger`).
Do **NOT** use `log.Printf` or `fmt.Printf`.
Do **NOT** use `logger.Log.Infof` to format strings with variables if those variables should be structured data.
## Proper Usage (The `w` methods)
Use the `w` variants of the log methods (`Infow`, `Debugw`, `Errorw`, `Warnw`). These methods take a message string as the first argument, followed by variadic key-value pairs.
### Example: API Endpoints
Always include a `"component", "API"` field.
```go
// GOOD
logger.Log.Infow("Triggered endpoint", "component", "API", "endpoint", "/applications", "status", "success")
// BAD - String interpolation hides the data from JSON parsers
logger.Log.Infof("[API] Triggered /applications with status %s", "success")
```
### Example: Background Workers
Include the worker ID and task ID.
```go
// GOOD
logger.Log.Errorw("Task processing failed", "component", "Worker", "worker_id", id, "task_id", task.ID, "error", err)
```
### Example: Database Operations
```go
// GOOD
logger.Log.Debugw("Running query", "component", "DB", "query", "SELECT * FROM jobs")
```
## Summary of `w` Methods
- `logger.Log.Debugw(msg string, keysAndValues ...interface{})`
- `logger.Log.Infow(msg string, keysAndValues ...interface{})`
- `logger.Log.Warnw(msg string, keysAndValues ...interface{})`
- `logger.Log.Errorw(msg string, keysAndValues ...interface{})`
- `logger.Log.Fatalw(msg string, keysAndValues ...interface{})` // Note: calls os.Exit(1)
+66
View File
@@ -0,0 +1,66 @@
# Hireme (GJCC)
**Hireme (Google Job Command Center)** is a high-performance, single-binary job application and tracking command center written in Go.
It completely automates the job search workflow by crawling job boards, analyzing job descriptions against your profile using Large Language Models (LLMs), and presenting a sleek, HTMX-powered UI to review, save, and track your applications.
## Key Features
- **Automated Crawling:** Background worker pools discover and fetch job listings from targets (e.g., Google Jobs).
- **LLM Job Analysis:** Integrates with LLMs (Mock, Gemini, Claude) to score jobs based on your qualifications, identify missing skills, and provide resume tailoring suggestions.
- **Smart Filtering:** Multi-stage filtering pipeline (Hard Keywords + Scoring Weights) configured via YAML to automatically reject unqualified jobs before expensive LLM calls.
- **Sleek UI:** A responsive, dark-mode dashboard built with Go Templates, HTMX, and Tailwind CSS.
- **Pipeline Management:** An interactive Apply Table to move jobs through your pipeline (Saved ▶ Applied ▶ Interview ▶ Offer).
- **Single Binary & SQLite:** Everything is packaged into a single Go binary using a local SQLite database (WAL mode enabled) for zero-dependency deployment.
## Quick Start
### Prerequisites
- Go 1.26+
- `make`
### Installation
1. **Clone the repository:**
```bash
git clone https://github.com/hireme/hireme.git
cd hireme
```
2. **Configure Data & Filters:**
Copy the example configurations and adjust them:
- `data/config/targets.yaml`: Setup crawler targets.
- `data/config/filters.yaml`: Setup hard keywords and scoring weights.
3. **Set Environment Variables:**
```bash
export LOG_LEVEL=debug
export GEMINI_API_KEY="your_api_key" # If using Gemini LLM
```
4. **Build and Run:**
```bash
make clean
make run
```
5. **Access the UI:**
Open your browser and navigate to [http://localhost:8080](http://localhost:8080).
## Commands
- `make build`: Builds the `hireme` binary into `build/`.
- `make run`: Builds and runs the binary.
- `make clean`: Removes the build binary and test databases.
## Contributing
Contributions are welcome! Please review the documentation in the `docs/` folder to understand the architecture and UI guidelines before submitting pull requests.
## License
MIT License.
+43
View File
@@ -0,0 +1,43 @@
# System Architecture
Hireme is designed as a single-binary, local-first web application. It combines a high-performance backend, an embedded database, background job processing, and a lightweight frontend into a cohesive, easy-to-deploy system.
## Components
### 1. Database Layer (`internal/db`)
- **Technology:** SQLite3 via `github.com/mattn/go-sqlite3`.
- **Mode:** WAL (Write-Ahead Logging) mode is enabled (`PRAGMA journal_mode=WAL;`) to support high concurrency between the HTTP server reads and background worker writes without "database is locked" errors.
- **Pattern:** Centralized query methods attached to a `DB` struct (`queries.go`).
### 2. Worker Pool & Task Queue (`internal/worker`, `internal/db/tasks.go`)
- **Technology:** Custom goroutine worker pool pulling from a `tasks` SQLite table.
- **Tasks:**
- `DISCOVER`: Initiates crawling on a target (e.g., Google Jobs search URL).
- `FETCH`: Fetches raw HTML for a specific job posting.
- `PROCESS`: Parses raw HTML, applies rule-based filtering (keywords, scoring), and enqueues for analysis if qualified.
- `ANALYZE`: Sends the parsed job to an LLM for final qualification scoring and tailoring tips.
- **Concurrency:** Managed via context cancellation and `atomic.Bool` flags for safe pausing and resuming.
### 3. Filters & Rules (`internal/filter`, `data/config/filters.yaml`)
- A pipeline pattern is used to quickly reject jobs before doing expensive LLM API calls.
- **Hard Keywords:** Immediate rejection if a keyword (e.g., "Clearance", "Staff") is found.
- **Scoring Weights:** Basic substring counting for required technologies (e.g., "Go", "Python"). If the raw score falls below a threshold, the job is rejected.
### 4. Crawlers (`pkg/crawler`)
- Currently implements Google Jobs (`pkg/crawler/google`).
- **Mechanism:** Parses embedded JSON (`AF_initDataCallback`) in the raw HTML response rather than fragile DOM traversal. This ensures stability against UI changes.
### 5. UI Layer (`internal/ui`)
- **Technology:** Standard Go HTTP server (`net/http`), Go Templates (`html/template`), HTMX, and Tailwind CSS.
- **Philosophy:** Server-Side Rendered (SSR) HTML fragments returned directly to HTMX for seamless, single-page application (SPA) like updates without heavy JS payloads.
- **Templates:** Statically compiled strings in `.go` files (`template_layout.go`, `template_jobs.go`) rather than external `.html` files to keep the binary fully self-contained.
### 6. Logging (`internal/logger`)
- **Technology:** `go.uber.org/zap` (Sugared Logger).
- **Pattern:** Structured logging using `w` methods (`Infow`, `Errorw`, `Debugw`) to allow for strongly-typed key-value pairs (`"component", "API"`) instead of string formatting.
+38
View File
@@ -0,0 +1,38 @@
# UI Guidelines
Hireme uses a modern, server-rendered UI stack that eliminates the need for heavy JavaScript frameworks (React, Vue, etc.) while maintaining a highly reactive, single-page application (SPA) feel.
## Stack
- **HTML / Go Templates:** Server-side rendering using `html/template`.
- **HTMX (`hx-*`):** Used for all dynamic interactions, form submissions, and UI updates.
- **Tailwind CSS:** Utility-first CSS framework for styling via CDN.
## Architecture & Patterns
### 1. Template Strings vs Files
Templates are declared as `const` strings in `.go` files (e.g., `template_layout.go`, `template_jobs.go`) and collected in a `TemplateRegistry` in `templates.go`. This keeps the final build as a single executable without requiring external static asset folders.
### 2. HTMX Updates
Instead of returning JSON and re-rendering via JS, API endpoints return rendered HTML fragments.
- **Example:** Clicking `+ Save` on a job POSTs to `/applications`. The handler updates the DB and returns the `template_jobs` HTML fragment, which HTMX swaps directly into the `#jobs-container` DOM element.
### 3. Layout & Navigation (Tab Persistence)
- The main UI uses a tabbed layout (Jobs, Apply, Targets).
- Switching tabs is handled via lightweight Vanilla JS (`switchTab(id)`) which toggles `.hidden` classes.
- Tab states are synced to the URL `#hash` so reloading the page preserves the active tab.
### 4. Client-Side Filtering & Sorting
- To prevent unnecessary server load for display formatting, table sorting and filtering (e.g., searching by keyword, or filtering by "Qualified") is done purely client-side using Vanilla JS.
- Data attributes (`data-sort-val`, `data-qual`, `data-app`) are embedded in the `<tr>` elements during server-render to aid the JS filter logic.
### 5. Design Aesthetics
- **Dark Mode Default:** The UI uses Tailwind's `dark:` classes implicitly by having `class="dark"` on the root `<html>` tag.
- **Micro-interactions:** Use hover states (`hover:bg-slate-800`), transitions (`transition-colors`), and subtle borders to create a premium feel.
- **Indicators:** Use badges and color-coded text (Emerald for success/qualified, Rose for rejected/not qualified, Indigo for actions).