9bf047ec45
Backend: - Migration 0021: task_logs table (FK → notes + users, CASCADE, indexed) - models/task_log.py: SQLAlchemy model with to_dict() - services/task_logs.py: CRUD with ownership checks, _UNSET sentinel for optional duration clear - routes/task_logs.py: GET/POST/PATCH/DELETE /api/tasks/<id>/logs - services/tools.py: log_work LLM tool (resolves task by title, creates log entry) - services/generation_task.py: retry assist generation up to 3× on HTTP 500 Frontend: - types/task.ts: TaskLog interface - TaskLogSection.vue: chronological work log with date+time timestamps, duration badge, inline edit, autofocus - InlineAssistPanel.vue: streaming preview + diff review rendered inline in editor column - useAssist.ts: removed chatStore.chatReady gate; toast notifications for errors - NoteEditorView.vue + TaskEditorView.vue: inline assist panel, aside restricted to idle state - TaskEditorView.vue: two-column layout (editor+log left, metadata sidebar right), body defaults to Preview, sidebarOpen accordion for mobile - editor-shared.css: .assist-active-hint style Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
29 lines
1.0 KiB
Python
29 lines
1.0 KiB
Python
"""Add task_logs table."""
|
|
|
|
from alembic import op
|
|
|
|
revision = "0021"
|
|
down_revision = "0020"
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute("""
|
|
CREATE TABLE IF NOT EXISTS task_logs (
|
|
id SERIAL PRIMARY KEY,
|
|
task_id INTEGER NOT NULL REFERENCES notes(id) ON DELETE CASCADE,
|
|
user_id INTEGER NOT NULL REFERENCES users(id) ON DELETE CASCADE,
|
|
content TEXT NOT NULL,
|
|
duration_minutes INTEGER,
|
|
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
)
|
|
""")
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_task_logs_task_id ON task_logs(task_id)")
|
|
op.execute("CREATE INDEX IF NOT EXISTS ix_task_logs_user_id ON task_logs(user_id)")
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute("DROP INDEX IF EXISTS ix_task_logs_user_id")
|
|
op.execute("DROP INDEX IF EXISTS ix_task_logs_task_id")
|
|
op.execute("DROP TABLE IF EXISTS task_logs")
|