from flask import Flask, render_template, redirect, url_for, flash, request, abort
from flask_sqlalchemy import SQLAlchemy
from flask_login import LoginManager, login_user, login_required, logout_user,
current_user
from [Link] import generate_password_hash, check_password_hash
from forms import RegisterForm, LoginForm, RecordForm, SearchForm
from models import db, User, MedicalRecord
import os
from datetime import datetime
app = Flask(__name__)
[Link]['SECRET_KEY'] = [Link]('SECRET_KEY', 'dev-secret-key') # change in
production
[Link]['SQLALCHEMY_DATABASE_URI'] = 'sqlite:///[Link]'
[Link]['SQLALCHEMY_TRACK_MODIFICATIONS'] = False
db.init_app(app)
login_manager = LoginManager()
login_manager.login_view = 'login'
login_manager.init_app(app)
@login_manager.user_loader
def load_user(user_id):
return [Link](int(user_id))
@app.before_first_request
def create_tables():
db.create_all()
@[Link]('/')
def index():
if current_user.is_authenticated:
return redirect(url_for('dashboard'))
return render_template('[Link]')
@[Link]('/register', methods=['GET','POST'])
def register():
form = RegisterForm()
if form.validate_on_submit():
if
[Link](([Link]==[Link])|([Link]==[Link])).fir
st():
flash('User with same email or username exists', 'danger')
return render_template('[Link]', form=form)
user = User(
username=[Link],
email=[Link],
role=[Link]
user.password_hash = generate_password_hash([Link])
[Link](user)
[Link]()
flash('Registration successful. Please login.', 'success')
return redirect(url_for('login'))
return render_template('[Link]', form=form)
@[Link]('/login', methods=['GET','POST'])
def login():
form = LoginForm()
if form.validate_on_submit():
user = [Link].filter_by(email=[Link]).first()
if user and check_password_hash(user.password_hash, [Link]):
login_user(user)
flash('Logged in successfully.', 'success')
next_page = [Link]('next')
return redirect(next_page or url_for('dashboard'))
flash('Invalid credentials', 'danger')
return render_template('[Link]', form=form)
@[Link]('/logout')
@login_required
def logout():
logout_user()
flash('Logged out.', 'info')
return redirect(url_for('index'))
@[Link]('/dashboard', methods=['GET','POST'])
@login_required
def dashboard():
search_form = SearchForm()
# Admins & doctors can see all records; patients see own
query = [Link]
if current_user.role == 'patient':
query = query.filter_by(patient_id=current_user.id)
if search_form.validate_on_submit():
q = search_form.[Link]()
query = [Link](
([Link](q)) |
([Link](q))
records = query.order_by(MedicalRecord.created_at.desc()).all()
return render_template('[Link]', records=records, search_form=search_form)
@[Link]('/records/new', methods=['GET','POST'])
@login_required
def create_record():
# only doctor or admin can create records
if current_user.role not in ('doctor', 'admin'):
abort(403)
form = RecordForm()
# allow selecting patient by username/email
if form.validate_on_submit():
patient = [Link].filter_by(username=form.patient_username.data).first()
if not patient or [Link] != 'patient':
flash('Specified patient not found', 'danger')
return render_template('create_record.html', form=form)
rec = MedicalRecord(
title=[Link],
diagnosis=[Link],
prescriptions=[Link],
notes=[Link],
patient_id=[Link],
created_by_id=current_user.id
[Link](rec)
[Link]()
flash('Medical record created.', 'success')
return redirect(url_for('dashboard'))
return render_template('create_record.html', form=form)
@[Link]('/records/<int:record_id>')
@login_required
def view_record(record_id):
rec = [Link].get_or_404(record_id)
# patient can view only own records
if current_user.role == 'patient' and rec.patient_id != current_user.id:
abort(403)
# doctors and admins can view all
return render_template('view_record.html', rec=rec)
@[Link]('/records/<int:record_id>/edit', methods=['GET','POST'])
@login_required
def edit_record(record_id):
rec = [Link].get_or_404(record_id)
if current_user.role not in ('doctor','admin') and not (current_user.role=='patient' and
rec.patient_id==current_user.id):
abort(403)
form = RecordForm(obj=rec)
# patient username field: show patient username in form for doctors/admin
if [Link] == 'GET':
form.patient_username.data = [Link](rec.patient_id).username
if form.validate_on_submit():
# only doctors/admin change main medical data
[Link] = [Link]
[Link] = [Link]
[Link] = [Link]
[Link] = [Link]
[Link]()
flash('Record updated.', 'success')
return redirect(url_for('view_record', record_id=[Link]))
return render_template('create_record.html', form=form, edit=True)
@[Link]('/records/<int:record_id>/delete', methods=['POST'])
@login_required
def delete_record(record_id):
if current_user.role not in ('doctor','admin'):
abort(403)
rec = [Link].get_or_404(record_id)
[Link](rec)
[Link]()
flash('Record deleted', 'info')
return redirect(url_for('dashboard'))
# Simple API endpoint to fetch records (JSON) - tokenless session-based for demo
@[Link]('/api/records')
@login_required
def api_records():
if current_user.role == 'patient':
records = [Link].filter_by(patient_id=current_user.id).all()
else:
records = [Link]()
return {
"records": [
"id": [Link],
"title": [Link],
"diagnosis": [Link],
"prescriptions": [Link],
"patient_id": r.patient_id,
"created_at": r.created_at.isoformat()
} for r in records
}
if __name__ == '__main__':
[Link](debug=True)
html
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Healthcare Records</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<link rel="stylesheet" href="{{ url_for('static', filename='[Link]') }}">
</head>
<body>
<header class="site-header">
<a href="{{ url_for('index') }}" class="brand">Healthcare Records</a>
<nav>
{% if current_user.is_authenticated %}
<span class="muted">Logged in as {{ current_user.username }} ({{ current_user.role
}})</span>
<a href="{{ url_for('dashboard') }}">Dashboard</a>
{% if current_user.role in ['doctor','admin'] %}
<a href="{{ url_for('create_record') }}">New Record</a>
{% endif %}
<a href="{{ url_for('logout') }}">Logout</a>
{% else %}
<a href="{{ url_for('login') }}">Login</a>
<a href="{{ url_for('register') }}">Register</a>
{% endif %}
</nav>
</header>
<main class="container">
{% with messages = get_flashed_messages(with_categories=true) %}
{% if messages %}
<div class="flash-container">
{% for category, message in messages %}
<div class="flash {{ category }}">{{ message }}</div>
{% endfor %}
</div>
{% endif %}
{% endwith %}
{% block content %}{% endblock %}
</main>
<footer class="site-footer">
<p>© {{ (loop and 2025) or 2025 }} Healthcare Records</p>
</footer>
</body>
</html>