Skip to content

feat: comment moderation - #108

Open
xhyrom wants to merge 29 commits into
mainfrom
feat/comment-moderation
Open

xhyrom wants to merge 29 commits into
mainfrom
feat/comment-moderation

Conversation

@xhyrom

@xhyrom xhyrom commented Aug 13, 2026 •

Copy link
Copy Markdown
Member

Copilot AI lite review requested due to automatic review settings August 13, 2026 14:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Adds AI-based moderation metadata and an asynchronous moderation workflow for issue comments, storing model evaluation results and auto-hiding comments that exceed a configurable threshold.

Changes:

  • Add ai_evaluation (jsonb) column to issues_comments.
  • Enqueue moderation for newly created user comments (after_create_commit) and persist evaluation results.
  • Introduce Issues::ModerateCommentJob to call Gemini with a structured schema and auto-hide comments above COMMENT_AUTO_HIDE_THRESHOLD.

Reviewed changes

Copilot reviewed 13 out of 13 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
db/structure.sql Adds ai_evaluation column to the issues_comments table and records the new migration version.
db/migrate/20260813133737_add_ai_evaluation_to_issues_comments.rb Migration adding the new jsonb column with a default value.
app/models/issues/comment.rb Adds moderate helper to enqueue the moderation job.
app/models/issues/user_comment.rb Triggers moderation after user comment creation (non-legacy/non-imported).
app/models/issues/user_private_comment.rb Updates schema annotation to include ai_evaluation.
app/models/issues/responsible_subject_comment.rb Updates schema annotation to include ai_evaluation.
app/models/issues/duplicate_issue_comment.rb Updates schema annotation to include ai_evaluation.
app/models/issues/agent_private_comment.rb Updates schema annotation to include ai_evaluation.
app/models/issues/agent_comment.rb Updates schema annotation to include ai_evaluation.
app/jobs/issues/moderate_comment_job.rb New background job that calls Gemini, stores the evaluation, and auto-hides the comment based on the score threshold.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread app/jobs/issues/moderate_comment_job.rb
Comment thread app/jobs/issues/moderate_comment_job.rb
Comment thread app/jobs/issues/moderate_comment_job.rb
@xhyrom
xhyrom requested a review from luciajanikova August 15, 2026 07:14

@mirrec mirrec left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Looks good to me, but I haven't test it.

Comment thread app/jobs/issues/moderate_comment_job.rb Outdated
Comment thread db/migrate/20260813133737_add_ai_evaluation_to_issues_comments.rb Outdated
Comment thread db/seeds/ai_prompts.rb
page.slug = "moderate-comments"
page.text = "-"
page.raw = File.read(Rails.root + 'db/seeds/fixtures/ai_prompt_moderatecomments.md')
end.save!

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Maybe a dump question, but will this get auto-created after the deploy?

Or let me ask this differently. Do we run seed after every deployment?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Description: The comment insults specific individuals, public officials, or municipal employees.

Category: sarcastic
Description: The comment contains heavy sarcasm, irony, or mocking that hinders constructive dialogue.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

OT the mocking part reminded me of this video 😄

