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 |
|---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 |
|---|---|
|
Builds the |
|
Orchestrates scrape β LLM extraction β template substitution |
|
Generates the scaffold folder and starter files |
|
Sends a free-form prompt to the LLM and returns the response |
|
Validates and appends a job record to the CSV tracker |
|
Filters and formats job records for display |
|
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 |
|---|---|
|
Read / write the |
|
Path resolution, directory creation, file copy helpers |
|
Reads |
|
Unified client for OpenAI and Perplexity APIs |
|
Loads Markdown prompt files from |
|
Fetches and cleans job-posting HTML via |
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 |
|---|---|
|
Loads settings and reports missing keys |
|
Resolves paths β injects variables β calls |
|
scraper β LLM β latex_repository β compiler |
|
filesystem helpers β initer logic |
|
prompt_repository β llm_client β oracles core |
|
validation β csv_repository |
|
csv_repository β formatter |
|
csv_repository β validation β write-back |
utils/ΒΆ
Stateless helpers shared everywhere. No layer-specific imports allowed here.
Module |
Contents |
|---|---|
|
String literals, default values, path constants |
|
Click styling helpers (colours, banners, progress indicators) |
|
Helpers used by the check command (key presence, format tests) |
|
CSV parsing, column normalisation, date formatting |
|
Text cleaning and chunking utilities for the hunt pipeline |
|
Template-file generation helpers for |
|
|
|
Prompt-building helpers for oracle queries |
|
Field-diff helpers for the update command |
|
Reads and caches Markdown prompt files from disk |
|
Assembled prompt strings passed to the LLM |