Skip to content

Commit f4e0cf7

Browse files
code quality updates
1 parent 834ee0b commit f4e0cf7

41 files changed

Lines changed: 1643 additions & 1345 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
8+
jobs:
9+
test-and-lint:
10+
runs-on: ubuntu-latest
11+
12+
steps:
13+
- name: Checkout
14+
uses: actions/checkout@v4
15+
16+
- name: Install uv
17+
uses: astral-sh/setup-uv@v4
18+
19+
- name: Set up Python
20+
uses: actions/setup-python@v5
21+
with:
22+
python-version: "3.13"
23+
24+
- name: Install dependencies
25+
run: uv sync --all-groups
26+
27+
- name: Ruff (Checking lint, imports, complexity, and commented-out code)
28+
run: uv run ruff check .
29+
30+
- name: Black (Checking code formatting)
31+
run: uv run black --check .
32+
33+
- name: Interrogate (Checking docstring coverage)
34+
run: uv run interrogate app
35+
36+
- name: Vulture (Checking unused/dead production code)
37+
run: uv run vulture app scripts --min-confidence 70
38+
39+
- name: Thin endpoint lint (Checking endpoint-layer boundaries)
40+
run: uv run python scripts/lint_thin_endpoints.py
41+
42+
- name: Pytest (Checking unit and integration tests)
43+
run: uv run pytest -q

README.md

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,6 @@ Full setup guide: [docs/RUNBOOK.md](docs/RUNBOOK.md)
5656
| `GET` | `/v1/documents/` | Admin (own company) or Super Admin |
5757
| `GET` | `/v1/documents/{id}` | Admin (own company) or Super Admin |
5858
| `DELETE` | `/v1/documents/{id}` | Admin (own company) or Super Admin |
59-
| `POST` | `/v1/chat/warmup` | Authenticated |
6059
| `POST` | `/v1/chat/invoke` | Admin or Employee |
6160

6261
---
@@ -103,7 +102,6 @@ ACCESS_TOKEN_EXPIRE_MINUTES=60
103102
EMBEDDING_MODEL=all-MiniLM-L6-v2
104103
CHUNK_SIZE=1000
105104
CHUNK_OVERLAP=200
106-
AGENT_WARMUP_ON_STARTUP=true
107105
108106
# Encoding
109107
ENCODING=utf-8
@@ -140,10 +138,12 @@ Full variable reference: [docs/RUNBOOK.md#environment-variables-reference](docs/
140138

141139
```bash
142140
# Linting and formatting
143-
ruff check app/ # lint
144-
ruff check app/ --fix # auto-fix
145-
black app/ # format
146-
interrogate app/ # docstring coverage (min 80%)
141+
uv run ruff check . # lint + complexity + commented-out code checks
142+
uv run ruff check . --fix # auto-fix
143+
uv run black --check . # format verification
144+
uv run python scripts/lint_thin_endpoints.py # endpoint thinness rule
145+
uv run interrogate app/ # docstring coverage (min 80%)
146+
uv run vulture app scripts --min-confidence 70 # dead-code scan
147147

148148
# Dependencies
149149
uv add <package> # add a runtime dependency
@@ -161,5 +161,5 @@ export OBJC_DISABLE_INITIALIZE_FORK_SAFETY=YES # macOS only
161161
celery -A app.worker.celery_app worker --pool=solo --loglevel=info
162162

163163
# Tests
164-
pytest
164+
uv run pytest -q
165165
```

alembic/env.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import asyncio
22
from logging.config import fileConfig
33

4-
from alembic import context
54
from sqlalchemy import pool
65
from sqlalchemy.ext.asyncio import async_engine_from_config
76

7+
from alembic import context
88
from app.core.config import settings
99
from app.db.models import Base
1010

alembic/versions/0001_initial_schema.py

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
Create Date: 2026-05-31
66
"""
77

8-
from typing import Sequence, Union
8+
from collections.abc import Sequence
9+
from typing import Union
910

1011
import sqlalchemy as sa
12+
1113
from alembic import op
1214

1315
revision: str = "0001"
@@ -72,9 +74,7 @@ def upgrade() -> None:
7274
PRIMARY KEY (id)
7375
)
7476
"""))
75-
op.execute(sa.text(
76-
"CREATE UNIQUE INDEX IF NOT EXISTS ix_companies_name ON companies (name)"
77-
))
77+
op.execute(sa.text("CREATE UNIQUE INDEX IF NOT EXISTS ix_companies_name ON companies (name)"))
7878

