diff --git a/.python-version b/.python-version new file mode 100644 index 0000000..455808f --- /dev/null +++ b/.python-version @@ -0,0 +1 @@ +3.12.4 diff --git a/backend/.gitignore b/backend/.gitignore new file mode 100644 index 0000000..9207f59 --- /dev/null +++ b/backend/.gitignore @@ -0,0 +1,185 @@ +# -------------------------------------------------------------- +# Python / FastAPI core +# -------------------------------------------------------------- + +# Byte‑compiled / optimized Python files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +build/ +dist/ +*.egg-info/ +*.egg +*.whl +pip-wheel-metadata/ + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +*.gcov +*.gcda +*.gcno +.pytest_cache/ +pytestdebug.log + +# Jupyter / IPython +.ipynb_checkpoints +profile_default/ +ipython_config.py + +# -------------------------------------------------------------- +# Virtual environments & environment files +# -------------------------------------------------------------- + +# Virtualenv / venv / conda environments +env/ +venv/ +ENV/ +VENV/ +.venv/ +.pyenv/ +conda-env/ +conda-requirements.txt + +# Environment variable files (keep secrets out of VCS) +.env +.env.* # e.g. .env.dev, .env.prod +.envrc +.env.local +.env.development +.env.production + +# -------------------------------------------------------------- +# FastAPI / ASGI / Uvicorn specifics +# -------------------------------------------------------------- + +# Uvicorn log files (if you redirect logs to files) +uvicorn.log +uvicorn-access.log + +# FastAPI generated OpenAPI / Swagger UI files (if you commit them) +openapi.json +swagger.json + +# -------------------------------------------------------------- +# Database / Alembic migrations +# -------------------------------------------------------------- + +# SQLite database files (often used in dev) +*.sqlite3 +*.db +*.db-journal + +# Alembic migration scripts (keep the folder but ignore compiled artifacts) +alembic/versions/*.pyc +alembic/versions/__pycache__/ + +# -------------------------------------------------------------- +# Static & media assets +# -------------------------------------------------------------- + +# Uploads / generated media (usually served by a CDN or separate storage) +media/ +uploads/ +staticfiles/ +static/ # keep if you have a folder you *do* want committed, otherwise ignore sub‑folders + +# -------------------------------------------------------------- +# Docker / CI / Deployment +# -------------------------------------------------------------- + +# Docker files that you might generate locally +docker-compose.override.yml +Dockerfile.dev + +# Docker volumes / data +docker-data/ +.docker/ + +# GitHub Actions / CI caches +.github/workflows/*.log + +# -------------------------------------------------------------- +# IDE / Editor specific +# -------------------------------------------------------------- + +# VS Code +.vscode/ +# PyCharm / IntelliJ +.idea/ +*.iml +*.iws +*.ipr +# Sublime Text +*.sublime-project +*.sublime-workspace +# Eclipse / VS +.project +.pydevproject +# Emacs / Vim +*~ +\#*\# +.*.swp +.*.swo +.#* +.session +*.un~ +*.orig +*.bak +*.tmp + +# -------------------------------------------------------------- +# OS generated files +# -------------------------------------------------------------- + +# macOS +.DS_Store +.AppleDouble +.LSOverride + +# Windows +Thumbs.db +ehthumbs.db +Desktop.ini +$RECYCLE.BIN/ + +# Linux +*~ +.nfs* + +# -------------------------------------------------------------- +# Miscellaneous +# -------------------------------------------------------------- + +# Logs +*.log +log/ +logs/ + +# Documentation build artifacts (Sphinx, MkDocs, etc.) +docs/_build/ +site/ + +# Backup files +*.bak +*.backup +*.old + +# sqlite db +database.db +database.db-journal \ No newline at end of file diff --git a/backend/chicken-scratch.sql b/backend/chicken-scratch.sql deleted file mode 100644 index d93ec8f..0000000 --- a/backend/chicken-scratch.sql +++ /dev/null @@ -1 +0,0 @@ --- SQLite diff --git a/backend/database/__init__.py b/backend/database/__init__.py new file mode 100644 index 0000000..32a52a0 --- /dev/null +++ b/backend/database/__init__.py @@ -0,0 +1,3 @@ +# database/__init__.py +from .connection import DatabaseConnection +from .repository import Repository diff --git a/backend/database/connection.py b/backend/database/connection.py new file mode 100644 index 0000000..aeac4bf --- /dev/null +++ b/backend/database/connection.py @@ -0,0 +1,24 @@ +import sqlite3 +from typing import List, Tuple + +class DatabaseConnection: + def __init__(self, db_name: str): + self.conn = sqlite3.connect(db_name) + self.cursor = self.conn.cursor() + + def close_connection(self): + self.conn.close() + + def execute_query(self, query: str, params: Tuple = None): + if params: + self.cursor.execute(query, params) + else: + self.cursor.execute(query) + self.conn.commit() + + def execute_query_with_return(self, query: str, params: Tuple = None): + if params: + self.cursor.execute(query, params) + else: + self.cursor.execute(query) + return self.cursor.fetchall() diff --git a/backend/database/models/__init__.py b/backend/database/models/__init__.py new file mode 100644 index 0000000..6cc1ce1 --- /dev/null +++ b/backend/database/models/__init__.py @@ -0,0 +1,6 @@ +# database/models/__init__.py +from .classification import Classification +from .member import Member +from .service_type import ServiceType +from .service import Service +from .service_availability import ServiceAvailability diff --git a/backend/database/models/classification.py b/backend/database/models/classification.py new file mode 100644 index 0000000..f842813 --- /dev/null +++ b/backend/database/models/classification.py @@ -0,0 +1,14 @@ +from ..connection import DatabaseConnection + +class Classification: + def __init__(self, classification_name: str): + self.classification_name = classification_name + + def save(self, db: DatabaseConnection): + query = "INSERT INTO Classifications (ClassificationName) VALUES (?)" + db.execute_query(query, (self.classification_name,)) + + @classmethod + def get_all(cls, db: DatabaseConnection): + query = "SELECT * FROM Classifications" + return db.execute_query_with_return(query) \ No newline at end of file diff --git a/backend/database/models/member.py b/backend/database/models/member.py new file mode 100644 index 0000000..3afdc86 --- /dev/null +++ b/backend/database/models/member.py @@ -0,0 +1,19 @@ +from ..connection import DatabaseConnection + +class Member: + def __init__(self, first_name: str, last_name: str, email: str, phone_number: str, classification_id: int, notes: str = None): + self.first_name = first_name + self.last_name = last_name + self.email = email + self.phone_number = phone_number + self.classification_id = classification_id + self.notes = notes + + def save(self, db: DatabaseConnection): + query = "INSERT INTO Members (FirstName, LastName, Email, PhoneNumber, ClassificationId, Notes) VALUES (?, ?, ?, ?, ?, ?)" + db.execute_query(query, (self.first_name, self.last_name, self.email, self.phone_number, self.classification_id, self.notes)) + + @classmethod + def get_all(cls, db: DatabaseConnection): + query = "SELECT * FROM Members" + return db.execute_query_with_return(query) \ No newline at end of file diff --git a/backend/database/models/service.py b/backend/database/models/service.py new file mode 100644 index 0000000..8bde040 --- /dev/null +++ b/backend/database/models/service.py @@ -0,0 +1,15 @@ +from ..connection import DatabaseConnection + +class Service: + def __init__(self, service_type_id: int, service_date: str): + self.service_type_id = service_type_id + self.service_date = service_date + + def save(self, db: DatabaseConnection): + query = "INSERT INTO Services (ServiceTypeId, ServiceDate) VALUES (?, ?)" + db.execute_query(query, (self.service_type_id, self.service_date)) + + @classmethod + def get_all(cls, db: DatabaseConnection): + query = "SELECT * FROM Services" + return db.execute_query_with_return(query) \ No newline at end of file diff --git a/backend/database/models/service_availability.py b/backend/database/models/service_availability.py new file mode 100644 index 0000000..6c28593 --- /dev/null +++ b/backend/database/models/service_availability.py @@ -0,0 +1,15 @@ +from ..connection import DatabaseConnection + +class ServiceAvailability: + def __init__(self, member_id: int, service_type_id: int): + self.member_id = member_id + self.service_type_id = service_type_id + + def save(self, db: DatabaseConnection): + query = "INSERT INTO ServiceAvailability (MemberId, ServiceTypeId) VALUES (?, ?)" + db.execute_query(query, (self.member_id, self.service_type_id)) + + @classmethod + def get_all(cls, db: DatabaseConnection): + query = "SELECT * FROM ServiceAvailability" + return db.execute_query_with_return(query) \ No newline at end of file diff --git a/backend/database/models/service_type.py b/backend/database/models/service_type.py new file mode 100644 index 0000000..58b5076 --- /dev/null +++ b/backend/database/models/service_type.py @@ -0,0 +1,14 @@ +from ..connection import DatabaseConnection + +class ServiceType: + def __init__(self, type_name: str): + self.type_name = type_name + + def save(self, db: DatabaseConnection): + query = "INSERT INTO ServiceTypes (TypeName) VALUES (?)" + db.execute_query(query, (self.type_name,)) + + @classmethod + def get_all(cls, db: DatabaseConnection): + query = "SELECT * FROM ServiceTypes" + return db.execute_query_with_return(query) \ No newline at end of file diff --git a/backend/database/repository.py b/backend/database/repository.py new file mode 100644 index 0000000..f056bd8 --- /dev/null +++ b/backend/database/repository.py @@ -0,0 +1,41 @@ +from .connection import DatabaseConnection +from .models import Classification, Member, ServiceType, Service, ServiceAvailability + +class Repository: + def __init__(self, db: DatabaseConnection): + self.db = db + + def create_classification(self, classification_name: str): + classification = Classification(classification_name) + classification.save(self.db) + + def create_member(self, first_name: str, last_name: str, email: str, phone_number: str, classification_id: int, notes: str = None): + member = Member(first_name, last_name, email, phone_number, classification_id, notes) + member.save(self.db) + + def create_service_type(self, type_name: str): + service_type = ServiceType(type_name) + service_type.save(self.db) + + def create_service(self, service_type_id: int, service_date: str): + service = Service(service_type_id, service_date) + service.save(self.db) + + def create_service_availability(self, member_id: int, service_type_id: int): + service_availability = ServiceAvailability(member_id, service_type_id) + service_availability.save(self.db) + + def get_all_classifications(self): + return Classification.get_all(self.db) + + def get_all_members(self): + return Member.get_all(self.db) + + def get_all_service_types(self): + return ServiceType.get_all(self.db) + + def get_all_services(self): + return Service.get_all(self.db) + + def get_all_service_availability(self): + return ServiceAvailability.get_all(self.db) \ No newline at end of file diff --git a/backend/main.py b/backend/main.py new file mode 100644 index 0000000..593ff5b --- /dev/null +++ b/backend/main.py @@ -0,0 +1,38 @@ +from database.repository import Repository +from database.connection import DatabaseConnection + +def main(): + db = DatabaseConnection("database.db") + repository = Repository(db) + + # Retrieve data + classifications = repository.get_all_classifications() + members = repository.get_all_members() + service_types = repository.get_all_service_types() + services = repository.get_all_services() + service_availability = repository.get_all_service_availability() + + print("Classifications:") + for classification in classifications: + print(classification) + + print("\nMembers:") + for member in members: + print(member) + + print("\nService Types:") + for service_type in service_types: + print(service_type) + + print("\nServices:") + for service in services: + print(service) + + print("\nService Availability:") + for availability in service_availability: + print(availability) + + db.close_connection() + +if __name__ == "__main__": + main() \ No newline at end of file