Skip to content

Commit 46c869f

Browse files
committed
Merge branch 'main' of github.com:codeforpdx/tenantfirstaid into feat/chat-refactor
2 parents 462c209 + b1cb141 commit 46c869f

28 files changed

+431
-267
lines changed

.github/workflows/deploy.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ jobs:
8383
cat > /etc/tenantfirstaid/env <<EOF
8484
ENV=prod
8585
OPENAI_API_KEY=${{ secrets.OPENAI_API_KEY }}
86+
FLASK_SECRET_KEY=${{ secrets.FLASK_SECRET_KEY }}
8687
DB_HOST=${{secrets.DB_HOST}}
8788
DB_PASSWORD=${{secrets.DB_PASSWORD}}
8889
DB_PORT=${{secrets.DB_PORT}}

.github/workflows/generate_conversations.yml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ on:
1111
num_rows:
1212
description: 'Number of rows to process'
1313
required: true
14-
default: '1'
14+
default: '1000'
1515
type: string
1616
reasoning_effort:
1717
description: 'Model reasoning effort'
@@ -53,7 +53,6 @@ jobs:
5353
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
5454
MODEL_NAME: ${{ inputs.model }}
5555
MODEL_REASONING_EFFORT: ${{ inputs.reasoning_effort }}
56-
MODEL_ENDPOINT: ${{ secrets.MODEL_ENDPOINT }}
5756
VECTOR_STORE_ID: ${{ secrets.VECTOR_STORE_ID }}
5857
run: |
5958
python chat.py --num-turns ${{ inputs.num_turns }} --num-rows ${{ inputs.num_rows }}
@@ -64,4 +63,4 @@ jobs:
6463
git config --global user.email '[email protected]'
6564
git add ${{ env.BACKEND_DIR }}/scripts/generate_conversation/tenant_questions_facts_with_new_conversations.csv
6665
git commit -m "Generated new conversations with turns=${{ inputs.num_turns }}, rows=${{ inputs.num_rows }}, effort=${{ inputs.reasoning_effort }}, model=${{ inputs.model }}"
67-
git push origin main
66+
git push origin $BRANCH_NAME

.github/workflows/pr-check.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,10 @@ jobs:
6666
- name: Install dependencies
6767
run: npm ci
6868

69+
- name: Run linting checks
70+
run: npm run lint
71+
- name: Run format checks
72+
run: npx prettier --check .
73+
6974
- name: Build frontend
7075
run: npm run build
71-
72-
- name: Run linting checks
73-
run: npm run lint

