Project: Building Maintenance System ๐๏ธ๐ ๏ธ โ
Welcome to your Capstone Project! ๐
This module brings together everything you've learned:
- Agile: Planning what to build.
- Python: Writing the logic.
- AI: Using your Copilot to build faster and better.
The Mission: You are a Junior Developer at "PropTech Solutions". Your boss wants a quick MVP (Minimum Viable Product) for a system to track maintenance requests (e.g., "Broken heater in Apt 3B").
Phase 1: Agile Planning (The Blueprint) ๐ โ
Integration: Agile Requirements | AI Design
1.1 The Scenario โ
It's Monday morning. Your Product Manager, Sarah, rushes in. "We have tenants complaining that their repair requests are getting lost in emails. We need a central list. Tenants report, Managers fix. Go!"
This is vague. If you code now, you will build the wrong thing.
1.2 From Vague Idea to User Stories โ
Your Task: Use AI to turn Sarah's vague request into clear User Stories.
Prompt:
"Act as a Product Manager. I need to build a 'Building Maintenance System' MVP. Break down the vague requirement 'Tenants report issues, Managers fix them' into 3 specific User Stories. Follow the format: 'As a [User], I want [Action], so that [Value]'."
The Backlog (Your Agile Board):
| ID | User Story | Priority | Status |
|---|---|---|---|
| US-1 | As a Tenant, I want to submit a request, so that my issue gets fixed. | High | To Do |
| US-2 | As a Manager, I want to view pending requests, so I know what to work on. | High | To Do |
| US-3 | As a Manager, I want to mark requests as 'Completed', so we don't duplicate work. | Medium | To Do |
1.3 Designing the Data Structure โ
We aren't using a SQL database yet. We'll use a Python List of Dictionaries.
Prompt:
"I am building a Python script for maintenance requests. Design a dictionary structure for a single request. It needs: ID, Apartment Number, Description, Status (Pending/Done), and Priority."
The Blueprint:
# Our "Database" is just a list in memory
requests_db = [
{
"id": 1,
"apt": "3B",
"description": "Leaky faucet",
"status": "Pending",
"priority": "Normal"
}
]Phase 2: The Core Logic (Python + AI) ๐ป โ
Integration: Pair Programming | Python Functions
We will build the logic in a file called maintenance.py.
2.1 The Skeleton Builder โ
Don't write the full code yet. Ask AI for the structure.
Prompt:
"Create a Python file structure for
maintenance.py. Write empty functions (withpass) and docstrings for:
add_request(db, apt, description)get_pending_requests(db)mark_completed(db, request_id)Don't implement the logic yet."
2.2 Implementing with "Driver Mode" โ
Now, you drive. You know Python lists and dicts. Fill in the functions.
Your Code (Draft):
def add_request(db, apt, description):
new_id = len(db) + 1
req = {
"id": new_id,
"apt": apt,
"description": description,
"status": "Pending",
"priority": "Normal"
}
db.append(req)
return reqAI Assist: If you get stuck on how to filter the list for pending requests, ask:
"How do I filter a list of dictionaries in Python to only show ones where
statusis 'Pending'?"
Phase 3: The CLI Interface (Interaction) ๐ฌ โ
Integration: Python Loops | Prompt Engineering
The logic needs a user interface. We'll build a simple command-line tool (main.py).
Prompt:
"Write a
main.pyscript that acts as the interface. It should importmaintenance. Use awhile Trueloop to show a menu:
- Report Issue
- View Jobs
- Finish Job
- Exit
Use
input()to get user choices. Call the functions frommaintenance.py."
Phase 4: Refactoring & Intelligence โจ โ
Integration: Refactoring
4.1 Auto-Priority (AI Logic) โ
Let's make the system smart. If the user types "Fire" or "Flood", priority should be "High".
Prompt:
"Write a helper function
calculate_priority(text). If the text contains urgent words like 'fire', 'leak', 'gas', return 'High'. Otherwise, return 'Normal'. Update myadd_requestfunction to use this."
4.2 Making it Persistent (Saving Data) โ
Right now, data vanishes when the script stops.
Prompt:
"Refactor
maintenance.pyto save the list to arequests.jsonfile.
- Write a
save_data(db)function using thejsonmodule.- Write a
load_data()function that returns the list from the file (or an empty list if file missing)."
Phase 5: Quality Assurance (Testing) ๐งช โ
Integration: Tests & Docs
You can't ship code without testing it.
5.1 Unit Tests โ
Prompt:
"Write 3
pytesttest cases foradd_request.
- Test adding a normal request.
- Test that the ID increments correctly.
- Test that priority is set to 'High' for urgent keywords."
5.2 Manual "Smoke Test" โ
Run your CLI. Try to break it.
- Enter text when it asks for a number.
- Try to complete a request ID that doesn't exist.
Prompt:
"I get a
ValueErrorwhen I type 'apple' instead of a Request ID. How do I handle this withtry/exceptin mymain.pyloop?"
Phase 6: Deployment (Going Live) ๐ โ
A CLI is cool, but a Web API is better.
6.1 The Flask Wrapper โ
We will wrap our Python functions in a tiny web server using Flask.
Prompt:
"I have
maintenance.py. Create a simpleapp.pyusing Flask.
GET /requests: Returns the list fromget_pending_requests.POST /requests: Takes JSON input and callsadd_request."
6.2 Deploying to Render.com โ
- Requirements: Ask AI "Generate a
requirements.txtfor this Flask app." - Git: Push your code to GitHub.
- Render: Connect your repo. Render detects the Python app and deploys it.
Result: You now have a live URL (e.g., https://my-proptech-app.onrender.com) that you can send to your "Manager"!
Appendix: The Full Code Solution ๐งฉ โ
Stuck? Here is the complete working code for the CLI version.
maintenance.py โ
import json
import os
DB_FILE = "requests.json"
def load_data():
if not os.path.exists(DB_FILE):
return []
with open(DB_FILE, "r") as f:
return json.load(f)
def save_data(db):
with open(DB_FILE, "w") as f:
json.dump(db, f, indent=4)
def calculate_priority(description):
urgent_words = ["fire", "leak", "gas", "flood", "broken", "danger"]
for word in urgent_words:
if word in description.lower():
return "High"
return "Normal"
def add_request(db, apt, description):
new_id = len(db) + 1
priority = calculate_priority(description)
req = {
"id": new_id,
"apt": apt,
"description": description,
"status": "Pending",
"priority": priority
}
db.append(req)
save_data(db)
return req
def get_pending_requests(db):
return [r for r in db if r["status"] == "Pending"]
def mark_completed(db, request_id):
for req in db:
if req["id"] == request_id:
req["status"] = "Completed"
save_data(db)
return True
return Falsemain.py โ
import maintenance
def main():
db = maintenance.load_data()
while True:
print("\n=== PropTech Maintenance System ===")
print("1. Report Issue")
print("2. View Pending Jobs")
print("3. Mark Job Completed")
print("4. Exit")
choice = input("Select an option: ")
if choice == "1":
apt = input("Apartment Number: ")
desc = input("Issue Description: ")
req = maintenance.add_request(db, apt, desc)
print(f"โ
Request #{req['id']} added with {req['priority']} priority.")
elif choice == "2":
pending = maintenance.get_pending_requests(db)
print(f"\nThere are {len(pending)} pending jobs:")
for req in pending:
print(f"[ID: {req['id']}] {req['apt']}: {req['description']} ({req['priority']})")
elif choice == "3":
try:
req_id = int(input("Enter Request ID to finish: "))
if maintenance.mark_completed(db, req_id):
print("โ
Job marked as completed.")
else:
print("โ ID not found.")
except ValueError:
print("โ Please enter a valid number.")
elif choice == "4":
print("Goodbye!")
break
else:
print("Invalid choice, try again.")
if __name__ == "__main__":
main()Congratulations! You have built a full-stack Python application using an AI-Assisted workflow. ๐