feat(break-time): add migrations for break_seconds, paused_at, and default break rules (Issue #561)

- Migration 137: add time_entries.break_seconds, time_entries.paused_at
- Migration 138: add settings break_after_hours_1/2, break_minutes_1/2 (e.g. 6h->30min, 9h->45min)
This commit is contained in:
Dries Peeters
2026-03-11 17:57:52 +01:00
parent 1eadcd090b
commit f66d5b7547
2 changed files with 99 additions and 0 deletions
@@ -0,0 +1,51 @@
"""Add break_seconds and paused_at to time_entries (Issue #561)
Revision ID: 137_add_break_time
Revises: 136_seed_overtime_leave_type
Create Date: 2026-03-11
Break time for timers (pause/resume) and manual time entries.
"""
from alembic import op
import sqlalchemy as sa
revision = "137_add_break_time"
down_revision = "136_seed_overtime_leave_type"
branch_labels = None
depends_on = None
def upgrade():
from sqlalchemy import inspect
bind = op.get_bind()
inspector = inspect(bind)
if "time_entries" not in inspector.get_table_names():
return
columns = {c["name"] for c in inspector.get_columns("time_entries")}
if "break_seconds" not in columns:
op.add_column(
"time_entries",
sa.Column("break_seconds", sa.Integer(), nullable=True, server_default="0"),
)
if "paused_at" not in columns:
op.add_column(
"time_entries",
sa.Column("paused_at", sa.DateTime(), nullable=True),
)
def downgrade():
from sqlalchemy import inspect
bind = op.get_bind()
inspector = inspect(bind)
if "time_entries" not in inspector.get_table_names():
return
columns = {c["name"] for c in inspector.get_columns("time_entries")}
if "paused_at" in columns:
op.drop_column("time_entries", "paused_at")
if "break_seconds" in columns:
op.drop_column("time_entries", "break_seconds")
@@ -0,0 +1,48 @@
"""Add default break rules to settings (Issue #561)
Revision ID: 138_add_break_rules
Revises: 137_add_break_time
Create Date: 2026-03-11
Optional default break rules (e.g. Germany: >6h = 30 min, >9h = 45 min).
"""
from alembic import op
import sqlalchemy as sa
revision = "138_add_break_rules"
down_revision = "137_add_break_time"
branch_labels = None
depends_on = None
def upgrade():
from sqlalchemy import inspect
bind = op.get_bind()
inspector = inspect(bind)
if "settings" not in inspector.get_table_names():
return
columns = {c["name"] for c in inspector.get_columns("settings")}
if "break_after_hours_1" not in columns:
op.add_column("settings", sa.Column("break_after_hours_1", sa.Float(), nullable=True, server_default="6"))
if "break_minutes_1" not in columns:
op.add_column("settings", sa.Column("break_minutes_1", sa.Integer(), nullable=True, server_default="30"))
if "break_after_hours_2" not in columns:
op.add_column("settings", sa.Column("break_after_hours_2", sa.Float(), nullable=True, server_default="9"))
if "break_minutes_2" not in columns:
op.add_column("settings", sa.Column("break_minutes_2", sa.Integer(), nullable=True, server_default="45"))
def downgrade():
from sqlalchemy import inspect
bind = op.get_bind()
inspector = inspect(bind)
if "settings" not in inspector.get_table_names():
return
columns = {c["name"] for c in inspector.get_columns("settings")}
for name in ["break_after_hours_2", "break_minutes_2", "break_after_hours_1", "break_minutes_1"]:
if name in columns:
op.drop_column("settings", name)