7979
op.execute(sa.text("""
8080
CREATE TABLE IF NOT EXISTS users (
@@ -87,9 +87,7 @@ def upgrade() -> None:
8787
PRIMARY KEY (id)
8888
)
8989
"""))
90-
op.execute(sa.text(
91-
"CREATE UNIQUE INDEX IF NOT EXISTS ix_users_username ON users (username)"
92-
))
90+
op.execute(sa.text("CREATE UNIQUE INDEX IF NOT EXISTS ix_users_username ON users (username)"))
9391

9492
op.execute(sa.text("""
9593
CREATE TABLE IF NOT EXISTS token_sessions (
@@ -105,9 +103,7 @@ def upgrade() -> None:
105103
PRIMARY KEY (id)
106104
)
107105
"""))
108-
op.execute(sa.text(
109-
"CREATE UNIQUE INDEX IF NOT EXISTS ix_token_sessions_jti ON token_sessions (jti)"
110-
))
106+
op.execute(sa.text("CREATE UNIQUE INDEX IF NOT EXISTS ix_token_sessions_jti ON token_sessions (jti)"))
111107

112108
op.execute(sa.text("""
113109
CREATE TABLE IF NOT EXISTS documents (

alembic/versions/0002_add_user_role_constraint.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,11 @@
55
Create Date: 2026-05-31
66
"""
77

8-
from typing import Sequence, Union
8+
from collections.abc import Sequence
9+
from typing import Union
910

1011
import sqlalchemy as sa
12+
1113
from alembic import op
1214

1315
revision: str = "0002"

app/agent/graph.py

Lines changed: 5 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,6 @@
88
from langgraph.graph.message import add_messages
99
from langgraph.prebuilt import ToolNode, tools_condition
1010

11-
from app.agent.tools.graph_generator import generate_graph
1211
from app.agent.tools.vector_search import search_documents
1312
from app.core.logger import get_logger
1413

@@ -21,7 +20,7 @@ class GraphState(TypedDict):
2120
messages: Annotated[list[BaseMessage], add_messages]
2221

2322

24-
tools = [search_documents, generate_graph]
23+
tools = [search_documents]
2524
tool_node = ToolNode(tools)
2625

2726
logger.info("Initialising LLM", extra={"model": "llama3.1", "temperature": 0})
@@ -37,27 +36,13 @@ def call_model(state: GraphState):
3736
system_instruction = SystemMessage(
3837
content=(
3938
"You are an expert financial and healthcare data assistant. "
40-
"You have two tools available:\n"
41-
"1. 'search_documents' — use this to look up factual information from uploaded documents.\n"
42-
"2. 'generate_graph' — use this ONLY when the user explicitly asks for a chart, graph, plot, "
43-
"or visual breakdown. This tool accepts a single JSON string parameter called 'data_json'.\n\n"
39+
"You have one tool available:\n"
40+
"1. 'search_documents' — use this to look up factual information from uploaded documents.\n\n"
4441
"CRITICAL RULES:\n"
45-
"- If the user asks for a chart or graph, you MUST call 'generate_graph'."
46-
" Do NOT just describe data in text.\n"
47-
"- Never print JSON like {\"name\": \"generate_graph\", ...} in normal text."
48-
" Use real tool-calling only.\n"
49-
"- First use 'search_documents' to gather the numbers if needed,"
50-
" then call 'generate_graph' with the data.\n"
51-
"- Only chart numbers that are explicitly present in retrieved document evidence."
52-
" Never invent placeholder values.\n"
53-
"- For requests like monthly revenue for a specific year, include all 12 months"
54-
" if the evidence supports it; otherwise clearly state the data is incomplete.\n"
42+
"- Use 'search_documents' whenever factual document evidence is needed.\n"
5543
"- Never call 'search_documents' repeatedly with the same query in a loop."
5644
" If you already called it and have results, produce a final answer.\n"
57-
"- If 'generate_graph' returns an error, do NOT call it again with the same payload."
58-
" Return a concise failure message asking for a clearer chart request.\n"
59-
"- After calling 'generate_graph', keep your final text response brief (e.g. 'Here is your chart.'). "
60-
"Do NOT re-list all the data points in your text answer — the chart already shows them."
45+
"- Do not fabricate data. If evidence is missing, say so clearly."
6146
)
6247
)
6348

app/agent/tools/graph_generator.py

Lines changed: 0 additions & 180 deletions
This file was deleted.

0 commit comments

Comments
 (0)