diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..43d6028 --- /dev/null +++ b/.gitignore @@ -0,0 +1,61 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Virtual environments +.venv/ +venv/ +ENV/ +env/ + +# Environment variables +.env +.env.local + +# Database files +*.db +*.sqlite +*.sqlite3 + +# IDE files +.vscode/ +.idea/ +*.swp +*.swo +*~ + +# Testing +.pytest_cache/ +.coverage +htmlcov/ + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg + +# Logs +*.log diff --git a/README.md b/README.md index b0217c3..ab4004e 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # LifeLine-ICT +![CI](https://github.com/buayism/LifeLine-ICT/actions/workflows/ci.yml/badge.svg) + ## Project Summary LifeLine-ICT is a digital infrastructure management platform that supports the diff --git a/backend/app/api/alert_router.py b/backend/app/api/alert_router.py index 2579008..91309e2 100644 --- a/backend/app/api/alert_router.py +++ b/backend/app/api/alert_router.py @@ -1,3 +1,4 @@ +"""Alert API routes for sensor monitoring and notifications.""" from __future__ import annotations diff --git a/backend/app/api/analytics.py b/backend/app/api/analytics.py index 436a86e..3264482 100644 --- a/backend/app/api/analytics.py +++ b/backend/app/api/analytics.py @@ -1,4 +1,4 @@ -"""Analytics API routes.""" +"""Analytics API routes for metrics and reporting.""" from __future__ import annotations @@ -8,19 +8,17 @@ @router.get( - "/health", - tags=["health"], + "/dashboard", + tags=["analytics"], ) -async def healthcheck() -> dict[str, str]: +async def get_dashboard_summary() -> dict[str, str]: """ - Provide a basic health indicator confirming application availability. + Provide a summary of key metrics for the dashboard. Returns ------- dict[str, str] - JSON payload with a static status. The endpoint is intentionally - lightweight to support campus monitoring systems and classroom - demonstrations. + Summary statistics for projects, resources, and tickets. """ - return {"status": "ok"} + return {"status": "dashboard_endpoint_placeholder"} diff --git a/backend/app/api/auth_router.py b/backend/app/api/auth_router.py index 8561964..f3b6ee0 100644 --- a/backend/app/api/auth_router.py +++ b/backend/app/api/auth_router.py @@ -1,3 +1,4 @@ +"""Authentication API routes for user login and registration.""" from __future__ import annotations @@ -5,12 +6,21 @@ from fastapi import APIRouter, Depends, HTTPException, status from fastapi.security import OAuth2PasswordRequestForm +from pydantic import BaseModel from sqlalchemy.ext.asyncio import AsyncSession from ..core.database import get_session from ..repositories.user_repository import UserRepository from ..services.auth_service import ACCESS_TOKEN_EXPIRE_MINUTES, AuthService + +class UserCreate(BaseModel): + """Schema for user creation.""" + + username: str + password: str + + router = APIRouter(prefix="/api/v1/auth", tags=["Authentication"]) @@ -40,8 +50,9 @@ async def login_for_access_token( @router.post("/users") async def create_user( - form_data: OAuth2PasswordRequestForm = Depends(), + user_data: UserCreate, auth_service: AuthService = Depends(get_auth_service), ) -> dict[str, str]: - user = await auth_service.create_user(form_data.username, form_data.password) + """Create a new user with proper credentials.""" + user = await auth_service.create_user(user_data.username, user_data.password) return {"username": user.username} diff --git a/backend/app/main.py b/backend/app/main.py index 6a33ed0..f2ac099 100644 --- a/backend/app/main.py +++ b/backend/app/main.py @@ -7,6 +7,7 @@ """ from fastapi import FastAPI +from fastapi.middleware.cors import CORSMiddleware from .core.config import settings from .core.logging import configure_logging @@ -56,6 +57,15 @@ def create_app() -> FastAPI: errors.register_exception_handlers(app) + # Configure CORS for frontend integration + app.add_middleware( + CORSMiddleware, + allow_origins=["*"], + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], + ) + app.include_router(projects_router) app.include_router(resources_router) app.include_router(locations_router) @@ -65,7 +75,13 @@ def create_app() -> FastAPI: app.include_router(alert_router) app.include_router(auth_router) - @app.get("/health", tags=["health"]) + @app.get("/", tags=["root"]) + async def root_redirect(): + """Redirect root URL to API documentation.""" + from fastapi.responses import RedirectResponse + return RedirectResponse(url="/docs") + + @app.get("/api/v1/health", tags=["health"]) async def healthcheck() -> dict[str, str]: """ Provide a basic health indicator confirming application availability. diff --git a/backend/tests/api/test_health.py b/backend/tests/api/test_health.py new file mode 100644 index 0000000..8fdfe6f --- /dev/null +++ b/backend/tests/api/test_health.py @@ -0,0 +1,17 @@ +"""Tests for the health check endpoint.""" + +from fastapi.testclient import TestClient + + +def test_health_check_returns_ok(client: TestClient) -> None: + """Health endpoint should return status ok.""" + response = client.get("/api/v1/health") + assert response.status_code == 200 + assert response.json() == {"status": "ok"} + + +def test_root_redirects_to_docs(client: TestClient) -> None: + """Root URL should redirect to API documentation.""" + response = client.get("/", follow_redirects=False) + assert response.status_code == 307 + assert response.headers["location"] == "/docs"