hcengineering / hcengineering/platform

Bug: Meeting minutes not shown in Room view - collection counter never incremented

Open
#10,526 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
27.7k
Forks
2.2k
PR merge metrics
No merged PRs in 30d

Description

### Describe the bug

After a meeting ends, the Room detail view shows **"No meeting minutes"** even though MeetingMinutes documents exist in the database with transcription data. The transcription pipeline works correctly (love-agent -> OpenAI STT -> aibot -> transactor -> CockroachDB), but the UI never renders the results.

### Environment

- **Version:** v0.7.353 (`hardcoreeng/*` images)
- **Database:** CockroachDB (single-node, self-hosted)
- **Deployment:** Dokploy template (docker-compose)

### Steps to reproduce

1. Start a meeting in any Room (e.g., "All hands")
2. Enable transcription (click the transcription button)
3. Speak for 30+ seconds so OpenAI STT generates transcriptions
4. End the meeting
5. View the Room detail page -> "Meeting minutes" section shows **"No meeting minutes"**

### Evidence from database

MeetingMinutes documents exist with correct data:

```sql
SELECT _id, _class, "attachedTo", data->>'status', data->>'transcription', data->>'title'
FROM meeting_minutes
WHERE "attachedTo" = '';
```

Returns 4 rows, the most recent with `"transcription": 8` (8 saved transcript messages). The data is there, the UI just can't see it.

### Root cause

The `MeetingMinutesSection.svelte` component guards rendering on the `meetings` collection counter:

```svelte
// plugins/love-resources/src/components/MeetingMinutesSection.svelte
{#if meetings > 0 && viewlet}

{:else}

{/if}
```

The `meetings` counter on the Room is **never incremented** because MeetingMinutes are created using `createDoc` / `createTxCreateDoc` instead of `addCollection` / `createTxCollectionCUD`.

**Client-side creation** (`plugins/love-resources/src/meetings.ts`):

```typescript
await client.createDoc(love.class.MeetingMinutes, core.space.Workspace, {
attachedTo: room._id,
status: MeetingStatus.Active,
title: await getNewMeetingTitle(room),
attachedToClass: love.class.Room,
collection: 'meetings'
})
```

**Server-side trigger** (`server-plugins/love-resources/src/index.ts`):

```typescript
const tx = control.txFactory.createTxCreateDoc(
love.class.MeetingMinutes,
core.space.Workspace,
{
attachedTo: info.room,
status: MeetingStatus.Active,
title: `...`,
attachedToClass: love.class.Room,
collection: 'meetings'
},
_id
)
```

The collection counter trigger in `server/packages/middleware/src/triggers.ts` only increments counters when `attachedTo`, `attachedToClass`, and `collection` are **top-level transaction properties**. `createDoc` puts `attachedTo`/`collection` inside `attributes` (the document data), not as top-level transaction properties. Only `addCollection` / `createTxCollectionCUD` promotes these to the top level. So the trigger never fires, and the Room's `meetings` counter stays at 0/undefined.

Additionally, the `@Model` decorator for `MeetingMinutes` extends `core.class.Doc` (not `core.class.AttachedDoc`), which means `hierarchy.isDerived(love.class.MeetingMinutes, core.class.AttachedDoc)` returns `false` even though the TypeScript class extends `TAttachedDoc`:

```typescript
// models/love/src/index.ts
@Model(love.class.MeetingMinutes, core.class.Doc, DOMAIN_MEETING_MINUTES)
export class TMeetingMinutes extends TAttachedDoc implements MeetingMinutes, Todoable {
```

### Suggested fix

**Fix 1:** Change the `@Model` decorator to extend `core.class.AttachedDoc`:

```typescript
@Model(love.class.MeetingMinutes, core.class.AttachedDoc, DOMAIN_MEETING_MINUTES)
```

**Fix 2:** Change client-side creation to use `addCollection`:

```typescript
await client.addCollection(
love.class.MeetingMinutes,
core.space.Workspace,
room._id,
love.class.Room,
'meetings',
{
status: MeetingStatus.Active,
title: await getNewMeetingTitle(room),
description: null
}
)
```

**Fix 3:** Change server-side trigger to use `createTxCollectionCUD`:

```typescript
const innerTx = control.txFactory.createTxCreateDoc(
love.class.MeetingMinutes,
core.space.Workspace,
{
description: null,
attachedTo: info.room,
status: MeetingStatus.Active,
title: `${roomName} ${date}`,
attachedToClass: love.class.Room,
collection: 'meetings'
},
_id
)
const tx = control.txFactory.createTxCollectionCUD(
love.class.Room,
info.room,
core.space.Workspace,
'meetings',
innerTx
)
```

### Impact

- **Transcription pipeline is unaffected.** love-agent, OpenAI STT, and aibot all work correctly. Transcripts are written to the `meeting_minutes` table via the transactor.
- **Data is preserved.** MeetingMinutes documents and their transcription ChatMessages exist in the database. Only the UI display is broken.
- **Affects all self-hosted deployments** on v0.7.353 using CockroachDB. May also affect Huly Cloud (unclear if the `worker` service compensates).

### Workaround (for self-hosted deployments on CockroachDB)

Manually reconcile the counter for all Rooms across all workspaces:

```sql
-- Fix meeting minutes counter on all Rooms/Offices (all workspaces)
UPDATE love
SET data = jsonb_set(COALESCE(data, '{}'::jsonb), '{meetings}', (
SELECT COALESCE(to_jsonb(count(*)), '0'::jsonb)
FROM meeting_minutes
WHERE "attachedTo" = love._id
AND "workspaceId" = love."workspaceId"
)::jsonb)
WHERE _class IN ('love:class:Room', 'love:class:Office');
```

This sets the `meetings` field on each Room to the actual count of MeetingMinutes. Refresh the browser after running.

**Note:** The counter will not auto-increment for future meetings until the upstream code is fixed.

### Related issues

- #8785 - Meeting minutes not shown in UI when room is deleted
- #7303 - Meeting minutes tracking

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.