"""App factory. Serves API + (in production) the built Vue frontend.""" import os from flask import Flask, send_from_directory from config import BASE_DIR, Config, UPLOAD_DIR, UPLOAD_URL_PREFIX from extensions import db DIST_DIR = os.path.join(BASE_DIR, "..", "frontend", "dist") def create_app(): app = Flask(__name__, static_folder=None) app.config.from_object(Config) os.makedirs(os.path.join(BASE_DIR, "instance"), exist_ok=True) db.init_app(app) db.app = app from routes import auth as auth_routes from routes import portal as portal_routes from routes import admin as admin_routes app.register_blueprint(auth_routes.bp) app.register_blueprint(portal_routes.bp) app.register_blueprint(admin_routes.bp) @app.route("/api/health") def health(): return {"status": "ok"} # Serve uploaded files os.makedirs(Config.UPLOAD_FOLDER, exist_ok=True) @app.route(UPLOAD_URL_PREFIX + "/") def uploaded_file(filename): return send_from_directory(Config.UPLOAD_FOLDER, filename) # ---- Serve built Vue SPA in production (after `npm run build`) ---- if os.path.isdir(DIST_DIR): @app.route("/", defaults={"path": ""}) @app.route("/") def spa(path): full = os.path.join(DIST_DIR, path) if path and os.path.isfile(full): return send_from_directory(DIST_DIR, path) return send_from_directory(DIST_DIR, "index.html") return app app = create_app() if __name__ == "__main__": with app.app_context(): db.create_all() from seed import seed_all seed_all() app.run(host="0.0.0.0", port=8090, debug=False)