Q161: the home page measures accepted work, not sessions that merely ended
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
c9117fe46d
commit
58871fbaed
15 files changed
+183
-17
No files matched your search
@@ -0,0 +1,37 @@
|
||||
// Verdicts on plain work, kept apart from tasks so deletions cannot rewrite them; past ones are read once from the audit trail.
|
||||
export const workVerdictsSchema = `
|
||||
create table if not exists work_verdicts (
|
||||
id text primary key,
|
||||
org_id text not null references organizations(id) on delete cascade,
|
||||
task_id text,
|
||||
verdict text not null check (verdict in ('accepted', 'returned')),
|
||||
at text not null
|
||||
);
|
||||
create index if not exists work_verdicts_org_at on work_verdicts(org_id, at);
|
||||
|
||||
with moves as (
|
||||
select e.id, e.org_id, e.entity_id as task_id, e.created_at as at, json_extract(e.payload_json, '$.status') as status,
|
||||
lag(json_extract(e.payload_json, '$.status')) over (partition by e.entity_id order by e.created_at, e.rowid) as from_status
|
||||
from audit_events e
|
||||
where e.entity_type = 'task' and e.action = 'status_changed'
|
||||
)
|
||||
insert into work_verdicts(id, org_id, task_id, verdict, at)
|
||||
select 'wv_' || m.id, m.org_id, m.task_id,
|
||||
case when m.status = 'done' then 'accepted' else 'returned' end, m.at
|
||||
from moves m join tasks t on t.id = m.task_id and t.origin is null
|
||||
where (m.status = 'done' and coalesce(m.from_status, '') <> 'done')
|
||||
or (m.from_status in ('review', 'done') and m.status in ('in_progress', 'backlog')
|
||||
and not exists (
|
||||
select 1 from approvals a join held_deliverables h on h.approval_id = a.id
|
||||
where h.task_id = m.task_id and a.kind = 'deliverable_review' and a.state = 'declined'
|
||||
and abs(julianday(m.at) - julianday(a.decided_at)) * 86400 < 5
|
||||
));
|
||||
|
||||
insert into work_verdicts(id, org_id, task_id, verdict, at)
|
||||
select 'wv_' || a.id, a.org_id, h.task_id, 'returned', a.decided_at
|
||||
from approvals a join held_deliverables h on h.approval_id = a.id join tasks t on t.id = h.task_id and t.origin is null
|
||||
where a.kind = 'deliverable_review' and a.state = 'declined' and a.decided_at is not null;
|
||||
|
||||
insert into schema_migrations(version, name, applied_at)
|
||||
values (103, 'work_verdicts', datetime('now'));
|
||||
`;
|
||||
@@ -101,6 +101,7 @@ import { dropRollbackRecordsSchema } from "./migrations/099-drop-rollback-record
|
||||
import { chatReplyRequestsSchema } from "./migrations/100-chat-reply-requests";
|
||||
import { taskBlockedSchema } from "./migrations/101-task-blocked";
|
||||
import { goalDueDateSchema } from "./migrations/102-goal-due-date";
|
||||
import { workVerdictsSchema } from "./migrations/103-work-verdicts";
|
||||
|
||||
interface Migration {
|
||||
version: number;
|
||||
@@ -211,6 +212,7 @@ const MIGRATIONS: Migration[] = [
|
||||
{ version: 100, name: "chat_reply_requests", sql: chatReplyRequestsSchema },
|
||||
{ version: 101, name: "task_blocked", sql: taskBlockedSchema },
|
||||
{ version: 102, name: "goal_due_date", sql: goalDueDateSchema },
|
||||
{ version: 103, name: "work_verdicts", sql: workVerdictsSchema },
|
||||
];
|
||||
|
||||
const SCHEMA_VERSION = MIGRATIONS[MIGRATIONS.length - 1].version;
|
||||
|
||||
Reference in new issue
Block a user