system_prompt: Ai::Prompt.get("moderatecomments"),
messages: [ prompt ],
response_schema: {
type: "OBJECT",

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Out of the scope of this PR, but I do find it a bit weird, that part of the prompt is in seeds and the rest is set up here. I would expected it to be on a single place (or at least collocated in some file or folder)

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

I think we could refactor this after we merge, since we use this exact same pattern elsewhere in the app

"content": {
"parts": [
{
"text": "{\n \"irrelevant\": 0.1,\n \"vulgar\": 0.0,\n \"insulting\": 0.0,\n \"sarcastic\": 0.0,\n \"political\": 0.0,\n \"overall_score\": 0.1,\n \"reason\": \"Slušná otázka na doplnenie detailov.\"\n}"

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Out of the scope of the PR. I do understand the endpoint returns encoded json, but the readability is hard. Maybe there's a way how to have a simple json that will be encoded eventually.

@xhyrom

xhyrom commented Oct 6, 2026

Copy link
Copy Markdown
Member Author

konflikty opravené, mało by byť READY cc @mirrec @jsuchal

@jsuchal

jsuchal commented Oct 7, 2026

Copy link
Copy Markdown
Member

@xhyrom tu ma este zaujima ze co ked nezbehne ten job (z akehokolvek dovodu) a odosle sa to do triaze. Nemalo by sa tu pockat na to kym tato validacia zbehne a az potom to posielat do triaze?

Zaroven skusili sme toto pustit na nejakych realistickych datach? Lebo toto moze zacat schovavat komenty a zacnu nam pisat ludia ze kde su.

@xhyrom

xhyrom commented Oct 8, 2026 •

Copy link
Copy Markdown
Member Author

@xhyrom tu ma este zaujima ze co ked nezbehne ten job (z akehokolvek dovodu) a odosle sa to do triaze. Nemalo by sa tu pockat na to kym tato validacia zbehne a az potom to posielat do triaze?

No momentálne sa to pošle do triáže. Chápem tvoj point ale chceme naozaj v podstate znemožniť posielať komentáre v prípade, že tento job bude zlyhávať napr. z dôvodu nejakého výpadku externých APIs?

Zaroven skusili sme toto pustit na nejakych realistickych datach? Lebo toto moze zacat schovavat komenty a zacnu nam pisat ludia ze kde su.

Nejaké staré/reálne dáta som až tak neskúšal, toto PR nezasahuje vôbec do historických dát. Skúšal som iba tak pár nejakých vzoriek a dal tú hranicu na 90% a v prípade veľa false-positives môžeme threshold modifikovať. A keď už to tu spomínaš, mali by sme asi spraviť nejakú notifikáciu pre autora komentáru a informovať ho o tom, že sme jeho komentár skryli.

@jsuchal

jsuchal commented Oct 9, 2026

Copy link
Copy Markdown
Member

A keď už to tu spomínaš, mali by sme asi spraviť nejakú notifikáciu pre autora komentáru a informovať ho o tom, že sme jeho komentár skryli.

@BarboraMel ?

No momentálne sa to pošle do triáže.

ok, ak to pristane len tam tak sme asi safe, ale teda o tom ze to je spam/schovane sa triaznici/plantaznici nedozvedia hej?

@xhyrom

xhyrom commented Oct 10, 2026

Copy link
Copy Markdown
Member Author

ok, ak to pristane len tam tak sme asi safe, ale teda o tom ze to je spam/schovane sa triaznici/plantaznici nedozvedia hej?

no ak sa ten job spustí, tak v triáži sa to potom zobrazuje takto:

def triage_activity_body
return "Zmazaný komentár: #{text}" if hidden
text
end

@xhyrom

xhyrom commented Oct 10, 2026 •

Copy link
Copy Markdown
Member Author

tu by sa ešte hodilo porozmýšľať či chceme s moderáciou počkať kým skončí editing window alebo validovať aj pri každej úprave (to by pri zaspamovaní úprav mohol byť trochu problém), mne dáva zmysel asi skôr počkať tých cca. 5min a až potom kontrolovať. cc @jsuchal

@mirrec

mirrec commented Oct 14, 2026

Copy link
Copy Markdown
Collaborator

@xhyrom toto, ked sa bude mergovat, tak podla mna seedy nezbehnu. tak ma potom pingni, a ja mozem dat merge, ked to bude hotove.

@jsuchal

jsuchal commented Oct 14, 2026

Copy link
Copy Markdown
Member

tu by sa ešte hodilo porozmýšľať či chceme s moderáciou počkať kým skončí editing window alebo validovať aj pri každej úprave (to by pri zaspamovaní úprav mohol byť trochu problém), mne dáva zmysel asi skôr počkať tých cca. 5min a až potom kontrolovať. cc @jsuchal

urcite ano.

zaroven by som este zvazil ci ten koment do triaze predsa len neposlat ale ho oznacit na zaciatku nejako.

@BarboraMel tu by sme mali vymysliet ako sa pouzivatel dozvie ze jeho koment bol schovany - toto by malo byt transparentne. cc @mirrec

@xhyrom

xhyrom commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

On ten komentár sa do triáže pošle, ale bude tam body ako "Zmazaný komentár: {body}".

@jsuchal

jsuchal commented Oct 14, 2026

Copy link
Copy Markdown
Member

@xhyrom potom uz len ostava ta cast na portali. napriklad diskusie na sme.sk napisu, ze "komentar bol odstraneny"...

@xhyrom

xhyrom commented Oct 14, 2026

Copy link
Copy Markdown
Member Author

Tak môžeme upraviť, že sa hidden komentáe budú zobrazovať ale teda namiesto reálneho textu tam bude, že bol odstránený. Prípadne chceme to mať ako špeciálnu aktivitu (#70)?

@jsuchal

jsuchal commented Oct 16, 2026

Copy link
Copy Markdown
Member

@xhyrom za mna tak, pokym @BarboraMel nepovie inak. Specialnu aktivitu by som nerobil - je mozne ze tie komenty sem tam "flipneme" aj manualne.

@xhyrom

xhyrom commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

@xhyrom za mna tak, pokym @BarboraMel nepovie inak. Specialnu aktivitu by som nerobil - je mozne ze tie komenty sem tam "flipneme" aj manualne.

Tu ešte je otázne, či chceme ukazovať, že bol komentár odstránený/skrytý pri všetkých typoch komentárov, alebo iba pri user komentároch a pri ostatných ich ani ukazovať nebudeme.

@xhyrom

xhyrom commented Oct 17, 2026

Copy link
Copy Markdown
Member Author

Vizuálne som to zatiaľ spravil takto, ale hodil by sa asi nejaký UXák na to keďže za mňa by to chcelo nejak kompaktnúť ten hidnutý komentár, keďže nemá zmysel, aby sa ukazoval takto celý (možno niečo ako má github?)
image

xhyrom and others added 2 commits October 17, 2026 15:21
@xhyrom xhyrom closed this Oct 17, 2026
@xhyrom xhyrom reopened this Oct 17, 2026

This branch has not been deployed

No deployments
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.

5 participants