diff --git a/.gitignore b/.gitignore index c0964bb..00c5916 100644 --- a/.gitignore +++ b/.gitignore @@ -193,3 +193,4 @@ package-lock.json # Tailwind CSS build output (keep source in git) app/static/dist/ /logs +logs/app.jsonl diff --git a/app/models/client_note.py b/app/models/client_note.py index 9c9b73f..ed8cdc5 100644 --- a/app/models/client_note.py +++ b/app/models/client_note.py @@ -25,7 +25,7 @@ class ClientNote(db.Model): # Relationships author = db.relationship('User', backref='client_notes') - client = db.relationship('Client', backref='notes') + client = db.relationship('Client', backref=db.backref('notes', cascade='all, delete-orphan')) def __init__(self, content, user_id, client_id, is_important=False): """Create a client note. diff --git a/app/routes/client_notes.py b/app/routes/client_notes.py index 16cc3d6..a663fb4 100644 --- a/app/routes/client_notes.py +++ b/app/routes/client_notes.py @@ -11,6 +11,9 @@ client_notes_bp = Blueprint('client_notes', __name__) @login_required def create_note(client_id): """Create a new note for a client""" + # Verify client exists first (before try block to let 404 abort properly) + client = Client.query.get_or_404(client_id) + try: content = request.form.get('content', '').strip() is_important = request.form.get('is_important', 'false').lower() == 'true' @@ -20,9 +23,6 @@ def create_note(client_id): flash(_('Note content cannot be empty'), 'error') return redirect(url_for('clients.view_client', client_id=client_id)) - # Verify client exists - client = Client.query.get_or_404(client_id) - # Create the note note = ClientNote( content=content, diff --git a/templates/timer/edit_timer.html b/templates/timer/edit_timer.html index fc3cf15..ab7a018 100644 --- a/templates/timer/edit_timer.html +++ b/templates/timer/edit_timer.html @@ -38,7 +38,7 @@ document.addEventListener('DOMContentLoaded', function() { }); } - // Add form submission confirmation for admin users (custom modal) + // Add form submission confirmation for admin users if (form) { form.addEventListener('submit', function(e) { // If we already confirmed, let it proceed @@ -77,53 +77,38 @@ document.addEventListener('DOMContentLoaded', function() { if (changes.length > 0) { e.preventDefault(); - const modalEl = document.getElementById('confirmChangesModal'); - const summaryEl = document.getElementById('confirmChangesSummary'); - const confirmBtn = document.getElementById('confirmChangesConfirmBtn'); - - summaryEl.innerHTML = changes.map(ch => ` -
+ {{ timer.project.name }}{% if timer.task %} - {{ timer.task.name }}{% endif %} +
++ {{ _('Admin Mode:') }} {{ _('You can edit all fields of this time entry, including project, task, start/end times, and source.') }} +
+ {{ _('As an admin, you have full editing privileges for this time entry. Changes will be logged for audit purposes.') }} +
+