ArchitectureΒΆ

The project follows a layered architecture split into seven top-level packages. Each layer has a single responsibility, making it easy to extend or swap components without touching unrelated code.

daiana/
β”œβ”€β”€ cli.py                  # Entry point β€” registers all Click commands
β”œβ”€β”€ commands/               # Thin Click command wrappers
β”œβ”€β”€ config/                 # Settings and environment loading
β”œβ”€β”€ core/                   # Business logic (one module per command)
β”œβ”€β”€ domain/                 # Data models and validation
β”œβ”€β”€ infra/                  # I/O adapters (files, LLM, CSV, scraping)
β”œβ”€β”€ services/               # Orchestration β€” glues core + infra together
└── utils/                  # Shared helpers and constants

cli.pyΒΆ

The single entry point declared in pyproject.toml. Imports every sub-command from commands/ and registers it on the root @cli group. You never need to edit this file unless you add a brand-new top-level command.

commands/ΒΆ

One file per CLI command. Each module contains only the Click decorator boilerplate (flags, prompts, option parsing) and a single call into the matching service. No business logic lives here.

Module

Command it wires up

check_comm.py

daiana check β€” validates the .env file

compiler_comm.py

daiana compile β€” compiles LaTeX β†’ PDF

hunter_comm.py

daiana hunt β€” scrapes a URL and runs the full AI pipeline

init_comm.py

daiana init β€” scaffolds the project folder

oracles_comm.py

daiana oracle β€” asks the LLM a free-form question

saver_comm.py

daiana save β€” saves a job to the CSV tracker

shower_comm.py

daiana show β€” displays saved jobs

updater_comm.py

daiana update β€” updates a job record

config/ΒΆ

settings.py loads .env via python-dotenv, exposes typed constants (provider, model, user name, paths), and raises clear errors when required keys are missing. Everything else reads config through this module β€” never directly from os.environ.

core/ΒΆ

Pure business logic. Each module mirrors a command and knows nothing about Click or the file system β€” it receives plain Python objects and returns them.

Module

Responsibility

compiler.py

Builds the pdflatex command, handles aux-file cleanup

hunter.py

Orchestrates scrape β†’ LLM extraction β†’ template substitution

initer.py

Generates the scaffold folder and starter files

oracles.py

Sends a free-form prompt to the LLM and returns the response

saver.py

Validates and appends a job record to the CSV tracker

shower.py

Filters and formats job records for display

updater.py

Locates a record by ID and applies field updates

domain/ΒΆ

models.py defines the data classes (e.g. JobRecord, HuntResult) shared across layers. validation.py contains reusable validators called from both core/ and services/ to enforce business rules before data is persisted or sent to an LLM.

infra/ΒΆ

Adapters that talk to the outside world. Swap any adapter without changing business logic.

Module

What it wraps

csv_repository.py

Read / write the job_tracking_*.csv files

filesystem.py

Path resolution, directory creation, file copy helpers

latex_repository.py

Reads .tex templates, applies \\newcommand substitutions

llm_client.py

Unified client for OpenAI and Perplexity APIs

prompt_repository.py

Loads Markdown prompt files from job_hunt/prompts/

scraper.py

Fetches and cleans job-posting HTML via requests + bs4

services/ΒΆ

Thin orchestration layer. Each service wires together one or more core modules with the infra adapters they need, then returns the result to the command layer. Keeping this separation means core logic stays unit-testable without mocking I/O.

Module

What it orchestrates

check_service.py

Loads settings and reports missing keys

compile_service.py

Resolves paths β†’ injects variables β†’ calls compiler.py

hunt_service.py

scraper β†’ LLM β†’ latex_repository β†’ compiler

init_service.py

filesystem helpers β†’ initer logic

oracle_service.py

prompt_repository β†’ llm_client β†’ oracles core

save_service.py

validation β†’ csv_repository

show_service.py

csv_repository β†’ formatter

update_service.py

csv_repository β†’ validation β†’ write-back

utils/ΒΆ

Stateless helpers shared everywhere. No layer-specific imports allowed here.

Module

Contents

constants.py

String literals, default values, path constants

design/

Click styling helpers (colours, banners, progress indicators)

for_check.py

Helpers used by the check command (key presence, format tests)

for_csv.py

CSV parsing, column normalisation, date formatting

for_hunt.py

Text cleaning and chunking utilities for the hunt pipeline

for_init.py

Template-file generation helpers for daiana init

for_latex.py

latex_escape() and replace_newcommand() string utilities

for_oracle.py

Prompt-building helpers for oracle queries

for_update.py

Field-diff helpers for the update command

prompt_loader.py

Reads and caches Markdown prompt files from disk

prompts.py

Assembled prompt strings passed to the LLM