backend/pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ build-backend = "setuptools.build_meta"
2626
dev = [
2727
"pytest>=8.3.5",
2828
"pytest-cov>=6.1.1",
29+
"pytest-mock>=3.14.1",
2930
"ruff>=0.11.13",
3031
"ty>=0.0.1a8",
3132
"types-Flask>=1.1.6",

backend/scripts/generate_conversation/chat.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ def process_csv(input_file=None, output_file=None, num_turns=5, num_rows=None):
197197

198198
# Save the results with the same encoding as input
199199
print(f"\nWriting results to {output_file}")
200-
df.to_csv(output_file, index=False, encoding="cp1252")
200+
df.to_csv(output_file, index=False, encoding="utf-8")
201201

202202
print(f"\nAll conversations generated and saved to {output_file}")
203203
return output_file
Lines changed: 34 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,62 @@
11
Original conversation,first_question,facts,New Conversation
22
"You: I just moved into a new apartment and it is so hot in the summer
3-
Bot: Has your landlord told you that you cant install a portable air-conditioning (or other cooling) unit, or placed any restrictions on it?
3+
Bot: Has your landlord told you that you cant install a portable air-conditioning (or other cooling) unit, or placed any restrictions on it?
44
You: no, but shouldn't the apartment have ac?
5-
Bot: Oregon only obligates landlords to supply built-in cooling if the building permits for your unit were issued on or after April 1, 2024 (ORS 90.320 (1)(m)). Otherwise, youre entitled to bring in a portable A/C (or similar device) and, with narrow safety-related exceptions, the landlord cant stop you (ORS 90.355).
5+
Bot: Oregon only obligates landlords to supply built-in cooling if the building permits for your unit were issued on or after April 1, 2024 (ORS 90.320 (1)(m)). Otherwise, youre entitled to bring in a portable A/C (or similar device) and, with narrow safety-related exceptions, the landlord cant stop you (ORS 90.355).
66

77
Do you know roughly when the building was constructed or last permitted?
88
You: its brand new, so they started accepting tenants in feb of 2025
9-
Bot: Do you know when the city issued the buildings certificate of occupancy (or final building permits)?
9+
Bot: Do you know when the city issued the buildings certificate of occupancy (or final building permits)?
1010
You: no, how would I know that? why does that matter?
11-
Bot: It matters because ORS 90.320 (1)(m) now says: if the building permits for a dwelling were issued on or after April 1, 2024, the landlord must supply adequate cooling facilities maintained in good working order. If the permits are older, built-in A/C is optional and your right is mainly to use a portable unit under ORS 90.355.
11+
Bot: It matters because ORS 90.320 (1)(m) now says: if the building permits for a dwelling were issued on or after April 1, 2024, the landlord must supply adequate cooling facilities maintained in good working order. If the permits are older, built-in A/C is optional and your right is mainly to use a portable unit under ORS 90.355.
1212

1313
Two quick ways to learn the permit date:
1414
1. Ask the manager or owner (they have the paperwork).
15-
2. Look it up online or call the city/county building department and request the certificate of occupancy date for your address (its public record).
15+
2. Look it up online or call the city/county building department and request the certificate of occupancy date for your address (its public record).
1616

17-
If the permits are post-4/1/24 and the landlord hasnt provided working cooling, you can give written notice demanding they fix the problem; if they dont, you can use the habitability remedies in ORS 90.360 and 90.365.
17+
If the permits are post-4/1/24 and the landlord hasnt provided working cooling, you can give written notice demanding they fix the problem; if they dont, you can use the habitability remedies in ORS 90.360 and 90.365.
1818

1919
Would you be willing to email the manager today and simply ask what date the final certificate of occupancy was issued?
2020
You: how can I find out without contacting my landlord?
21-
Bot: You can usually pull the permit history yourself (its public): most Oregon cities/counties have an online building permits or e-permitting searchtype in the street address and the system shows the issue dates for permits and the certificate of occupancy. If theres no web portal, you can phone or email the city/county building department and ask for the final building permit / C of O date for the address.
21+
Bot: You can usually pull the permit history yourself (its public): most Oregon cities/counties have an online building permits or e-permitting searchtype in the street address and the system shows the issue dates for permits and the certificate of occupancy. If theres no web portal, you can phone or email the city/county building department and ask for the final building permit / C of O date for the address.
2222

2323
Which city (or county) is your apartment in?
2424
You: Oregon City in clackamas county
25-
Bot: Use Oregon Citys public permit site (Search: Oregon City eTRAKiT permits) ? enter your address ? look for the Certificate of Occupancy or final building-permit issue date.
25+
Bot: Use Oregon Citys public permit site (Search: Oregon City eTRAKiT permits) ? enter your address ? look for the Certificate of Occupancy or final building-permit issue date.
2626
Or phone the Oregon City Building Division (503-722-3789) and ask for the final permit date for your address.
2727

2828
Would you like the direct web link?
2929
You: yes please
30-
Bot: Here�s the portal: https://etrakit.orcity.org/etrakit/ (Use �Permit Search,� enter your street address and look for the �Certificate of Occupancy� or �Final� permit date.)",I just moved into a new apartment and it is so hot in the summer,"[""Tenant recently moved into a new apartment."", ""Tenant finds the apartment very hot during summer."", ""Tenant�s landlord has not restricted the installation of a portable air-conditioning unit."", ""The apartment building is brand new and began accepting tenants in February 2025."", ""Tenant does not know the date the city issued the building�s certificate of occupancy or final permits."", ""Tenant wants to learn the permit date without contacting the landlord."", ""Tenant�s apartment is located in Oregon City, Clackamas County, Oregon.""]","BOT: Sorry the place is so uncomfortable. To see what legal remedies you might have, can you tell me whether your lease says the landlord must provide air-conditioning or maintain the unit below a certain temperature? (ORS 90.320(1) lists what habitability standards a landlord must meet.)
31-
USER: I just checked my lease, and it doesn't say anything about the landlord providing air-conditioning or keeping the apartment below a certain temperature.
32-
BOT: Under Oregon law a landlord has to keep the unit �safe, sanitary and in good repair,� but air-conditioning is not listed as required habitability equipment. ORS 90.320(1). Unless your lease promises A/C or the heat level is so extreme that the place is unsafe (e.g., creating a health hazard), the landlord generally has no duty to install or run A/C.
30+
Bot: Here’s the portal: https://etrakit.orcity.org/etrakit/ (Use “Permit Search,” enter your street address and look for the “Certificate of Occupancy” or “Final” permit date.)",I just moved into a new apartment and it is so hot in the summer,"[""Tenant recently moved into a new apartment."", ""Tenant finds the apartment very hot during summer."", ""Tenant’s landlord has not restricted the installation of a portable air-conditioning unit."", ""The apartment building is brand new and began accepting tenants in February 2025."", ""Tenant does not know the date the city issued the building’s certificate of occupancy or final permits."", ""Tenant wants to learn the permit date without contacting the landlord."", ""Tenant’s apartment is located in Oregon City, Clackamas County, Oregon.""]","BOT: Oregon habitability law gives you a few tools:
3331

34-
What you can do:
35-
1. Put your concern in writing and ask the landlord to approve a tenant-supplied window unit or other cooling device.
36-
2. If you believe the temperature makes the unit unsafe, give written notice describing the condition and asking for correction within a reasonable time (usually 30 days). If they don�t act, ORS 90.360(1) lets you terminate the rental or, for smaller fixes, repair and deduct.
32+
• If the building’s permits were issued on or after April 1 2024, your landlord must provide “adequate cooling facilities” in at least one room and keep them working.
33+
• Even in older buildings, any air-conditioning or ventilation equipment the landlord already supplied has to be kept “in good repair”.
34+
• You are allowed to install and use your own portable air-conditioner or evaporative cooler unless it breaks specific safety rules, and any landlord limits on that must be in writing.
3735

38-
If you�re in Portland, you may also request a free cooling device grant under Portland City Code 30.01.
39-
USER: Thanks for the information! My landlord hasn�t restricted the installation of a portable A/C unit, so I might go ahead and get one. But I�m wondering if there are any building rules that might limit things like that. How can I identify when this new building received its final permits or certificate of occupancy? I think knowing that might help me learn more about the building's rules.
40-
BOT: To pull the permit or certificate-of-occupancy file you�ll need to search the local building department�s database, and the exact site depends on where the property sits.
41-
Which city (or county if you�re outside a city) is the building located in? (Under ORS 90.320(1)(a) the landlord must comply with �applicable building codes,� so the permit record will show what rules apply.)
42-
USER: The apartment building is located in Oregon City, which is in Clackamas County, Oregon.
43-
BOT: Try Oregon City�s public permit portal first:
36+
First step is usually to send the landlord a short dated letter (keep a copy) describing the heat problem and what you want fixed or allowed. If nothing happens, remedies such as rent reduction or repairing at the landlord’s cost may be available under ORS 90.360 or 90.365.
4437

45-
1. Go to eTRAKiT: https://etrakit.orcity.org
46-
2. In the �Search� box choose �Permits,� enter the street number and name, and hit �Search.�
47-
3. Look for a record type labeled �CO� (Certificate of Occupancy) or �BLD-Final.� The issue date on that line is the final approval date.
38+
Question: Did your lease include an air-conditioner or other cooling device that has stopped working?
39+
USER: No, my lease didn’t include any air-conditioner or cooling device.
40+
BOT: Because no cooling was included, the landlord’s duty depends on the building’s age:
4841

49-
If nothing comes up, call Oregon City Building Division (503-722-3789, option 6) and ask staff to email you the certificate-of-occupancy or final inspection card; they can also search by tax lot if the address has changed.
42+
• If the building’s permits were issued on/after Apr 1 2024, the landlord must supply and maintain “adequate cooling facilities” in at least one room — it’s a basic habitability duty under ORS 90.320(1)(m).
43+
• In any building, the landlord cannot forbid a tenant-supplied portable A/C or evaporative cooler unless the written lease lists a specific safety/code reason under ORS 90.355(2)–(3).
5044

51-
Why it matters: Under ORS 90.320(1)(a) a landlord must keep the unit in compliance with the building code that was in force when that final approval issued, so the permit file shows what standards apply.
45+
Next question: Do you know whether your building’s construction permits were issued before or after April 1 2024?
46+
USER: I don’t know the exact date the permits were issued, but the building is brand new and just started renting to tenants in February 2025. Can I find out the permit date without contacting the landlord?
47+
BOT: Yes. Most Oregon cities and counties publish building-permit data online; you can search by street address to see the issue date. If you tell me which city or county the building is in, I can point you to the right website. ORS 90.320(1)(m).
48+
USER: The apartment is in Oregon City, Clackamas County, Oregon. Where should I look to find the permit date?
49+
BOT: Use Oregon City’s public permit site first:
5250

53-
Let me know if you need help reading the permit record.
54-
USER: Thank you for the detailed instructions! I�ll check out the eTRAKiT system and see what I can find about the permits or certificate of occupancy. If I get confused or need help understanding the records, I�ll reach out again. Thanks for your help so far!
55-
BOT: You�re welcome�happy to help. Would you like a quick guide to the key fields you�ll see in an Oregon City permit record (issue date, inspection status, code edition, etc.) so you can tell whether the unit meets ORS 90.320(1)(a) habitability standards?
56-
USER: That sounds like it would be really helpful! Please share the guide so I�ll know what to look for when I check the permit records.
51+
1. Go to https://permits.oregoncity.gov/etrakit3/
52+
2. Click “Permit Search,” enter the street address, and open the newest building-permit record—the “Issued” date is the one that matters.
53+
54+
If nothing shows up there (some very recent permits are still routed through the county), try Clackamas County’s “Development Direct” portal at https://developmentdirect.clackamas.us/ and run the same address search; the issue date is listed in the permit details.
55+
56+
Knowing whether that date is on or after April 1 2024 will tell us if the landlord must supply cooling under ORS 90.320(1)(m).
57+
58+
Please check one of those portals and let me know the permit’s “Issued” date.
59+
USER: OK, I’ll go check one of those sites! Thanks for pointing me in the right direction.
60+
BOT: You’re welcome! Once you find the permit’s “Issued” date, please tell me what it is so we can see if the cooling-equipment rule in ORS 90.320(1)(m) applies.
61+
USER: Got it! I’ll check the permit date and let you know if it’s before or after April 1, 2024. Thanks again!
5762
"

backend/tests/test_citations.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import pytest
2+
from flask import Flask
3+
from tenantfirstaid.citations import get_citation, SECTIONS
4+
5+
6+
@pytest.fixture
7+
def app():
8+
app = Flask(__name__)
9+
app.add_url_rule("/api/citation", view_func=get_citation, methods=["GET"])
10+
return app
11+
12+
13+
@pytest.fixture
14+
def client(app):
15+
return app.test_client()
16+
17+
18+
def test_get_citation_success(client):
19+
# Use a valid section from SECTIONS
20+
section = next(iter(SECTIONS))
21+
response = client.get(f"/api/citation?section={section}")
22+
assert response.status_code == 200
23+
data = response.get_json()
24+
assert data["section"] == section
25+
assert data["text"] == SECTIONS[section]
26+
27+
28+
def test_get_citation_missing_param(client):
29+
response = client.get("/api/citation")
30+
assert response.status_code == 400
31+
assert b"missing query param" in response.data
32+
33+
34+
def test_get_citation_unknown_section(client):
35+
response = client.get("/api/citation?section=notarealsection")
36+
assert response.status_code == 404
37+
assert b"not found" in response.data
38+
39+
40+
def test_get_citation_empty_section_param(client):
41+
response = client.get("/api/citation?section=")
42+
assert response.status_code == 400
43+
assert b"missing query param" in response.data

backend/tests/test_session.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import pytest
2+
from tenantfirstaid.session import TenantSession
3+
4+
5+
@pytest.fixture
6+
def mock_valkey(mocker):
7+
"""Mock the Valkey class with the db_con.ping(), db_con.get(), and db_con.set() methods."""
8+
mock_client = mocker.Mock()
9+
mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_client)
10+
11+
_data = {}
12+
13+
mock_client.set = mocker.Mock(
14+
side_effect=lambda key, value: _data.update({key: value})
15+
)
16+
mock_client.get = mocker.Mock(side_effect=lambda key: _data.get(key, None))
17+
mock_client.ping = mocker.Mock()
18+
return mock_client
19+
20+
21+
@pytest.fixture
22+
def mock_environ(monkeypatch):
23+
monkeypatch.setenv("DB_HOST", "8.8.8.8")
24+
monkeypatch.setenv("DB_PORT", "8888")
25+
monkeypatch.setenv("DB_PASSWORD", "test_password")
26+
monkeypatch.setenv("DB_USE_SSL", "false")
27+
28+
29+
def test_session_set_and_get(mock_valkey, mock_environ):
30+
tenant_session = TenantSession()
31+
32+
mock_valkey.get.return_value = '"test_value"'
33+
tenant_session.set("some_session_id", "test_value")
34+
value = tenant_session.get("some_session_id")
35+
assert value == "test_value"
36+
37+
38+
def test_session_get_unknown_session_id(mock_valkey, mock_environ):
39+
tenant_session = TenantSession()
40+
41+
mock_valkey.get.return_value = None
42+
value = tenant_session.get("some_session_id")
43+
assert value == []
44+
45+
46+
def test_session_init_ping_exception(mocker, mock_environ, capsys):
47+
# Patch Valkey so that ping raises an exception
48+
mock_client = mocker.Mock()
49+
mock_client.ping = mocker.Mock(side_effect=Exception("Ping failed"))
50+
mocker.patch("tenantfirstaid.session.Valkey", return_value=mock_client)
51+
# Should not raise, but print the exception
52+
_obj = TenantSession()
53+
captured = capsys.readouterr()
54+
assert "Ping failed" in captured.out

0 commit comments

Comments
 (0)