Add PM extension (Projects, Work Logs, Comments) + Quill rich-text UI
Projects: Brick-backed model with list/detail screens and nav entry. Work Logs: per-contributor time ledger, assignee running-clock + helper logged minutes with Hours/Minutes input; pause-after-save and helper-deduct prompts. Comments: threaded comments with file attachments and Quill composer. Detail screen: tabbed layout (Work Log / Comments / Activity), editable title + description via edit dialog, Quill-rendered descriptions with legacy plain-text fallback. Create dialog: fixed-width (480px max), Quill description editor. Shared QuillFieldEditor + QuillReadOnly widgets extracted for reuse. RLS: hardened activity-log actor binding, immutable creator_id/ created_at triggers, SECURITY INVOKER visibility helper, append-only work-log and scoped comment policies. Brick migration for project_id FK on programmer_tasks. Co-Authored-By: claude-flow <ruv@ruv.net>
This commit is contained in:
@@ -29,14 +29,17 @@ DateTime? resolveExecutionStart(
|
||||
}
|
||||
|
||||
/// Computes the effective worked duration, subtracting all paused intervals
|
||||
/// between the resolved start and [endAt].
|
||||
/// between the resolved start and [endAt], then subtracting [adjustment]
|
||||
/// (e.g. time reassigned to another task when the user helped elsewhere).
|
||||
///
|
||||
/// [events] must be in DESCENDING order (newest first) — the same order
|
||||
/// returned by activity-log queries with `ascending: false`.
|
||||
/// returned by activity-log queries with `ascending: false`. The result never
|
||||
/// goes below zero.
|
||||
Duration computeEffectiveDuration({
|
||||
required DateTime? fallbackStartedAt,
|
||||
required DateTime endAt,
|
||||
required List<DurationEvent> events,
|
||||
Duration adjustment = Duration.zero,
|
||||
}) {
|
||||
final start = resolveExecutionStart(events, fallbackStartedAt);
|
||||
if (start == null || !endAt.isAfter(start)) return Duration.zero;
|
||||
@@ -67,7 +70,7 @@ Duration computeEffectiveDuration({
|
||||
pausedTotal += endAt.difference(pausedSince);
|
||||
}
|
||||
|
||||
final total = endAt.difference(start) - pausedTotal;
|
||||
final total = endAt.difference(start) - pausedTotal - adjustment;
|
||||
return total.isNegative ? Duration.zero : total;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user