""" main.py - Flask API with auth routes and module registry Domain routes are registered via the routes registry. """ import os import flask import core.auth as auth import core.users as users import core.postgres as postgres import api.routes.routines as routines_routes import api.routes.medications as medications_routes app = flask.Flask(__name__) ROUTE_MODULES = [routines_routes, medications_routes] def register_routes(module): """Register a routes module. Module should have a register(app) function.""" ROUTE_MODULES.append(module) # ── Auth Routes ──────────────────────────────────────────────────── @app.route("/api/register", methods=["POST"]) def api_register(): data = flask.request.get_json() username = data.get("username") password = data.get("password") if not username or not password: return flask.jsonify({"error": "username and password required"}), 400 result = users.registerUser(username, password, data) if result: return flask.jsonify({"success": True}), 201 else: return flask.jsonify({"error": "username taken"}), 409 @app.route("/api/login", methods=["POST"]) def api_login(): data = flask.request.get_json() username = data.get("username") password = data.get("password") if not username or not password: return flask.jsonify({"error": "username and password required"}), 400 token = auth.getLoginToken(username, password) if token: return flask.jsonify({"token": token}), 200 else: return flask.jsonify({"error": "invalid credentials"}), 401 # ── User Routes ──────────────────────────────────────────────────── @app.route("/api/getUserUUID/", methods=["GET"]) def api_getUserUUID(username): header = flask.request.headers.get("Authorization", "") if not header.startswith("Bearer "): return flask.jsonify({"error": "missing token"}), 401 token = header[7:] if auth.verifyLoginToken(token, username): return flask.jsonify(users.getUserUUID(username)), 200 else: return flask.jsonify({"error": "unauthorized"}), 401 @app.route("/api/user/", methods=["GET"]) def api_getUser(userUUID): header = flask.request.headers.get("Authorization", "") if not header.startswith("Bearer "): return flask.jsonify({"error": "missing token"}), 401 token = header[7:] if auth.verifyLoginToken(token, userUUID=userUUID): user = postgres.select_one("users", {"id": userUUID}) if user: user.pop("password_hashed", None) return flask.jsonify(user), 200 else: return flask.jsonify({"error": "user not found"}), 404 else: return flask.jsonify({"error": "unauthorized"}), 401 @app.route("/api/user/", methods=["PUT"]) def api_updateUser(userUUID): header = flask.request.headers.get("Authorization", "") if not header.startswith("Bearer "): return flask.jsonify({"error": "missing token"}), 401 token = header[7:] if auth.verifyLoginToken(token, userUUID=userUUID): data = flask.request.get_json() result = users.updateUser(userUUID, data) if result: return flask.jsonify({"success": True}), 200 else: return flask.jsonify({"error": "no valid fields to update"}), 400 else: return flask.jsonify({"error": "unauthorized"}), 401 @app.route("/api/user/", methods=["DELETE"]) def api_deleteUser(userUUID): header = flask.request.headers.get("Authorization", "") if not header.startswith("Bearer "): return flask.jsonify({"error": "missing token"}), 401 token = header[7:] if auth.verifyLoginToken(token, userUUID=userUUID): data = flask.request.get_json() password = data.get("password") if not password: return flask.jsonify( {"error": "password required for account deletion"} ), 400 result = auth.unregisterUser(userUUID, password) if result: return flask.jsonify({"success": True}), 200 else: return flask.jsonify({"error": "invalid password"}), 401 else: return flask.jsonify({"error": "unauthorized"}), 401 # ── Health Check ─────────────────────────────────────────────────── @app.route("/health", methods=["GET"]) def health_check(): return flask.jsonify({"status": "ok"}), 200 if __name__ == "__main__": for module in ROUTE_MODULES: if hasattr(module, "register"): module.register(app) app.run(host="0.0.0.0", port=5000)