Skip to content

fix: annotate conference list with has_errors, has_warnings, participants_count#22

Merged
agonza1 merged 3 commits into
peermetrics:masterfrom
Boanerges1996:fix/conference-list-annotations
Apr 10, 2026
Merged

fix: annotate conference list with has_errors, has_warnings, participants_count#22
agonza1 merged 3 commits into
peermetrics:masterfrom
Boanerges1996:fix/conference-list-annotations

Conversation

@Boanerges1996
Copy link
Copy Markdown
Contributor

Problem

After expand_fields was removed from the conference list (PR #19), the dashboard lost:

  • Error/warning icons on the conference list
  • Participant count data for the "Number of participants" chart (shows all zeros)

Fix

Annotate the conference queryset with lightweight fields computed in the same SQL query:

objs = Conference.filter(**filters).annotate(
    has_errors=Exists(Issue.objects.filter(conference=OuterRef('pk'), type='e')),
    has_warnings=Exists(Issue.objects.filter(conference=OuterRef('pk'), type='w')),
    participants_count=Count('participants', distinct=True),
)

No N+1 queries — all computed as subqueries/aggregations in one query.

API response

{
  "conference_id": "sessionshealth-abc123",
  "has_errors": false,
  "has_warnings": true,
  "participants_count": 2,
  ...
}

Test plan

  • Conference list shows error/warning icons
  • "Number of participants" chart shows correct counts instead of zeros
  • Verified locally: participants_count=2 in API response

…ants_count

After expand_fields was removed (PR peermetrics#19), the conference list no longer
includes participants or issues arrays. This broke the dashboard charts
for error/warning icons and participant counts.

Adds lightweight annotations via Exists() subqueries and Count() so the
list includes:
- has_errors (boolean)
- has_warnings (boolean)
- participants_count (integer)

No N+1 queries — all computed in the same SQL query.
@agonza1
Copy link
Copy Markdown
Contributor

agonza1 commented Apr 10, 2026

@codex

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d8f7df3394

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/views/conference_view.py Outdated
has_warnings=Exists(
Issue.objects.filter(conference=OuterRef('pk'), type='w', is_active=True)
),
participants_count=Count('participants', distinct=True),
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Derive participants_count without participant join filter

When participantId is present, Conference.filter(**filters) introduces a join on participants constrained to that specific participant, and Count('participants', distinct=True) then counts only that filtered join row(s). In that path, participants_count no longer reflects the conference total (often returning 1), which regresses the participant-count chart for participant-scoped queries. This needs an aggregation that is independent of the request’s participant filter (e.g., a separate subquery over the M2M table).

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Contributor

@agonza1 agonza1 Apr 10, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good approach. Annotations are the right call here.

One bug codex found: participants_count will be wrong when participantId is in the query string. Django reuses the filtered JOIN on the M2M table, so Count('participants') only counts the one filtered participant (returns 1 instead of the real total).

has_errors/has_warnings don't have this problem because Exists() runs its own subquery.

Claude suggested fix: use a subquery for the count too:

participants_count=Subquery(
    Participant.objects.filter(
        conferences=OuterRef('pk')
    ).order_by().values('conferences').annotate(
        cnt=Count('id', distinct=True)
    ).values('cnt')[:1],
    output_field=IntegerField(),
)

Count('participants') reuses the filtered JOIN when participantId is in
the query string, returning 1 instead of the real total. Switched to a
Subquery that counts independently of the request's participant filter.

Addresses review feedback from Codex and Alberto.
@Boanerges1996
Copy link
Copy Markdown
Contributor Author

@codex

Copy link
Copy Markdown

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 638cab3556

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread app/views/conference_view.py Outdated
Comment on lines +54 to +55
Participant.objects.filter(
conferences=OuterRef('pk')
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Exclude soft-deleted participants from participant counts

The participants_count subquery uses Participant.objects.filter(...), which bypasses the model’s Participant.filter(...) wrapper that enforces is_active=True. This means soft-deleted participants are still included in participants_count, so conference list metrics can be overstated after participant deletions. Previously, participant expansion paths used the wrapper and implicitly excluded inactive rows, so this changes API semantics for dashboards that rely on active participant totals.

Useful? React with 👍 / 👎.

The Subquery used Participant.objects.filter() which bypasses the
is_active=True check, overcounting if any participants were soft-deleted.
@agonza1 agonza1 merged commit 5390a4f into peermetrics:master Apr 10, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants